此篇可作为开发人员部署环境, 请先查看CICD流程篇章

前提环境:

kubernetes

Jenkins

Gitlab

Harbor

必须有Master与Slave分布式 环境

涉及参考文档:

  • Pipeline 获取构建项目的用户 Pipeline 语法1
  • Jenkinsfile 获取构建项目的用户 Pipeline 语法2
  • 钉钉机器人插件 语法介绍

插件文档介绍:

  • build user vars 插件介绍
  • DingTalk 插件介绍

接着上篇文章操作 Kubernetes CICD发布架构流程思路

一、配置Job构建参数

1、web 界面手动设置构建参数

kubesphere密码规则_maven

kubesphere密码规则_git_02

2、书写Pipeline 构建语法

pipeline {
	environment{
	    Giturl =  'http://192.168.11.178/root/aliyun.git'  //gitlab仓库
		BRANCH =  sh(returnStdout: true,script: 'echo $branch').trim()  //设置分支变量
		Project_Namespace = 'jenkins' //设置名称空间名称
		Project_Nmae = 'maven-test'	 //设置应用的Pod名称
		version =  sh(returnStdout: true,script: 'date +%Y%W%d%H%M').trim()  //设置当前时间为镜像版本标记
	}	
    agent{
        node{
          label 'jnlp-slave'
        }
      }
    stages {
		stage('Git拉取代码') {
            steps {                
				git branch: '${BRANCH}', credentialsId: '', url: "$Giturl"  //可以选定构建的分支
            }
        }
        stage('编译') {
            steps {
				timeout(5)   //超时5分钟中断任务
				{
				script {
					container('maven') { 
						// 打包构建出来的是jar包或者war包
						echo "[BUILD INFO] 文件编译中,请耐心等待......"
						if(params.jar_war == 'jar') { 
							sh """
								echo "开始编译 jar 包......"
								mvn clean package -X -P production -e -U
								"""
						} else{ 
							sh """
								echo "开始编译 war 包......"
								mvn -e clean package -U -Dmaven.test.skip=true -P production
								""" 
							}
						}
					}
				}
			}
		}
		stage('镜像打包上传镜像仓库'){
          steps{
			  timeout(3)   //超时3分钟中断任务
			  {	container("kaniko") {
                  sh """
						kaniko -f `pwd`/Dockerfile -c `pwd`  --skip-tls-verify=true --destination=192.168.11.130:4430/$Project_Namespace/$Project_Nmae:$version
					"""
					}
				}
			}
		}
		stage('发布到k8s集群'){
          steps{
              container("kubectl") {
                  withKubeConfig(caCertificate: '',  //如果serverUrl提供了,则用于验证API服务器证书的群集证书颁发机构。如果未提供参数,则跳过验证。
								clusterName: '', 	//修改当前上下文的集群。cluster如果serverUrl提供了a ,也用于生成的块。
								contextName: '', 	//将当前上下文切换到该名称。上下文必须已经存在于KubeConfig文件中。
								credentialsId: 'admin-sa',	//普通KubeConfig文件的Jenkins ID。(webp配置admin的serviceaccount)
								namespace: '',	//	修改当前上下文的命名空间
								serverUrl: 'https://kubernetes.default.svc.cluster.local'  //API服务器的网址。这将创建一个新cluster块并修改当前上下文以使用它。
								)
							{ 
								sh """
									sed -i 's/\$Project_Namespace/$Project_Namespace/g'   `pwd`/deployment.yaml  #替换名称空间
									sed  -i 's/\$Project_Nmae/$Project_Nmae/g' 	  `pwd`/deployment.yaml	 # 替换项目名称
									sed  -i 's/\$version/$version/g' `pwd`/deployment.yaml  #替换镜像版本号——时间代替版本号
									kubectl apply -f `pwd`/deployment.yaml 
									kubectl wait --for=condition=Ready pod -l app=jenkins-java-demo --timeout=60s -n jenkins
								 """
						}
					}
				}
			}
    }
}

二、新建分支并提交代码

1、创建并切换分支

git checkout -b newmaven

kubesphere密码规则_maven_03

2、修改 deployment.yaml文件

kubesphere密码规则_kubesphere密码规则_04

vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: $Project_Nmae
  namespace: $Project_Namespace
