zaki work log

作業ログやら生活ログやらなんやら

GitLab CE/GitLab Runner on Docker環境でexecutorもDockerなCI/CD環境

"GitLab CE/GitLab Runner" on Docker環境で、CI/CDの実行環境であるexecutorもDockerで動かす。

f:id:zaki-hmkc:20200314192252p:plain

これまでの流れ

  1. DockerでGitLab CEを動かす
  2. GitLab CE on Dockerをdocker-composeで動かす
  3. GitLab CE on DockerにGitLab Runner on Dockerを追加

本記事は、更にGitLab Runner executorもon Dockerにする手順です。

環境

$ sudo docker version
Client: Docker Engine - Community
 Version:           19.03.5
 API version:       1.40
 Go version:        go1.12.12
 Git commit:        633a0ea
 Built:             Wed Nov 13 07:25:41 2019
 OS/Arch:           linux/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.5
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.12.12
  Git commit:       633a0ea
  Built:            Wed Nov 13 07:24:18 2019
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.2.10
  GitCommit:        b34a5c8af56e510852c35414db4c1f4fa6172339
 runc:
  Version:          1.0.0-rc8+dev
  GitCommit:        3e425f80a8c931f88e6d94a8c831b9d5aa481657
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

docker executor

executorの種類についてはこちら

docs.gitlab.com

設定の追加

コンテナで構築済みのGitLab CE & GitLab Runner環境で、executorの指定にdockerと入力する。

[zaki@registry gitlab-compose]$ sudo docker-compose exec gitlab-runner bash
[sudo] zaki のパスワード:
root@365f57ba0691:/# 
root@365f57ba0691:/# gitlab-runner register
Runtime platform                                    arch=amd64 os=linux pid=376 revision=003fe500 version=12.7.1
Running in system-mode.                            
                                                   
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
https://gitlab-ce.example.org:8443/              # GitLab CEのURLを入力
Please enter the gitlab-ci token for this runner:
oQyQbs-qbp3sMYdn8MLM                             # tokenを入力
Please enter the gitlab-ci description for this runner:
[365f57ba0691]: exec-container-sample            # Runnerの名称
Please enter the gitlab-ci tags for this runner (comma separated):
                                                 # tagはとりあえず空欄
Registering runner... succeeded                     runner=oQyQbs-q
Please enter the executor: docker, parallels, docker+machine, docker-ssh+machine, kubernetes, custom, docker-ssh, shell, ssh, virtualbox:
docker                                           # executorに"docker"を指定
Please enter the default Docker image (e.g. ruby:2.6):
centos:7                                         # docker executor実行時に使用するコンテナイメージ
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded! 

executorにdockerを入力すると、実行に使用するコンテナイメージも聞かれるので、とりあえずcentos:7と入力。
登録自体は特に問題なく完了。
/etc/gitlab-runner/config.tomlに以下の設定が追加される。

[[runners]]
  name = "exec-container-sample"
  url = "https://gitlab-ce.example.org:8443/"
  token = "VrU7GY5pCBVsjnrvQkAR"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.docker]
    tls_verify = false
    image = "centos:7"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    shm_size = 0
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]

webの"Settings"->"CI/CD"の画面でも、登録した項目を確認できる。

f:id:zaki-hmkc:20200314180128p:plain

CI/CDの実行(Host is unreachable)

.gitlab-ci.ymlpushする

と、jobがfailedになった。

 Running with gitlab-runner 12.7.1 (003fe500)
   on exec-container-sample VrU7GY5p
Using Docker executor with image centos:7 ...
 Pulling docker image centos:7 ...
 Using docker image sha256:5e35e350aded98340bc8fcb0ba392d809c807bc3eb5c618d4a0674d98d88bccd for centos:7 ...
