GitLab Runner を Docker Machine の Generic ドライバを使って構築する

はじめに

GitLab Runner を使った CI/CD を行っています。 GitLab Runner を実行するサーバには、現在はクラウドサービスを利用せず、オンプレミスサーバ(という名の余っているPC)を使っています。

GitLab Runner を稼働させる物理PCを増やせば一度に実行できるジョブを増やせるのですが、増設作業と管理が面倒だなーと思っていました。 具体的には GitLab Runner を増設するときには、1台ごとに次の作業を行っています。

  1. サーバOSのセットアップ
  2. Docker のインストール
  3. GitLab Runner のインストール
  4. GitLab に GitLab Runner を登録する
  5. GitLab Runner の設定を調整する

一回セットアップしてしまえば、あとはほぼ安定して稼働してくれるのですが、GitLab Runner の設定値を変更したい場合には、各サーバで作業しなくてはならず煩わしく感じていました。

これらの問題に対して、GitLab Runner では Autoscaling GitLab Runner という機能を提供しています。 これを使うと必要なリソースに応じて EC2 や Kubernetes 上に用意したリソースを割り当てることができます。

今回は、オンプレ(という名の余っているPC)で気軽に増設と管理がしたかったので、Docker Machine の Generic ドライバで管理しているリモートの Docker Engine に対して GitLab Runner を設定してみます。

検証環境

次の3台のサーバを用意しました。 GitLab Runner と Docker Machine をインストールした master サーバと、Docker Engine をインストールした node サーバ2台を用意しました。

f:id:u9bo:20190331201316p:plain:w300

Docker Machine の generic ドライバを利用して、Docker Machine をインストールした master サーバから、node サーバ2台を操作します。

http://docs.docker.jp/machine/drivers/generic.html

  • GitLab Runner サーバ(ホスト名: master)
    • Ubuntu Server 18.04 LTS
    • GitLab Runner
    • Docker Engine
    • Docker Machine
  • Docker Engine サーバ(ホスト名: node1, node2)
    • Ubuntu Server 18.04 LTS
    • Docker Engine

Ubuntu のインストール

よしなに進めます。今回は VMware ESXi 上に構築しました。

update / upgrade

iterm2 で複数接続に対して同時入力(ブロードキャスト)するときは、command + D で分割して、 option + command + i (覚えた!)

$ sudo apt-get update
$ sudo apt-get upgrade

node サーバ

sudo 権限の設定

docker-machine から接続した際に、sudo 権限をパスワード確認なしに実行できるようにします(怖いですね)。

$ sudo visudo

に以下を追加(username は対象のユーザ名に読み替えてください)

username ALL=NOPASSWD: ALL

master サーバ

Docker / Docker Machine のインストール

ドキュメントに沿って、よしなに進めます。

http://docs.docker.jp/engine/installation/linux/docker-ce/ubuntu.html

http://docs.docker.jp/machine/install-machine.html

Docker Engine

$ sudo apt-get remove docker docker-engine docker.io && \
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common && \
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \
sudo apt-key fingerprint 0EBFCD88 && \
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable" && \
sudo apt-get update && sudo apt-get install docker-ce

Docker Machine

$ curl -L https://github.com/docker/machine/releases/download/v0.16.1/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
    chmod +x /tmp/docker-machine &&
    sudo cp /tmp/docker-machine /usr/local/bin/docker-machine

バージョンは必要に応じて確認してください。

SSH鍵の作成

$ ssh-keygen -t rsa

生成された公開鍵は node1, node2 に登録しておきます。

$ ssh node1 "cd ~/ && mkdir .ssh && touch .ssh/authorized_keys && chmod 700 .ssh && chmod 600 .ssh/authorized_keys"
$ cat ~/.ssh/id_rsa.pub | ssh node1 "cat >> ~/.ssh/authorized_keys"
$ ssh node2 "cd ~/ && mkdir .ssh && touch .ssh/authorized_keys && chmod 700 .ssh && chmod 600 .ssh/authorized_keys"
$ cat ~/.ssh/id_rsa.pub | ssh node2 "cat >> ~/.ssh/authorized_keys"

Docker Macine に Docker Engine (node1, node2)の追加

Docker Macine に Docker Engine を追加します。

$ docker-machine create \
  --driver generic \
  --generic-ip-address=node1 \
  --generic-ssh-user=username \
  --generic-ssh-key=$HOME/.ssh/id_rsa \
  node1
$ docker-machine create \
  --driver generic \
  --generic-ip-address=node2 \
  --generic-ssh-user=username \
  --generic-ssh-key=$HOME/.ssh/id_rsa \
  node2

このとき、 docker-machine create では次のことを行います。

