本文主要是介绍基于docker+gitlabCI搭建私有集成环境,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
看了几天的docker,感觉好极了。现在回到我一开始的目标:构建一个团队内部的持续集成(下文统称CI)环境,并梳理出适合我们自己的工作流。
今天我们主要是来搭建依赖的环境:
- virtualBox
- ubuntu server 16
- docker
- gitlab version8+(该版本以上自带CI模块)
- gitlab runner
- gitlab需要的其它组件(redis,postgresql)
之前学习docker时,一直都是基于自己的工作机,装的是win7 64bit,win下和docker相关的问题可以看我之前的文章。由于我们现在是要搭建一个自动化CI环境,提供web ui来供用户使用,所以环境搭建部分的操作完全不需要使用者参与,就不存在之前考虑的所谓的OS水土不服问题!介于网上多数资料都是使用ubuntu来作为docker的宿主系统,所以我这里就放弃了亲爱的centos(其实centos也是没问题的,我只是低调的炫耀自己通吃而已~见谅)。
老规矩,先来共享一下相关的文献资料:
- Gitlab CI 文档
- 使用Gitlab CI & Docker搭建CI环境(主要借鉴该文章后半部分提到的“提升构建速度”)
- sameersbn/gitlab(gitlab docker镜像的使用文档)
ubuntu下安装docker
我们这次不使用win下的dockerToolbox来安装docker了,而是直接在虚拟机中安装unbuntu系统,然后直接在unbuntu中安装docker:
|
|
目前这样的安装方式,依然需要注意,后面运行gitlab容器时配置的端口映射只是将容器的端口映射到了ubuntu虚拟机系统上,如果想让物理机直接访问,还需要在virtualBox上再进行一次端口映射,具体步骤在这篇文章中我已经详细介绍过了。
镜像选择问题
docker环境装好后,就需要开始下载所需要的镜像了:
- sameersbn/gitlab:latest
- sameersbn/postgresql:latest
- sameersbn/redis:latest
- sameersbn/gitlab-ci-multi-runner:latest
由于我们是在国内,所以直接使用hub.docker.com来下载无异于浪费生命,还好国内也有良心镜像库:
- sameersbn/gitlab:latest
- sameersbn/postgresql:latest
- sameersbn/redis:latest
- sameersbn/gitlab-ci-multi-runner:latest
这里需要提醒的是,尽管灵雀云上显示的sameersbn/gitlab
镜像版本是”7.14.1”,不过别担心,只是md文件没有更新而已,可以切换到页面的“版本”选项卡来确认latest
版本。
这样基本上20分钟就可以把三个镜像全部下载到本地啦~
启动容器
镜像下载完毕后,根据官方文档我们需要创建对应的docker容器来启动相关的服务,我并没有使用官方提供的第一种方法(docker-compose),主要是不熟悉~
我们手动来完成三个容器的启动:
|
|
注意,上面的命令我已经改成使用我们本地镜像的名字了,还有在启动gitlab容器时我使用了一个自定义的字符串来赋值GITLAB_SECRETS_DB_KEY_BASE
,由于是本地测试环境,外加我实在不知道如何通过在--env
命令中使用shell变量来使用pwgen -Bsv1 64
生成的随机字符串(手动输入简直等于自杀!)~知道如何做的朋友请留言赐教,不胜感激。
根据自己的硬件配置,可能需要稍等那么一分钟左右,在做好物理机端口映射配置后,我们就可以在本地浏览器中访问http://localhost:10080/来使用gitlab了!(可能由于gitlab首次启动初始化问题,你可能会看到gitlab提示的500错误,稍等一下再刷新即可)
现在你基本上就已经拥有了本地的gitlab环境,你可以使用本地的git客户端来创建一个gitlab测试项目,试试clone到本地,试试commit到gitlab,应该妥妥的~
Gitlab Runner
这部分内容文章开头给的文档并没有汉化,不过没关系,我们都懂英文,对吧?
出于性能考虑官方不推荐将Runner安装在和gitlab同一台物理机上,出于安全考虑也不推荐将其安装在独立的物理机上,靠,也只能用docker来跑了!
这里还有两个概念:
- 特定Runner
- 共享Runner
前者适配有特殊需求的项目,同时也可以避免重要的项目runner资源被占用的问题。
而如果多个项目的优先级一样,并且有非常相似的依赖环境,那使用共享Runner是一个不错的选择。
既然我们决定使用docker容器来跑runner,那就先选个镜像吧,官方提供的是:gitlab-ci-multi-runner,我是用的灵雀云镜像了,注意,这里灵雀云镜像上的md介绍依然是错误的,镜像本身是和官方镜像一致的,小不完美啊 :———(~
还要说的一点是,官方提供的这个镜像是纯净镜像,不包含任何其它的环境(例如java环境或node环境),而你需要根据自己的项目实际情况来创建满足的自定义镜像。官方提供了几个语言环境的例子~
这种使用runner的思路相当于我们拿这个运行着runner的docker容器当作一个“物理机”,然后在这台“物理机”上做.gitlab-ci.yml
指定要做的事儿。在此基础上,我们依然可以让Runner执行docker build模式,这里就涉及到“docker-in-docker”的思想了。具体细节官方提供了比较清晰的文档。(其实,如果你使用文档中提到的“docker-in-docker”方案的话,那实际上就是“docker-in-(docker-in-docker)”,好绕啊~)
提到Runner的executor的类型,文档里有提到不少(shell,docker,ssh,等等),差别我感觉都不是太大,主要还是shell和docker两大类。
理论姿势就这么多,接下来我们跑起我的runner容器:
|
|
这里需要提醒的是两点:
- 你自己的gitlab生成的token可以在http://localhost:10080/admin/runners看到(我假设你和我一样要创建的是一个共享Runner)
- CI_SERVER_URL参数不要使用你物理机浏览器地址栏里的值,我们在上面的命令中已经将之前创建的gitlab容器link到了runner容器,so,我们只需要填写设置的主机名即可,否则无法注册成功!
接下来刷新你的gitlab管理员后台,你将会看到注册成功的Runner信息。
还没完,由于我们使用的是shell
模式,所以我们还需要进入到runner容器中来安装docker环境:
|
|
如果可以看到正确的docker版本信息,那就说明一切顺利。但怎么可能那么顺利!! 事实证明我太天真了,在docker容器中由于文件系统是只读的,所以无法安装docker环境~至少我们现在的做法还不行,如下图:
{% image http://pic.yupoo.com/kazaff/FCMGzWlk/143Y2S.png '' '' %}
这里说一个插曲,当得到这个结论后的我失望的打算将这个悲剧的镜像删除,我在gitlab admin后台的runner页面点击“remove”按钮,然后又将对应的docker容器也删除掉。当我再次使用相同的命令打算启动一个干净的runner容器时,我发现gitlab的runner页面不在提示成功注册runner了!我彻底方了!一切都和第一次执行流程一致,为啥这次就不认了呢?
于是我发现了一个秘密,上面的创建runner容器的命令中有一个参数:
|
|
我在宿主机的/srv/docker/gitlab-runner
目录下找到了答案,原来一直试图想找到的config.toml
文件在这里,也是因为这个文件的缘故所以gitlab才不在接受我的runner注册的!删除并重建这个目录即可!
走了弯路不可怕,可怕的是接下来不知道怎么办?没关系,我们现在先在宿主机上安装gitlab-ci-multi-runner环境,并使用官方提供的docker-in-docker方式来增加一台runner:
|
|
记住,我们这里要填写的gitlab-ci coordinator URL应该是:http://localhost:10080/ci
。
这里还有个细节是官方文档没有提到的,那就是让注册好的Runner运行起来,不过其实默认安装好gitlab-ci-multi-runner后它就自己已经以服务的方式注册到系统里了(服务名:gitlab-runner),每次注册runner导致config.toml
文件变更后都会自动触发该服务的reload。但了解一下这个细节还是对分析问题很有帮助的!
这样我们就应该有两个runner了(一个是shell类型,一个是docker类型):

//todo ubuntu -> docker-in-docker -> runner -> docker engine
.gitlab-ci.yml
这个文件应该放在我们的项目repo的根目录下,用来描述当发生目标行为后,runner要做的工作。官方文档有对其语法的描述。
环境基本上就搭建好了,下一篇我们就开始设计工作流了。
趁热打铁,根据之前我们自己搭建的gitlab-ci环境,我们来跑一个demo项目,爽一下~
我们的目的是,程序员提交代码到gitlab,会触发自动创建镜像,并上传到公共的镜像仓库(目前先这么搞)。
根据官方的文档,我们先在gitlab上搭建一个项目,结构如下:
|
|
其中,.dockerignore
文件内容:
|
|
.gitignore
:
|
|
.gitlab-ci.yml
:
|
|
Dockerfile
:
|
|
app.js
:
|
|
package.json
:
|
|
好了,把上面这个项目提交到我们的gitlab环境下,就会触发自动的“build”了(确保你的gitlab配置开启了”build”)!
不过怎么可能顺利呢?第一次一般都是失败的,查看错误日志:
|
|
你的错误信息可能和我的不完全一样,不过问题是一样的:Runner启动的docker容器里无法访问到localhost:10080
这个地址(能访问到才怪)。这一般是由于我们的测试环境没有使用域名导致的,gitlab论坛里也不少人讨论这个问题,如果你是在部署正式的gitlab环境,那你自然会有一个域名来使用。不过我这里只是搭建测试环境,所以我使用了一种投机的方法:
修改Runner的/etc/gitlab-runner/config.toml
文件,在其中的[runner.docker]
下增加:
|
|
意思是,让runner启动的容器中将”localhost”域映射到我的ubuntu宿主机,这样runner请求”localhost:10080”时就会被路由到正确的地址,不推荐正式环境下这么做~
然后再次触发build,这次看看还会碰到什么问题么:
|
|
这次悲剧了,我的ubuntu虚拟主机分配的磁盘空间太小,结果现在提示硬盘控件不足……(这里我发现其实我分配的磁盘控件(8G)才使用了2G多一点,不明白VirtualBox为什么不给虚拟机扩展容量了!)
我只能删除掉一些不使用的镜像和容器来腾出一些地儿,再次build,好家伙,虚拟机直接死掉了。
[直播]
对,目前还处于无响应状态,不知道为啥,我只能等。。。
已经快二十分钟,妈蛋!
我方了,咋办?
……
我强行重启虚拟机后一切都归零了,gitlab container无法正常启动了,娃哈哈哈哈~玩我呢是吧?也没有任何错误日志给我参考,得了,重新装一次环境得了~
重新安装环境很快的其实,我们只需要停止所有的容器,然后删除重建一下/srv/docker/gitlab/
这个目录即可,该目录就是之前我们搭建环境时往相关容器中加载的本地卷,重建它们以为这之前在gitlab上的操作都不要了,再次start相关容器,一个干净的gitlabCI环境就好了(docker的魔力)~~
除此之外由于我们的gitlabCI重建后Runner的token也更新了,所以要重新register一下我们的Runner,一切又和好如初!
不怕死的我再一次尝试build,这次会成功么?(有了这次教训,建议你再重新开始build之前先对虚拟机做一个快照,这样再失败就可以直接回滚了~)
由于之前碰到了磁盘空间不足的问题,所以这里就建议使用微容器,可以省下来一笔相当可观的空间和流量啊,Dockerfile的第一行改成:
|
|
好了,漫长的等待后(全看网速)就可以看到灵雀云中已经成功创建好镜像了!
这里需要 强烈提醒:在测试该镜像时:
|
|
一定要加-it
,不然你就傻逼了,像我一样无法退出该docker容器了。。。。草!有知道如何解决这个问题的朋友请一定要给我留言啊!
这篇关于基于docker+gitlabCI搭建私有集成环境的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!