引言

看过docker-compose真香的园友可能留意到当时是【把部署dll文件拷贝到生产机器】,即时打包成镜像并启动容器,并没有完成CI/CD。

经过长时间实操验证,终于完成基于Gitlab的CI/CD实践,本次实践的坑位很多, 实操过程尽量接近最佳实践(不做hack, 不做骚操作),记录下来加深理解。

第一部分: Gitlab CI/CD 原理 和 Gitlab Runner 安装(这里使用shell执行器)

第二部分: Gitlab CI/CD 实践:

  • 宏观项目架构图
  • .gitlab-ci.yml 文件
  • 项目部署目录

第一部分:gitlab CICD原理

Gitlab CI/CD架构

  • Gitlab CI/CD   存储【构建】和【构建状态】的api应用程序, 提供友好的管理界面,  构建过程由 .gitlab-ci.yml文件定义,而这个文件一般置于代码仓库的根目录。
  • Gitlab Runner 执行构建过程的应用程序,可与Gitlab Server 形成分布式部署, 如上图所示, 其通过api 与Gitlab Server交互

Gitlab CI/CD 配置界面 & Gitlab Runner 安装

Gitlab CI/CD提供配置界面(项目菜单栏-设置-CI/CD),可指定

- 将要使用何种形式的Runner

-  配置Runner要用到环境变量

注册时需要关注的两个配置是:

  • tags 与此Runner相关的任务标签, 用于在共享Runner中区分不同的Project,.gitlab-ci.yml会用到

  • runner  executor   执行构建任务的方式,这里使用shell方式

Shell是最简单的配置执行器,需要将构建所需的所有依赖项手动安装在安装了Runner的同一台计算机上。

注册过程和结果请参考下图:

第二部分:基于docker-compose的Gitlab-CI  实践

项目架构图

 

原则上不允许自动部署Prod,本次使用Gitlab Runner服务器作为Gitlab CD的部署机器。

Gitlab-CI Pipeline构建ReceiverAPP、webAPP镜像(附带本次git:tag)并推送到hub.docker.com;

Gitlab-CD docker-compose拉取远端nginx、ReceiveAPP、webapp镜像,启动容器。

  • Pipeline对每一次提交或合并都会执行build任务, 形成Continous Intergation

  • Pipeline对git: tag会执行build_Image任务,自动构建至deploy_staging任务,这样就能形成基于git:tag的部署版本管理(部署出错,也能很快回滚到上次的部署tag)

本处使用Gitlab Runner 服务器作为staging部署机器; 原则上不允许自动随意部署Prod(实践中登陆到 Prod机器上执行部署命令,以下GitLab-CD也没有完成Prod的自动部署过程,自行补上登陆终端的脚本即可)

.gitlab-ci.yml 文件

  以上Gitlab Pipeline定义了 build-->build_image-->deploy 三个任务, 某些任务还包括不同分支Job,写.gitlab-ci.yml 的过程就是将以上执行动作脚本化,更多Gitlab-CI的资料

  stages:
- build
- build_image
- deploy variables:
# CI_DEBUG_TRACE: "true"                     
deploy_path: "/home/xxxx/eqidmanager"   # CI变量,用于配置部署目录 before_script:
- "docker info" build:
stage: build
script:
- "for d in $(ls src);do echo $d;prog=$(pwd)/src/$d/$d.csproj; dotnet build $prog; done"
tags:                                 
- another-tag build_image:EqidManager:
stage: build_image
script:
- dotnet publish src/EqidManager/EqidManager.csproj -c release -o ../../container/app/publish/
- docker build --pull -t $CI_REGISTRY_USER/eqidmanager:$CI_COMMIT_REF_NAME container/app
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD
- docker push $CI_REGISTRY_USER/eqidmanager:$CI_COMMIT_REF_NAME
tags:
- another-tag
only:            #Pipeline Job构建策略,代码仓库打tag会执行该任务, 支持正则
- tags build_image:EqidReceiver:
stage: build_image
script:
- dotnet publish src/EqidReceiver/EqidReceiver.csproj -c release -o ../../container/receiver/publish
- docker build -t $CI_REGISTRY_USER/eqidreceiver:$CI_COMMIT_REF_NAME container/receiver
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD
- docker push $CI_REGISTRY_USER/eqidreceiver:$CI_COMMIT_REF_NAME
tags:
- my-tag
only:
- tags deploy:staging:
stage: deploy
script:
- cd $deploy_path
- export TAG=$CI_COMMIT_REF_NAME  # 引入本次CI的git:tag名称,覆盖.env文件默认配置
- "docker-compose -f docker-compose.yml -f docker-compose.prod.yml build"         
- "docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d"
tags:
- my-tag deploy:prod:
stage: deploy
script:
- # TODO 需要写脚本登陆到Prod机器上
- export TAG=$CI_COMMIT_REF_NAME
- cd $deploy_path
- "docker-compose -f docker-compose.yml -f docker-compose.prod.yml build"
- "docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d"
tags:
- my-tag
when: manual