作成時、ドライバは以下の処理を行います。

  • ホスト上で docker が動いていなければ、自動的にインストールを行う。
  • ホスト上のパッケージを更新します( apt-get update yum update … )
  • docker デーモンを安全にする証明書を生成する。
  • docker デーモンを再起動するため、実行中のコンテナは全て停止される。
  • ホスト名がマシン名に対応します。

参照: http://docs.docker.jp/machine/drivers/generic.html

どんなコマンドが実行されているかは debug オプション docker-machine -D create ... を指定します。

docker-machine create が完了したら、追加されているか確認してみましょう

$ docker-machine ls
NAME    ACTIVE   DRIVER    STATE     URL                SWARM   DOCKER     ERRORS
node1   -        generic   Running   tcp://node1:2376           v18.09.3
node2   -        generic   Running   tcp://node2:2376           v18.09.3

Docker Machine から node1, node2 の Docker Engine に接続できていることが確認できました。

また、各 Docker Engine の環境変数を確認しておきます。

$ docker-machine env node1
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://node1:2376"
export DOCKER_CERT_PATH="/home/username/.docker/machine/machines/node1"
export DOCKER_MACHINE_NAME="node1"
# Run this command to configure your shell:
# eval $(docker-machine env node1)
$ docker-machine env node2
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://node2:2376"
export DOCKER_CERT_PATH="/home/username/.docker/machine/machines/node2"
export DOCKER_MACHINE_NAME="node2"
# Run this command to configure your shell:
# eval $(docker-machine env node2)

補足: Docker Machine から Docker Engine を削除する

もし、docker-machine create に失敗した場合や、Docker Engine を削除したい場合は、次のコマンドで削除できます。

$ docker-machine rm node1

強制的に削除する場合は、

$ docker-machine rm -f node1

補足: Docker Engine をホストするサーバ(node1, node2)に接続する

$ docker-machine ssh node1

GitLab Runner のインストール

GitLab CI/CD から Docker Engine が使えるように GitLab Runner をインストールします。 こちらもドキュメントに沿ってよしなに進めます。 https://docs.gitlab.com/runner/install/

$ curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash
$ sudo apt-get install gitlab-runner

Runner の登録

gitlab-runner の設定

デフォルトの場合、ジョブの同時実行数(/etc/gitlab-runner/config.tomlconcurrent の値)は1つに設定されています。 今回は Docker Engine を2台登録しているので、2 に設定します。 必要に応じて実行数を増やしてもよいでしょう。

concurrent = 2 # ジョブの同時実行数を2にする

https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section

Runner の登録

先ほど確認した Docker Engine の環境変数を元に、次のコマンドで登録可能です。

$ sudo gitlab-runner register \
  --non-interactive \
  --url "https://gitlab.com/" \
  --registration-token "YOUR_TOKEN" \
  --name "node1" \
  --limit "3" \
  --executor "docker" \
  --docker-image "alpine:latest"\
  --tag-list "docker,node1" \
  --docker-host "tcp://node1:2376" \
  --docker-tlsverify \
  --docker-cert-path "/home/username/.docker/machine/machines/node1" \
  --run-untagged \
  --locked="false"
$ sudo gitlab-runner register \
  --non-interactive \
  --url "https://gitlab.com/" \
  --registration-token "YOUR_TOKEN" \
  --name "node2" \
  --limit "3" \
  --executor "docker" \
  --docker-image "alpine:latest" \
  --tag-list "docker,node2" \
  --docker-host "tcp://node2:2376" \
  --docker-tlsverify \
  --docker-cert-path "/home/username/.docker/machine/machines/node2" \
  --run-untagged \
  --locked="false"

オプション一覧を確認したい場合には、以下のコマンドで確認できます。

$ gitlab-runner register --help

確認

最終的な /etc/gitlab-runner/config.toml は次のようになりました。

concurrent = 2
check_interval = 0

[session_server]
  session_timeout = 1800

[[runners]]
  name = "node1"
  limit = 1
  url = "https://gitlab.com/"
  token = "NODE1_TOKEN"
  executor = "docker"
  [runners.docker]
    host = "tcp://node1:2376"
    tls_cert_path = "/home/username/.docker/machine/machines/node1"
    tls_verify = true
    image = "alpine:latest"
    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]

[[runners]]
  name = "node2"
  limit = 1
  url = "https://gitlab.com/"
  token = "NODE1_TOKEN"
  executor = "docker"
  [runners.docker]
    host = "tcp://node2:2376"
    tls_cert_path = "/home/username/.docker/machine/machines/node2"
    tls_verify = true
    image = "alpine:latest"
    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]

また、GitLab の CI / CD Settings に Runner が追加されていることが確認できます。

f:id:u9bo:20190331201531p:plain:w500