引言

看过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的资料

  1. stages:
  2. - build
  3. - build_image
  4. - deploy
  5.  
  6. variables:
  7. # CI_DEBUG_TRACE: "true"                     
  8. deploy_path: "/home/xxxx/eqidmanager"   # CI变量,用于配置部署目录
  9.  
  10. before_script:
  11. - "docker info"
  12.  
  13. build:
  14. stage: build
  15. script:
  16. - "for d in $(ls src);do echo $d;prog=$(pwd)/src/$d/$d.csproj; dotnet build $prog; done"
  17. tags:                                 
  18. - another-tag
  19.  
  20. build_image:EqidManager:
  21. stage: build_image
  22. script:
  23. - dotnet publish src/EqidManager/EqidManager.csproj -c release -o ../../container/app/publish/
  24. - docker build --pull -t $CI_REGISTRY_USER/eqidmanager:$CI_COMMIT_REF_NAME container/app
  25. - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD
  26. - docker push $CI_REGISTRY_USER/eqidmanager:$CI_COMMIT_REF_NAME
  27. tags:
  28. - another-tag
  29. only:            #Pipeline Job构建策略,代码仓库打tag会执行该任务, 支持正则
  30. - tags
  31.  
  32. build_image:EqidReceiver:
  33. stage: build_image
  34. script:
  35. - dotnet publish src/EqidReceiver/EqidReceiver.csproj -c release -o ../../container/receiver/publish
  36. - docker build -t $CI_REGISTRY_USER/eqidreceiver:$CI_COMMIT_REF_NAME container/receiver
  37. - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD
  38. - docker push $CI_REGISTRY_USER/eqidreceiver:$CI_COMMIT_REF_NAME
  39. tags:
  40. - my-tag
  41. only:
  42. - tags
  43.  
  44. deploy:staging:
  45. stage: deploy
  46. script:
  47. - cd $deploy_path
  48. - export TAG=$CI_COMMIT_REF_NAME  # 引入本次CI的git:tag名称,覆盖.env文件默认配置
  49. - "docker-compose -f docker-compose.yml -f docker-compose.prod.yml build"         
  50. - "docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d"
  51. tags:
  52. - my-tag
  53.  
  54. deploy:prod:
  55. stage: deploy
  56. script:
  57. - # TODO 需要写脚本登陆到Prod机器上
  58. - export TAG=$CI_COMMIT_REF_NAME
  59. - cd $deploy_path
  60. - "docker-compose -f docker-compose.yml -f docker-compose.prod.yml build"
  61. - "docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d"
  62. tags:
  63. - my-tag
  64. 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}路径下建立了如下部署文件:

  1. ├── appsettings.secrets.json
  2. ├── docker-compose.prod.yml
  3. ├── docker-compose.yml
  4. ├── .env
  5. ├── EqidManager.db
  6. ├── nginx
  7.    ├── Dockerfile
  8.    └── nginx.conf
  9. └── 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文件

  1. ------.env 文件----
    TAG=master   # 该TAG变量会在Pipeline:deploy_staging任务中被覆盖,形成基于git:tag的imageName:tag
  2. docker_host=172.16.1.1
  3. COMPOSE_PROJECT_NAME=EqidManager
  4. 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制图,均为原创,看官请不吝好评+关注,  ~。。~

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

 

