鯨魚上的麻雀型 GitLab-CI|Piece of DevOps

顧名思義,就是在 Docker 上建個五臟俱全的 GitLab-CI (雖然這類的文章很多,但凡事求個圓,希望能讓 CI 雕蟲小技系列可以完整一點)。但怎樣算是麻雀型 GitLab-CI 呢?在我的定義上,有以下兩個角色:
  • GitLab:本體。少了他,一切變得沒有意義。
  • GitLab-Runner:乖乖聽話的手腳。
GitLab 這個角色沒有什麼好爭議的。但在 GitLab-Runner 上,就看個人的喜好。有些人喜歡直接在 Runner 上建立特定的環境,讓 Runner 單純執行特定任務。例如,在 Runner 上建立 Python 3.6 的環境,讓他單純只執行 Python 3.6 相關的任務。這樣的好處是可以有較高的環境的掌控度,想要預先安裝什麼套件或放置什麼檔案都可以,也代表著在 CI 的前處理上可以較為輕鬆。

另一種方式,則是在 Runner 上跑 Docker。執行 CI 相關階段 (Stage) 時,再決定需要使用什麼 Image 來執行對應的指令。這樣的好處在於,你可以不用做出一個盡善盡美的 Runner,隨身攜帶上百種的武器,以面對任何情況。等到需要的時候,再拉下需要的 Image 即可。但相對的,能拉下的 Image 不可能每次都那麼剛好,完全符合需求。所以我們需要額外花一些力氣,多寫一些指令,補足缺失的部分。雖然補足缺少的部分有些麻煩,但這也代表著,你知道怎麼把專案對環境的依賴程度降低。我個人比較偏好後者,所以在此就介紹他(Docker executor)。

以上是我對這隻麻雀的想法,接下來進入正題,就讓我們從沒有爭議的本體開始!

GitLab

因為是鯨魚上的 GitLab,我們就從 Docker Hub 上,把他拉下來吧。
$ docker pull gitlab/gitlab-ce
成功拉下來後,先別急著使用 docker run 招喚他,因為我們還有一些前置動作需要處理,以利後續把 GitLab 跟 Runner 接在起來。那我們需要哪些前置動作呢?首先,我們要在 Docker 上建立一個 CICD 的網路。如此,才能為 Container 指定 IP ,進而有利於管理環境(如果直接使用 Default 的網路 bridge,是無法指定 IP 的哦!):
$ docker network create --subnet=172.18.0.0/16 cicd
如此,我們就建好一個網路了。接下來確認 GitLab 要使用的 IP,這樣我們才能知道 GitLab 的 Domain Name 需要指向哪個 IP。確認的方法如下:
$ docker network inspect cicd | grep IPv4                                                  
此指令可以幫助我們找到 cicd 網路中,已經使用哪些 IP 了。所以我們只要跳過這些 IP,選一個同網域 (172.17.0.0/16) 的下的 IP 即可。因為 cicd 是新建立的網路,所以沒有任何的 IP被使用,就安心的選吧!

在這裡我們為 GitLab 選擇 IP:172.18.0.2 及 Domain Name:gitlab.devops.com。接下來,我們可以好好招喚他了。其指令如下:
$ mkdir gitlab-ce
$ cd gitlab-ce
$ docker run -d --name=gitlab-ce \
             --network=cicd \
             --ip=172.18.0.2 \
             --hostname=gitlab.devops.com \
             --add-host=gitlab.devops.com:172.18.0.2 \
             -v $(pwd)/gitlab-etc:/etc/gitlab \
             -v $(pwd)/gitlab-opt:/var/opt/gitlab \
             -v $(pwd)/gitlab-log:/var/log/gitlab \
             -p 8080:80 -p 8443:443 -p 8022:22 gitlab/gitlab-ce
指令中我們建一個目錄 gitlab-ce ,並在其中放置 GitLab 使用的相關 Volume (etc, opt, log)。我們也給了 GitLab 名字,也就是 gitlab.devops.com。這個名字主要是方便後續與 Runner 及其他服務連接。

