思路
- maven ant 插件将打包好的jar放置在指定位置
- 每个模块单独的 dockerfile
- 每个模块单独的 jenkinsfile
- 使用 maven 分模块打包能力
- 每个模块单独流水线
- 使用 kubesphere 流水线中正则过滤的方式进行选择性执行
- 提交时附带好需要运行的标识符(可以被相关流水线的正则捕获)
- 使用 webhook 进行触发即可
maven ant 配制
- 将打包好的文件添加到 moquan-server/docker/jars/user 中
xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>deleteJar</id>
<phase>clean</phase>
<configuration>
<target>
<delete includeemptydirs="false" failonerror="false" verbose="true" >
<fileset dir="${basedir}/../../docker/jars/user">
<include name="*.jar" />
</fileset>
</delete>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<execution>
<id>copyJar</id>
<phase>package</phase>
<configuration>
<target>
<mkdir dir="${basedir}/../../docker/jars/user" />
<copy todir="${basedir}/../../docker/jars/user" overwrite="true">
<fileset dir="${project.build.directory}" erroronmissingdir="false">
<include name="*.jar" />
</fileset>
</copy>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
单独 dockerfile
- 构建容器使用, 将 jar 包添加到容器指定位置
sh
FROM openjdk:8-jdk as builder
VOLUME /tmp
RUN mkdir /application/java -p
RUN mkdir /app/logs/ -p
ADD user-service.jar /application/java/user-service.jar
RUN echo "Asia/Shanghai" > /etc/timezone
EXPOSE 8888
ENTRYPOINT ["java","-Xms512m","-Xmx4g","-XX:MaxPermSize=512m" ,"-XX:MaxNewSize=128m","-server","-Djava.security.egd=file:/dev/./urandom","-jar","-Dlogging.file=/app/logs/user.log","/application/java/user-service.jar"]
单独 jenkinsfile
- 使用 kubesphere 进行容器管理
- 代码拉取
- <www.gitLabAddress.com> git仓库地址
- gitToken 登陆信息
- develop 拉取的分支
- 代码打包
- -T 10
- -T : 使用多线程进行执行 maven 命令
- 10 : 10 个线程
- -P test
- -P : 使用 profile 进行多环境打包
- test : 使用 test 环境
- -pl moquan-server/mqs-user-service -am
- -pl : 指定模块进行打包
- moquan-server/mqs-user-service : 模块地址
- moquan-server 父POM的 artifactId
- mqs-user-service 子POM的 artifactId
- 指定那个模块就写到那个POM, 例如: xxx/yyy/zzz/.../aaa
- -am : 关联模块一起进行打包
- -T 10
- 删除构建启动都是 docker 指令
- $BUILD_NUMBER 为流水线顺序号, 所以没有显示赋值
sh
pipeline {
agent {
node {
label 'maven'
}
}
stages {
stage('代码拉取') {
agent none
steps {
container('maven') {
git(url: 'www.gitLabAddress.com', credentialsId: 'gitToken', branch: 'develop', changelog: true, poll: false)
}
}
}
stage('代码打包') {
agent none
steps {
container('maven') {
sh 'mvn -T 10 clean compile package install -P test -pl moquan-server/mqs-user-service -am'
}
}
}
stage('删除容器和镜像') {
agent none
steps {
container('maven') {
sh '(docker stop $USER_NAMESPACE && docker rm $USER_NAMESPACE) || true '
}
}
}
stage('删除旧镜像') {
agent none
steps {
container('maven') {
sh '(docker rmi $(docker images -f "reference=*/devops*:*" -f "reference=*/*/*/devops*:*" --format "{{.Repository}}:{{.Tag}}" -q)) || true'
}
}
}
stage('构建') {
agent none
steps {
container('maven') {
sh 'cd docker/jars/user/ && docker build -t $USER_NAMESPACE/$APP_NAME:$BUILD_NUMBER .'
}
}
}
stage('启动容器') {
agent none
steps {
container('maven') {
sh 'docker run -itd --name=$USER_NAMESPACE --restart=always --network=host -v /usr/share/zoneinfo/Asia/Shanghai:/usr/share/zoneinfo/Etc/UTC -v /usr/bin/vim:/usr/bin/vim -v /usr/bin/netstat:/bin/netstat -v /usr/lib64/libgpm.so.2:/usr/lib64/libgpm.so.2 -v /usr/lib/libgpm.so.2:/usr/lib/libgpm.so.2 $USER_NAMESPACE/$APP_NAME:$BUILD_NUMBER'
}
}
}
}
environment {
USER_NAMESPACE = 'user'
APP_NAME = 'devops-java-sample'
}
parameters {
string(name: 'TAG_NAME', defaultValue: '', description: '')
}
}
maven 多环境配制
- build resources resource
- directory : SpringBoot 项目中 resource 文件夹地址
- includes : 包含那些文件
- filtering
- true : 是否替换 @@ 中的内容
- profiles profile
- id : 环境配制名, 类似于命名空间那种
- properties : 环境中的参数列表
- evn : 这个就是环境中的一个参数, 标签中间的就是这个参数的值
- activation activeByDefault
- true 默认启用
举个栗子
- 使用 local 环境进行打包
- 环境中有个 evn 的参数, 参数值为 dev
- 在 build resources resource 所配制的资源文件中使用 @env@
- 打包完成后 env 会被替换为 dev (build resources resource filtering 需要为 true)
yml
spring:
profiles:
active: @evn@
application:
name: user-server
xml
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>**/*.*</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>product</id>
<properties>
<evn>product</evn>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<evn>test</evn>
</properties>
</profile>
<profile>
<id>local</id>
<properties>
<evn>dev</evn>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
</profiles>