上篇主要介绍了 GitLab WorkFlow 以及 CI/CD 做的事情,并且详细分析 GitLab CI 跟 Runner 信息交互是如何进行的。接下来将为大家讲解 Executor 的实现,再通过两个例子具体展示 GitLab CI 的使用。

Executor

本章主要讲了在Runner 在接收到任务之后,会调用 Executor,Executor 是怎么实现的,重点介绍 Docker Executor 的实现细节

其实 Runner 会去调用对应的 executor,由 executor 来完成接下去的工作。

图 12 是从 GitLabMutliRunner 项目中截取的一部分代码,基本可以说明 executor 的流程。

图 12

第一步:Prepair,做准备工作;

第二步:拉取代码,根据 Job 里的 git_info 字段,Runner 去 GitLab 仓库拉取代码;

第三步:还原缓存,这些缓存是上一次构建留下的;

第四步:下载 artifacts,这是前一个阶段的产生的中间结果;

第五步:执行用户定义的脚本,这里指的是 before_scripts 跟 scripts 两部分;

第六步:执行 after_scripts;

第七步:保存缓存打包 artifacts 等;

第八步:上传 artifacts 供下一阶段使用。

基于这样一个流程,官方提供了 ssh、shell、docker、docker-ssh、virtualbox、kubernates 等执行器,来应对实际使用中的不同场景,本次分享主要也是从 Docker 跟 Docker-ssh 进行展开的。由于Docker 的隔离性强、秒级别启动容器、轻量、回收方便这些特点非常符合集成测试的要求。

首先,如果要使用 Docker executor,CI 配置文件需要做如下调整:

图 13

1.定义 image 字段,该字段指定了本次测试环境使用的 Docker 镜像;

2. services,这个字段定义了本次测试依赖的服务,这里依赖的是 redis 跟 mysql。

Docker executor 的实现

第一步:Prepare,Runner 会先去下载 redis、mysql 等项目依赖的服务,启动映射了目录代码的容器,启动映射了缓存目录的容器。

图 14

第二步:GetSource,Runner 会在启动一个 predefine 的容器,通过 volume from 的方式挂载项目代码路径,再通过 predefine 这个容器去拉取代码。由于目录共享,所以 volumes 里的这个容器数据内容也发生了改变。

图 15

第三步:执行脚本,runner 会启动一个 build 容器,通过 docker link 的方式把依赖的服务连接起来,通过 docker volume from 的方式加载项目代码以及缓存,然后执行 job 中定义的脚本。

图 16

Artifacts

当图片处理项目 Nami 刚接入到 CI 时,是分成 Test 跟 Build 两个阶段处理,Test 阶段需要先编译 Nami,然后启动测试。等测试通过后,执行第二阶段,进行 Docker Build,这时又需要重新再编译依次 Nami,这个过程很费时。后来了解到了 Artifacts 这个功能,可以把这个阶段中产生的文件上传到 GitLab 供下一个阶段来使用,这样以来就不需要二次编译了。

图 17

完成优化后,将整个过程拆成了 3 个阶段,第一个阶段进行编译,第二个阶段使用上一个阶段编译好的结果进行测试,第三个阶段使用第一个阶段编译好的二进制做 Docker Build。这样一来,整个过程中只需要做一次编译,大大缩短了构建耗费的时间。

图 18

另外上传 GitLab 还有一个好处,安装包可以直接通过网页下载回来。

关于 GitLab CI 的实践经验

C/C++ 编译优化

CDN 项目依赖 Nginx,并且增加了公司定制的逻辑,所以每次测试都需要重新编译 Nginx,但是众所周知编译是十分耗时的。为了解决这个问题,我们引入了 CCACHE。CCACHE 是一个编辑器驱动器,第一次编译时 CCACHE 会缓冲 GCC 的 -E 输出,编译选项以及 O 文件到 $HOME/.ccache 下,第二次编译时尽量利用缓冲,必须时更新缓冲。但是这里会有一个问题,测试跑完之后容器立刻就被回收了,怎么把编译缓存保留到下一次测试呢?

这里就需要用到前面提交的 cache 选项了,cache 选项可以把上一次的缓存目录保留到下一次测试中,供下一次测试使用。但是我们需要对 ccache 做一下配置,修改缓存的路径,指定到 /cache 目录下。

$ ccache —set-config=cache_dir=/cache/.ccache
$ ccache -F 0 && ccache -M 0

Localhost 问题

图 19

如果测试中依赖第三方服务的话,docker executor 是通过 docker link 的方式,但是采用这种方式的话,Build 这个容器就无法通过 127.0.0.1 来访问 Redis、Mysql 了。但是研发同学常会把测试环境的配置写成 127.0.0.1,方便本地开发测试。这样一来,接入到 CI 之后就会有不少困扰。针对这个问题,我们给出了两种解决方案。

第一种解决方案是使用别名:在定义 services 的时候,可以定义 alias,来指定该服务的别名,指定好别名之后,Build 容器内就会多一条该别名的解析记录,解析到指定的容器 IP。这种方式下,研发同学只要修改下测试配置就可以把服务跟测试跑起来,不过本地开发的时候,需要增加一条解析记录,把别名解析到 127.0.0.1。

图 20

第二种解决方案是端口转发,这种方式更加简单灵活些。拿 redis 举个例子,如果测试中以来了 redis,需要在 build 容器中安装 3proxy 做端口转发,并且把对 6379 端口的请求,都转发到 redis 对应容器的 6379 上去,通过这种方式来解决访问 127.0.0.1:6379。这种方式更加方便,研发同学不需要去修改测试的配置,但是需要在执行测试之前,去启动 3proxy 并配置端口转发规则。