Running on runner-VrU7GY5p-project-1-concurrent-0 via 365f57ba0691...
Fetching changes with git depth set to 50...
 Initialized empty Git repository in /builds/zaki/example/.git/
 Created fresh repository.
 fatal: unable to access 'https://gitlab-ce.example.org:8443/zaki/example.git/': Failed to connect to gitlab-ce.example.org port 8443: Host is unreachable
 ERROR: Job failed: exit code 1

指定したcentos:7pullはうまくいってRunnerのコンテナ起動までは良いっぽくて、そのあとのコンテナ内からのGitLab CEへのHTTPSアクセスに失敗してる。
Runnerのコンテナを追加しようとしたときに、Dockerのコンテナ間通信のとこで、ホストOSの外部IPアドレスになっているFQDNアクセスがうまくいかなかったときと同じ状況ね。

というわけで、Dockerのexecutorも、同じDockerネットワークで動かせれば万事OKのハズなんだけど、Runner登録時のgitlab-runner registerってexecutorにdockerを指定するだけで、そんな細かい設定聞かれない。
んじゃどうするかというと、gitlab-runner register --helpしたら「細かい設定」するための大量のオプションがあった:)

# gitlab-runner register --help
Runtime platform                                    arch=amd64 os=linux pid=409 revision=003fe500 version=12.7.1
NAME:
   gitlab-runner register - register a new runner

USAGE:
   gitlab-runner register [command options] [arguments...]

OPTIONS:
   -c value, --config value                                     Config file (default: "/etc/gitlab-runner/config.toml") [$CONFIG_FILE]
   --template-config value                                      Path to the configuration template file [$TEMPLATE_CONFIG_FILE]
   --tag-list value                                             Tag list [$RUNNER_TAG_LIST]
   -n, --non-interactive                                        Run registration unattended [$REGISTER_NON_INTERACTIVE]

:
:

   --docker-network-mode value                                  Add container to a custom network [$DOCKER_NETWORK_MODE]

:
:

はい。

というか、--non-interactiveがあるので、docker execと合わせてコマンド1発で設定できそう。

既存設定を削除

root@365f57ba0691:/# gitlab-runner list
Runtime platform                                    arch=amd64 os=linux pid=456 revision=003fe500 version=12.7.1
Listing configured runners                          ConfigFile=/etc/gitlab-runner/config.toml
sample-runner                                       Executor=shell Token=PUSws8kkxEnz5Qn4npye URL=https://gitlab-ce.example.org:8443/
exec-container-sample                               Executor=docker Token=VrU7GY5pCBVsjnrvQkAR URL=https://gitlab-ce.example.org:8443/
root@365f57ba0691:/# gitlab-runner unregister -n sample-runner 
Runtime platform                                    arch=amd64 os=linux pid=482 revision=003fe500 version=12.7.1
Running in system-mode.                            
                                                   
Unregistering runner from GitLab succeeded          runner=PUSws8kk
Updated /etc/gitlab-runner/config.toml             
root@365f57ba0691:/# gitlab-runner unregister -n exec-container-sample 
Runtime platform                                    arch=amd64 os=linux pid=490 revision=003fe500 version=12.7.1
Running in system-mode.                            
                                                   
Unregistering runner from GitLab succeeded          runner=VrU7GY5p
Updated /etc/gitlab-runner/config.toml   
root@365f57ba0691:/# gitlab-runner list
Runtime platform                                    arch=amd64 os=linux pid=498 revision=003fe500 version=12.7.1
Listing configured runners                          ConfigFile=/etc/gitlab-runner/config.toml

docker networkの設定

Composeを使うことで、デフォルトのネットワークが作成されるので、それをexecutorでも指定すれば良いと思うけど、せっかくなのでネットワーク名を明示して設定する。

[zaki@registry gitlab-compose]$ sudo docker-compose up -d
Creating network "gitlab-compose_gitlab-network" with the default driver
Recreating gitlab-compose_gitlab-ce.example.org_1 ... done
Recreating gitlab-compose_gitlab-runner_1         ... done
[zaki@registry gitlab-compose]$ sudo docker network ls
NETWORK ID          NAME                            DRIVER              SCOPE
0926d5e3735c        bridge                          bridge              local
c2b0c6e7af5a        gitlab-compose_default          bridge              local
a39488d10ed4        gitlab-compose_gitlab-network   bridge              local
dd0c214d8a50        host                            host                local
ea4f23a6b8d6        none                            null                local

