Skip to main content

高可用性構成へのノードの追加

プライマリ 高可用性 (HA) データセンターにノードを追加します。 これは、プライマリ ノードから CPU 負荷の高いタスクをオフロードすることを目的としており、 GitHub Enterprise Server インスタンスの水平方向のスケーリングが可能になります。

水平方向のスケーリングを検討している GitHub Enterprise Server のお客様にとって、クラスターへの移行と運用はオプションですが、リソースを大量に消費し、時間がかかります。 別の方法として、HA 構成にノードを追加することをお勧めします。

"追加ノード" と "ステートレス ノード" という用語は、この記事全体で同じ意味で使用されます。 ステートレス ノードは、少なくとも 1 つのレプリカを含む HA デプロイにのみ追加できます。

その他のノード

GitHub Enterprise Server アプライアンスで実行されているすべてのサービスの中で、Unicorn は CPU とメモリの消費量が最も大きいことが多く、その次に Aqueduct、Git、MySQL が続きます。 Unicorn と Aqueduct はステートレス サービスであるため、水平スケーリングに適しており、個別のノードセットで実行できます。 残りのサービスは、データセンターごとに 1 つのインスタンスで動作し続けることができます。

追加のノードを使用すると、Web ワークロードとジョブ ワークロードを水平方向にスケーリングできます。 プライマリノードから、Unicorn と Aqueduct をオフロードして、残りのステートフルサービスに対する多くのコンピューティング リソースとメモリ リソースを解放することもできます。 ユニコーン インスタンスによる CPU 使用率の高さからパフォーマンスに関連した障害が発生している場合は、ノードを追加することをお勧めします。 データセンター内で追加できるこれらのノードの数に大きな制限はありません。

条件

HA 構成でプライマリ ノードの過負荷が原因でパフォーマンスが低下している場合は、HA 環境にノードを追加することを検討する必要があります。 プライマリ ノードを超えて Web ロールとジョブ ロールを水平方向にスケーリングすることで、これらの追加ノードはプライマリ ホストの負荷を軽減するのに役立ちます。

たとえば、UnicornまたはAqueductキューでバックログに気付いた場合や、他の種類のリソース競合が発生している場合は、この方法を検討する必要があります。 目に見えるキューがない場合でも、プライマリ ノードで CPU が不足することは、もう 1 つの明確なシグナルです。 このような場合は、ノードを追加し、ノードあたりのワーカー数を減らすことができます。そのため、プライマリ ノードは全体的なワークロードの処理量を減らすことができます。

ノードの追加

HA デプロイに追加する各ノードは、 GitHub Enterprise Server ソフトウェアを実行する仮想マシン (VM) です。 プライマリと同じソフトウェアを実行している必要があります。 一般に、ステートレス ノードは、プライマリのメモリ、CPU、またはストレージの仕様と一致する必要はありません。 ただし、ステートレス ノードとプライマリ インスタンスの両方にミリ秒未満の接続が必要です。 レプリカの接続要件は変更されません。

HA 構成のプライマリ データセンターにノードを追加するには、 ghe-add-node コマンドを使用します。 ghe-add-node コマンドは、HA デプロイ内のノードとして現在のアプライアンスを設定し、プライマリ データ ノードから CPU 負荷の高いタスクをオフロードし、水平スケーリングを可能にすることを目的としています。 これらのノードは、Web ワークロードとジョブ ワークロードを処理するように設計されているため、ワークロードの分散と管理をより効率的に行うことができます。 このコマンドは次の形式になります。

Shell
/usr/local/share/enterprise/ghe-add-node PRIMARY_IP [--hostname HOSTNAME]
  • PRIMARY_IP: プライマリ ノードの IP アドレス。
  • HOSTNAME (省略可能): 追加されたホストに必要なホスト名。

たとえば、ホスト名が ghes-node-1 されたノードを HA プライマリ データセンターの IP アドレス 192.168.1.1 HA プライマリ インスタンスに追加するには、次のコマンドを実行します。

Shell
/usr/local/share/enterprise/ghe-add-node 192.168.1.1 --hostname ghes-node-1