想知道 GitLab 啟動完了嗎?你可以透過 docker ps 確認 gitlab-ce 的 STATUS 是否處於 healthy 的狀態:
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                        PORTS                                                               NAMES
0f36ce69ab99        gitlab/gitlab-ce    "/assets/wrapper"   42 minutes ago      Up About a minute (healthy)   0.0.0.0:8022->22/tcp, 0.0.0.0:8080->80/tcp, 0.0.0.0:8443->443/tcp   gitlab-ce
確認完後,就可以透過 127.0.0.1:8080 找到他。第一次開啟時,GitLab 會請你設定 root 的密碼,也就可以利用其密碼,以 root 登入。這部分完成後,接下來,我們先把 Runner 也 Run 起來吧。

GitLab-Runner

Runner 的部分,也是透過 Docker Hub 取得 Image。
$ docker pull gitlab/gitlab-runner
這裡我們選擇 IP:172.18.0.5 當作 Runner 的 IP。並記得告訴 Runner,GitLab 的 Domain Name 及 IP。另外,因為我們是要在 Runner 上跑 Docker 所以也要記得幫他掛上 /var/run/docker.sock,這樣 Runner 才能執行 Docker 相關的操作:
$ cd .. # 回到上層目錄
$ mkdir gitlab-runner
$ cd gitlab-runner
$ docker run -d --name=gitlab-runner \
             --network cicd \
             --ip=172.18.0.3 \
             --add-host="gitlab.devops.com:172.18.0.2" \
             -v /var/run/docker.sock:/var/run/docker.sock \
             -v $(pwd):/etc/gitlab-runner gitlab/gitlab-runner
除了掛載 docker.sock,我們也將 Runner 內的 /etc/gitlab-runner 掛出來,也是便利之後設定 Runner 相關參數。

現在 GitLab 跟 Runner 都準備好了,那就開始註冊 Runner 到 GitLab 中吧!

註冊 Runner

首先,我們需要先在 GitLab 上取得 Runner Resignation Token。取得方法是透過 GitLab 的 UI 介面進行,其步驟如下:
  1. 以 Root 登入 GitLab。
  2. 點擊上方巡航列的鈑手符號,進入管理者介面 (Admin Area)。
  3. 點擊左方巡航欄 Overview 底下的 Runners,進入Runners 管理介面。
  4. 頁面的右邊,就會顯示 Runner Resignation Token。
你或許注意到了頁面上也有顯示:

Specify the following URL during the Runner setup: http://127.0.0.1:8080/

但在這裡,這只是個幌子。因為他是依連接的網址來顯示,此網址顯然不是在 Docker 內使用的。因此,等一下註冊 Runner 的時候,還是要使用我們填上的 Domain Name 才能讓 Runner 找得到 GitLab。取得 Token 後,GitLab 的部分,就告一個段落,接下來到 Runner 上開始註冊:
$ docker exec -it gitlab-runner bash
$ root@ccfedce15250:/# gitlab-runner register --docker-network-mode cicd --docker-extra-hosts "gitlab.devops.com:172.18.0.2"
Runtime platform                                    arch=amd64 os=linux pid=70 revision=ac8e767a version=12.6.0
Running in system-mode.
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
http://gitlab.devops.com/
Please enter the gitlab-ci token for this runner:
<your token>
Please enter the gitlab-ci description for this runner:
[ccfedce15250]: all-in-one
Please enter the gitlab-ci tags for this runner (comma separated):
all-in-one
Registering runner... succeeded                     runner=Q9xxCJiS
Please enter the executor: shell, ssh, docker+machine, kubernetes, docker, docker-ssh, parallels, custom, virtualbox, docker-ssh+machine:
docker
Please enter the default Docker image (e.g. ruby:2.6):
frekele/java:jdk8
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
$ exit # 退出 runner
以上的內容,依需要的內容填寫即可。此 Runner 被規劃來做任何事情,所以直接命名為 all-in-one。最重要的是記得將 executor 填入 docker,讓他符合我們的期待。

除了需要填寫的內容,指令本身也有兩個重點,也就是 --docker-network-mode 及 --docker-extra-hosts。透過這兩個參數,在 Runner 中跑的 container 才能跟 GitLab 在同一個網路中,並得知對應的 Domain Name,進而取得 GitLab 中的專案、執行對應的要求。

以上,我們已經將這隻麻雀完成囉!開始試試看自己的 gitlab-ci.yml 吧!

熱門文章