gitlab-compose_gitlab-networkが作成された。
(gitlab-compose_defaultが残骸として残ってしまった…)

docker network指定でRunnerの再作成

インタラクティブ版で入力してた項目は以下の通り

項目 入力値
URL https://gitlab-ce.example.org:8443/
token oQyQbs-qbp3sMYdn8MLM
description exec-container-sample
tags N/A
executor docker
Docker image centos:7

これにgitlab-compose_gitlab-networkをネットワークとして追加指定する。
というわけで、実行するgitlab-runner registerはこんな感じ。

$ gitlab_url=https://gitlab-ce.example.org:8443/
$ runner_token=oQyQbs-qbp3sMYdn8MLM
$ runner_name=exec-container-sample
$ sudo docker-compose exec gitlab-runner gitlab-runner register -n \
  --url ${gitlab_url} \
  --registration-token ${runner_token} \
  --name ${runner_name} \
  --executor docker \
  --docker-image centos:7 \
  --docker-network-mode gitlab-compose_gitlab-network

tagの指定がある場合は--tag-list foo-tag,bar-tag,...も追加する。

[zaki@registry gitlab-compose]$ sudo docker-compose exec gitlab-runner gitlab-runner register -n \
>   --url ${gitlab_url} \
>   --registration-token ${runner_token} \
>   --name ${runner_name} \
>   --executor docker \
>   --docker-image centos:7 \
>   --docker-network-mode gitlab-compose_gitlab-network
Runtime platform                                    arch=amd64 os=linux pid=43 revision=003fe500 version=12.7.1
Running in system-mode.                            
                                                   
Registering runner... succeeded                     runner=oQyQbs-q
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded! 

(コンテナ名のgitlab-runnerとコマンドのgitlab-runnerが同じで片方指定忘れでPATH上にそんなもんねぇと何度も怒られたことは秘密)

設定ファイルは以下の通り

[zaki@registry gitlab-compose]$ sudo docker-compose exec gitlab-runner cat /etc/gitlab-runner/config.toml
concurrent = 1
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "exec-container-sample"
  url = "https://gitlab-ce.example.org:8443/"
  token = "oT8fwM5We2xUVCS9bJKe"
  executor = "docker"
  [runners.custom_build_dir]
  [runners.docker]
    tls_verify = false
    image = "centos:7"
    privileged = false
    disable_entrypoint_overwrite = false
    oom_kill_disable = false
    disable_cache = false
    volumes = ["/cache"]
    network_mode = "gitlab-compose_gitlab-network"
    shm_size = 0
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]

webの画面だとこの通り。

f:id:zaki-hmkc:20200314184603p:plain

jobの再実行

.gitlab-ci.ymlファイルをpushし直さなくても、Pipelineの一覧から失敗しているものは、リトライボタンがあるので手動で再実行できる。

f:id:zaki-hmkc:20200314185017p:plain

リトライボタン押下ですぐ再実行が始まる

f:id:zaki-hmkc:20200314185228p:plain

今度はうまく行きました。

f:id:zaki-hmkc:20200314185349p:plain

 Running with gitlab-runner 12.7.1 (003fe500)
   on exec-container-sample oT8fwM5W
Using Docker executor with image centos:7 ...
 Pulling docker image centos:7 ...
 Using docker image sha256:5e35e350aded98340bc8fcb0ba392d809c807bc3eb5c618d4a0674d98d88bccd for centos:7 ...