次に、プライマリ ノードで、次のコマンドを実行する必要があります。

Shell
ghe-config-apply
ghe-cluster-balance rebalance --yes

ghe-config-apply コマンドは、ステートレス ノードを追加するための要件です。

ステートレス ノードを追加するには、メンテナンス期間をお勧めします。

追加ノードの削除

追加のノードを削除する前に、HA デプロイ内のすべてのノードに機能リリース用の同じ最新のパッチをインストールし、メンテナンス期間をスケジュールします。 削除を開始する前に、アップグレードまたは構成の実行が完了するまで待ちます。

  1. HA プライマリで、HA デプロイ内のすべてのノードの状態を確認します。

    Shell
    ghe-cluster-nodes
    ghe-cluster-nodes --offline
    nomad node status
    ghe-cluster-status --extended --verbose
    

    両方の ghe-cluster-nodes コマンドで同じホスト名が一覧表示され、削除するノードのホスト名が含まれているか確認します。 すべてのノードの Nomad 状態が ready であり、 connect-sshenterprise-version がすべてのノードに対して ok されていることを確認します。 プライマリとすべてのレプリカのステートフル サービスが正常であることを確認します。 レプリカが残っていない場合は、MySQL レプリカが見つからなかったことを示す警告が表示されます。 ターゲット上の Web、ジョブ、または memcache ワークロードに限定されたエラーは、削除をブロックしません。 他のノード レベルまたはステートフル サービスのチェックが失敗した場合は、削除する前に GitHub のサポート にお問い合わせください。

  2. HA プライマリで、追加のノードを削除します。 HOSTNAMEを追加ノードのホスト名に置き換えます。

    Shell
    ghe-remove-node --verbose HOSTNAME
    

    別の非プライマリ ノードが残っている場合、コマンドはターゲットをドレインし、HA 構成から削除して、 ghe-config-apply実行します。 プライマリ以外のノードが残っていない場合、コマンドはクラスター メタデータを削除し、 ghe-config-applyを実行せずにプライマリをスタンドアロン インスタンスに変換します。 どちらの場合も、 ghe-config-apply を個別に実行しないでください。

  3. 削除を確認します。

    別の非プライマリ ノードが残っている場合は、HA プライマリで次のコマンドを実行します。 ホスト名が存在しないこと、および HA 構成が正常な状態であることを確認してください。

    Shell
    ghe-cluster-nodes --offline
    ghe-cluster-status --extended --verbose
    

    プライマリ以外のノードが残っていない場合は、クラスターのみのコマンドを実行しないでください。 削除出力に Cluster artifacts removed; now standalone.が含まれていることを確認し、プライマリがユーザー トラフィックを処理し、Web ワークロードとジョブ ワークロードを処理することを確認します。

追加のノードがオフライン、到達不能、または別のバージョンにある場合、または ghe-remove-node または検証チェックが失敗した場合は、 GitHub のサポートにお問い合わせください。 cluster.confを手動で編集しないでください。

以前にホストされていたノードの再プロビジョニング GitHub Enterprise Server

以前にホストされ、 GitHub Enterprise Server を実行したノードをステートレス ノードとして使用できます。 そのためには、ノードをバージョン 3.18 以降に更新し、デプロイ内のすべてのノードで同じバージョンが実行されている必要があります。 そのノードで、 /data/user/common/cluster.conf が既に存在するかどうかを確認します。 その場合は、ステートレス ノードで ghe-add-node コマンドを実行する前にクリーンアップを実行する必要があります。

例えば次が挙げられます。

Shell
sudo rm -f /etc/github/cluster /data/user/common/cluster.conf
sudo timeout -k4 10 systemctl stop wireguard 2>/dev/null || sudo ip link delete tun0 || true

制限と動作

追加できるノードの数に理論的な制限はありません。 ただし、実際には、ノードを追加しすぎると、問題が発生し、安定性やパフォーマンスに影響を与える可能性があります。 現時点では、新しく追加されたノードは、定義済みの一連のタスクを処理します。 オフロードするタスクの種類を選択することはできません。 すべての API は、追加ノードによって処理できます。

