Insight Technology

2020.12.22

GitLab CI/CD 発展編 ~GitLab Runnerの使い方~

このエントリーをはてなブックマークに追加

こんばんは。インサイトテクノロジー札幌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用の設定手順が確認できます。


gitlabrunnersettings.png

右側の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 の手順内からクリップボードにコピーできます。

gitlabrunnerwebui.PNG


$ 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の設定画面でも、登録できているか確認します。
gitlabrunnerregister.png

これで、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を実行して試してみましょう。

実行結果


result_pipeline.png
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:  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:  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:  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名を指定すると、どうなるでしょう?

sametag.png
“Partial token for reference only” と出て、Activateされないようですね。

終わりに

今回も、前々回、前回に引き続き、GitLab CI/CDについてお話しました。
今回はGitLab Runnerの種類・導入・使い分け・使い所についてという、かなりニッチなネタをメインで取り扱いました。
どうやら弊社は開発メンバーを募集しているようです。ご興味があればjoin us。

GitLab CI/CD シリーズ

TOP
ページトップへ