ランナーとは何ですか?

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 つのユースケース

  1. 複数チームでも干渉なし プラットフォームチームとプロダクトチームの両方が Semaphore を使っているとします。異なるプロジェクト、異なるサーバー、異なるリスク許容度で、それぞれ独立して作業しています。プロジェクトランナーを使えば、各チームが自分専用のランナーを持てます。片方のチームのランナーが落ちても、もう片方のチームは気付きません。

  2. 複数リージョンにまたがる分散インフラ Web サイトはニューヨークのデータセンターで動き、バックエンドサービスはオーストラリアで動いているとします。ヨーロッパに 1 台だけ集中配置したランナーで運用すると、すべてのデプロイが地球の反対側まで SSH で接続することになり、遅くて無駄です。

    ニューヨークに 1 台、オーストラリアに 1 台のランナーを用意し、それぞれに合わせて Inventory にタグを付けます。すると各タスクは同じネットワーク内でローカル接続され、最高速度で実行されます。デプロイが速くなるだけでなく、攻撃対象領域も小さくなります。

  3. Webhook + AWS Lambda でクラウドコストを削減 ここは少し丁寧に見る価値があります。意味のあるコスト最適化につながるからです。ランナーは 2 つのイベント、タスク開始とタスク終了に対する webhook をサポートしています。これを使えば、クラウドリソースを自動的に起動・停止できます。

    構成はこうです。ランナーは AWS EC2 インスタンス上で動作します。起動している間はコストが発生し、停止していればコストはかかりません。

    • タスク開始時 -> webhook が Lambda 関数を呼び出す -> Lambda が EC2 インスタンスを起動する -> ランナーがオンラインになり、Semaphore に接続してタスクを受け取る
    • タスク終了時 -> webhook が別の Lambda を呼び出す -> Lambda が EC2 インスタンスを停止する

    ランナーは実際に仕事をしているときだけ動作します。断続的な負荷しかないチームであれば、これだけで Pro プランを正当化できることもあります。

プロジェクトランナーの設定方法

  1. プロジェクト設定を開き、Runners タブを開きます。ここに既存のランナーが一覧表示されます。

  2. New Runner をクリックします。名前とタグを付けます。たとえば new-york です。

  3. 保存すると、Semaphore は 2 つの認証情報を生成します。1 つは両側に保存されて識別に使われるトークン、もう 1 つはランナー側にだけ保存されて通信中のデータを暗号化するための秘密鍵です。次の手順で必要になるので、秘密鍵をダウンロードしてください。

  4. 対象サーバーにランナーをデプロイします。最も簡単なのは 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
    
  5. 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 プランで利用できます。上で挙げたような状況、つまり増え続けるタスクキュー、複数チーム、分散インフラに当てはまるなら、検討する価値があります。