Git 操作がパス内にある場合は、プライマリ ノードでのみ Git 操作を処理するロジックが存在します。 Git 操作は、追加のノードでは処理されません。 たとえば、ブランチの削除は Git 操作であり、ステートレス ノードでは処理されません。

ステートレス ノードは Elasticsearch ワークロードを実行しませんが、kafka-lite を実行します。

システムとネットワークの要件

一般に、ステートレス ノードは、プライマリ ノードのメモリ、CPU、ストレージの仕様と一致する必要はありません。 システム要件では、プライマリ ノード上の Web サービスとジョブ サービスの既存のリソース消費量と、プライマリ ノードがそれらのワークロードを新しいノードに完全にオフロードするかどうかを考慮する必要があります。

ステートレス ノードとプライマリ インスタンスには、ミリ秒未満の接続が必要です。 一般に、プライマリ データセンター内のすべてのノードにはミリ秒未満の接続が必要です。 レプリカの接続要件は変更されません。

トラフィック ルーティングと要求の処理

プライマリは、トラフィックを追加のノードにルーティングします。 複数のステートレス ノードが存在する場合、プライマリは、その時点でアクティブな接続が最も少ない新しい接続をサーバーに送信します。

追加ノードを使用した HA デプロイのアップグレード

アップグレード シーケンスの例を次に示します。

  • メンテナンス期間を開始します。
  • レプリカを停止します。
  • ステートレス ノードを並列でアップグレードします。
  • プライマリ ノードをアップグレードします。
  • レプリカをアップグレードします。 これらは、ディザスター リカバリーの設定に応じて、並列または順番にアップグレードできます。
  • レプリカを起動します。
  • メンテナンスウィンドウを削除します。

追加のノードでは、アップグレード中に追加のダウンタイムが発生しないようにする必要があります。

フェールオーバーとディザスター リカバリーの動作

データが含まれていないため、追加のノードを "破棄" する必要はありません。

フェールオーバー中、レプリカ ノードは元のデプロイから削除され、スタンドアロン ノードに変換されます。 ステートレスノードは、フェールオーバー後に追加のレプリカを再アタッチする方法と同様に、プロモートされたレプリカに再アタッチする必要があります。

プライマリ ノードが機能していて、レプリカをプライマリに昇格させる場合は、昇格されたノードに再度追加する前に、 ghe-remove-node コマンドを使用してプライマリからステートレス ノードを削除する必要があります。

プライマリ ノードに到達できず、回復できない場合は、元のプライマリからノードを削除せずにステートレス ノードを再追加できます。

監視、ログ、およびサポート バンドル

プライマリ ノードの管理コンソール監視ダッシュボードには、ステートレス ノードを含むすべてのノードのメトリックが表示されます。 ghe-cluster-nodesghe-cluster-statusなどのコマンドには、ステートレス ノードの詳細が含まれています。 すべての管理コンソール要求は、プライマリ ノードによって処理されます。

ログは、ステートレス ノードにローカルに格納されます。 これらのノードからサードパーティのログ管理サービスにエクスポートできます。

ghe-cluster-support-bundleコマンドとghe-support-bundle コマンドを使用して、クラスターバンドルまたは単一ノードバンドルを生成およびアップロードできます。

単一コア softirq の飽和を軽減する

GitHub Enterprise Server高可用性デプロイにステートレス ノードを追加すると、1 つの WireGuard トンネル経由で 2 つのノード間のすべてのトラフィックが送信されます。 そのノード ペアのすべてのパケットは 1 つの UDP ポートを共有するため、ネットワーク カードはそれを 1 つの受信キューに誘導し、1 つの CPU コアはすべての受信パケットを処理します。 トラフィックが多い場合、コアは 100% に達し、他のトラフィックはアイドル状態のままになり、ノードはパケットをドロップします。 GitHub Enterprise Server には、以下に説明する組み込みの軽減策が含まれています。

1. ステートレス ノードを増やしてスケールアウトする

