mirror of https://github.com/easzlab/kubeasz.git
195 lines
11 KiB
Markdown
195 lines
11 KiB
Markdown
## 3.1 配置 gitlab-ci.yml
|
||
|
||
示例应用搭建 CI/CD 流水线的背景需求
|
||
|
||
- 应用测试环境部署在本地k8s平台,生产环境部署在阿里云上k8s平台
|
||
- 应用的多个feature分支可以并行测试
|
||
- 对于即将发布的release分支,本地提供封版测试环境,阿里云上提供UAT测试环境
|
||
|
||
以下示例配置为个人经验总结,仅供参考,可以根据自己的理解和项目需要不断优化完善;总体来说 gitlab-ci.yml 配置很丰富,基本上能够满足各种个性化的CI/CD流程需要。
|
||
|
||
``` bash
|
||
$ cat > .ci/gitlab-ci.yml << EOF
|
||
variables: ### 定义全局变量 http://gitlab.test.com/help/ci/variables/README.md
|
||
PROJECT_NS: '$CI_PROJECT_NAMESPACE-$CI_JOB_STAGE' # 定义项目命名空间,对应k8s的namespace
|
||
APP_NAME: '$CI_PROJECT_NAME-$CI_COMMIT_REF_SLUG' # 使用项目名和git提交信息作为应用名
|
||
IMAGE_NAME: '$CI_PROJECT_NAMESPACE-$CI_PROJECT_NAME:$CI_PIPELINE_ID' # 定义镜像名称
|
||
|
||
stages: ### 定义ci各阶段
|
||
- beta-build # beta环境编译打包
|
||
- beta-deploy # beta环境部署
|
||
- beta-feature-delete # beta环境feature分支手动删除
|
||
- prod-build # prod环境编译打包
|
||
- prod-uat-deploy # prod-uat环境部署
|
||
- prod-deploy # prod环境部署
|
||
- prod-rollback # prod回滚
|
||
|
||
job_beta_build:
|
||
stage: beta-build # beta环境编译打包
|
||
tags:
|
||
- build-shell # 定义带`build-shell`标签的runner可以运行该job
|
||
only: # 定义只在如下分支或者tag运行该job
|
||
- master
|
||
- develop
|
||
- /^feature.*$/
|
||
- release
|
||
#when: manual # 调试阶段可以先手动,后续可以注释掉以自动运行
|
||
script: ### runner上运行的脚本
|
||
- bash .ci/config.sh # 不同环境配置替换,后文详解 config.sh
|
||
- mvn clean install -Dmaven.test.skip=true -U # mvn 编译,可以去runner 虚机上手动执行编译测试
|
||
- mv example-web/target/*.jar dockerfiles/ # 把mvn生成的xxx.jar移动到dockerfiles目录下
|
||
- export IMAGE=`echo $IMAGE_NAME | sed 's/\//-/g'` # 转换镜像名,例:mygroup/java/example:172 >> mygroup-java-example:172
|
||
- cd dockerfiles && docker build -t $BETA_HARBOR/example/$IMAGE . # 创建 docker 镜像
|
||
- docker login -u $BETA_HARBOR_USR -p $BETA_HARBOR_PWD $BETA_HARBOR # 登录到内部镜像仓库 harbor,并推送
|
||
- docker push $BETA_HARBOR/example/$IMAGE
|
||
- docker logout $BETA_HARBOR
|
||
|
||
job_push_beta: ### 推送到beta环境,可以推送不同分支 develop, feature-1, ...>
|
||
stage: beta-deploy # 可以做到多分支同时测试,甚至最后的release分支也要在beta封版测试
|
||
tags:
|
||
- beta-shell # 定义带`beta-shell`标签的runner可以运行该job
|
||
only:
|
||
- master
|
||
- develop
|
||
- /^feature.*$/
|
||
- release
|
||
when: manual # 调试阶段可以先手动,后续可以注释掉以自动运行
|
||
variables:
|
||
BETA_EXP_Domain: '$CI_COMMIT_REF_SLUG.example.test.com' # job内部变量,指定该应用在beta环境的 ingress 域名
|
||
script:
|
||
- export IMAGE=`echo $IMAGE_NAME | sed 's/\//-/g'` # 转换 $IMAGE_NAME 中可能的 / 字符
|
||
- export PROJECT_NS=`echo $PROJECT_NS | sed 's/\//-/g'` # 转换命名空间中可能有的 / 字符
|
||
# 替换beta环境的参数配置
|
||
- sed -i "s/PROJECT_NS/$PROJECT_NS/g" .ci/app.yaml ### app.yaml 即k8s的部署模板文件,详见后面 app.yaml.md 文档,注意这里的变量有的来自>
|
||
- sed -i "s/APP_NAME/$APP_NAME/g" .ci/app.yaml # gitlab 系统变量, 有的是在项目 CI/CD 设置里面用户定义的变量
|
||
- sed -i "s/APP_REP/$BETA_APP_REP/g" .ci/app.yaml
|
||
- sed -i "s/AppDomain/$BETA_EXP_Domain/g" .ci/app.yaml
|
||
- sed -i "s/ProjectImage/$BETA_HARBOR\/example\/$IMAGE/g" .ci/app.yaml
|
||
- sed -i "s/DOCKER_KEY/$BETA_KEY/g" .ci/app.yaml # DOCKER_KEY 为k8s平台能从镜像仓库pull所需的认证信息,详见harbor文档
|
||
#
|
||
- mkdir -p /opt/kube/$PROJECT_NS/$APP_NAME # 在runner:beta-shell虚机本地创建应用配置目录,调试检查用
|
||
- cp -f .ci/app.yaml /opt/kube/$PROJECT_NS/$APP_NAME
|
||
- kubectl --kubeconfig=/etc/.beta/config apply -f .ci/app.yaml # 部署应用(runner虚机上预先配置了kubectl权限执行测试k8s平台)
|
||
|
||
job_delete_beta: ### 多测试环境并行部署在beta k8s平台,feature分支测试完毕后删除代码分支,
|
||
stage: beta-feature-delete # 同时需要删除该分支在k8s平台上的部署,可以由开发人员自行执行该job删除
|
||
tags:
|
||
- beta-shell
|
||
only:
|
||
- /^feature.*$/
|
||
when: manual
|
||
script:
|
||
- export PROJECT_NS=`echo $PROJECT_NS | sed 's/\//-/g'`
|
||
- kubectl --kubeconfig=/etc/.beta/config delete deploy,svc,ing $APP_NAME -n $PROJECT_NS
|
||
|
||
job_prod_build: ### prod环境编译打包,这里prod环境我们使用阿里云上的K8S
|
||
stage: prod-build # 阿里云k8s平台上运行的uat环境和正式环境都使用本次打包镜像
|
||
tags:
|
||
- build-shell
|
||
only: # 仅master和release分支可以执行该job
|
||
- master
|
||
- release
|
||
#when: manual
|
||
script:
|
||
- bash .ci/config.sh # config.sh 会执行替换生产环境的变量
|
||
- mvn clean install -Dmaven.test.skip=true -U # mvn 编译,可以去runner 虚机上手动执行编译测试
|
||
- mv example-web/target/*.jar dockerfiles/ # 把mvn生成的xxx.jar移动到dockerfiles目录下
|
||
- export IMAGE=`echo $IMAGE_NAME | sed 's/\//-/g'`
|
||
- cd dockerfiles && docker build -t $PROD_HARBOR/example/$IMAGE .
|
||
- docker login -u $PROD_HARBOR_USR -p $PROD_HARBOR_PWD $PROD_HARBOR
|
||
- docker push $PROD_HARBOR/example/$IMAGE
|
||
- docker logout $PROD_HARBOR
|
||
|
||
job_push_prod_uat: ### 部署至阿里云uat环境
|
||
stage: prod-uat-deploy
|
||
tags:
|
||
- prod-shell
|
||
when: manual
|
||
only: # 仅master和release分支可以执行该job
|
||
- master
|
||
- release
|
||
variables:
|
||
PROD_EXP_Domain: 'example-uat.xxxx.com' # job内部变量,指定该应用在uat环境的 ingress 域名
|
||
script:
|
||
- export IMAGE=`echo $IMAGE_NAME | sed 's/\//-/g'`
|
||
- export PROJECT_NS=`echo $PROJECT_NS | sed 's/\//-/g'`
|
||
# 替换prod环境的参数配置
|
||
- sed -i "s/PROJECT_NS/$PROJECT_NS/g" .ci/app.yaml
|
||
- sed -i "s/APP_NAME/$CI_PROJECT_NAME/g" .ci/app.yaml
|
||
- sed -i "s/APP_REP/1/g" .ci/app.yaml
|
||
- sed -i "s/AppDomain/$PROD_EXP_Domain/g" .ci/app.yaml
|
||
- sed -i "s/ProjectImage/$PROD_HARBOR\/example\/$IMAGE/g" .ci/app.yaml
|
||
- sed -i "s/DOCKER_KEY/$PROD_KEY/g" .ci/app.yaml
|
||
#
|
||
- mkdir -p /opt/kube/$PROJECT_NS/$APP_NAME
|
||
- cp -f .ci/app.yaml /opt/kube/$PROJECT_NS/$APP_NAME
|
||
- kubectl --kubeconfig=/etc/.aliyun/config apply -f .ci/app.yaml
|
||
|
||
job_push_prod_release: ### 部署至阿里云正式环境
|
||
stage: prod-deploy
|
||
tags:
|
||
- prod-shell
|
||
when: manual
|
||
only: # 仅master和release分支可以执行该job
|
||
- master
|
||
- release
|
||
variables:
|
||
PROD_EXP_Domain: 'example.xxxx.com' # 指定该应用在阿里云正式环境的 ingress 域名
|
||
script:
|
||
- export IMAGE=`echo $IMAGE_NAME | sed 's/\//-/g'`
|
||
- export PROJECT_NS=`echo $PROJECT_NS | sed 's/\//-/g'`
|
||
# 替换prod环境的参数配置
|
||
- sed -i "s/PROJECT_NS/$PROJECT_NS/g" .ci/app.yaml
|
||
- sed -i "s/APP_NAME/$CI_PROJECT_NAME/g" .ci/app.yaml
|
||
- sed -i "s/APP_REP/$PROD_APP_REP/g" .ci/app.yaml
|
||
- sed -i "s/AppDomain/$PROD_EXP_HOST/g" .ci/app.yaml
|
||
- sed -i "s/ProjectImage/$PROD_HARBOR\/example\/$IMAGE/g" .ci/app.yaml
|
||
- sed -i "s/DOCKER_KEY/$PROD_KEY/g" .ci/app.yaml
|
||
#
|
||
- mkdir -p /opt/kube/$PROJECT_NS/$APP_NAME
|
||
- cp -f .ci/app.yaml /opt/kube/$PROJECT_NS/$APP_NAME
|
||
- kubectl --kubeconfig=/etc/.aliyun/config apply -f .ci/app.yaml
|
||
|
||
1/3 rollback: ### 定义生产环境回退job
|
||
stage: prod-rollback
|
||
tags:
|
||
- prod-shell
|
||
when: manual
|
||
only:
|
||
- master
|
||
- /^release.*$/
|
||
variables:
|
||
PROJECT_NS: '$CI_PROJECT_NAMESPACE-prod-deploy' # 定义job内变量覆盖全局变量设置
|
||
script:
|
||
- kubectl --kubeconfig=/etc/.aliyun/config -n $PROJECT_NS rollout undo deployment $CI_PROJECT_NAME --to-revision=1
|
||
|
||
2/3 rollback:
|
||
stage: prod-rollback
|
||
tags:
|
||
- prod-shell
|
||
when: manual
|
||
only:
|
||
- master
|
||
- /^release.*$/
|
||
variables:
|
||
PROJECT_NS: '$CI_PROJECT_NAMESPACE-prod-deploy' # 定义job内变量覆盖全局变量设置
|
||
script:
|
||
- kubectl --kubeconfig=/etc/.aliyun/config -n $PROJECT_NS rollout undo deployment $CI_PROJECT_NAME --to-revision=2
|
||
|
||
3/3 rollback:
|
||
stage: prod-rollback
|
||
tags:
|
||
- prod-shell
|
||
when: manual
|
||
only:
|
||
- master
|
||
- /^release.*$/
|
||
variables:
|
||
PROJECT_NS: '$CI_PROJECT_NAMESPACE-prod-deploy' # 定义job内变量覆盖全局变量设置
|
||
script:
|
||
- kubectl --kubeconfig=/etc/.aliyun/config -n $PROJECT_NS rollout undo deployment $CI_PROJECT_NAME --to-revision=3
|
||
EOF
|
||
```
|
||
|
||
恭喜终于看完 gitlab-ci.yml 文件,怎么样,是不是一千个人可以写出一万个 CI/CD 流程 :)
|