这里有些知识点和 坑位需要指出:

第8行: 预先定义的环境变量,该变量定义gitlab CD的部署目录

第16行:  对src开发目录下两个程序执行dotnet build命令

第17行:tags定义具备该tags的Runner可以执行该任务, 注意这里的tags必须是字符串数组

第23-26行:构建镜像并推送到镜像仓库的过程,用到两种CI变量

   - 密钥变量CI_REGISTRY_USER、CI_REGISTRY_PASSWORD ,可在GitLab-CI 界面配置

- 预定义变量CI_COMMIT_REF_NAME, 该变量标记构建项目的git:branch或git:tag名称,用于生成镜像tag

注意变量可被重写,重写有优先级 http://www.ttlsa.com/auto/gitlab-cicd-variables-zh-docum

第29行; only定义此Job只在产生git:tag时被触发,与上面我们使用 CI-COMMIT_REF_NAME 变量相呼应

第47行: Gialab-CI pipeline每个Job会重新拉取git源码执行Job任务(可登录到Gitlab Runner工作目录下观察Runner执行过程),CD时需要选择合适目录,这是deploy_staging上使用deploy_path CI变量的原因

第48行:注入本次Gitlab-CI git:tag名称, 实际上是覆盖了.env同名环境变量

第49行:若存在docker-compose.yml、docker-compose.override.yml 两个文件,docker-compose命令会自动merge这2个文件(使用docker-compose config命令查看merge 之后的结果)。

第64行:上述Job若没有出错,会自动执行下一步;而when指令定义该Job 是需要在界面上手动执行

部署目录

在Gitlab Runner服务器的{deploy_path}路径下建立了如下部署文件:

├── appsettings.secrets.json
├── docker-compose.prod.yml
├── docker-compose.yml
├── .env
├── EqidManager.db
├── nginx
│   ├── Dockerfile
│   └── nginx.conf
└── receiver.secrets.json
  • 在部署目录建立定义docker-compose.yml、docker-compose.prod.yml 两个yml文件,前者定义常规容器服务,后者定义适用于本Prod环境的容器服务
  • 密钥文件不要进入代码管理,因此我们定义appsetting.secrets.json 和 receiver.secrets.json密钥文件,由dccker-compose.yml挂载进入容器

  • .env文件存储相对固定、与本次docker-compose命令相关的环境变量,docker-compose命令默认寻找同级目录下.env文件

------.env 文件----
TAG=master   # 该TAG变量会在Pipeline:deploy_staging任务中被覆盖,形成基于git:tag的imageName:tag
docker_host=172.16.1.1
COMPOSE_PROJECT_NAME=EqidManager
DOCKER_REGISTRY=***

 project打上git:tag之后,触发Gitlab Runner CI/CD Pipeline:

跳转到部署目录->应用本次git:tag->执行docker-compose命令拉取指定tag镜像并启动容器。

That'all, 本次应用Gitlab Runner(shell执行器)实践CI/CD, Gitlab菜单界面有所有构建构成的日志(便于排查构建问题);另外上文对于关键知识均附带传送门,可进一步对比研究。

作者:JulianHuang

码甲拙见,如有问题请下方留言大胆斧正;码字+Visio制图,均为原创,看官请不吝好评+关注,  ~。。~

本文欢迎转载,请转载页面明显位置注明原作者及原文链接

 

最新文章

  1. CANopen学习——协议栈
  2. UVA1395 Slim Span(枚举最小生成树)
  3. 如何用腾讯云打造一款微视频APP
  4. Redis集群明细文档
  5. Chromuim开发机配置
  6. Get Files from Directory
  7. 【转】增加eclipse的运行内存 -- 不错!!
  8. PHP编译错误Don't know how to define struct flock on this system, set --enable-opcache=no
  9. VS 2012 显示Link的参数
  10. "NO 3D support is available from the host"
  11. c#中 uint--byte[]--char[]--string相互转换汇总
  12. JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解
  13. angular2 学习笔记 ( unit test 单元测试 )
  14. [HNOI2014]世界树
  15. fiddler和手机连接抓包实现
  16. WPF 水平进度条
  17. 使用Logstash filter grok过滤日志文件
  18. break和continue语句(初学者)
  19. android 中的一些资源注解,让编译器帮你检查代码
  20. uname command

热门文章

  1. 关于爬虫平台的架构实现和框架的选型(二)--scrapy的内部实现以及实时爬虫的实现
  2. 20190719 NOIP模拟测试6 (考后反思)
  3. 简介SoftICE是Compuware NuMega公司1的产品,是目前公认最好的系统级调试工具
  4. Salesforce Admin篇(三) Delegated Administrator
  5. pymysql指南
  6. 如何利用Azure Automation以及Tag自动开关VM
  7. TensorFlow(1)-基础知识点总结
  8. Modify column Vs change column
  9. python课堂整理17---文件操作(上)
  10. About dycf