为了账号安全,请及时绑定邮箱和手机立即绑定

Gitlab CI多环境持续集成实战

标签:
运维工具

一 背景

当不同项目组进行测试环境集成,目前遇到了dev环境在一台单独的云服务器,但是test环境在k8s中,利用gitlab ci实现持续集成,简单快速高效上线,特有此记。

二 上线流程

图片描述
首先提交自己的代码merge到dev环境后dev的gitlab ci pipeline自动构建部署到测试环境,构建成功后,先在测试环境进行功能测试及bug fix,待一个大版本功能完成后将dev merge到master分支,master执行master分支的gitlab ci pipeline,进行正式环境构建部署。

三 环境差异

目前在项目下注册了两个gitlab runner来分别执行不通分支的ci任务

图片描述

两个不同的runner负责执行不同环境的ci job,目前发布测试环境利用的是与k8s的node节点网络可以互通的云服务器,后续可以改进为docker形式,可以来并发执行,且可以保证环境一致性。
注意⚠️:runner注册为gitlab-runner用户,需要切换到此用户进行k8s正式环境访问。

四 test环境ci详解

4.1 .gitlab-ci.yml文件

stages:
  - deploy_src_dev
  - install_dependency_dev
  - restart_server_dev
  - deploy_static_src_dev
  - check_server_dev
  - deploy_src_test
  - build_image_test
  - deploy_k8s_test
  - check_k8s_test


variables:
  DEV_RUNNER_HOME: "/home/gitlab-runner/builds/ZxxxxxxxC/0/devops"
  PROD_RUNNER_HOME: "/home/gitlab-runner/builds/FKxxxxxF/0/devops"
  BASE_DIR: "/sxxxxxxxps/"
  APP_NAME: "smartcs_ops"
  PROJECET_NAME: "devops"


before_script:
  - export APP_TAG="${CI_COMMIT_TAG:-${CI_COMMIT_SHA::8}}"




job deploy_src_test_job:
  stage: deploy_src_dev
  script:
    - sudo rsync -az --delete ${DEV_RUNNER_HOME}${BASE_DIR}/ /opt${BASE_DIR}
  tags:
    - smartops-opsaudit
  only:
    - dev
  when: always


job install_dependency_test_job:
  stage: install_dependency_dev
  script:
    - sudo /opt/py3/bin/python -m pip install -r /opt${BASE_DIR}requirements/requirements.txt
    - sudo \cp -rf /opt/config/config.yml /opt${BASE_DIR}/cfg/
    - sudo mkdir -p /opt${BASE_DIR}/tmp
  tags:
    - smartops-opsaudit
  only:
    - dev
  when: always


job restart_server_test_job:
  stage: restart_server_dev
  script:
    - sudo /opt/py3/bin/supervisorctl restart all
  tags:
    - smartops-opsaudit
  only:
    - dev
  when: always


job deploy_static_src_test_job:
  stage: deploy_static_src_dev
  script:
    - sudo mkdir /opt/smartcs-ops/data/ops-audit
    - sudo \cp -rf /opt/smartcs-ops/data/static/ /opt/smartcs-ops/data/ops-audit
  tags:
    - smartops-opsaudit
  only:
    - dev
  when: always


job check_server_test_job:
  stage: check_server_dev
  script:
    - sudo /opt/py3/bin/supervisorctl status
  tags:
    - smartops-opsaudit
  only:
    - dev
  when: always


job deploy_src_test_job:
  stage: deploy_src_test
  script:
    - sudo rsync -az --delete ${PROD_RUNNER_HOME}${BASE_DIR}/ /opt${BASE_DIR}
    - sudo \cp -rf /opt${BASE_DIR}apps/static /opt${BASE_DIR}data
    - sudo mkdir /opt${BASE_DIR}data/ops-audit
    - sudo \cp -rf /opt${BASE_DIR}data/static/ /opt${BASE_DIR}data/ops-audit
  tags:
    - smartcs-ops-prod
  only:
    - master
  when: always




