Jenkins-构建
一、Java项目构建
1、配置文件结构
配置文件主要有:Jenkinsfile
、deployment.yaml
、Dockerfile
Jenkinsfile
:jenkins的流水线构建文件
deployment.yaml
:k8s的部署文件
Dockerfile
:docker镜像构建文件
2、创建一个流水线任务
名称:mdm-server (该名称同时用于镜像名,注意命令规范)
类型:流水线
- 设置历史构建保留方式
勾选丢弃旧的构建
,在保持构建的天数:30
天(可自定义);保持构建的最在个数:10
个(可自定义)
3、配置流水线
SCM:Git
Repository URL : http://git.spm.wiseda.com.cn:2080/A22011ZK/mdm-parent.git (项目地址)
Credentials :lixw/******** (可直接使用此账号,也可以用自己账号创建gitlab授权信息)
指定分支 :*/master (默认master,可指定其他分支)
脚本路径 :Jenkinsfile (jenkins流水线配置文件,项目根目录)
4、Jenkinsfile 配置
HARBOR_USER:推送镜像到harobr用户(全局配置中定义,直接使用)
HARBOR_AUTH:推送镜像到harobr授权信息(全局配置中定义,直接使用)
gitlab-拉取代码:
credentialsId:18121c1f-0c74-4f08-ae5a-d6968404eba6 (全局配置中定义,直接使用)
git url:http://git.spm.wiseda.com.cn:2080/A22011ZK/mdm-parent.git (实际项目地址)
maven-编译打包: (可以默认配置,或自定义mvn指令)
docker-镜像构建:
configName: k8s-deploy (远程主机,可构建docker镜像,执行kubectl部署到k8s)
基础路径: /root/k8s/jenkins/ (配置在远程主机基础路径)
remoteDirectory: dmm/mdm-server (基于
基础路径
下生成的项目构建地址,以项目名或项目简称,注意不要重名冲突了) sourceFiles: mdm-server/target/*.jar Dockerfile (编译后,需要复制的文件,复制到
remoteDirectory
) ${DOCKER_REGISTRY}: 系统配置自定义环境变量(对应harbor地址:172.16.102.2:5000)
${JOB_BASE_NAME}: jenkins内置属性(当前任务名称,即
mdm-server
) **${BUILD_TIMESTAMP}:**时间戳(默认格式:
yyyyMMdd
) ${BUILD_ID}:构建ID
# 构建镜像:${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:latest (dmm:为harbor的项目编码,请以实际名称为准) docker build -t ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:latest .
rancher-部署K8S:
remoteDirectory: dmm/mdm-server (保持与上面镜像构建目录一致)
**sourceFiles:**deployment.yaml (复制k8s部署文件,复制到
remoteDirectory
) kubectl scale --replicas: (这里通过将副本数设置为0,之后再调整为1来实现重启部署Pod)
# -n dmm-mdm (dmm-mdm为k8s上命名空间) kubectl scale --replicas=0 deployment ${JOB_BASE_NAME} -n dmm-mdm
pipeline {
// 指定任务在哪个集群节点运行(any:任一节点)
agent any
// 声明全局变量,方便后面使用
// sh 'printenv' (输出环境变量)
environment {
HARBOR_USER=credentials('a8b11788-17ba-4693-9f3c-6885bfdf2064')
HARBOR_AUTH=credentials('e2bdfcab-d494-4e90-80c4-9cf5eb2d8f77')
}
stages {
stage('gitlab-拉取代码') {
steps {
git credentialsId: '18121c1f-0c74-4f08-ae5a-d6968404eba6', url: 'http://git.spm.wiseda.com.cn:2080/A22011ZK/mdm-parent.git'
}
}
stage('maven-编译打包') {
// 默认jdk17进行构建,正常情况在maven里指定jdk版本为1.8也能正常构建,如果使用了比较老工具类或接口,取消下面注释,将以jdk1.8版本进行构建
// tools{
//jdk 'jdk1.8'
//}
steps {
sh '/var/jenkins_home/apache-maven-3.8.6/bin/mvn clean package -DskipTests'
}
}
stage('docker-镜像构建') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'k8s-deploy', transfers: [sshTransfer(cleanRemote: true, excludes: '', execCommand: '''
cd /root/k8s/jenkins/dmm/mdm-server
docker build -t ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:latest .
docker tag ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:latest ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:${BUILD_TIMESTAMP}${BUILD_ID}
docker login -u ${HARBOR_USER} -p ${HARBOR_AUTH} ${DOCKER_REGISTRY}
docker push ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:latest
docker push ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:${BUILD_TIMESTAMP}${BUILD_ID}
docker rmi ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:latest
docker rmi ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:${BUILD_TIMESTAMP}${BUILD_ID}
''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'dmm/mdm-server',
remoteDirectorySDF:
false, removePrefix: '', sourceFiles: 'mdm-server/target/*.jar Dockerfile')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
stage('rancher-部署K8S') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'k8s-deploy', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''
cd /root/k8s/jenkins/dmm/mdm-server
kubectl apply -f deployment.yaml
kubectl scale --replicas=0 deployment ${JOB_BASE_NAME} -n dmm-mdm
kubectl scale --replicas=1 deployment ${JOB_BASE_NAME} -n dmm-mdm
''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false,
patternSeparator: '[, ]+', remoteDirectory: 'dmm/mdm-server', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'deployment.yaml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
stage('clean-清理工作空间') {
steps {
cleanWs()
}
}
}
}
5、deployment.yaml配置
deployment.yaml
配置文件参考,相关的属性参照着修改
kind: Service
apiVersion: v1
metadata:
name: mdm-server-service
namespace: dmm-mdm
spec:
selector:
app: mdm-server
ports:
- protocol: TCP
port: 8850
targetPort: 8850
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mdm-server
namespace: dmm-mdm
labels:
app: mdm-server
spec:
replicas: 1
selector:
matchLabels:
app: mdm-server
strategy:
# 先启新pod,再删旧pod maxSurge: 最大增量pod数;maxUnavailable:最大不可用的pod数
rollingUpdate:
maxSurge: 2
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: mdm-server
spec:
imagePullSecrets:
# 用于拉取镜像时的凭证 (保持跟镜像凭证中配置的名称一致)
- name: docker-harbor-dmm
containers:
- name: mdm-server
# ${CICD_IMAGE}:镜像地址;${CICD_EXECUTION_SEQUENCE}:镜像标签(版本)
image: 172.16.102.2:5000/dmm/mdm-server:latest
# 因镜像版本固定,这里设置每次从镜像仓库harbor拉取
imagePullPolicy: Always
ports:
- containerPort: 8850
# 就绪检测(容器启动后10秒开始检查8850端口,每30秒检查一次,检查超时为2秒,默认检查失败次数为3次,3次失败重启pod)
readinessProbe:
initialDelaySeconds: 10
periodSeconds: 120
timeoutSeconds: 5
httpGet:
path: /mdm-server/actuator/health
port: 8850
# 存活检测(容器启动后10秒开始检查8850端口,每60秒检查一次,检查超时为2秒,默认检查失败次数为3次,3次失败重启pod)
livenessProbe:
initialDelaySeconds: 10
periodSeconds: 120
timeoutSeconds: 5
httpGet:
path: /mdm-server/actuator/health
port: 8850
# 资源配额 1C=1000m 请求内存:512M,CPU:500m,限制最大内存:2G,CPU:1000m
resources:
limits:
cpu: 500m
memory: 1Gi
requests:
cpu: 200m
memory: 512Mi
deployment.yaml
文件跟原来配置一致,唯一修改的就是指定了镜像版本xxx:latest
,默认获取最新版本(构建一次latest更新为最新的,在docker tag时生成当时的版本标签,用于指定版本发布)
image: 172.16.102.2:5000/dmm/mdm-server:latest
# 因镜像版本固定,这里设置每次从镜像仓库harbor拉取
imagePullPolicy: Always
正常构建结果,如果出现异常,点击查看日志,确定问题所在。
二、Web项目构建
1、配置文件结构
配置文件主要有:Jenkinsfile
、deployment.yaml
、Dockerfile
、default.conf
Jenkinsfile
:jenkins的流水线构建文件
deployment.yaml
:k8s的部署文件
Dockerfile
:docker镜像构建文件
default.conf
:nginx的配置文件修改
2、创建一个流水线任务
名称:mdm-web (该名称同时用于镜像名,注意命令规范)
类型:流水线
3、配置流水线
SCM:Git
Repository URL : http://git.spm.wiseda.com.cn:2080/A22011ZK/mdm-web.git (项目地址)
Credentials :lixw/******** (可直接使用此账号,也可以用自己账号创建gitlab授权信息)
指定分支 :*/master (默认master,可指定其他分支)
脚本路径 :Jenkinsfile (jenkins流水线配置文件,项目根目录)
4、Jenkinsfile 配置
HARBOR_USER:推送镜像到harobr用户(全局配置中定义,直接使用)
HARBOR_AUTH:推送镜像到harobr授权信息(全局配置中定义,直接使用)
gitlab-拉取代码:
credentialsId:18121c1f-0c74-4f08-ae5a-d6968404eba6 (全局配置中定义,直接使用)
git url:http://git.spm.wiseda.com.cn:2080/A22011ZK/mdm-web.git (实际项目地址)
maven-编译打包: (可以默认配置,或自定义mvn指令)
docker-镜像构建:
configName: k8s-deploy (远程主机,可构建docker镜像,执行kubectl部署到k8s)
基础路径: /root/k8s/jenkins/ (配置在远程主机基础路径)
remoteDirectory: dmm/mdm-web(基于
基础路径
下生成的项目构建地址,以项目名或项目简称,注意不要重名冲突了) sourceFiles: mdm-web/target/*.jar Dockerfile (编译后,需要复制的文件,复制到
remoteDirectory
) ${DOCKER_REGISTRY}: 系统配置自定义环境变量(对应harbor地址:172.16.102.2:5000)
${JOB_BASE_NAME}: jenkins内置属性(当前任务名称,即
mdm-web
) **${BUILD_TIMESTAMP}:**时间戳(默认格式:
yyyyMMdd
) ${BUILD_ID}:构建ID
# 构建镜像:${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:latest (dmm:为harbor的项目编码,请以实际名称为准) docker build -t ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:latest .
rancher-部署K8S:
remoteDirectory: dmm/mdm-web (保持与上面镜像构建目录一致)
**sourceFiles:**deployment.yaml (复制k8s部署文件,复制到
remoteDirectory
) kubectl scale --replicas: (这里通过将副本数设置为0,之后再调整为1来实现重启部署Pod)
# -n dmm-mdm (dmm-mdm为k8s上命名空间) kubectl scale --replicas=0 deployment ${JOB_BASE_NAME} -n dmm-mdm
pipeline {
// 指定任务在哪个集群节点运行(any:任一节点)
agent any
// 声明全局变量,方便后面使用
// sh 'printenv' (输出环境变量)
environment {
HARBOR_USER=credentials('a8b11788-17ba-4693-9f3c-6885bfdf2064')
HARBOR_AUTH=credentials('e2bdfcab-d494-4e90-80c4-9cf5eb2d8f77')
}
stages {
stage('gitlab-拉取代码') {
steps {
git credentialsId: '18121c1f-0c74-4f08-ae5a-d6968404eba6', url: 'http://git.spm.wiseda.com.cn:2080/A22011ZK/mdm-web.git'
}
}
stage('node-编译打包') {
steps {
// node18版本构建,如需要高版本的构建,取消下面注释,并注释node16版本配置
//nodejs(configId: 'd738e50f-e265-443d-9a86-a3f3f9a31d8f', nodeJSInstallationName: 'node18') {
nodejs(configId: 'de6ff097-d46e-403b-81db-bfa0222b0cf9', nodeJSInstallationName: 'node16') {
sh 'npm install && npm run build'
}
}
}
stage('docker-镜像构建') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'k8s-deploy', transfers: [sshTransfer(cleanRemote: true, excludes: '', execCommand: '''
cd /root/k8s/jenkins/dmm/mdm-web
docker build -t ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:latest .
docker tag ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:latest ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:${BUILD_TIMESTAMP}${BUILD_ID}
docker login -u ${HARBOR_USER} -p ${HARBOR_AUTH} ${DOCKER_REGISTRY}
docker push ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:latest
docker push ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:${BUILD_TIMESTAMP}${BUILD_ID}
docker rmi ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:latest
docker rmi ${DOCKER_REGISTRY}/dmm/${JOB_BASE_NAME}:${BUILD_TIMESTAMP}${BUILD_ID}
''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'dmm/mdm-web',
remoteDirectorySDF:
false, removePrefix: '', sourceFiles: 'dist/** Dockerfile default.conf')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
stage('rancher-部署K8S') {
steps {
sshPublisher(publishers: [sshPublisherDesc(configName: 'k8s-deploy', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '''
cd /root/k8s/jenkins/dmm/mdm-web
kubectl apply -f deployment.yaml
kubectl scale --replicas=0 deployment ${JOB_BASE_NAME} -n dmm-mdm
kubectl scale --replicas=1 deployment ${JOB_BASE_NAME} -n dmm-mdm
''', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false,
patternSeparator: '[, ]+', remoteDirectory: 'dmm/mdm-web', remoteDirectorySDF: false, removePrefix: '', sourceFiles: 'deployment.yaml')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
}
}
stage('clean-清理工作空间') {
steps {
cleanWs()
}
}
}
}
5、deployment.yaml配置
deployment.yaml
配置文件参考,相关的属性参照着修改
kind: Service
apiVersion: v1
metadata:
name: mdm-web-service
namespace: mdm-vue
spec:
selector:
app: mdm-web
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mdm-web
namespace: mdm-vue
labels:
app: mdm-web
spec:
replicas: 1
selector:
matchLabels:
app: mdm-web
strategy:
# 先启新pod,再删旧pod (要先删旧pod,再启新pod则设置maxSurge:0 maxUnavailable:1)
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
type: RollingUpdate
template:
metadata:
labels:
app: mdm-web
spec:
imagePullSecrets:
- name: docker-harbor
containers:
- name: mdm-web
image: 172.16.102.2:5000/mdm/mdm-web:latest
# 因镜像版本固定,这里设置每次从镜像仓库harbor拉取
imagePullPolicy: Always
ports:
- containerPort: 80
# 就绪检测(容器启动后5秒开始检查80端口,每30秒检查一次,默认检查超时为2秒,默认检查失败次数为3次,3次失败重启pod)
readinessProbe:
initialDelaySeconds: 5
periodSeconds: 30
tcpSocket:
port: 80
# 存活检测(容器启动后5秒开始检查80端口,每30秒检查一次,默认检查超时为2秒,默认检查失败次数为3次,3次失败重启pod)
livenessProbe:
initialDelaySeconds: 5
periodSeconds: 30
tcpSocket:
port: 80
# 资源配额 1C=1000m 请求内存:64M,CPU:100m,限制最大内存:128M,CPU:200m
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 100m
memory: 64Mi
deployment.yaml
文件跟原来配置一致,唯一修改的就是指定了镜像版本xxx:latest
,默认获取最新版本(构建一次latest更新为最新的,在docker tag时生成当时的版本标签,用于指定版本发布)
image: 172.16.102.2:5000/dmm/dmm-web:latest
# 因镜像版本固定,这里设置每次从镜像仓库harbor拉取
imagePullPolicy: Always
正常构建结果,如果出现异常,点击查看日志,确定问题所在。