Kubernetes持续集成
基本流程还是根据之前的博客,思路基本一样,补充下不同的地方,可以参考下我之前的博文 https://www.cnblogs.com/shiji888/p/12512136.html
说下主要的区别,之前我在使用docker-compose更新的时候,镜像的标签不管是哪个分支都使用的标签是latest,这样在compose up升级的时候,每次都会去拉最新的镜像。
但是deployment不行,deployment管里的pod没有消亡时,不会去拉取相同标签的镜像,即使镜像更新过(这里尝试过拉取策略改为Always也无法更新pod镜像),当然,你可以每次delete pod之后,在create pod,如果你愿意这么做的话。
如果不想采取每次删除在创建的方式,那么每次就需要更新deployment拉取的镜像标签了,这边我采用了在jenkinsfile里获取发布序列号来当docker image的tag。
1,jenkinsfile了,同样三分支,master,pre,dev,除了mater之外,其余分支均使用自动部署。
pipeline { agent any parameters { string(name:'BRANCH_FOR_BODY',defaultValue:"${BRANCH_NAME}",description:'parameters used by ding talk') #字符参数,jenkins工程名称,推送脚本使用 string(name:'BUILD_URL_FOR_BODY',defaultValue:"${BUILD_URL}",description:'build uri for body') #字符参数,jenkins工程url,推送脚本使用 string(name:'DOCKER_IMAGE_TAG',defaultValue:"${BUILD_NUMBER}",description:'docker image tag') #字符参数,jenkins工程构建号,作为images标签 } triggers{ #gitlab触发器配置,这里的触发器可以设置排除分支,如果不希望主分支自动部署,可以直接在这里排除master分支,当然思路不一样,jenkinfile步骤也不一样了 gitlab( triggerOnPush: true, triggerOnMergeRequest: true, branchFilterType: "NameBasedFilter", includeBranchesSpec: "master,dev,pre", secretToken: "028d848ab64f" ) } stages { stage('Deploy-master') { #主分支构建步骤 when { branch 'master' } steps { sh ''' docker build -t ${DOCKER_IMAGE_NAME}-master:${BUILD_NUMBER} -f Dockerfile . #构建docker image ''' sh 'docker login -u xxxxxx@qq.com -p xxxxxxx registry.cn-hangzhou.aliyuncs.com' #登录阿里云私仓库 sh 'docker push ${DOCKER_IMAGE_NAME}-master:${BUILD_NUMBER}' #推送镜像 sh 'docker rmi ${DOCKER_IMAGE_NAME}-master:${BUILD_NUMBER}' #删除本地镜像,这里注意如果在之前的步骤就已经报错,那么本地的打好镜像镜像就不会被删除掉,需要大家自己做好定时删除的任务 } post { success { sh 'sh notice.sh "${DOCKER_SERVICE_NAME}生产环境镜像推送成功通知" "${DOCKER_SERVICE_NAME}" "推送镜像成功" ${BRANCH_NAME} ${BUILD_URL}' } failure{ sh 'sh notice.sh "${DOCKER_SERVICE_NAME}生产环境镜像推送失败通知" "${DOCKER_SERVICE_NAME}" "推送镜像失败" ${BRANCH_NAME} ${BUILD_URL}' } } } stage('Deploy-pre') { #预发分支构建步骤 when { branch 'pre' } steps { sh ''' docker build -t ${DOCKER_IMAGE_NAME}-pre:${BUILD_NUMBER} -f Dockerfile . ''' sh 'docker login -u xxxxxxxxx@qq.com -p xxxxxxx registry.cn-hangzhou.aliyuncs.com' sh 'docker push ${DOCKER_IMAGE_NAME}-pre:${BUILD_NUMBER}' sh 'docker rmi ${DOCKER_IMAGE_NAME}-pre:${BUILD_NUMBER}' sh 'curl ${DOCKER_DEPLOY_URI}/pre?service=${DOCKER_SERVICE_NAME}&tag=${BUILD_NUMBER}' #推送成功后请求发布程序接口,自动部署 } post { success { sh 'sh notice.sh "${DOCKER_SERVICE_NAME}预发环境镜像部署成功通知" "${DOCKER_SERVICE_NAME}" "成功" ${BRANCH_NAME} ${BUILD_URL}' } failure{ sh 'sh notice.sh "${DOCKER_SERVICE_NAME}预发环境镜像部署失败通知" "${DOCKER_SERVICE_NAME}" "失败" ${BRANCH_NAME} ${BUILD_URL}' } } } stage('Deploy-dev') { #测试分支构建步骤 when { branch 'dev' } steps { sh ''' docker build -t ${DOCKER_IMAGE_NAME}-dev:${BUILD_NUMBER} -f Dockerfile . ''' sh 'docker login -u xxxxxxxx@qq.com -p xxxxxxxxx registry.cn-hangzhou.aliyuncs.com' sh 'docker push ${DOCKER_IMAGE_NAME}-dev:${BUILD_NUMBER}' sh 'docker rmi ${DOCKER_IMAGE_NAME}-dev:${BUILD_NUMBER}' sh 'curl ${DOCKER_DEPLOY_URI}/dev?service=${DOCKER_SERVICE_NAME}&tag=${BUILD_NUMBER}' } post { success { sh 'sh notice.sh "${DOCKER_SERVICE_NAME}测试环境镜像部署成功通知" "${DOCKER_SERVICE_NAME}" "成功" ${BRANCH_NAME} ${BUILD_URL}' } failure{ sh 'sh notice.sh "${DOCKER_SERVICE_NAME}测试环境镜像部署失败通知" "${DOCKER_SERVICE_NAME}" "失败" ${BRANCH_NAME} ${BUILD_URL}' } } } } environment { DOCKER_DEPLOY_URI = 'http://dockerup.test.shiji.com' #发布程序地址 DOCKER_IMAGE_NAME = 'registry.cn-hangzhou.aliyuncs.com/banshiji/k8stest' #私仓地址,带上服务名称 DOCKER_SERVICE_NAME = 'k8s-test' #服务名称 }
}
2,我们去阿里云私仓创建仓库 ,当然仓库,不存在也是能推进去的,这里为了方便记录流程,还是去创建了,注意阿里云免费docker私人仓库命名空间只能创建三个。
3,我们先去掉请求接口的步骤来推送三条流水线来推送镜像,jenkins,gilab等配置参考之前的博文
4,关于发布程序的接口
接口用python写的,放在master节点上,在dev和pre最后步骤请求接口,只需要传入服务名称和镜像标签执行下面的发布脚本即可,后面在补上吧
关于master分支的发布接口是对接到发布平台上需要发布人员手工确认的,这部分内容就不再这边放出了
5,发布脚本
#!/bin/bash TAG="$2" if [ ! -n "$2" ] ;then echo "you have not input tag!" exit fi # k8s-test if [ $1 == "k8stest-master" ] then cd /data/docker-service/k8stest-master sed -i "s#registry.cn-hangzhou.aliyuncs.com/banshiji/k8stest-master:.*#registry.cn-hangzhou.aliyuncs.com/banshiji/k8stest-master:$2#g" deployment-service.yaml kubectl apply -f deployment-service.yaml echo "success" elif [ $1 == "k8stest-pre" ] then cd /data/docker-service/k8stest-pre sed -i "s#registry.cn-hangzhou.aliyuncs.com/banshiji/k8stest-master:.*#registry.cn-hangzhou.aliyuncs.com/banshiji/k8stest-pre:$2#g" deployment-service.yaml kubectl apply -f deployment-service.yaml echo "success" elif [ $1 == "k8stest-dev" ] then cd /data/docker-service/k8stest-dev sed -i "s#registry.cn-hangzhou.aliyuncs.com/banshiji/k8stest-master:.*#registry.cn-hangzhou.aliyuncs.com/banshiji/k8stest-dev:$2#g" deployment-service.yaml kubectl apply -f deployment-service.yaml echo "success" else echo "no equal service" fi ~
6,deplyment,service文件
apiVersion: v1 kind: Service metadata: name: tianpeng namespace: default spec: selector: app: tianpeng ports: - name: http targetPort: 80 port: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: tianpeng-front-pod namespace: default spec: replicas: 1 selector: matchLabels: app: tianpeng template: metadata: labels: app: tianpeng spec: containers: - name: tianpeng image: registry.cn-hangzhou.aliyuncs.com/banshiji/k8stest-master:1 imagePullPolicy: Always ports: - name: http containerPort: 80 imagePullSecrets: - name: ali-regsecret
7,ingress文件
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-tianpeng namespace: default annotations: kubernetes.io/ingress.class: "nginx" spec: rules: - host: tianpeng.banshiji.com http: paths: - path: backend: serviceName: tianpeng servicePort: 80