# 自架GitLab - 為GitLab添加Runner
[TOC]
## 簡介
在上一篇的[自架GitLab - 基於Docker的實作](https://hackmd.io/@davidho9713/self_host_gitlab_setup)中,我們實作了利用Docker建立自架GitLab服務。在CI/CD中,一個用於執行檢測以及佈署任務的Runner/Worker是不可或缺的,那我們要如何為自架的GitLab服務添加Runner呢?
答案很簡單:利用Docker來建立Runner容器並將其註冊至GitLab即可。接下來我們將示範如何實作。
## 利用Docker建立GitLab-Runner容器
:::warning
請務必將以下教學中的`/path/to/your`前綴更改成讀者自身所設定的位置。
:::
首先,我們可以利用GitLab所提供的`gitlab/gitlab-runner`搭配`docker-compose`指令來建立`GitLab-Runner`容器。
首先,我們修改上一篇中的`docker-compose.yml`,將`GitLab-Runner`的容器設定加入其中:
```=
version: '3.5'
services:
gitlab:
image: gitlab/gitlab-ce
hostname: gitlab.me
container_name: gitlab-main
restart: always
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url "https://gitlab.me"
letsencrypt['enable'] = false
volumes:
- /path/to/your/gitlab/config:/etc/gitlab
- /path/to/your/gitlab/logs:/var/log/gitlab
- /path/to/your/gitlab/data:/var/opt/gitlab
- /var/run/docker.sock:/var/run/docker.sock
ports:
- '443:443'
- '80:80'
extra_hosts:
- "gitlab.me:192.168.0.101"
networks:
- devops-net
gitlab-runner:
image: gitlab/gitlab-runner:latest
container_name: gitlab-runner
restart: always
networks:
- devops-net
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /path/to/your/gitlab-runner:/etc/gitlab-runner
extra_hosts:
- "gitlab.me:192.168.0.101"
networks:
devops-net:
```
這樣我們就可以將`gitlab-runner`容器納入`devops-net`這個與`gitlab-main`容器相同的網路中了。
在修改好設定之後,只需要重新執行`docker-compose up -d`更新設定之後,就會產生一個名為`gitlab-runner`的容器了。
:::info
雖然我們這邊將兩者納入相同的網路之中,但由於我們仍使用實體IP溝通,故在此篇中無法看到基於此設定的一些特點。
:::
## 將GitLab-Runner註冊至GitLab團隊
在將`GitLab-Runner`註冊至GitLab之前,我們需要先取得一組`token`用以提供給`gitlab-runner register`進行註冊。
### 取得Token
首先,先登入自架的GitLab網站,
![](https://i.imgur.com/HxCs4Wq.png)
點擊上方的`+`號,建立一個團隊,
![](https://i.imgur.com/RHe0hct.png)
在團隊的頁面中,點擊左側面板的`CI/CD`選項,進入該設定頁面,
![](https://i.imgur.com/20atnd1.png)
點擊右方的`Register a group runner`按鈕,就會跳出一個對話窗,並提供一組Token用以註冊,
![](https://i.imgur.com/yiUV0dg.png)
請記住這一組Token,稍後將需要使用。
### 註冊GitLab-Runner
在上一步驟中,我們取得了一組Token,接下來我們將利用該組Token將`GitLab-Runner`註冊至上一步中建立的團隊。有兩種作法可以將`GitLab-Runner`註冊至GitLab服務。
1. Docker
要利用Docker註冊`GitLab-Runner`到GitLab,需要先建立一個`GitLab-Runner`的容器,再利用互動模式輸入相對應的資訊來註冊。讀者可以透過下方的指令啟動一個`gitlab-runner`容器。
```shell=
docker run -itd --restart always --name gitlab-runner \
-v /path/to/your/gitlab-runner:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
-e CA_CERTIFICATES_PATH=/etc/gitlab-runner/certs/server.crt \
-e LOCAL_CA_PATH=/usr/local/share/ca-certificates/ \
--add-host gitlab.me:192.168.0.101 gitlab/gitlab-runner
```
以互動模式註冊的相應步驟,我們將在`Docker-compose`章節一同介紹。
:::info
上方的`-e CA_CERTIFICATES_PATH=...`以及`-e LOCAL_CA_PATH=...`是在使用HTTPS連線時所需要的參數,用以讓`gitlab/gitlab-runner`的預設`entrypoint`將自簽SSL證書加入容器的信任憑證之中。在使用HTTP連線時,不需要提供此兩項資訊。
:::
2. Docker-compose
* 更新`docker-compose.yml`
在上方章節中,我們介紹了如何利用`docker run`指令搭配相應參數來註冊。在本章節我們將介紹如何利用`docker-compose`指令的方式來建立並註冊`GitLab-Runner`。我們先回顧一下先前我們用以設定GitLab服務的`docker-compose.yml`檔案。
```=
version: '3.5'
services:
gitlab:
image: gitlab/gitlab-ce
hostname: gitlab.me
container_name: gitlab-main
restart: always
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url "https://gitlab.me"
letsencrypt['enable'] = false
volumes:
- /path/to/your/gitlab/config:/etc/gitlab
- /path/to/your/gitlab/logs:/var/log/gitlab
- /path/to/your/gitlab/data:/var/opt/gitlab
- /path/to/your/var/run/docker.sock:/var/run/docker.sock
ports:
- '443:443'
- '80:80'
extra_hosts:
- "gitlab.me:192.168.0.101"
networks:
- devops-net
networks:
devops-net:
```
我們可以透過在上方的設定中的`serviers`部份之下新增一個`gitlab-runner`部份,並將相對應的資訊帶入設定之中,用以讓`docker-compose`指令能夠依照設定建立一個`gitlab-runner`容器。
```=
version: '3.5'
services:
gitlab:
image: gitlab/gitlab-ce
hostname: gitlab.me
container_name: gitlab-main
restart: always
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url "https://gitlab.me"
letsencrypt['enable'] = false
volumes:
- /path/to/your/gitlab/config:/etc/gitlab
- /path/to/your/gitlab/logs:/var/log/gitlab
- /path/to/your/gitlab/data:/var/opt/gitlab
- /path/to/your/var/run/docker.sock:/var/run/docker.sock
ports:
- '443:443'
- '80:80'
extra_hosts:
- "gitlab.me:192.168.0.101"
networks:
- devops-net
gitlab-runner:
image: gitlab/gitlab-runner:latest
container_name: gitlab-runner
restart: always
networks:
- devops-net
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/david/gitlab-runner:/etc/gitlab-runner
extra_hosts:
- "gitlab.me:192.168.0.101"
# Only need when using HTTPS
environment:
CA_CERTIFICATES_PATH: "/etc/gitlab-runner/certs/server.crt"
LOCAL_CA_PATH: "/usr/local/share/ca-certificates/"
networks:
devops-net:
```
上方為更新後的`docker-compose.yml`,只要在執行一次`docker-compose up -d`指令,就能將此容器納入與GitLab服務相同的組成之中。上方的設定中,有一個`environment`的部份,是用以將自簽SSL證書的位置以環境變數的方式宣告至容器內,與上一節的`-e ...`相同,是為了讓啟動容器時的`entrypoint`能自動將我們的證書加入信任憑證之中。
* 利用互動模式註冊`gitlab-runner`
在上一步驟,我們利用`docker-compose`指令建立了一個`gitlab-runner`容器,接下來需要用先前的Token來註冊`gitlab-runner`。
1. 首先執行以下指令,此指令為啟動註冊程序
```shell
docker exec -it gitlab-runner gitlab-runner register
```
2. 根據提示輸入必要資訊,例如:GitLab服務連結,Token資訊以及`GitLab Executer`設定以及相關標籤。
```shell=
user@CPUNode:~/workplace/devops$ docker exec -it gitlab-runner gitlab-runner register
Runtime platform arch=amd64 os=linux pid=1337 revision=7f093137 version=15.2.0
Running in system-mode.
Enter the GitLab instance URL (for example, https://gitlab.com/):
https://gitlab.me
Enter the registration token:
<PLACE YOUR TOKEN HERE>
Enter a description for the runner:
[4b3193ddb657]: cpu
Enter tags for the runner (comma-separated):
cpu
Enter optional maintenance note for the runner:
cpu
Registering runner... succeeded runner=GR1348941bf4A3CAE
Enter an executor: virtualbox, kubernetes, custom, docker, parallels, ssh, docker-ssh, shell, docker+machine, docker-ssh+machine:
docker
Enter the default Docker image (for example, ruby:2.7):
python:3.9.13
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
Configuration (with the authentication token) was saved in "/etc/gitlab-runner/config.toml"
```
以上就是註冊`GitLab-Runner`到GitLab的基本流程了。在完成註冊後,將可以在團隊的`CI/CD`頁面看到`Runner`的資訊。
![](https://i.imgur.com/S1x4BqN.png)
## 延伸閱讀 - 將Host資訊以及SSL憑證設定傳遞至GitLab Docker Executor
在前述的章節中,我們成功的將Runner註冊至GitLab,但還有些事情必須去完成。以GitLab-Runner的Executor來說,有`virtualbox`,`kubernetes`, `custom`, `parallels`, `ssh`, `docker+machone`, `shell`以及 `docker-ssh+machine`等不同的Executor。
有些Executor是基於實體系統的,我們可以在實體系統中預先設定好Host資訊以及相關憑證信任設定,但如果是像Docker這種容器,本身不一定能夠同步使用實體系統的Host資訊時,又該如何呢?接下來我們將以`GitLab Docker Executor`為例,示範如何為`GitLab-Runner`所建立的容器添加相關設定以及資訊。
對於`GitLab-Runner`的設定修改,都是透過對`config.toml`做修改來達成的。只要在相對硬的部份加入正確的設定即可。
1. 在`[[runners.docker]]`設定中新增Host設定以及憑證設定
* 掛載憑證至容器內
為了使新建的容器能夠取用到憑證,我們必須在`[[runners.docker]]`設定中用`volumes`設定將憑證掛載至容器中的位置。如下所示:
```
[[runners]]
....
[runners.docker]
tls_verify = false
image = "python:3.9.13"
privileged = false
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache", "/home/david/gitlab-runner/certs/server.crt:/etc/gitlab-runner/certs/server.crt:ro"]
shm_size = 0
```
* 新增Host資訊
為了能讓新建的容器能夠連線至我們自架的`gitlab.me`網站,我們可以透過在`[[runners.docker]]`設定中新增`extra_hosts`資訊,或是直接將`network_mode`指定為`"host"`模式來讓容器取用實體系統的Host設定。以下是兩種方法的示範:
作法一:新增`extra_hosts`資訊
```
[[runners]]
....
[runners.docker]
tls_verify = false
image = "python:3.9.13"
privileged = false
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache", "/home/david/gitlab-runner/certs/server.crt:/etc/gitlab-runner/certs/server.crt:ro"]
extra_hosts = ["gitlab.me:192.168.0.101"]
shm_size = 0
```
作法二:設定`network_mode`
```
[[runners]]
....
[runners.docker]
tls_verify = false
image = "python:3.9.13"
privileged = false
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache", "/home/david/gitlab-runner/certs/server.crt:/etc/gitlab-runner/certs/server.crt:ro"]
network_mode = "host"
shm_size = 0
```
2. 在`[[runners]]`設定中新增`pre_build_script`
在上一步驟中,我們將憑證資訊掛載到了容器之中,但還需要一個步驟來讓新建的容器能夠信任憑證。處理方法為在`[[runners]]`設定中新增`pre_build_script`來讓容器在建立之時執行相關指令來更新憑證信任。這邊我們以基於Ubuntu的容器為範例來示範如何進行設定。
```
[[runners]]
name = "test"
url = "https://gitlab.me"
token = "<YOUR TOKEN>"
executor = "docker"
pre_build_script = """
apt-get update -y > /dev/null
apt-get install -y ca-certificates > /dev/null
cp /etc/gitlab-runner/certs/ca.crt /usr/local/share/ca-certificates/ca.crt
update-ca-certificates --fresh > /dev/null
"""
[runners.docker]
...
```
:::info
關於GitLab-Runner的自簽憑證設定,可以至[GitLab官方教學:link:](https://docs.gitlab.com/runner/configuration/tls-self-signed.html)獲取詳細資訊。
:::
完成上述設定之後,就能夠成功讓`GitLab-Runner`新建的容器也能信任我們的自簽憑證以及自定義的網域了。
## 參考資料
1. [如何在區域網路用 Docker 架設有 SSL 的 Gitlab](https://blog.niclin.tw/2020/02/10/build-internal-gitlab-by-self-certificate/)
2. [GitLab - The Docker executor](https://docs.gitlab.com/runner/executors/docker.html)
3. [GitLab - Install GitLab Runner](https://docs.gitlab.com/runner/install/)
4. [GitLab官方教學 - 憑證設定](https://docs.gitlab.com/runner/configuration/tls-self-signed.html)
###### tags: `技術隨筆` `DevOps` `GitLab` `GitLab-Runner` `Docker` `Docker-compose` `HTTPS` `HTTP` `Self-Host`