2026年10月15日木曜日

GitHub Actions Self-hosted runner で Jenkins のオフラインノードを表現する

GitHub Actions で常駐型の self-hosted runner を運用していると困ることがあります。
その1つがランナーのオフラインが気軽にできないというところです。
Jenkins であればオフラインノードとすることで、新しいジョブを受け付けなくなり、実行中のジョブの完了を待って、マシンのメンテナンスなどが可能でした。そして、オンラインに戻せばすぐにジョブが実行可能になります。
一方、GitHub Actions は管理画面にランナーの Remove はありますが、オフラインにすることはできません。self-hosted runner マシンでサービス停止すればオフラインになり、サービス再開すれば元に戻ります。しかし、これはそのマシン上での操作が必要であること、そしてジョブの完了を待つような安全なオフライン化ができません。

ジョブが実行されていない状態を作るために、以前は無限ループするジョブを用意して、それを該当マシンのランナー上で実行し、そのジョブが実行中にメンテナンスをするという方法を取っていました。
この方法であれば、実質的にオフライン状態にできます。

しかし、この方法にも問題があります。それはこのジョブが実行されるまでに、先にキューイングされているジョブの完了を待つ必要があるというところです。
GitHub Actions でのジョブが実行される順序は決まっているわけではないですが、先に条件を満たしたジョブからランナーの割り当てが基本的にされていると思います。
そうすると、オフライン状態にしたいと思っても、すぐにはならないですし、いつオフライン状態になるのかもわからないので、メンテナーとしては面倒くさいわけです。
(通知入れてもいいですが、本質はそこではない)
理想は、すぐにオフライン状態になり、今実行中のものだけ実行完了を待ちたいです。

そこで作ったのが gh runner-kit cordon コマンドです。
https://github.com/srz-zumix/gh-runner-kit
このコマンドがその理想的なオフライン状態を作ってくれます。
もとに戻すときは uncordon コマンドを使ってください。
ランナーは --id か --name で指定します。--label でラベル指定も可能で、これはそのラベルにマッチするランナーすべてをオフラインしてくれるので、便利です。

気になる仕組みですが、至って単純です。
GitHub Actions にランナーグループというものがあります。
このランナーグループではそのグループに所属するランナーが、どのリポジトリで利用可能なのか設定することが可能です。通常は All repository にしていることが多いでしょう。もしくは、特定のリポジトリのみに許可、除外するという使い方をしているところもあるかもしれません。
おわかりですね。どのリポジトリも許可しない、利用不可能なランナーグループを別途作成し、そのランナーグループにオフラインにしたいランナーを移動させることで、理想的なオフライン状態を作っています。
実は、グループの作成・移動は GitHub の管理ページからもできるので CLI でなくてもできます。なので、ぱっと試したい方はそちらでやってみてもよいかと思います。
CLI ではそれらの操作をまとめてやってくれるのと、もともとのグループを覚えているので元に戻すという操作を確実に実施してくれます。

以上です。このツールで GitHub Actions の self-hosted runner を運用されている方が少しでも楽になれば幸いです。
では。

0 件のコメント:

コメントを投稿