ランナーとは何ですか?
Semaphore UI のランナーは、UI を持たないスタンドアロンの Semaphore インスタンスです。メインの Semaphore サーバーに接続し、タスクを取得して実行します。ランナーは任意のリージョンやネットワークにある別サーバー上でホストでき、Semaphore UI がどこで動いているかとは完全に独立しています。
どんな問題を解決するのですか?
ランナーがない場合、すべての自動化タスクは 1 台のサーバー上で実行されます。最初はそれでも問題ありませんが、チーム、またはチーム数が増えるにつれて、たいてい次の 3 つの問題が出てきます。
- 負荷。 1 台のサーバーのリソースを大量のタスクが奪い合うため、全体が遅くなります。
- 分離。 複数のチームが同じ実行環境を共有していると、1 つの壊れたパイプラインが他の全員に影響することがあります。
- 地理。 Ansible は SSH でサーバーに接続します。インフラがシドニーにあり、Semaphore インスタンスがフランクフルトにある場合、すべてのデプロイは大陸をまたぐ接続を通ることになります。 ランナーはこの 3 つすべてを解決します。
グローバルランナーとプロジェクトランナー
Semaphore には 2 種類のランナーがあり、その違いは Pro プランを検討するときに重要です。
| 機能 | グローバルランナー (OSS) | プロジェクトランナー (Pro) |
|---|---|---|
| 利用可能なプラン | OSS (無料) | Pro |
| 負荷分散 | ✅ | ✅ |
| ネットワーク分離 | ❌ | ✅ |
| タグベースのルーティング | ❌ | ✅ |
| プロジェクト単位の制御 | ❌ | ✅ |
グローバルランナーは、すべてのプロジェクトに対してランダムに割り当てられます。負荷分散には最適ですが、どのランナーがどのタスクを取るかを制御できません。プロジェクトランナーでは、任意の Template や Inventory にタグを付けて、特定のタスクを特定のランナーへルーティングできます。これによって分離と地理ベースのルーティングが可能になります。
ランナーの現実的な 3 つのユースケース
-
複数チームでも干渉なし プラットフォームチームとプロダクトチームの両方が Semaphore を使っているとします。異なるプロジェクト、異なるサーバー、異なるリスク許容度で、それぞれ独立して作業しています。プロジェクトランナーを使えば、各チームが自分専用のランナーを持てます。片方のチームのランナーが落ちても、もう片方のチームは気付きません。
-
複数リージョンにまたがる分散インフラ Web サイトはニューヨークのデータセンターで動き、バックエンドサービスはオーストラリアで動いているとします。ヨーロッパに 1 台だけ集中配置したランナーで運用すると、すべてのデプロイが地球の反対側まで SSH で接続することになり、遅くて無駄です。
ニューヨークに 1 台、オーストラリアに 1 台のランナーを用意し、それぞれに合わせて Inventory にタグを付けます。すると各タスクは同じネットワーク内でローカル接続され、最高速度で実行されます。デプロイが速くなるだけでなく、攻撃対象領域も小さくなります。
-
Webhook + AWS Lambda でクラウドコストを削減 ここは少し丁寧に見る価値があります。意味のあるコスト最適化につながるからです。ランナーは 2 つのイベント、タスク開始とタスク終了に対する webhook をサポートしています。これを使えば、クラウドリソースを自動的に起動・停止できます。
構成はこうです。ランナーは AWS EC2 インスタンス上で動作します。起動している間はコストが発生し、停止していればコストはかかりません。
- タスク開始時 -> webhook が Lambda 関数を呼び出す -> Lambda が EC2 インスタンスを起動する -> ランナーがオンラインになり、Semaphore に接続してタスクを受け取る
- タスク終了時 -> webhook が別の Lambda を呼び出す -> Lambda が EC2 インスタンスを停止する
ランナーは実際に仕事をしているときだけ動作します。断続的な負荷しかないチームであれば、これだけで Pro プランを正当化できることもあります。
プロジェクトランナーの設定方法
-
プロジェクト設定を開き、Runners タブを開きます。ここに既存のランナーが一覧表示されます。
-
New Runner をクリックします。名前とタグを付けます。たとえば
new-yorkです。 -
保存すると、Semaphore は 2 つの認証情報を生成します。1 つは両側に保存されて識別に使われるトークン、もう 1 つはランナー側にだけ保存されて通信中のデータを暗号化するための秘密鍵です。次の手順で必要になるので、秘密鍵をダウンロードしてください。
-
対象サーバーにランナーをデプロイします。最も簡単なのは Docker を使う方法です。
docker run \ -e SEMAPHORE_WEB_ROOT=https://semaphore.example.com \ -e SEMAPHORE_RUNNER_TOKEN=/ADwjSWmWV8FZB4pwQaaEOWgqIdOR+oDOeOXe2a3JD0= \ -e SEMAPHORE_RUNNER_PRIVATE_KEY_FILE=/config.runner.key \ -v "/path/to/private/key:/config.runner.key" \ -d semaphoreui/runner:v2.17.28あるいは、対話形式のセットアップコマンドも使えます。
semaphore runner setup -
Semaphore に戻り、任意の Template または Inventory を開いて、ランナータグ
new-yorkを割り当てます。これでそのタスクは常にニューヨークのランナーで実行されます。
Template だけでなく Inventory にもタグを付ける
サーバーがリージョンやネットワークごとにまとまっている場合、タスクをルーティングするもっと賢いやり方があります。各 Template に個別にタグを付ける代わりに、ランナータグを Inventory に直接割り当てられます。
Semaphore の Inventory は、Ansible がサーバーへ接続するために使う IP アドレスの一覧です。あるサーバー群がニューヨークにあると分かっているなら、その Inventory に new-york を付けてください。そうすれば、その Inventory を使う Template はすべて自動的にニューヨークのランナーで実行され、Template ごとの設定は不要になります。
これは新しい Template を追加するときに特に便利です。適切な Inventory を選ぶだけで、ランナーのルーティングが自然に機能します。
もう 1 つ: 同時実行数の制限
同時実行数を制限したい場合は、ランナーごとの並列タスク数の上限を設定します。デフォルトでは無制限 (0) です。これを 5 に設定し、そのランナーがすでにビジーであれば、Semaphore は同じタグを持つ別のランナーにそのタスクを回します。
試してみる準備はできましたか?
プロジェクトランナーは Semaphore Pro プランで利用できます。上で挙げたような状況、つまり増え続けるタスクキュー、複数チーム、分散インフラに当てはまるなら、検討する価値があります。