# 自架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`