こんばんは。インサイトテクノロジー札幌R&Dセンターの笹谷です。
好きなキャンベルタウンはスプリングバンクとグレンガイル、好きなローランドはオーヘントッシャンとアイルサベイ、好きなアイランズはタリスカー、ロックランザ、スキャパです。
業務ではGitLabを用いたCI/CDの構築、開発部門の業務プロセスの改善タスクを担当しております。
前々回、前回に引き続き、GitLab CI/CDの構築に際し、GitLab CI/CDのjobの実行主体であるGitLab Runnerについてお話します。
GitLab Runnerとは
前々回でも軽く触れましたが、改めて今回もご説明します。
GitLab RunnerとはGitLab CI/CDにおけるjobの実行主体です。
GitLab CI/CDのpipeline内でjobが実行されるときは、GitLab.com上のRunnerまたはGitLab Runnerをinstallしたマシン上のいずれかで実行されます。
Runnerには複数の実行形態があり、Docker, kubernetes, VirtualBox, Parallels executorといった仮想環境を利用するものや、SSH、Shell executorといった、Runnerを導入した環境でそのままjobを実行するものもあります。
GitLab Runnerの種類
GitLab Runnerには大別して3種類あります。
- Shared Runner
- GitLab.comのリソースを共有する形でjobを実行するRunner
- Specific Runner
- GitLabRunnerを導入した環境(物理・仮想マシン問わず)で、tokenを用いてregisterすることでGitLabと連携し、CI/CDが実行される
- Project単位でjob実行環境を専有可能なRunner
- Group Runner(今回は説明割愛)
- Specific Runnerはproject単位だが、Group内のsubgroup, project共有可能なRunner
GitLabのprojectで、Pipeline/Jobの実行環境を、ローカルサーバーやVM上で登録する場合、GitLab Runnerの導入と、registerの作業が必要になります。
今回は、Shared RunnerとSpecific Runnerをメインでご紹介し、Group RunnerはSpecific RunnerとShared Runnerの中間くらいのイメージ(今のところ弊社では出番なし)なので割愛します。
各Runnerの使い所
Shared RunnerとSpecific Runnerの使いどころは、各々の特質上、以下のようにまとめられます。
Shared Runner
GitLabがデフォルトで提供する機能・リソースを利用する性質上、
- CI/CDを気軽に試したい状況
- SpecificRunnerを用意するマシンリソースがない状況
- jobにリソースを大きく消費する処理がなく、簡単なCI/CDだけを想定している状況
- 一度に大量のpipeline/jobを実行したい場合
などが考えられます。
Shared Runnerのスペック
ちなみに、Shared Runnerで利用するリソースのスペックは、Linux版、Windows版それぞれ以下の設定のようです。
Linux Shared Runner:
- GCP n1-standard-1 instances
- CoreOS + Docker Engine
- vCPU:1
- RAM:3.75GB
- HDD:25GB
(参考: https://docs.gitlab.com/ee/user/gitlab_com/#linux-shared-runners)
Windows Shared Runner(Beta):
- GCP n1-standard-2 instances
- vCPU:2
- RAM:7.5GB
- HDD:50GB
(参考: https://docs.gitlab.com/ee/user/gitlab_com/#windows-shared-runners-beta)
各インスタンスの詳細情報は、各RunnerのdocumentationのConfiguration項目をご覧ください。
Specific Runner
自前の環境を指定することで、専有利用できる性質上、
- 自前のマシンリソースを利用してjobを処理したい状況
- 物理CPUを複数使い、並列処理を行いたい、など
- Shared RunnerはGitLab.com上にあるため、ネットワークのボトルネックを避けたい状況
- jobがどの環境で実行されているのかコントロールしたい状況
- Projectごとに使用するRunnerを分けるなど
- 限られた数のpipeline/jobをシーケンシャルに実行したい場合
- FIFO方式
などで利用を検討する余地があります。
また、GitLab自体、GitLab.comを使わずに、オンプレのサーバーでローカル運用することができるため、Runnerもオンプレミス運用にすることが可能です。
この場合、Shared Runner、Specific Runnerは双方ともローカルリソースを使うことになります。
Projectで利用可能なGitLab Runnerの確認方法
GitLabのUI上から、Settings -> CI/CD -> Runners
をExpandすると、現在使用可能なShared Runnerと、Specific Runner用の設定手順が確認できます。
右側のAvailable shared Runners:
は、利用可能なShared Runner一覧です。
GitLab Runnerのinstall
前々回、GitLab CI/CD
のjobを実行するrunnerの種類について簡単にご説明しました。その際、デフォルトで実行する場合GitLabのShared Runnerが使われる旨をお話しましたが、今回は自前のサーバなどのローカル環境にGitLab Runnerを導入し、Specific Runnerを登録、使用することにします。
インストールするマシンのOSはUbuntu18.04で、dockerがinstallされています。ローカルIPアドレスは172.18.11.40
で固定しています。
GitLab Runnerのinstallは、公式ドキュメントに沿って進めます。
今回は、バイナリファイルからインストールします。
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64`
downloadしたファイルに実行権限を付与します。
sudo chmod +x /usr/local/bin/gitlab-runner
GitLab Runner用のuserを作成します。
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
GitLab Runnerをインストールし、serviceとしてstartします。
sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo gitlab-runner start
正常にインストールできれば、以下のようにコマンド実行することでstatusを表示できます。
user@gitlab-runner-server:~$ sudo gitlab-runner status
Runtime platform arch=amd64 os=linux pid=18899 revision=a987417a version=13.6.0
gitlab-runner: Service is running!
installしただけでは、GitLab RunnerをSpecific Runnerとしては利用できません。
Specific Runner用のtokenを使って、gitlab-runner register
コマンドで、ワンライナーで登録します。(対話的にregisterも可能です。)
tokenは、下の画像のように、Settings -> CI/CD -> Runners -> Specific Runners
の、Set up a specific Runner manually
の手順内からクリップボードにコピーできます。
$ sudo gitlab-runner register -n --executor shell --tag-list "blog-sandbox" --url https://gitlab.com/ --registration-token $GITLAB_SPECIFIC_RUNNER_TOKEN --description "shell executor for sandbox"
今回はshell executorを利用します。--registration-token
オプションに、先程コピーしたtokenを利用します。--tag-list
オプションには、.gitlab-ci.yml
のjob内でtags:
で指定する文字列が入っています。
今回はblog-sandbox
という名前でtagをつけています。
登録成功すると下記のように表示されます。
Runtime platform arch=amd64 os=linux pid=17510 revision=a987417a version=12.2.0
Running in system-mode.
Registering runner... succeeded runner=xxxxxxx
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
念の為、GitLab.com上のRunnerの設定画面でも、登録できているか確認します。
これで、GitLab CI/CD
のjob内でSpecific Runnerを使う準備ができました。
ディレクトリ構成
GitLab Runner
の使い分けをお試しするために、最低限必要なのは、設定ファイルだけなので、以下のようにレポジトリ内に.gitlab-ci.yml
を配置します。
sample-repository/
└─── .gitlab-ci.yml
.gitlab-ci.yml
GitLab CI/CD
の設定ファイルは以下のように記述しています。
同時並行に2つのRunnerに対してtest-runnerのtagでjobを実行します。tagsのgitlab-org
でShared Runnerを、blog-sandbox
でSpecific Runnerを指定しています。
# .gitlab-ci.yml
stages:
- test-runner
shared-runner-test:
stage: test-runner
# Shared Runnerを明示的に指定する
tags:
- gitlab-org
script:
- cat /etc/*-release
- ip addr show
- docker --version
specific-runner-test:
stage: test-runner
# Specific Runnerを明示的に指定する
tags:
- blog-sandbox
script:
- cat /etc/*-release
- ip addr show enp0s31f6
- docker --version
説明
stages:
今回は1つだけです。rules:
節もないため、今回はこちらを設定している2つのjobがパラレルに走ります。
shared-runner-test:
gitlab-org
というtagを持ったShared Runnerの環境を対象に、script:
節で定義したコマンドを実行します。
specific-runner-test:
blog-sandbox
というtagを持ったShared Runnerの環境を対象に、script:
節で定義したコマンドを実行します。
script:
上記の2つのjob内では、似たようなコマンドを3つ実行します。
cat /etc/*-release
コマンド
Shared RunnerとSpecific RunnerでOSが異なれば、違った結果が想定できます。
ip addr
コマンド
Shared Runner側ではおそらくdockerコンテナー内でipコマンドを実行したときと同様、eth<n>@if<n>
の形で、vethのipが得られ、
Specific Runner側は明示的にinterfaceを指定したものが実行でき、固定ローカルIPの172.18.11.40
が表示されるはずです。
docker --version
コマンド
Shared Runner側はdocker executorでdocker in dockerベースイメージではないため失敗し、
Specific Runner側は正常にバージョンを返すと想定されます。
ともあれ、あくまで上記は想定ですので、実際にCIを実行して試してみましょう。
実行結果
tags以外は同じ内容の2つのjobですが、Shared Runnerではjobが失敗しましたがSpecific Runnerを使ったjobは成功しています。
各jobのlogも見てみましょう。まずShared Runnerを使ったjobのログをみると、
Running with gitlab-runner 13.6.0 (8fa89735)
on docker-auto-scale-com 8a6210b8
Preparing the "docker+machine" executor
00:24
Using Docker executor with image ruby:2.5 ...
Pulling docker image ruby:2.5 ...
Using docker image sha256:875fc97a76ff1cdb9347d1890f94a4ca8bda524b10125675e490df43a32d3243 for ruby:2.5 with digest ruby@sha256:97336544ed12d5717bd00f3a572b53ac8624b526d3e3586a0da936bcc4ac1e1f ...
Preparing environment
00:02
Running on runner-8a6210b8-project-20243403-concurrent-0 via runner-8a6210b8-gsrm-1606895214-8625d7a5...
Getting source from Git repository
00:01
$ eval "$CI_PRE_CLONE_SCRIPT"
Fetching changes with git depth set to 50...
Initialized empty Git repository in /builds/iti-dev/qa-set/sandbox/.git/
Created fresh repository.
Checking out ee96d9f3 as runner-test...
Skipping Git submodules setup
Executing "step_script" stage of the job script
00:01
$ cat /etc/*-release
PRETTY_NAME="Debian GNU/Linux 10 (buster)"
NAME="Debian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
$ ip addr show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
176: eth0@if177: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1460 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fc00::242:ac11:3/7 scope global nodad
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:3/64 scope link tentative
valid_lft forever preferred_lft forever
$ docker --version
/bin/bash: line 107: docker: command not found
Cleaning up file based variables
00:01
ERROR: Job failed: exit code 1
base imageがruby 2.5
、OSはDebian 10
のdockerコンテナーで実行されていることがわかります。
また、想定通り、ip addr
コマンドがeth0@if177
のIPを返しています。docker in dockerの構成でないようで、dockerコマンドが失敗、jobも失敗していますね。
続いて、Specific Runnerを使ったjobのログを見てみましょう。
Skipping Git submodules setup
Executing "step_script" stage of the job script
00:00
$ cat /etc/*-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS"
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
$ ip addr show enp0s31f6
2: enp0s31f6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 70:4d:7b:8b:ce:c3 brd ff:ff:ff:ff:ff:ff
inet 172.18.11.40/23 brd 172.18.11.255 scope global enp0s31f6
valid_lft forever preferred_lft forever
inet6 fe80::724d:7bff:fe8b:cec3/64 scope link
valid_lft forever preferred_lft forever
$ docker --version
Docker version 19.03.8, build afacb8b7f0
Cleaning up file based variables
00:00
Job succeeded
OSがUbuntu 18.04.4 LTS
で、ip addr enp0s31f6
の実行結果として、172.18.11.40
がIPとして返ってきています。docker --version
コマンドも、想定通り成功しています。
上記の例から、tagsによって、Shared Runner, Specific Runnerの使い分けができていることがわかります。
ちなみに、上記のお試しとは別の話題ですが、localのSpecific Runnerをregisterするとき、Shared Runnerと同じtag名を指定すると、どうなるでしょう?
“Partial token for reference only” と出て、Activateされないようですね。
終わりに
今回も、前々回、前回に引き続き、GitLab CI/CD
についてお話しました。
今回はGitLab Runnerの種類・導入・使い分け・使い所についてという、かなりニッチなネタをメインで取り扱いました。
どうやら弊社は開発メンバーを募集しているようです。ご興味があればjoin us。