jenkins在k8s中的CICD(第二版)
早在二年前,公司项目上线使用aws一系列产品时,记录过一篇 《jenkins在aws eks中的CI/CD及slave》,这篇文章更多详细的记录了非常详细的安装和使用过程;今日,由于公司使用腾讯云,且使用的也是云k8s,本篇文章更多记录CI/CD的一些升级的做法,简单的插件安装等这里就不做介绍。
所以最大的变化是,k8s项目集群的配置文件变更为git管理,jenkinsfile做了小小的改动,其余的变化不大。
1.文件目录
/k8s/config └── h5-infra ├── environments │ ├── dev │ │ └── gcc-mh1 │ │ ├── backend │ │ │ ├── jenkins │ │ │ │ └── gcc-mh1-backend.groovy │ │ │ └── tke │ │ │ ├── default.conf │ │ │ ├── gcc-mh1-backend-configmap.yaml │ │ │ ├── gcc-mh1-backend-deployment.yaml │ │ │ ├── gcc-mh1-backend-ingress.yaml │ │ │ ├── gcc-mh1-backend-service.yaml │ │ │ └── kustomization.yaml │ │ └── frontend │ │ ├── jenkins │ │ │ └── gcc-mh1-frontend.groovy │ │ └── tke │ │ ├── default.conf │ │ ├── gcc-mh1-frontend-deployment.yaml │ │ ├── gcc-mh1-frontend-ingress.yaml │ │ ├── gcc-mh1-frontend-service.yaml │ │ └── kustomization.yaml │ └── prod │ └── gcc-mh1 │ ├── backend │ │ ├── jenkins │ │ │ └── gcc-mh1-backend.groovy │ │ └── tke │ │ ├── default.conf │ │ ├── gcc-mh1-backend-configmap.yaml │ │ ├── gcc-mh1-backend-deployment.yaml │ │ ├── gcc-mh1-backend-ingress.yaml │ │ ├── gcc-mh1-backend-service.yaml │ │ └── kustomization.yaml │ └── frontend │ ├── jenkins │ │ └── gcc-mh1-frontend.groovy │ └── tke │ ├── default.conf │ ├── gcc-mh1-frontend-deployment.yaml │ ├── gcc-mh1-frontend-ingress.yaml │ ├── gcc-mh1-frontend-service.yaml │ └── kustomization.yaml ├── scripts │ ├── create_project.sh │ ├── create_project_web.sh │ └── git_update.sh └── template ├── h5-web-template-dev │ ├── backend │ │ ├── jenkins │ │ │ └── h5-web-template-backend.groovy │ │ └── tke │ │ ├── default.conf │ │ ├── h5-web-template-backend-configmap.yaml │ │ ├── h5-web-template-backend-deployment.yaml │ │ ├── h5-web-template-backend-ingress.yaml │ │ ├── h5-web-template-backend-service.yaml │ │ └── kustomization.yaml │ └── frontend │ ├── jenkins │ │ └── h5-web-template-frontend.groovy │ └── tke │ ├── default.conf │ ├── h5-web-template-frontend-deployment.yaml │ ├── h5-web-template-frontend-ingress.yaml │ ├── h5-web-template-frontend-service.yaml │ └── kustomization.yaml ├── h5-web-template-prod │ ├── backend │ │ ├── jenkins │ │ │ └── h5-web-template-backend.groovy │ │ └── tke │ │ ├── default.conf │ │ ├── h5-web-template-backend-configmap.yaml │ │ ├── h5-web-template-backend-deployment.yaml │ │ ├── h5-web-template-backend-ingress.yaml │ │ ├── h5-web-template-backend-service.yaml │ │ └── kustomization.yaml │ └── frontend │ ├── jenkins │ │ └── h5-web-template-frontend.groovy │ └── tke │ ├── default.conf │ ├── h5-web-template-frontend-deployment.yaml │ ├── h5-web-template-frontend-ingress.yaml │ ├── h5-web-template-frontend-service.yaml │ └── kustomization.yaml ├── h5-web-template-web-dev │ └── frontend │ ├── jenkins │ │ └── h5-web-template-frontend.groovy │ └── tke │ ├── default.conf │ ├── h5-web-template-frontend-deployment.yaml │ ├── h5-web-template-frontend-ingress.yaml │ ├── h5-web-template-frontend-service.yaml │ └── kustomization.yaml └── h5-web-template-web-prod └── frontend ├── jenkins │ └── h5-web-template-frontend.groovy └── tke ├── default.conf ├── h5-web-template-frontend-deployment.yaml ├── h5-web-template-frontend-ingress.yaml ├── h5-web-template-frontend-service.yaml └── kustomization.yaml
可以看到,k8s文件目录主要分为environments、scritps、template,其中:
-
- environments里面存放的文件为项目文件的jenkinsfile以及k8s的deploy文件。
- scripts为k8s的deploy的生成脚本,本篇文章不会讲解。
- template为生成environments里的项目时的固定模板,里面的字符串都是固定的,为了脚本操作时方便。
最主要的当然是environments,另外三个文件夹也是辅助他的存在,项目的重要文件全部在里面。
2.environments讲解
这是整个流程中最重要的目录,所以拿出来单独讲解。
├── environments │ ├── dev │ │ └── gcc-mh1 │ │ ├── backend │ │ │ ├── jenkins │ │ │ │ └── gcc-mh1-backend.groovy │ │ │ └── tke │ │ │ ├── default.conf │ │ │ ├── gcc-mh1-backend-configmap.yaml │ │ │ ├── gcc-mh1-backend-deployment.yaml │ │ │ ├── gcc-mh1-backend-ingress.yaml │ │ │ ├── gcc-mh1-backend-service.yaml │ │ │ └── kustomization.yaml │ │ └── frontend │ │ ├── jenkins │ │ │ └── gcc-mh1-frontend.groovy │ │ └── tke │ │ ├── default.conf │ │ ├── gcc-mh1-frontend-deployment.yaml │ │ ├── gcc-mh1-frontend-ingress.yaml │ │ ├── gcc-mh1-frontend-service.yaml │ │ └── kustomization.yaml │ └── prod │ └── gcc-mh1 │ ├── backend │ │ ├── jenkins │ │ │ └── gcc-mh1-backend.groovy │ │ └── tke │ │ ├── default.conf │ │ ├── gcc-mh1-backend-configmap.yaml │ │ ├── gcc-mh1-backend-deployment.yaml │ │ ├── gcc-mh1-backend-ingress.yaml │ │ ├── gcc-mh1-backend-service.yaml │ │ └── kustomization.yaml │ └── frontend │ ├── jenkins │ │ └── gcc-mh1-frontend.groovy │ └── tke │ ├── default.conf │ ├── gcc-mh1-frontend-deployment.yaml │ ├── gcc-mh1-frontend-ingress.yaml │ ├── gcc-mh1-frontend-service.yaml │ └── kustomization.yaml
可以看出路径为environments/dev/gcc-mh1/backend和frontend,最下面分为jenkins以及tke文件。
其中jenkins中是jenkinsfile文件,tke则是k8s的相关文件。
后面通过脚本的更改,将各文件的内容替换掉。整个jenkins都可以围绕整个文件夹为中心。
3.持续部署持续交付
具体细节这里就不做过多讲解,可以参考本人2年前的博客。
1.创建一个”流水线项目”,首先进入参数化构建过程.
发布与回滚需要用到参数化构建过程中3个选项参数,一个运行时参数.(参数值最好不要用“-”,否则pipeline读取变量时无法识别)
分支参数
Git使用这个的变量来判断拉取哪个分支的代码.
命名空间
用这个控制服务部署在k8s的哪个命名空间下
在之前的项目中,jenkins写在了jenkins的pipeline里,这样不好管理,也比较繁琐,这里,直接将任何项目的jenkinsfile放在了git上
2.流水线语法
这里改动不是很大,所以,这里就不详细解释语法用法,最新版本的jenkinsfile甚至取消了回滚功能,但是本篇文章主要讲解项目文件的规范管理方式,如果有需要增加回滚等功能,在上面拓展即可。
注意:这里frontend以及backend的jenkinsfile也有稍微的改动,但是这里就不做对比了,具体的文件参考本人的项目文件留档。
[root@k8s-lizexiong jenkins]# cat gcc-mh1-frontend.groovy // 公共 def REGISTRY= "denadocker.tencentcloudcr.com" def GIT_ADDRESS = "https://私有git/h5-development/gcc-mh1.git" def GIT_INFRA_ADDRESS = "http://私有git/devops_web/h5-infra.git" def PROJECT_NAME ="gcc" def ACTIVITY_NAME = "mh1" //def CDN_DIR= "${PROJECT_NAME}/(ACTIVITY_NAME.replaceAll('/','-'))" def CDN_DIR= "${PROJECT_NAME}"+ "/" + "${ACTIVITY_NAME}".replaceAll('-','/') def POJECT_TYPE = "frontend" // 项目 def REGISTRY_NAMESPACE = "h5-web" def BRANCH_STR= (branch.replaceAll('/','-')) def IMAGE_NAME= "${REGISTRY}/${REGISTRY_NAMESPACE}/${PROJECT_NAME}-${ACTIVITY_NAME}-${POJECT_TYPE}:${BRANCH_STR}-${BUILD_NUMBER}" def SERVICE_DIR = "h5" def INFRA_DIR = "h5-infra" // 认证 def TCR_AUTH = "973589fa-7ae2-4a08-9002-b139ea04c61c" def GIT_AUTH = "93766ad8-ffee-42f4-ac01-afa590157c3b" def K8S_AUTH = "h5web-k8s-test" //def ENVIRONMENT="" //def branch="" node() { stage('checkout service code') { checkout([$class: 'GitSCM', branches: [[name: "${branch}"]], extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: "${SERVICE_DIR}"],[$class: 'CleanBeforeCheckout']], userRemoteConfigs: [[credentialsId: "${GIT_AUTH}", url: "${GIT_ADDRESS}"]]]) } stage('compile code') { withDockerContainer(image: "node:14") { sh """ echo ${CDN_DIR} cd ${SERVICE_DIR}/frontend npm install && npm run build """ } } stage('build and push image') { withCredentials([usernamePassword(credentialsId: "${TCR_AUTH}", passwordVariable: 'TCR_PASSWORD', usernameVariable: 'TCR_USERNAME')]) { sh """ # login to TCR echo "Login to TCR" echo ${TCR_PASSWORD} | docker login --password-stdin -u ${TCR_USERNAME} https://${REGISTRY} echo "docker build & push" cd ${SERVICE_DIR}/frontend echo ' FROM denadocker.tencentcloudcr.com/h5-web/nginx:1.19.10-logformat-v1 ADD ./dist/*.html /usr/share/nginx/html/ EXPOSE 80 ' > Dockerfile echo "docker build & push" docker build -f ./Dockerfile -t ${IMAGE_NAME} . docker push ${IMAGE_NAME} """ } } stage('upload resources to the CDN'){ sh "ossutil64 cp -rf ${SERVICE_DIR}/frontend/dist/static/ oss://cn-op-web/cdn/h5/${CDN_DIR}/static/" //sh "ossutil64 cp -rf ${SERVICE_DIR}/frontend/dist/static/ oss://cn-op-web/cdn/h5/${PROJECT_NAME}/${ACTIVITY_NAME}/static/" } stage('checkout infra code') { checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: "${INFRA_DIR}"],[$class: 'CleanBeforeCheckout']], userRemoteConfigs: [[credentialsId: "${GIT_AUTH}", url: "${GIT_INFRA_ADDRESS}"]]]) } stage('deploy'){ sh """ echo deploy service cd ./${INFRA_DIR}/environments/${ENVIRONMENT}/${PROJECT_NAME}-${ACTIVITY_NAME}/${POJECT_TYPE}/tke sed -i 's#\$IMAGE_NAME#${IMAGE_NAME}#' ${PROJECT_NAME}-${ACTIVITY_NAME}-${POJECT_TYPE}-deployment.yaml cd - kustomize build --load_restrictor none ./${INFRA_DIR}/environments/${ENVIRONMENT}/${PROJECT_NAME}-${ACTIVITY_NAME}/${POJECT_TYPE}/tke >${PROJECT_NAME}-${ACTIVITY_NAME}-${POJECT_TYPE}.yaml """ kubernetesDeploy configs: "${PROJECT_NAME}-${ACTIVITY_NAME}-${POJECT_TYPE}.yaml", kubeconfigId: "${K8S_AUTH}" } }
可以看出2年前版本的jenkinsfile比较明显的改变就是npm编译直接使用docker容器,而不是本地安装,在最后CD的过程钱使用了kustomize来校对管理k8s的配置文件。
4.总结
整篇文档没有两年前的安装和解释那么详细,但是给人了一种文件规范管理的思路,这样,即使跳板机更改和一些其它情况,配置文件都能规范同步,规范管理。
如果对安装以及版本流程不太清楚的,可以参考本人两年前的jenkins博客:https://www.cnblogs.com/lizexiong/p/14863602.html