spec:
  replicas: 2
  selector:
    matchLabels:
      app: $Project_Nmae
  template:
    metadata:
      labels:
        app: $Project_Nmae
    spec:
      containers:
      - name: $Project_Nmae
        image: 192.168.11.130:4430/$Project_Namespace/$Project_Nmae:$version
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: $Project_Nmae
  namespace: $Project_Namespace
spec:
  ports:
  - name: $Project_Nmae
    port: 8080
    targetPort: 8080
    nodePort: 30082
  selector:
    app: $Project_Nmae
  type: NodePort

3、对本次操作打标签并且提交代码

git add  -A &&  git commit  -m "v1"

kubesphere密码规则_kubesphere密码规则_05

git  push  origin newmaven

kubesphere密码规则_git_06

三、项目构建测试

1、构建新建 newmaven 分支(后期优化自动获取git分支)

kubesphere密码规则_kubesphere密码规则_07

点击构建测试

kubesphere密码规则_maven_08

kubesphere密码规则_Jenkins_09

2、查看服务是否重启更新

kubectl  get po -n jenkins -w

kubesphere密码规则_git_10

3、日志发现时间正确

kubesphere密码规则_maven_11

原因分析:

  • 搭建Jenkins 我已经将Jenkins与宿主机的时间文件挂载,同时这是一个新的Pod允许那问题就是宿主机(node节点),时间服务不正常。(问题排除)
  • kubesphere密码规则_maven_12

  • kubesphere密码规则_git_13

  • Jenkins 容器时间正常。
  • 接下来就是确定是否新起来容器时间有问题,简单只需要重新起一个新的Pod即可查看,Jenkins web界面再次构建测试。
  • kubesphere密码规则_Jenkins_14

  • kubesphere密码规则_maven_15

  • 问题已排除到。 进行修复即可。

4、Slave Pod 挂载时间文件(/etc/localtime)

kubesphere密码规则_kubesphere密码规则_16

kubesphere密码规则_Jenkins_17

kubesphere密码规则_kubesphere密码规则_18

5、再次构建Job

kubesphere密码规则_git_19

这时候可登录黑屏操作新的 jnlp-slave容器 的时间

kubesphere密码规则_maven_20

kubesphere密码规则_Jenkins_21

四、钉钉构建通知

安装插件:

  • DingTalk
  • kubesphere密码规则_git_22

  • build user vars

1、系统配置 钉钉 ID

kubesphere密码规则_git_23

kubesphere密码规则_git_24

kubesphere密码规则_maven_25

kubesphere密码规则_maven_26

2、书写Pipeline 构建语法

