Matrix GitOps 篇三:项目CI升级
升级前遇到的问题
- 部署文件很乱,不知道每个应用的部署文件位置。
- 部署来源和部署时间不清楚
- 难以可视化当前应用的部署
使用的工具
我们采用argo cd来解决上面这些问题,argo cd部署见篇一。
升级对象
主要将matrix应用的CI脚本旧部署流程升级为argo cd新部署流程。
详见infrastructure仓库issue 51
其中一部分应用采用Helm部署,另一部分(scheduler和git-service)直接写plain yaml部署。
升级采用Helm部署的应用
以course-fe为例
升级前
原来course-fe仓库 -> .gitlab-ci.yml -> deploy-test的代码如下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| deploy-test: stage: deploy image: harbor.matrix.moe/library/helm-kubectl tags: ["kubernetes"] variables: DEPLOY_DOMAIN: staging.matrix.moe only: - test before_script: - echo "Deploy to staging.matrix.moe" script: - sh k8s/deploy.sh environment: name: staging url: https://staging.matrix.moe kubernetes: namespace: course-fe
|
k8s/deploy.sh如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| set -xe kubectl config set-cluster "$CI_PROJECT_NAME" --server="$KUBE_URL" --certificate-authority="$KUBE_CA_PEM_FILE" kubectl config set-credentials "$CI_PROJECT_NAME" --token="$KUBE_TOKEN" kubectl config set-context "$CI_PROJECT_NAME" --namespace="$KUBE_NAMESPACE" --cluster="$CI_PROJECT_NAME" --user="$CI_PROJECT_NAME" kubectl config use-context "$CI_PROJECT_NAME" kubectl create namespace "$KUBE_NAMESPACE" --save-config --dry-run -o yaml | kubectl apply -f - kubectl create secret docker-registry harbor-registry --docker-server=$HARBOR_REGISTRY --docker-username=$HARBOR_DEPLOY_USER --docker-password=$HARBOR_DEPLOY_PASSWORD --docker-email=$DEPLOY_EMAIL --save-config --dry-run -o yaml | kubectl apply -f - helm registry login -u $HARBOR_REGISTRY_USER --password $HARBOR_REGISTRY_PASSWORD $HARBOR_REGISTRY helm chart pull $DEPLOY_CHART_URL helm chart export $DEPLOY_CHART_URL
if [ $CI_COMMIT_REF_SLUG = "master" ] || [ $CI_COMMIT_REF_SLUG = "prerelease" ]; then CUSTOM_INGRESS=true kubectl apply -f k8s/ingress.abtest.yaml fi
helm upgrade --install $DEPLOY_NAME -n $KUBE_NAMESPACE \ --kube-context $CI_PROJECT_NAME \ --set image.repository=${DOCKER_IMAGE_REPOSITORY} \ --set image.tag=${DOCKER_IMAGE_TAG} \ --set ingress[0].host=${DEPLOY_DOMAIN} \ --set customIngress=$CUSTOM_INGRESS \ --set annotations."app\.gitlab\.com/app"=${CI_PROJECT_PATH_SLUG} \ --set annotations."app\.gitlab\.com/env"=${CI_ENVIRONMENT_SLUG} \ --set ingressAnnotations."traefik\.ingress\.kubernetes\.io/router\.tls"=true \ --set imagePullSecret="harbor-registry" \ $DEPLOY_CHART_NAME
|
原来的部署流程:
- 使用kubectl初始化namespace,设定部署集群
- 拉取helm chart
- 部署abtest (test分支不执行此步骤)
- 设定helm value更新应用。
升级后
course-fe仓库 -> .gitlab-ci.yml -> deploy-test的代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| deploy-test: stage: deploy image: harbor.matrix.moe/devops-tools/matrix/gitops-helper:0.1.0 tags: ["kubernetes"] only: - test before_script: - echo "Deploy to staging.matrix.moe" script: | git clone "https://${GITOPS_GIT_USERNAME}:${GITOPS_GIT_PASSWORD}@gitlab.matrix.moe/Matrix/infra/apps.git" _argo && cd _argo yq e 'del (.spec.source.helm.parameters.[] | select (.name == "image.repository")) | del (.spec.source.helm.parameters.[] | select (.name == "image.tag")) | .spec.source.helm.parameters = .spec.source.helm.parameters + [{"name": "image.repository", "value": env(DOCKER_IMAGE_REPOSITORY)}, {"name": "image.tag", "value": env(DOCKER_IMAGE_TAG)}]' -i matrix/course-fe/app.yaml git add matrix/course-fe/app.yaml git config user.email "ops@matrix.moe" && git config user.name "Matrix Ops Bot" git commit -m "update: course-fe -> ${DOCKER_IMAGE_TAG}" && git push environment: name: staging url: https://staging.matrix.moe kubernetes: namespace: course-fe
|
升级后的部署流程:
- 拉取gitops-helper镜像启动容器(这个容器里包含了一些隐私信息,比如bot的密码)
- 修改
matrix/course-fe/app.yaml部署文件,比如修改image tag。
- commit更新到git,argo cd自动将新的配置文件应用到集群
升级采用plain yaml部署的应用
以scheduler为例
因为上面讲过了两种部署流程的区别,所以这里直接贴代码
升级前
旧部署代码:
.gitlab-ci.yml -> deploy-test
1 2 3 4 5 6 7 8 9 10 11
| deploy-test: stage: deploy image: dtzar/helm-kubectl only: - test script: - ./deploy.sh k8s-deploy.test.yaml environment: name: staging tags: ["docker"]
|
./deploy.sh
1 2 3 4 5 6 7 8 9 10 11
| kubectl config set-cluster "$CI_PROJECT_NAME" --server="$KUBE_URL" --certificate-authority="$KUBE_CA_PEM_FILE" kubectl config set-credentials "$CI_PROJECT_NAME" --token="$KUBE_TOKEN" kubectl config set-context "$CI_PROJECT_NAME" --namespace="$KUBE_NAMESPACE" --cluster="$CI_PROJECT_NAME" --user="$CI_PROJECT_NAME" kubectl config use-context "$CI_PROJECT_NAME" sed -i "s~<IMAGE_NAME>~${DOCKER_IMAGE_NAME}~g" $1 sed -i "s~<DEPLOY_NAME>~${DEPLOY_NAME}~g" $1 sed -i "s~<DEPLOY_DOMAIN>~${DEPLOY_DOMAIN}~g" $1 kubectl create namespace "$KUBE_NAMESPACE" --save-config --dry-run -o yaml | kubectl apply -f - kubectl create secret docker-registry gitlab-registry --docker-server=$CI_REGISTRY --docker-username=$DEPLOY_USER --docker-password=$DEPLOY_PASSWORD --docker-email=$DEPLOY_EMAIL --save-config --dry-run -o yaml | kubectl apply -f - kubectl patch serviceaccount default -p '{"imagePullSecrets":[{"name":"gitlab-registry"}]}' kubectl apply -f $1
|
升级后
.gitlab-ci.yml -> deploy-test
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| deploy-test: stage: deploy image: harbor.matrix.moe/devops-tools/matrix/gitops-helper:0.1.0 only: - test script: | git clone "https://${GITOPS_GIT_USERNAME}:${GITOPS_GIT_PASSWORD}@gitlab.matrix.moe/Matrix/infra/apps.git" _argo && cd _argo cp scheduler/template.yaml.bak scheduler/defination.yaml sed -i "s~<IMAGE_NAME>~${DOCKER_IMAGE_NAME}~g" scheduler/defination.yaml sed -i "s~<DEPLOY_NAME>~${DEPLOY_NAME}~g" scheduler/defination.yaml sed -i "s~<DEPLOY_DOMAIN>~${DEPLOY_DOMAIN}~g" scheduler/defination.yaml git add scheduler/defination.yaml git config user.email "ops@matrix.moe" && git config user.name "Matrix Ops Bot" git commit -m "update: matrix-scheduler -> ${DOCKER_IMAGE_TAG}" && git push environment: name: staging kubernetes: namespace: scheduler tags: ["docker"]
|
注:
- 升级后脚本第二行
scheduler/template.yaml.bak文件,其实就是原本k8s-deploy.test.yaml的内容,是部署的模板。
总结
这次升级以后所有matrix app都可以自动部署到git仓库上,由argo cd控制应用的部署,极大方便了对k8s集群应用部署的管理。
CI升级思路很简单,把“写部署文件并且配置”的旧流程,改为“写部署文件并且上传到git”的新流程。至于如何部署,部署到哪个集群这些事,就交给argo cd做。WebUI交互+可视化真香。