【干货】基于镜像部署的Gitlab-CI/CD实践和坑位指南的更多相关文章

  1. .NetCore 配合 Gitlab CI&CD 实践 - 单体项目

    前言 上一篇博文 .NetCore 配合 Gitlab CI&CD 实践 - 开篇,主要简单的介绍了一下 GitLab CI 的持续集成以及持续部署,这篇将通过 GitLab CI 发布一个 ...

  2. .NetCore 配合 Gitlab CI&CD 实践 - 开篇

    引言 这是一个系列的文章,讲述的是一个中小型开发团队如何从零开始使用搭建基建 GitLab 代码托管平台,以及使用 GitLab Runner 实现 CI/CD 的故事.本系列通过部署一个完整的 .n ...

  3. GitLab CI/CD的官译【原】

    CI / CD方法简介 软件开发的持续集成基于自动执行脚本,以最大限度地减少在开发应用程序时引入错误的可能性.从新代码的开发到部署,它们需要较少的人为干预甚至根本不需要干预. 它涉及在每次小迭代中不断 ...

  4. spring-boot 2.5.4,nacos 作为配置、服务发现中心,Cloud Native Buildpacks 打包镜像,GitLab CI/CD

    spring-boot 2.5.4,nacos 作为配置.服务发现中心,Cloud Native Buildpacks 打包镜像,GitLab CI/CD 本文主要介绍 Java 通过 Cloud N ...

  5. .Net Core自动化部署系列(三):使用GitLab CI/CD 自动部署Api到Docker

    之前写过使用Jenkins实现自动化部署,最近正好没事研究了下GitLab的自动化部署,顺便记录一下. 使用GitLab部署我们需要准备两件事,第一个起码你得有个GitLab,自己搭建或者使用官方的都 ...

  6. GitLab CI/CD 自动化部署入门

    前言:因为找了B站内推,测试开发,正好知道内部使用GitLab做自动化测试,所以简单学了一下,有错误的地方请指正. 入门 初始化 cp: 无法获取'/root/node-v12.9.0-linux-x ...

  7. 实践分享!GitLab CI/CD 快速入门

    用过 GitLab 的同学肯定也对 GitLab CI/CD 不陌生,GitLab CI/CD 是一个内置在 GitLab 中的工具,它可以帮助我们在每次代码推送时运行一系列脚本来构建.测试和验证代码 ...

  8. 前端初探 Gitlab CI/CD

    前言 纵观人类历史的发展以及三次工业革命,你会发现利用机器来替代部分人力劳动,将重复的工作自动化从而解放生产力都是发展的必然趋势,在软件工程领域也不例外,其中 CI/CD 就是其中一项,那么什么是 C ...

  9. GitLab CI/CD持续集成设置

    GitLab CI/CD持续设置 官方文档地址(https://docs.gitlab.com/ee/ci/README.html) GitLab CI.CD功能非常完善,只需要简单几步,就可以完成项 ...

随机推荐

  1. Spring Boot2(十三):整合定时任务发送邮件

    一.前言 主要玩一下SpringBoot的定时任务和发送邮件的功能.定时发送邮件,这在实际生成环境下主要用户系统性能监控时,当超过设定的阙值,就发送邮件通知预警功能.这里只通过简单的写个定时结合邮件通 ...

  2. C# 管道式编程

    受 F# 中的管道运算符和 C# 中的 LINQ 语法,管道式编程为 C# 提供了更加灵活性的功能性编程.通过使用 扩展函数 可以将多个功能连接起来构建成一个管道. 前言 在 C# 编程中,管道式编程 ...

  3. C程序中可怕的野指针

    一.疑问点指针是C语言一个很强大的功能,同时也是很容易让人犯错的一个功能,用错了指针,轻者只是报个错,重者可能整个系统都崩溃了.下面是大家在编写C程序时,经常遇到的一种错误的使用方法,也许在你的学习和 ...

  4. 这样子来理解C语言中指针的指针

    友情提示:阅读本文前,请先参考我的之前的文章<从四个属性的角度来理解C语言的指针也许会更好理解>,若已阅读,请继续往下看. 我从4个属性的角度来总结了C语言中的指针概念.对于C语言的一个指 ...

  5. 工作经验之石氏thinking

    经常听到N多人说工作经验这个名词:也时常听到人说工作多少年就是多少年工作经验.我听着总觉得有点别扭,感觉他们把这个名词说的太简单了,而且觉得不是工作N年就一定有所谓的工作经验.我觉得归根结底还是在于工 ...

  6. .net持续集成cake篇之cake任务依赖、自定义配置荐及环境变量读取

    系列目录 新建一个构建任务及任务依赖关系设置 上节我们通过新建一个HelloWorld示例讲解了如何编写build.cake以及如何下载build.ps1启动文件以及如何运行.实际项目中,我们使用最多 ...

  7. [原创]Zabbix3.4_API的python示例

    说明: 1.python版本为:python2.7 2.zabbix版本为:zabbix3.4 3.通过python脚本调用zabbix的api接口可以实现批量增删改查主机的信息. 示例如下: #-* ...

  8. springboot序

    springboot序 1.写在前面 (1) 前段时间把文章分了下类(说的是专栏,谈不上),分了三类:springboot.springcloud.mpp数据库greenplum,后来给springc ...

  9. C#7.2 新增功能

    连载目录    [已更新最新开发文章,点击查看详细] C# 7.2 又是一个单点版本,它增添了大量有用的功能. 此版本的一项主要功能是避免不必要的复制或分配,进而更有效地处理值类型. C# 7.2 使 ...

  10. 移动端开发用touch事件还是click事件

    前端开发现在包含了跨浏览器,跨平台(不同操作系统)和跨设备(不同尺寸的设备)开发. 在移动开发的过程中,到底选取touch事件还是click事件?对了,请不要鄙视click,click在移动端开发用着 ...