各ステートレス ノードは、独自の WireGuard トンネル経由でプライマリに到達するため、プライマリは個別の受信キューと CPU コアで各ノードのトラフィックを処理します。 より小さなステートレス ノードにワークロードを分散すると、ロード バランサーはプライマリのコアの多くでクロストンネル負荷を共有でき、これはトンネル レベルのハッシュに依存しません。 2 つのノードはコアごとの受信負荷をほぼ半分にし、3 つで約 3 分の 1 に切断します。

GitHub Enterprise Server は、各ノードの Web ワーカーをメモリからサイズ変更し、独自の値を 30 に制限します。 ノードあたり 30 個近い app.github.github-workers 保持します。コスト メモリの数が多く、トンネル ストール中は、プライマリで余分なワーカーがブロックされるため、スループットではなくキューの深さを追加します。 容量を増やすには、ステートレス ノードを追加します。

2. マルチトンネル WireGuard (オプトイン)

GitHub Enterprise Server では、ノード間トラフィックを複数の WireGuard トンネルに分散できます。 各トンネルは独自の UDP ポートを使用するため、異なる接続が異なる受信キューに配置され、異なる CPU コアが作業を共有します。 トンネル数を、クラスター ノード全体の受信キューの最小数 、 ethtool -l eth0の "結合" 値に設定します。

Shell
ghe-config wireguard.num-tunnels 8
ghe-config-apply

既定値は 1 です。 最大値は 16 です。より大きい値には上限が設定されます。 インターフェイスが受信キューを持つよりもトンネルが多いほど、メリットはありません。 元に戻すには、設定を削除して適用します。

Shell
ghe-config --unset wireguard.num-tunnels
ghe-config-apply

有効にする前 (1 回限り):

  • 外部ファイアウォールまたはクラウド セキュリティ グループで、すべてのレプリカを含むすべてのノード間で追加のトンネル UDP ポートを開きます。 ポートは 1194 からカウントアップされるため、8 つのトンネルで UDP 1194 から 1201 が使用されます。 完全な範囲には UDP 1194 から 1209 が必要です。
  • マルチトンネルを有効にすると、ホスト ファイアウォールが更新されます。 すべてのノードを再起動するか、各ノードで sudo ufw reload を使用してファイアウォールを再読み込みして、1 回適用します。 ufw の再読み込みによって規則が一時的に削除されて再作成されるため、ネットワーク セキュリティ グループで受信アクセスが既に制限されたことを確認します。 後で num-tunnels 変更を行う必要はありません。

3. プライマリでのローカル Git プロキシ ルーティング (自動)

それ以外の場合、ステートレス ノードがトンネル経由で送り返されることを Git が要求すると、Git データが既に存在するプライマリにとどまります。 これにより、クロストンネル パケットの大きな共有が削除され、アクションは必要ありません。 プライマリは最初にローカル Git プロキシを使用し、ローカルの Git プロキシが使用できない場合にのみリモート ノードにフォールバックします。

4. 容量ベースの Web 要求の重み付け (オプトイン)

ノードが異なる数の Web ワーカーを実行する場合、 GitHub Enterprise Server は、各ノードのワーカー数に比例して要求を均等に分散できます。 ワーカー数が不均等な場合 (たとえば、100 個のワーカーを持つプライマリノード、30 個のステートレス ノードなど) に有効にします。

Shell
ghe-config app.github.unicorn-weight-by-capacity true
ghe-config-apply

既定値はオフです。

有効にする内容の選択

まず、よりステートレスなノードにスケールアウトします。 これは最も完全なオプションであり、ロード バランサーを介してプライマリのコアの多くに負荷を分散し、機能フラグは必要ありません。 1 つのコアがまだ飽和している場合は、マルチトンネル WireGuard を有効にします。 ワーカー数がノード間で異なる場合にのみ、容量ベースの重み付けを有効にします。

既知の制限

この機能は monorepos 向けに設計されていませんが、新しいステートレス ノードを追加すると、プライマリ ノード上の Web ワークロードとジョブ ワークロードを減らすことで、モノレポ操作が間接的に向上する可能性があります。 自動スケール機能とスケールダウン機能はありません。