当谈到 GitLab CI 的时候,我们都该聊些什么(下篇)
上篇主要介绍了 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 的时候,我们都该聊些什么(下篇)的更多相关文章
- 当谈到 GitLab CI 的时候,我们该聊些什么(上篇)
"微服务"这个概念近两年非常热,正在慢慢改变 DevOps 的思路.微服务架构把一个庞大的业务系统拆解开来,每一个组件变得更加独立自治.松耦合.但是,同时也伴随着部署单元粒度越来越 ...
- 使用GitLab CI + Capistrano部署CakePHP应用程序
使用GitLab CI + Capistrano部署CakePHP应用程序 摘要:本文描述了如使用GitLab CI + Capistrano部署CakePHP应用程序. 目录 1. 问题2. 解决方 ...
- GitLab CI持续集成配置方案(补)
上篇文章介绍了GitLab CI的持续集成配置方法,本篇文章将主要介绍NUnit的持续集成和遇到的一些坑 1.NUnit单元测试持续集成 下载NUnit.3.4.1.msi,https://githu ...
- GitLab CI持续集成配置方案
目录 1. 持续集成介绍 1.1 概念 1.2 持续集成的好处 2. GitLab持续集成(CI) 2.1 简介 2.2 GitLab简单原理图 2.3 GitLab持续集成所需环境 2.4 需要了解 ...
- GitLab CI
GitLab CI持续集成配置方案 目录 1. 持续集成介绍 1.1 概念 1.2 持续集成的好处 2. GitLab持续集成(CI) 2.1 简介 2.2 GitLab简单原理图 2.3 Git ...
- Gitlab CI 自动部署 asp.net core web api 到Docker容器
为什么要写这个? 在一个系统长大的过程中会经历不断重构升级来满足商业的需求,而一个严谨的商业系统需要高效.稳定.可扩展,有时候还不得不考虑成本的问题.我希望能找到比较完整的开源解决方案来解决持续集成. ...
- Ubuntu Docker 安装和配置 GitLab CI 持续集成
相关文章: Ubuntu Docker 简单安装 GitLab 劈荆斩棘:Gitlab 部署 CI 持续集成 目的:在 Ubuntu 服务器上,使用 Docker 安装和配置 GitLab Runne ...
- Ubuntu & GitLab CI & Docker & ASP.NET Core 2.0 自动化发布和部署(1)
相关博文: Ubuntu 简单安装和配置 GitLab Ubuntu 简单安装 Docker Ubuntu Docker 简单安装 GitLab Ubuntu Docker 安装和配置 GitLab ...
- Ubuntu & GitLab CI & Docker & ASP.NET Core 2.0 自动化发布和部署(2)
上一篇:Ubuntu & GitLab CI & Docker & ASP.NET Core 2.0 自动化发布和部署(1) 服务器版本 Ubuntu 16.04 LTS. 本 ...
随机推荐
- SNS团队Beta阶段第二次站立会议(2017.05.23)
1.立会照片 2.每个人的工作 每个成员的分工: 成员 今天已完成的工作 明天计划完成的工作 罗于婕 完善代码规范文档 辅助完善生词本 龚晓婷 界面优化 辅助开发新功能 林仕庄 界面图标不对齐bug ...
- Java学习8——类(对象)之间的关系
(基础语法结束,开始看面向对象) 关联 关联体现的是两个类之间语义级别的一种依赖关系,比如我和我的老师. 继承(一般和特殊) 继承是指一个类继承另外一个类的的功能,并可以增加新的功能,"XX ...
- 201521123074 《Java程序设计》第7周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. (嗯..都画了那么久的导图,还是用导图归纳吧~) 2. 书面作业 ArrayList代码分析 1.1 解释ArrayList ...
- 201521123095《java程序设计》第4周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结上课内容. 对于一个系统中,对于名词大多为类或属性,对于动词大多为方法. 1.3 注释的应用 使用类的注释与 ...
- 201521123093 java 第十三周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...
- 201521123098 《Java程序设计》第9周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 1. 在catch时需要考虑各个异常的继承关系,存在继承关系时需要先把子类异常的catch放在前面: 2. 当try ...
- 201521123050 《Java程序设计》第12周学习总结
1. 本周学习总结 2. 书面作业 将Student对象(属性:int id, String name,int age,double grade)写入文件student.data.从文件读出显示. 1 ...
- 201521123110 《Java程序设计》第1周学习总结
第一周学习总结 本周开始了对java的初次学习接触,Java是一门新的编程语言不同于C,由于有了c的基础,对于Java的理解和学习也相对从前学C更容易些. 也学习了Java的诞生发展以及运用包括JVN ...
- Java实现Map集合二级联动
Map集合可以保存键值映射关系,这非常适合本实例所需要的数据结构,所有省份信息可以保存为Map集合的键,而每个键可以保存对应的城市信息,本实例就是利用Map集合实现了省市级联选择框,当选择省份信息时, ...
- Mybatis第三篇【动态SQL】
动态SQL 何为动态SQL??回顾一下我们之前写的SSH项目中,有多条件查询的情况,如下图 我们当时刚开始做的时候,是需要在Controller中判断SQL是否已经有条件了,因为SQL语句需要拼接起来 ...