メインコンテンツまでスキップ

アーキテクチャ

Semaphore のデプロイには、必須の要素が 3 つあります。1 つの サーバープロセス、1 つの データベース、そして タスクが実行される場所 です。それ以外のもの(ランナー、Redis、リバースプロキシ、ID プロバイダー)はすべて任意で、具体的な必要が生じたときに追加します。

構成要素

サーバー

単一の Go バイナリです。コンパイル済みの Web インターフェイスを内包しているため、1 つのプロセスが UI、REST API、そしてタスク出力を開いているブラウザーへ配信する /api/ws の WebSocket エンドポイントを提供します。既定ではポート 3000 で待ち受けます。

そのプロセスの内部では、いくつかの要素が同時に動いています。

要素役割
HTTP API と UIブラウザーと API クライアントが呼び出すすべて。
タスクプールタスクのキュー、同時実行数の制限、状態の管理。
スケジューラーテンプレートを cron スケジュール に従って開始します。
ローカルエグゼキューターリモートランナーが処理しないタスクを、サーバー自身の上で実行します。
通知機能タスク終了時に アラート を送信します。

データベース

SQLite、MySQL、PostgreSQL のいずれかを dialect オプションで選択します。ここにはプロジェクト、テンプレート、インベントリ、スケジュール、ユーザー、ロール、タスク履歴、そしてキーストアの暗号化された内容が保持されます。バックアップが必須なのはこれだけで、他はすべて再構築できます。

SQLite が既定であり、単一サーバーに適しています。複数の人がこのサービスに依存する場合は PostgreSQL か MySQL を使い、複数ノードで運用する場合は必ずそうしてください。

ファイルキャッシュ

tmp_path(既定では /tmp/semaphore)のディレクトリには、クローンされたリポジトリと各実行の作業ディレクトリが置かれます。これはストレージではなくキャッシュです。削除してもプロジェクトごとにクローンが 1 回余分に発生するだけです。プロジェクト設定の キャッシュをクリア はまさにそれを行います。

タスクを実行するマシンがこのキャッシュを保持します。ローカル実行ならサーバーが、そうでなければ各ランナーが保持します。

タスクが実行される場所

既定では、サーバー自身が自分のファイルシステムと自分のネットワークアクセスを使ってタスクを実行します。これは最も単純な構成であり、サーバーからすでに到達できるホストを管理する小規模チームには最適です。

ランナー を追加すると、この 2 つが分離されます。ランナーは semaphore runner start で起動した同じバイナリです。データベース接続を持たず、受信ポートも開きません。ベアラートークンを使って HTTPS でサーバーをポーリングし、ジョブを受け取り、リポジトリをクローンし、ツールを実行し、出力をストリーミングで返します。ランナーによって次のことが可能になります。

  • サーバーが到達できないネットワークの内側で実行する、
  • 本番用の認証情報を、Web インターフェイスを提供しないマシンに置いておく、
  • 複数のマシンに負荷を分散する、
  • (Pro では)タグ を使ってタスクを特定のランナーに振り分ける。

各ランナーは、executor.type によってジョブの起動方法を選びます。

エグゼキュータージョブの実行場所
localランナーのホスト上のプロセスとして、tmp_path の中で実行します。
dockerランナーがそのジョブのために起動し、終了後に削除するコンテナーの中で実行します。
k8sランナーがクラスター内に作成し、終了後に削除する Pod の中で実行します。

ポートと通信方向

すべての接続は、それを開始したコンポーネントからの外向き接続です。これがランナーをネットワーク境界をまたいで利用できる理由です。

送信元宛先目的
ブラウザー、API クライアントサーバー :3000UI、REST API、WebSocket。
サーバーデータベースすべての永続的な状態。
サーバー、ランナーGit リモートリポジトリのクローン。
サーバー、ランナー管理対象ホスト、クラウド API実際の自動化処理。
ランナーサーバー :3000ジョブのポーリング、出力のストリーミング。
サーバーLDAP、OIDC、SMTP、チャットの Webhookサインインと通知。

スケールアウト

2 つの軸が独立してスケールします。

実行能力を増やす には、ランナーを増やします。サーバーは単一プロセスのままで、タスクは接続されているランナーへ分散されます。

可用性を高める には、サーバーを増やします。複数のノードが 1 つの PostgreSQL または MySQL データベースに対して動作し、分散ロック、共有キュー状態、pub/sub のために Redis を使い、WebSocket に対応したロードバランサーの背後に配置します。これが 高可用性 であり、Enterprise の機能です。SQLite は使用できません。

次のステップ