pipeline {
	environment{
	    Giturl =  'http://192.168.11.178/root/aliyun.git'
		BRANCH =  sh(returnStdout: true,script: 'echo $branch').trim()
		Project_Namespace = 'jenkins'
		Project_Nmae = 'maven-test'	
		version =  sh(returnStdout: true,script: 'date +%Y%W%d%H%M').trim()
		NowTimes =  sh(returnStdout: true,script: 'date +%F" "%T').trim()
		BUILD_USER = ""
	}	
    agent{
        node{
          label 'jnlp-slave'
        }
      }
    stages {
		stage('Git拉取代码') {
            steps {                
				git branch: '${BRANCH}', credentialsId: '', url: "$Giturl"
            }
        }
        stage('编译') {
            steps {
				timeout(5)
				{
				script {
					container('maven') { 
						// 打包构建出来的是jar包或者war包
						echo "[BUILD INFO] 文件编译中,请耐心等待......"
						if(params.jar_war == 'jar') { 
							sh """
								echo "开始编译 jar 包......"
								mvn clean package -X -P production -e -U
								"""
						} else{ 
							sh """
								echo "开始编译 war 包......"
								mvn -e clean package -U -Dmaven.test.skip=true -P production
								""" 
						}
					}
                }
            }
        }
		}
		stage('镜像打包上传镜像仓库'){
          steps{
			  timeout(3)  
			  {	container("kaniko") {
                  sh """
						kaniko -f `pwd`/Dockerfile -c `pwd`  --skip-tls-verify=true --destination=192.168.11.130:4430/$Project_Namespace/$Project_Nmae:$version
					"""
					}
				}
			}
		}
		stage('发布到k8s集群'){
          steps{
              container("kubectl") {
                  withKubeConfig(caCertificate: '',  //如果serverUrl提供了,则用于验证API服务器证书的群集证书颁发机构。如果未提供参数,则跳过验证。
								clusterName: '', 	//修改当前上下文的集群。cluster如果serverUrl提供了a ,也用于生成的块。
								contextName: '', 	//将当前上下文切换到该名称。上下文必须已经存在于KubeConfig文件中。
								credentialsId: 'admin-sa',	//普通KubeConfig文件的Jenkins ID。(webp配置admin的serviceaccount)
								namespace: '',	//	修改当前上下文的命名空间
								serverUrl: 'https://kubernetes.default.svc.cluster.local'  //API服务器的网址。这将创建一个新cluster块并修改当前上下文以使用它。
								)
							{ 
								sh """
									sed -i 's/\$Project_Namespace/$Project_Namespace/g'   `pwd`/deployment.yaml  #替换名称空间
									sed  -i 's/\$Project_Nmae/$Project_Nmae/g' 	  `pwd`/deployment.yaml	 # 替换项目名称
									sed  -i 's/\$version/$version/g' `pwd`/deployment.yaml  #替换镜像版本号——时间代替版本号
									kubectl apply -f `pwd`/deployment.yaml 
									kubectl wait --for=condition=Ready pod -l app=jenkins-java-demo --timeout=60s -n jenkins
								 """
						}
					}
				}
			}
    }
	post {
		success {
				wrap([$class: 'BuildUser']) {
                   script {
                       BUILD_USER_ID = "${env.BUILD_USER_ID}"
                       BUILD_USER = "${env.BUILD_USER}"
                       BUILD_USER_EMAIL = "${env.BUILD_USER_EMAIL}"
                   }
				   dingtalk (
                        robot: 'dingding',
                        type: 'MARKDOWN', 
                        title: '恭喜 $JOB_BASE_NAME Job部署成功',
                        text: [
								'# [$Project_Nmae 应用部署成功](${env.JOB_URL})', 
								'',
								'---',
								'',
								'# [=====================](${env.JOB_URL}) ',
								'<font color=red>项目状态</font>: [部署成功](${env.JOB_URL}) 🤩',
								'# [ ]()',
								'部署时间: ${NowTimes}',
								'# [ ]()',
								'构建镜像:  192.168.11.130:4430/$Project_Namespace/$Project_Nmae:$version',
								'# [                                      ]()',
								'持续时间: 待定',  
								'# [ ]()',
								'执行人:  [${BUILD_USER}](${env.JOB_URL})',
								'',
								'# [=====================](${env.JOB_URL}) ',
								'',
								'---',
								'',			
								'![成功](https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3047085180,1986287365&fm=26&gp=0.jpg)'		
                        ],
						atAll: true,
						)
					}
				}
		failure {
			wrap([$class: 'BuildUser']) {
				script {
					BUILD_USER = "${env.BUILD_USER}"
					}
				dingtalk (
                        robot: 'dingding',
                        type: 'ACTION_CARD',
                        title: '$JOB_BASE_NAME Job 部署失败 😈',
                        text: [
								'# [$Project_Nmae 应用部署失败](${env.JOB_URL})', 
								'',
								'---',
								'',
								'<font color=red>项目状态</font>: 部署失败 😈',
								'# [ ]()',
								'部署时间: ${NowTimes}',
								'# [ ]()',
								'构建镜像:  192.168.11.130:4430/$Project_Namespace/$Project_Nmae:$version',
								'# [ ]()',
								'持续时间: 待定',  
								'# [ ]()',
								'执行人:  ${BUILD_USER}',
								'',
								'---',
								'',
								'![](https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1228642624,727395396&fm=26&gp=0.jpg)'								
                        ],
						btns: [
							[
								title: '部署失败😈',
								actionUrl: ''
							  ],
							[
								title: '跳转$JOB_BASE_NAME Job',
								actionUrl: '${BUILD_URL}'
							]
						 ],
						atAll: true,
					)
			}
		}
	}	
}

2、 再次构建测试

实验成功 都再次跑在 CICD 测试这个Job,看到不同的Job没事,代码是相同的。

kubesphere密码规则_git_27

kubesphere密码规则_kubesphere密码规则_28

3、查看钉钉消息

kubesphere密码规则_maven_29

服务也发布成功

kubesphere密码规则_kubesphere密码规则_30

访问服务

kubesphere密码规则_maven_31