job build_image_test_job:
  stage: build_image_test
  script:
    - sudo chmod +x entrypoint.sh run_server.py
    - sudo docker build -t ${HARBOR_REGISTRY}/${PROJECET_NAME}/${APP_NAME}:${APP_TAG} .
    - sudo echo "${HARBOR_PASSWORD}" | docker login ${HARBOR_REGISTRY} -u "${HARBOR_USERNAME}" --password-stdin
    - sudo docker push ${HARBOR_REGISTRY}/${PROJECET_NAME}/${APP_NAME}:${APP_TAG}
  tags:
    - smartcs-ops-prod
  only:
    - master
  when: always


job deploy_k8s_test_job:
  stage: deploy_k8s_test
  script:
    - '[ -n "${KUBE_CONFIG_CONTENT}" ] && mkdir -p "${HOME}/.kube" && echo "${KUBE_CONFIG_CONTENT}" > "${HOME}/.kube/config"'
    - sudo grep -E "^[[:space:]]+image:" deploy-prod/*-deployment.yml |awk '{print $2}' |head -1
    - sudo sed -i "s@$(grep -E "^[[:space:]]+image:" deploy-prod/*-deployment.yml |awk '{print $2}' |head -1)@${HARBOR_REGISTRY}/${PROJECET_NAME}/${APP_NAME}:${APP_TAG}@g" deploy-prod/*-deployment.yml
    - kubectl apply -f deploy-prod/.
  tags:
    - smartcs-ops-prod
  only:
    - master
  when: always


job check_backend_test_job:
  stage: check_k8s_test
  script:
    - kubectl rollout status -w --timeout=120s deployment/smartcs-ops-backend
  tags:
    - smartcs-ops-prod
  only:
    - master
  when: always


job check_celery_test_job:
  stage: check_k8s_test
  script:
    - kubectl rollout status -w --timeout=120s deployment/smartcs-ops-celery
  tags:
    - smartcs-ops-prod
  only:
    - master
  when: always


job check_beat_test_job:
  stage: check_k8s_test
  script:
    - kubectl rollout status -w --timeout=120s deployment/smartcs-ops-beat
  tags:
    - smartcs-ops-prod
  only:
    - master
  when: always

4.2 前提条件

环境变量注入,为了避免敏感信息暴露在代码配置文件中,将harbor仓库登录信息及kubeconf等敏感信息利用gitlab ci 的环境管理来进行注入

4.3 步骤详解

  • deploy_src_prod
    此步骤为拉取源码到prod服务器上,进行nginx静态文件的更新

  • build_image_prod
    此步骤为构建镜像,并推送镜像至harbor

  • deploy_k8s_prod
    此步骤为替换代码托管中的镜像tag,之后部署进k8s环境中

  • check_k8s_prod
    设立失败检测机制,通过rollout status -w在部署期间实时检测容器是否更新完成,如果容器有异常未启动,则状态为异常不会更新容器中的镜像,并行检测三个deployment的状态。

五 prod环境ci部署

5.1 为gitlab-runner提取docker权限

将gitlba-runner用户添加至docker组

usermod -a -G docker gitlab-runner

5.2 prod云服务器安装kubectl

由于是在prod服务器上进行的镜像build和push以及发布到k8s环境,需要在prod云服务器上进行kubectl 工具安装

curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl

六 注意事项

  • 此gitlab ci文件适用于利用gitlab ci完成CI的情况下,可以在一个.gitlab-ci.yml中编写多个环境的job。
  • runner可以后期改造成docker形式,来并发执行多个job且保证环境一致性。
  • 镜像的tag在此项目中定义为commit id,方便排查
  • 将k8s的yaml文件托管在项目代码的目录结构下,每次仅替换image的tag,然后幂等性的apply。
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
全栈工程师
手记
粉丝
6495
获赞与收藏
192

关注作者,订阅最新文章

阅读免费教程

  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消