基于阿里云容器的 CI/CD 落地实践( 四 )


  • 根目录下的values.yaml是所有环境公共的属性集合 , 比如关于创建serviceAccount , rbac相关的属性信息 , dev/test/stage/production.yaml是与部署环境有关的属性集合 。
  • 执行helm install 命令来部署当前Helm包模版 , 例如
  • ?
helm upgrade index ./helm/ -i -nbss-dev -f ./helm/values.yaml -f ./helm/dev.yaml --set 'image.tag=latest' --set 'image.repo=bss.index' --set 'ingress.hosts.paths={/index}'
  • 前文提到了我们使用声明式Jenkinsfile语法构建部署流水线逻辑 , 与传统groovy不一样的是 , 我们可以通过声明pipeline , agent/node , stages/step等对象 , 直接将部署流程的定义声明 。 以部署基于helm的jar包应用为例 , 部署物为在阿里云私有镜像仓库的镜像文件 , 上文例子所示 。 部署流程包括两个步骤:1. 获取helm代码 2. 执行helm install , 具体如下:
  • ?
def branch_namedef revisiondef registryIp = "registry-vpc.cn-shanghai-finance-1.aliyuncs.com"?pipeline {agent{node{label 'slave-java' // Jenkins Slave Pod Template}}parameters {choice(name: 'App', choices: ['111', '222', '333','444'], description: '选择部署应用')choice(name: 'Env', choices: ['dev', 'stage', 'test',], description: '选择部署环境')string(name: 'Tag', defaultValue: 'latest', description: '请输入将要部署的构建物镜像Tag')}stages {stage ('CheckoutHelm') {steps {script {def repo = checkout scmrevision = sh(script: 'git log -1 --format=\'%h.%ad\' --date=format:%Y%m%d-%H%M | cat', returnStdout: true).trim()branch_name = repo.GIT_BRANCH.take(20).replaceAll('/', '_')if (branch_name != 'master') {revision += "-${branch_name}"}}}}?stage ('Deploy') {steps {container('helm-kubectl') {sh "chmod +x ./helm/setRevision.sh"sh "./helm/setRevision.sh ${revision}"sh "helm upgrade -i ${params.App} ./helm/ -nxxx-${params.Env} -f ./helm/${params.Env}.yaml --set-file appConfig=./appConfig/${params.Env}/${params.App}.yml --set image.tag=${params.Tag} --set image.repo=bss.${params.App} --set ingress.hosts.paths={/${params.App}}"}}}}post {always {echo 'This will always run'}success {echo 'This will run only if successful'}failure {emailext (to: 'XXX@example.com',subject: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",body: """FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':
Check console output at "${env.JOB_NAME} [${env.BUILD_NUMBER}]"
""",recipientProviders: [[$class: 'DevelopersRecipientProvider']])}unstable {echo 'This will run only if the run was marked as unstable'}changed {echo 'This will run only if the state of the Pipeline has changed'echo 'For example, if the Pipeline was previously failing but is now successful'}}}?
【基于阿里云容器的 CI/CD 落地实践】?
经验总结与展望流水线自助化改进
  • 笔者团队面对的业务架构是不断增长的微服务集群 。 基于此 , 对于CICD的自动化要求以及发布频率不断提出了新的挑战 。 原先我们的做法是每个微服务拥有独立的helm部署包 , 但是由于快速增加的微服务数量 , 对于快速注册新服务到现有CICD流水线中 , 产生了开发快速构建部署服务的需求 。
  • 面临的问题主要是helm部署模版是以应用部署所需的资源对象构建为单元 , 在不同部署环境做配置 。 每个应用都会创建一套helm部署包以及的独立的构建和部署任务 。 当越来越多的微服务部署需求不断增加时 , 构建helm包以及相应的构建部署任务的配置工作量就会成为CICD流程的效率瓶颈 。
  • 解决方案是抽象一个公共helm部署包模版 , 将各个应用部署时定制化的属性信息集合从原有helm包结构中再抽象出来 , 以AppConfig File方式独立成一层配置信息 , 例如:
  • ?

基于阿里云容器的 CI/CD 落地实践文章插图
  • 这里的模版抽象实现主要是依赖Helm命令里-f 传入values.yaml 时 , 可以同时-f 多个属性集合文件 , 并且位于后面的-f 的文件可以覆盖前面的属性参数值 。 如果定制化配置信息文件不是Go template可以直接使用的格式 , 可以考虑使用flag --set-file 直接将Config文件里的内容写入某个上层的属性参数 。
安全问题