self-hosted runnerをDockerイメージにする
はじめに
はじめまして。DAAE開発1グループの中本です。
self-hosted runnerをDockerイメージにしてみたので紹介します。
self-hosted runnerとは
一言で言うと、GitHub Actionsの実行環境を自分で用意できる機能です。
通常、GitHub ActionsのワークフローはGitHubが用意するホストランナー上で実行されます。GitHubのホストランナーは事前準備なしで使える一方、実行環境のカスタマイズ等はできません。
自社サーバー上でCI/CD実行したい、実行環境のスペックをもっと上げたい、などの要件があれば、自前で用意したサーバーにself-hosted runnerを構築することで実現できます。
そんなself-hosted runnerをコンテナ環境でも動かせるとCI/CD環境の選択肢がもっと広がるよね、ということでDockerイメージにしてみました。
self-hosted runnerをubuntu 22.04に構築する
まずはGitHubの手順通りにself-hosted runnerを構築してみます。
GitHub -> Settings -> Actions -> Runnerと移動し、 「New self-hosted runner」 をクリック
Create self-hosted runner で「Linux」 「x64(※)」を選択
※M1 Macの場合は「ARM64」と読み替えてください
手順の確認はコンテナ内で行います。コンテナのベースイメージはubuntu:22.04にしました。
手順でcurlコマンドが使われているので、Dockerfileでインストールしておきます。
Dockerfile
FROM ubuntu:22.04
RUN apt-get update && \
apt-get install \
curl \
-y
Dockerfileをビルドし、コンテナに入ります。
$ docker build -t self-hosted-runner .
$ docker run --rm -it self-hosted-runner bash
#
このあとはGitHubの手順通りにコマンドを叩いていきます。
# mkdir actions-runner && cd actions-runner
#
# curl -o actions-runner-linux-x64-2.299.1.tar.gz -L https://github.com/actions/runner/releases/download/v2.299.1/actions-runner-linux-x64-2.299.1.tar.gz
・・・
#
# echo "147c14700c6cb997421b9a239c012197f11ea9854cd901ee88ead6fe73a72c74 actions-runner-linux-x64-2.299.1.tar.gz" | shasum -a 256 -c
bash: shasum: command not found
さっそくエラーが出ました。 「shasum -a 256」を「sha256sum」に置き換えて実行します。
# echo "147c14700c6cb997421b9a239c012197f11ea9854cd901ee88ead6fe73a72c74 actions-runner-linux-x64-2.299.1.tar.gz" | sha256sum -c
actions-runner-linux-x64-2.299.1.tar.gz: OK
#
# tar xzf ./actions-runner-linux-x64-2.299.1.tar.gz
#
以上で、Downloadはすんなりできました。
続いてConfigureに進みます。
# ./config.sh --url https://github.com/{オーナー名}/{リポジトリ名} --token {トークン}
Must not run with sudo
エラーが出ました。config.shを確認してみます。
# cat config.sh
・・・
if [ $user_id -eq 0 -a -z "$RUNNER_ALLOW_RUNASROOT" ]; then
echo "Must not run with sudo"
exit 1
fi
・・・
環境変数RUNNER_ALLOW_RUNASROOTを設定するとこのエラーを回避できそうです。
# export RUNNER_ALLOW_RUNASROOT=1
#
もう一度、config.shを実行します。
# ./config.sh --url https://github.com/{オーナー名}/{リポジトリ名} --token {トークン}
Libicu's dependencies is missing for Dotnet Core 6.0
Execute sudo ./bin/installdependencies.sh to install any missing Dotnet Core 6.0 dependencies.
またエラーが出ました。エラーメッセージのとおりinstalldependencies.shを叩きます。
# ./bin/installdependencies.sh
・・・
-----------------------------
Finish Install Dependencies
-----------------------------
さらにもう一度、config.shを実行します。
# ./config.sh --url https://github.com/{オーナー名}/{リポジトリ名} --token {トークン}
--------------------------------------------------------------------------------
| ____ _ _ _ _ _ _ _ _ |
| / ___(_) |_| | | |_ _| |__ / \ ___| |_(_) ___ _ __ ___ |
| | | _| | __| |_| | | | | '_ \ / _ \ / __| __| |/ _ \| '_ \/ __| |
| | |_| | | |_| _ | |_| | |_) | / ___ \ (__| |_| | (_) | | | \__ \ |
| \____|_|\__|_| |_|\__,_|_.__/ /_/ \_\___|\__|_|\___/|_| |_|___/ |
| |
| Self-hosted runner registration |
| |
--------------------------------------------------------------------------------
# Authentication
√ Connected to GitHub
# Runner Registration
Enter the name of the runner group to add this runner to: [press Enter for Default]
Enter the name of runner: [press Enter for b18b73aa37e7]
This runner will have the following labels: 'self-hosted', 'Linux', 'X64'
Enter any additional labels (ex. label-1,label-2): [press Enter to skip]
√ Runner successfully added
√ Runner connection is good
# Runner settings
Enter name of work folder: [press Enter for _work]
√ Settings Saved.
今度はランナーの設定ができました!
ランナー名などを対話で設定するプロンプトがいくつか出ましたが、全てデフォルトのままEnterしました。
GitHubにもランナーが設定されました。
続いてランナーを起動します。
# ./run.sh
√ Connected to GitHub
Current runner version: '2.299.1'
2022-12-06 23:30:02Z: Listening for Jobs
ランナー起動後はGitHubのランナーステータスがidleになりました。
最後に、ランナー上でサンプルワークフローが動作するかを確認します。
サンプルワークフロー
name: self-hosted runner🚀
on: [push]
jobs:
build:
runs-on: self-hosted
steps:
- uses: actions/checkout@v2
- run: echo self-hosted runner working🎉
GitHubの手順にもありますがruns-on: self-hosted とするのがポイントです。
実行結果
サンプルワークフローが動きました!
以上で手順の確認が出来たので、run.shをCtrl + Cで中断し、コンテナからexitします。
self-hosted runnerをDockerイメージにする
これまで確認した手順を元に、self-hosted runnerをDockerイメージにしたいと思います。
config.sh実行より前の手順は、Dockerfileにそのまま記述できます。
Dockerfile
FROM ubuntu:22.04
RUN apt-get update && \
apt-get install \
curl \
-y
RUN mkdir actions-runner && cd actions-runner && \
curl -o actions-runner-linux-x64-2.299.1.tar.gz -L \
https://github.com/actions/runner/releases/download/v2.299.1/actions-runner-linux-x64-2.299.1.tar.gz && \
echo "147c14700c6cb997421b9a239c012197f11ea9854cd901ee88ead6fe73a72c74 actions-runner-linux-x64-2.299.1.tar.gz" | sha256sum -c - && \
tar xzf ./actions-runner-linux-x64-2.299.1.tar.gz && \
./bin/installdependencies.sh
あとは、config.shの実行をどうするかです。
config.shの--tokenオプションに設定するランナー設定用トークンの取得や、対話で設定するプロンプトへの対応が必要です。
ここはシェルスクリプトを作成します。
ランナー設定用トークンはregistration-token APIから取得できそうです。
対話で設定するプロンプトはexpectコマンドで対応できそうです。
最終的に、以下のシェルスクリプトが出来ました。これをexec-runner.shと名前を付けて保存します。
exec-runner.sh
#!/bin/bash
# repo scopeのあるアクセストークン
if [ -z "${GITHUB_ACCESS_TOKEN}" ]; then
echo "GITHUB_ACCESS_TOKEN must be set" 1>&2
exit 1
fi
if [ -z "${GITHUB_API_DOMAIN}" ]; then
echo "GITHUB_API_DOMAIN must be set" 1>&2
exit 1
fi
if [ -z "${GITHUB_DOMAIN}" ]; then
echo "GITHUB_DOMAIN must be set" 1>&2
exit 1
fi
if [ -z "${GITHUB_REPOSITORY_NAME}" ]; then
echo "GITHUB_REPOSITORY_NAME must be set" 1>&2
exit 1
fi
if [ -z "${GITHUB_REPOSITORY_OWNER}" ]; then
echo "GITHUB_REPOSITORY_OWNER must be set" 1>&2
exit 1
fi
# ランナー設定用トークンを取得する
export GITHUB_RUNNER_REGISTRATION_TOKEN=$(curl \
-X POST \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer $GITHUB_ACCESS_TOKEN" \
-H "X-GitHub-Api-Version: 2022-11-28" \
https://$GITHUB_API_DOMAIN/repos/$GITHUB_REPOSITORY_OWNER/$GITHUB_REPOSITORY_NAME/actions/runners/registration-token \
| jq .token | sed -e 's/"//g')
export RUNNER_ALLOW_RUNASROOT=1
runnerName=`hostname`
# config.shを実行する
expect -c "
set timeout 10
log_user 0
spawn ./config.sh --url https://${GITHUB_DOMAIN}/${GITHUB_REPOSITORY_OWNER}/${GITHUB_REPOSITORY_NAME} --token ${GITHUB_RUNNER_REGISTRATION_TOKEN} --ephemeral
log_user 1
expect -re \"Enter the name of the runner group to add this runner to:.*\"
send \"\n\"
expect -re \"Enter the name of runner:.*\"
send \"${runnerName}\n\"
expect -re \"Enter any additional labels.*\"
send \"\n\"
expect -re \"Enter name of work folder:.*\"
send \"\n\"
expect \"#\"
exit 0
"
./run.sh
補足として、config.sh実行時にephemeralオプションを付けています。
このオプションを付けるとジョブ終了時にGitHubのランナー設定も削除されます。
1回限りのCI/CD環境が欲しい場合に付けると便利なオプションです。
exec-runner.sh用の環境変数定義ファイルも用意します。
env.txt
GITHUB_ACCESS_TOKEN=(access token with repo scope)
GITHUB_REPOSITORY_OWNER=(repository owner name)
GITHUB_REPOSITORY_NAME=(repository name)
GITHUB_DOMAIN=github.com
GITHUB_API_DOMAIN=api.github.com
exec-runner.shをDockerfileのCMDで実行します。
Dockerfile
FROM ubuntu:22.04
RUN apt-get update && \
apt-get install \
curl \
expect \
jq \
-y
RUN mkdir actions-runner && cd actions-runner && \
curl -o actions-runner-linux-x64-2.299.1.tar.gz -L \
https://github.com/actions/runner/releases/download/v2.299.1/actions-runner-linux-x64-2.299.1.tar.gz && \
echo "147c14700c6cb997421b9a239c012197f11ea9854cd901ee88ead6fe73a72c74 actions-runner-linux-x64-2.299.1.tar.gz" | sha256sum -c - && \
tar xzf ./actions-runner-linux-x64-2.299.1.tar.gz && \
./bin/installdependencies.sh
COPY exec-runner.sh /actions-runner/exec-runner.sh
RUN chmod +x /actions-runner/exec-runner.sh
WORKDIR /actions-runner
CMD ["/actions-runner/exec-runner.sh"]
これでDockerfileが完成しました!
それではself-hosted runnerコンテナを立ち上げてみます。
# docker build -t self-hosted-runner .
# docker run --rm -it --env-file=./env.txt self-hosted-runner
・・・
self-hosted runnerが立ち上がりました。
先ほどのサンプルワークフローをもう一度実行してみます。
・・・動きました!
サンプルワークフロー終了後、ephemeralオプションによりGitHubからランナー設定が削除されていました。
これにてself-hosted runnerをDockerイメージにすることができました!
参考情報
About self-hosted runners
Self-hosted runners
\もっと身近にもっとリアルに!DAAE公式Twitter/
\明日の記事もお楽しみに!/
お問合せはお気軽に
https://service.shiftinc.jp/contact/
SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/
SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/
SHIFTの導入事例
https://service.shiftinc.jp/case/
お役立ち資料はこちら
https://service.shiftinc.jp/resources/
SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/