基于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:
curl -sSL https://get.docker.com/ | sudo sh
目前這樣的安裝方式,依然需要注意,后面運行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),主要是不熟悉~
我們手動來完成三個容器的啟動:
#啟動postgresql容器 docker run --name gitlab-postgresql -d \ --env 'DB_NAME=gitlabhq_production' \ --env 'DB_USER=gitlab' --env 'DB_PASS=password' \ --env 'DB_EXTENSION=pg_trgm' \ --volume /srv/docker/gitlab/postgresql:/var/lib/postgresql \ index.alauda.cn/sameersbn/postgresql #啟動redis容器 docker run --name gitlab-redis -d \ --volume /srv/docker/gitlab/redis:/var/lib/redis \ index.alauda.cn/sameersbn/redis #最后啟動gitlab容器 docker run --name gitlab -d \ --link gitlab-postgresql:postgresql --link gitlab-redis:redisio \ --publish 10022:22 --publish 10080:80 \ --env 'GITLAB_PORT=10080' --env 'GITLAB_SSH_PORT=10022' \ --env 'GITLAB_SECRETS_DB_KEY_BASE=kazaffisagoodcoder' \ --volume /srv/docker/gitlab/gitlab:/home/git/data \ index.alauda.cn/sameersbn/gitlab
注意,上面的命令我已經改成使用我們本地鏡像的名字了,還有在啟動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容器:
mkdir -p /srv/docker/gitlab-runner docker run --name gitlab-ci-multi-runner -d --restart=always \ --volume /srv/docker/gitlab-runner:/home/gitlab_ci_multi_runner/data \ --link gitlab:gitlab --env='CI_SERVER_URL=http://gitlab/ci' \ --env='RUNNER_TOKEN=你gitlab生成的token' \ --env='RUNNER_DESCRIPTION=myrunner' --env='RUNNER_EXECUTOR=shell' \ index.alauda.cn/sameersbn/gitlab-ci-multi-runner
這里需要提醒的是兩點:
- 你自己的gitlab生成的token可以在 http://localhost:10080/admin/runners 看到(我假設你和我一樣要創建的是一個共享Runner)
- CI_SERVER_URL參數不要使用你物理機瀏覽器地址欄里的值,我們在上面的命令中已經將之前創建的gitlab容器link到了runner容器,so,我們只需要填寫設置的主機名即可,否則無法注冊成功!
接下來刷新你的gitlab管理員后臺,你將會看到注冊成功的Runner信息。
還沒完,由于我們使用的是 shell 模式,所以我們還需要進入到runner容器中來安裝docker環境:
docker exec -it gitlab-ci-multi-runner bash curl -sSL https://get.docker.com/ | sudo sh sudo usermod -aG docker gitlab-runner sudo -u gitlab-runner -H docker info
如果可以看到正確的docker版本信息,那就說明一切順利。 但怎么可能那么順利!! 事實證明我太天真了,在docker容器中由于文件系統是只讀的,所以無法安裝docker環境~至少我們現在的做法還不行,如下圖:
這里說一個插曲,當得到這個結論后的我失望的打算將這個悲劇的鏡像刪除,我在gitlab admin后臺的runner頁面點擊“remove”按鈕,然后又將對應的docker容器也刪除掉。當我再次使用相同的命令打算啟動一個干凈的runner容器時,我發現gitlab的runner頁面不在提示成功注冊runner了!我徹底方了!一切都和第一次執行流程一致,為啥這次就不認了呢?
于是我發現了一個秘密,上面的創建runner容器的命令中有一個參數:
--volume /srv/docker/gitlab-runner:/home/gitlab_ci_multi_runner/data
我在宿主機的 /srv/docker/gitlab-runner 目錄下找到了答案,原來一直試圖想找到的 config.toml 文件在這里,也是因為這個文件的緣故所以gitlab才不在接受我的runner注冊的!刪除并重建這個目錄即可!
走了彎路不可怕,可怕的是接下來不知道怎么辦?沒關系,我們現在先在宿主機上 安裝gitlab-ci-multi-runner環境 ,并使用官方提供的docker-in-docker方式來增加一臺runner:
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.deb.sh | sudo bash sudo apt-get install gitlab-ci-multi-runner sudo gitlab-ci-multi-runner register -n \ --url http://localhost:10080/ci \ --token 你gitlab生成的token \ --executor docker \ --description "My Docker Runner" \ --docker-image "index.alauda.cn/library/docker:latest" \ --docker-privileged
記住,我們這里要填寫的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要做的工作。官方文檔有對其語法的 描述 。
環境基本上就搭建好了,下一篇我們就開始設計工作流了。
來自: http://blog.kazaff.me/2016/06/15/基于docker gitlabCI搭建私有持續集成環境/