Running on runner-oT8fwM5W-project-1-concurrent-0 via 46ccbe8224e8...
Fetching changes with git depth set to 50...
 Initialized empty Git repository in /builds/zaki/example/.git/
 Created fresh repository.
 From https://gitlab-ce.example.org:8443/zaki/example
  * [new ref]         refs/pipelines/6 -> refs/pipelines/6
  * [new branch]      master           -> origin/master
 Checking out 075be87c as master...
 Skipping Git submodules setup
$ uname -r
 3.10.0-1062.9.1.el7.x86_64
 $ ls -alF
 total 4
 drwxrwxrwx. 3 root root  57 Mar 14 09:50 ./
 drwxrwxrwx. 4 root root  40 Mar 14 09:50 ../
 drwxrwxrwx. 6 root root 113 Mar 14 09:50 .git/
 -rw-rw-rw-. 1 root root  90 Mar 14 09:50 .gitlab-ci.yml
 -rw-rw-rw-. 1 root root   0 Mar 14 09:50 README.md
 $ ps auxwwf
 USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
 root          1  0.0  0.0  11692  1388 ?        Ss   09:50   0:00 /usr/bin/bash
 root          7  0.0  0.0  11696  1000 ?        S    09:50   0:00 /usr/bin/bash
 root         11  0.0  0.0  51748  1680 ?        R    09:50   0:00  \_ ps auxwwf
 $ hostname
 runner-oT8fwM5W-project-1-concurrent-0
 $ id
 uid=0(root) gid=0(root) groups=0(root)
 Job succeeded

これで、Dockerコンテナを使ってexecutorが動くので、CI/CDの度にまっさらな状態で実行されるので、前回実行時の残骸による影響を除外して動作させることができる。

ちなみに、実行が完了してもコンテナ自体はexit 0で残り続けるので、docker ps -aすると実行完了したコンテナの残骸がどんどん溜まってるのが確認できる。適当にrmすること。

実行時のイメージの指定

executor実行環境のコンテナイメージは、executor作成時にcentos:7を指定しているが、.gitlab-ci.ymlimage設定すればそちらが優先される。

---
image: ubuntu:18.04

job01:
  script:
    - uname -r
    - ls -alF
    - ps auxwwf
    - hostname
    - id
    - ls /etc

と書いておけば、ubuntu:18.04コンテナで実行される。

docker-compose.yml

---
version: '3'
services:
  gitlab-ce.example.org:
    image: gitlab/gitlab-ce:12.7.4-ce.0
    hostname: gitlab-ce.example.org
    restart: always
    ports:
      - "8443:8443"
      - "25000:25000"
    environment:
      GITLAB_OMNIBUS_CONFIG: "external_url 'https://gitlab-ce.example.org:8443'; nginx['listen_port']=8443; gitlab_rails['registry_enabled']=true; registry_external_url 'https://gitlab-ce.example.org:25000'"
    volumes:
      - /opt/gitlab-reg/config:/etc/gitlab:Z
      - /opt/gitlab-reg/logs:/var/log/gitlab:Z
      - /opt/gitlab-reg/data:/var/opt/gitlab:Z
      - /opt/gitlab-reg/registry:/var/opt/gitlab/gitlab-rails/shared/registry:Z
      - /opt/gitlab-cert:/etc/gitlab/ssl
    networks:
      - gitlab-network
  gitlab-runner:
    image: gitlab/gitlab-runner:v12.7.1
    restart: always
    volumes:
      - /opt/gitlab-runner/config:/etc/gitlab-runner:Z
      - /var/run/docker.sock:/var/run/docker.sock
      - /opt/gitlab-cert:/etc/gitlab-runner/certs
    networks:
      - gitlab-network

networks:
  gitlab-network:

実は別の環境(ホストOSはCentOSでなくRHELでdockerも古かった気がする)だとSELinuxの影響で/var/run/docker.sockがRunnerコンテナから実行できずにexecutorが起動しなかったんだけど、おうちのCentOS(Docker 19.03)だと特に問題なかったな。。

Runnerの公式ドキュメントでSELinux周りの説明はこちら

関連


そろそろアプリ作りたいっすねぇ。。