当谈到 GitLab CI 的时候,我们都该聊些什么(下篇)的更多相关文章

  1. 当谈到 GitLab CI 的时候,我们该聊些什么(上篇)

    "微服务"这个概念近两年非常热,正在慢慢改变 DevOps 的思路.微服务架构把一个庞大的业务系统拆解开来,每一个组件变得更加独立自治.松耦合.但是,同时也伴随着部署单元粒度越来越 ...

  2. 使用GitLab CI + Capistrano部署CakePHP应用程序

    使用GitLab CI + Capistrano部署CakePHP应用程序 摘要:本文描述了如使用GitLab CI + Capistrano部署CakePHP应用程序. 目录 1. 问题2. 解决方 ...

  3. GitLab CI持续集成配置方案(补)

    上篇文章介绍了GitLab CI的持续集成配置方法,本篇文章将主要介绍NUnit的持续集成和遇到的一些坑 1.NUnit单元测试持续集成 下载NUnit.3.4.1.msi,https://githu ...

  4. GitLab CI持续集成配置方案

    目录 1. 持续集成介绍 1.1 概念 1.2 持续集成的好处 2. GitLab持续集成(CI) 2.1 简介 2.2 GitLab简单原理图 2.3 GitLab持续集成所需环境 2.4 需要了解 ...

  5. GitLab CI

    GitLab CI持续集成配置方案   目录 1. 持续集成介绍 1.1 概念 1.2 持续集成的好处 2. GitLab持续集成(CI) 2.1 简介 2.2 GitLab简单原理图 2.3 Git ...

  6. Gitlab CI 自动部署 asp.net core web api 到Docker容器

    为什么要写这个? 在一个系统长大的过程中会经历不断重构升级来满足商业的需求,而一个严谨的商业系统需要高效.稳定.可扩展,有时候还不得不考虑成本的问题.我希望能找到比较完整的开源解决方案来解决持续集成. ...

  7. Ubuntu Docker 安装和配置 GitLab CI 持续集成

    相关文章: Ubuntu Docker 简单安装 GitLab 劈荆斩棘:Gitlab 部署 CI 持续集成 目的:在 Ubuntu 服务器上,使用 Docker 安装和配置 GitLab Runne ...

  8. Ubuntu & GitLab CI & Docker & ASP.NET Core 2.0 自动化发布和部署(1)

    相关博文: Ubuntu 简单安装和配置 GitLab Ubuntu 简单安装 Docker Ubuntu Docker 简单安装 GitLab Ubuntu Docker 安装和配置 GitLab ...

  9. Ubuntu & GitLab CI & Docker & ASP.NET Core 2.0 自动化发布和部署(2)

    上一篇:Ubuntu & GitLab CI & Docker & ASP.NET Core 2.0 自动化发布和部署(1) 服务器版本 Ubuntu 16.04 LTS. 本 ...

随机推荐

  1. Http协议详解,获取doPost,doGet提交的数据,以及编码问题

    一 什么是Http协议 http协议: 浏览器客户端 和  服务器端 之间数据传输的格式规范 二 如何查看Http协议的内容 1)使用火狐的firebug插件(右键->firebug->网 ...

  2. 团队作业1——团队展示&选题

    Deadline: 2017-4-5 22:00PM,以博客发表日期为准 评分基准: 按时交 - 有分,检查的项目包括后文的四个方面 团队博客 团队选题 团队计划 团队成员贡献分分配规则 晚交 - 0 ...

  3. 201521123092, 《java程序设计》第1周学习总结。

    #1.本周学习总结 这一周是我学习java的第一周,刚接触一门全新的编程语言,觉得还是有点困难的,很多基础性的java知识需要一点点学习,我会请教同学以及查询网上的学习资料,认真学好这一门学科. 本周 ...

  4. cnpack热键

    CnPack的热键为ALt+space,当不自动补齐时按下Alt+space则会补齐

  5. [04] 利用注解生成实体类对应的建表sql语句

    1.实现功能 我们已经对注解有了基本的认识,知道了如何自定义注解,如何使用和最基本的处理注解. 本篇主要介绍,如何使用运行时级别的注解,配合反射来自动生成建表的sql语句.如下例: 我们有实体类Stu ...

  6. Java是如何解析xml文件的(DOM)

    Java解析xml文件 在Java程序中读取xml文件的过程也称为"解析xml文件": 解析的目的: 获取 节点名和节点值 获取 属性名.属性值. 四中解析方式: DOM SAX ...

  7. SimpleRpc-系统边界以及整体架构

    系统边界 什么是系统边界?系统边界就是在系统设计之初,对系统所要实现的功能进行界定,不乱添加,不多添加.这么做的好处就是,系统简单明了,主旨明确,方便开发和用户使用.举个例子,一个自动售货机的本职工作 ...

  8. [js高手之路] 设计模式系列课程 - DOM迭代器(2)

    如果你对jquery比较熟悉的话,应该用过 eq, first, last, get, prev, next, siblings等过滤器和方法.本文,我们就用迭代设计模式来封装实现,类似的功能 < ...

  9. mybatis快速入门(五)

    今天写写user表和orders表的mybatis的高级映射,一对一映射和一对多映射 1.创建一个orders.java文件 1.1一对一映射,一条订单对应一个用户 package cn.my.myb ...

  10. E - 今年暑假不AC HDU - 2037

    "今年暑假不AC?"  "是的."  "那你干什么呢?"  "看世界杯呀,笨蛋!"  "@#$%^&* ...