災害復旧(Geo)

Geoは、データベース、gitリポジトリ、その他いくつかの資産をレプリケートします。 将来的には、より多くのデータをサポートし、レプリケートすることで、災害時に最小限の労力でフェイルオーバーできるようにする予定です。

詳しくはGeoの現在の制限をご覧ください。

警告:マルチセカンダリ構成のディザスタリカバリはアルファ版です。 最新のアップデートについては、マルチセカンダリのディザスタリカバリエピックをご確認ください。

単一セカンダリ構成におけるセカンダリGeoノードのプロモート

現在のところ、Geoレプリカをプロモートしてフェイルオーバーを行う自動化された方法は提供していませんが、マシンにroot アクセスできる場合は手動で行うことができます。

このプロセスにより、セカンダリGeo ノードがプライマリ・ノードに昇格します。 地理的な冗長性をできるだけ早く回復するために、これらの指示に従った後、すぐに新しいセカンダリ・ノードを追加してください。

ステップ1.可能であればレプリケーションを終了させます。

セカンダリノードがまだプライマリノードからデータをレプリケートしている場合は、不必要なデータ損失を避けるために、計画されたフェイルオーバーのドキュメントにできるだけ忠実に従います。

ステップ2.プライマリノードを永久に無効にします。

警告:プライマリ・ノードがオフラインになった場合、セカンダリ・ノードにレプリケートされていないデータがプライマリ・ノードに保存されている可能性があります。 この場合、このデータは失われたものとして処理する必要があります。

プライマリノードで障害が発生した場合、2つの異なるGitLabインスタンスで書き込みが発生するスプリットブレインの状況を避け、復旧作業を複雑にしないようにできる限りのことをしなければなりません。 そこで、フェイルオーバーに備えるために、プライマリノードを無効にしなければなりません。

  1. 可能であれば、プライマリノードにSSH接続してGitLabを停止し、無効にします:

    sudo gitlab-ctl stop
    

    サーバーが予期せず再起動した場合、GitLabが再び起動しないようにします:

    sudo systemctl disable gitlab-runsvdir
    
    注意:(CentOSのみ)CentOS 6以降では、マシンが再起動したときにGitLabが起動しないようにする簡単な方法はありません(Omnibus GitLab issue #3058参照)。 GitLabパッケージを完全にアンインストールするのが一番安全かもしれません:
    yum remove gitlab-ee
    
    Note:(Ubuntu 14.04 LTS) 古いバージョンのUbuntuやUpstart initシステムを使ったディストリビューションを使っている場合は、以下のようにすることでマシンが再起動してもGitLabが起動しないようにすることができます:
    initctl stop gitlab-runsvvdir
    echo 'manual' > /etc/init/gitlab-runsvdir.override
    initctl reload-configuration
    
  2. プライマリ・ノードにSSHでアクセスできない場合は、マシンをオフラインにして、自由に使える手段でリブートできないようにします。 これを実現するには様々な方法があるので、推奨される方法を1つに絞るのは避けます。 必要な場合もあります:

    • ロードバランサーを再設定します。
    • DNSレコードを変更します(例えば、プライマリノードの使用を停止するために、プライマリDNSレコードをセカンダリノードに向けます)。
    • 仮想サーバーを停止します。
    • ファイアウォールを介してトラフィックをブロックします。
    • プライマリ・ノードからオブジェクト・ストレージ権限を取り消します。
    • マシンを物理的に切断します。
  3. プライマリドメインのDNSレコードを更新する予定がある場合は、伝播速度を上げるためにTTLを下げることをお勧めします。

ステップ3.セカンダリノードのプロモート

セカンダリーを昇格させる際には、以下の点に注意してください:

  • 新しいセカンダリを追加する場合は、セカンダリを プライマリに昇格させる全プロセスが完了してから行ってください。
  • このプロセス中にActiveRecord::RecordInvalid: Validation failed: Name has already been takenエラーが発生した場合は、トラブルシューティングアドバイスをお読みください。

単一マシン上で動作するセカンダリノードのプロモート

  1. セカンダリノードにSSH接続し、rootでログインします:

    sudo -i
    
  2. geo_secondary_roleを有効にしていた行をすべて削除し、プライマリとしての新しいステータスを反映するよう/etc/gitlab/gitlab.rb を編集します:

    ## In pre-11.5 documentation, the role was enabled as follows. Remove this line.
    geo_secondary_role['enable'] = true
    
    ## In 11.5+ documentation, the role was enabled as follows. Remove this line.
    roles ['geo_secondary_role']
    
  3. セカンダリノードを プライマリノードにプロモートします。

    セカンダリノードをプライマリに昇格させる前に、プリフライトチェックを実行する必要があります。 プリフライトチェックは、個別に実行することも、昇格スクリプトと一緒に実行することもできます。

    セカンダリノードをプライマリに昇格させ、プリフライトチェックを行います:

    gitlab-ctl promote-to-primary-node
    
    警告:プリフライトチェックをスキップすると、セカンダリをプライマリに昇格させます!

    プリフライトチェックをすでに実行した場合や、実行したくない場合は、次のようにしてプリフライトチェックをスキップできます:

    gitlab-ctl promote-to-primary-node --skip-preflight-check
    

    プリフライトチェックを個別に実行することもできます:

    gitlab-ctl promotion-preflight-checks
    
  4. セカンダリ・ノードで以前に使用したURLを使用して、新しく昇格したプライマリ・ノードに接続できることを確認します。
  5. 成功すると、セカンダリ・ノードが プライマリ・ノードに昇格します。

複数のサーバーを持つセカンダリー・ノードのプロモート

gitlab-ctl promote-to-primary-node コマンドはまだ複数のサーバーと組み合わせて使用することはできません。セカンダリには1台のマシンしかないため、変更を実行することはできません。 代わりに、手動で行う必要があります。

  1. セカンダリのデータベースノードにSSHでログインし、PostgreSQLを読み書きできるようにします:

    sudo gitlab-pg-ctl promote
    

    GitLab 12.8 以前では、Message:sudo: gitlab-pg-ctl: command not foundを参照してください。

  2. geo_secondary_roleを有効にしていた行をすべて削除して、プライマリとしての新しいステータスを反映するように、セカンダリの各マシンで/etc/gitlab/gitlab.rb を編集します:

    ## In pre-11.5 documentation, the role was enabled as follows. Remove this line.
    geo_secondary_role['enable'] = true
    
    ## In 11.5+ documentation, the role was enabled as follows. Remove this line.
    roles ['geo_secondary_role']
    

    変更後 GitLab を再設定し、変更を反映させます。

  3. セカンダリを プライマリに昇格させます。単一のアプリケーション・サーバにSSH接続して実行します:

    sudo gitlab-rake geo:set_secondary_as_primary
    
  4. 以前にセカンダリに使用したURLを使用して、新しく昇格したプライマリに接続できることを確認します。
  5. 成功!セカンダリーは プライマリーに昇格しました。

外部PostgreSQLデータベースによるセカンダリノードのプロモート

gitlab-ctl promote-to-primary-node コマンドは外部の PostgreSQL データベースと組み合わせて使うことはできません。GitLab とデータベースが同じマシンにあるセカンダリノードでしか変更を実行できないからです。 その結果、手作業が必要になります:

  1. セカンダリ・サイトに関連付けられているレプリカ・データベースをプロモートします。 これにより、データベースは読み書き可能に設定されます:
    • Amazon RDS -リードレプリカのスタンドアロンDBインスタンスへのプロモート
    • Azure Database for PostgreSQL -レプリケーションの停止
    • その他の外部 PostgreSQL データベース - 以下のスクリプトをセカンダリノード(例えば/tmp/geo_promote.sh)に保存し、接続パラメータを環境に合わせて変更してください。 その後、このスクリプトを実行してレプリカを昇格させてください:

       #!/bin/bash
      
       PG_SUPERUSER=postgres
      
       # The path to your pg_ctl binary. You may need to adjust this path to match
       # your PostgreSQL installation
       PG_CTL_BINARY=/usr/lib/postgresql/10/bin/pg_ctl
      
       # The path to your PostgreSQL data directory. You may need to adjust this
       # path to match your PostgreSQL installation. You can also run
       # `SHOW data_directory;` from PostgreSQL to find your data directory
       PG_DATA_DIRECTORY=/etc/postgresql/10/main
      
       # Promote the PostgreSQL database and allow read/write operations
       sudo -u $PG_SUPERUSER $PG_CTL_BINARY -D $PG_DATA_DIRECTORY promote
      
  2. geo_secondary_roleを有効にしていた行をすべて削除して、プライマリとしての新しいステータスを反映するように、セカンダリ・サイトのすべてのノードで/etc/gitlab/gitlab.rb を編集します:

    ## In GitLab 11.4 and earlier, remove this line.
    geo_secondary_role['enable'] = true
    
    ## In GitLab 11.5 and later, remove this line.
    roles ['geo_secondary_role']
    

    変更後 各ノードで GitLab を再設定し、変更を反映させます。

  3. セカンダリを プライマリに昇格させます。セカンダリ・アプリケーション・ノード1台にSSH接続して実行します:

    sudo gitlab-rake geo:set_secondary_as_primary
    
  4. セカンダリ・サイトで以前に使用した URL を使用して、新しく昇格したプライマリ・サイトに接続できることを確認します。

セカンダリサイトが プライマリサイトに昇格しました。

ステップ4(オプション)プライマリドメインDNSレコードの更新

プライマリ・ドメインの DNS レコードをセカンダリ・ノードを指すように更新すれば、Git リモートや API URL の変更など、プライマリ・ドメインへの参照をすべてセカンダリ・ドメインに更新する必要がなくなります。

  1. セカンダリノードにSSH接続し、rootでログインします:

    sudo -i
    
  2. プライマリドメインのDNSレコードを更新します。 プライマリドメインのDNSレコードをセカンダリノードを指すように更新した後、セカンダリノードで /etc/gitlab/gitlab.rb 、新しいURLを反映するように編集します:

    # Change the existing external_url configuration
    external_url 'https://<new_external_url>'
    
    注意external_url を変更しても、セカンダリDNSレコードがそのままであれば、古いセカンダリURLからのアクセスは妨げられません。
  3. 変更を有効にするには、セカンダリノードを再設定します:

    gitlab-ctl reconfigure
    
  4. 以下のコマンドを実行して、新しく昇格したプライマリ・ノードのURLを更新します:

    gitlab-rake geo:update_primary_node_url
    

    このコマンドは、/etc/gitlab/gitlab.rbで定義された変更後のexternal_url コンフィギュレーションを使用します。

  5. GitLab 11.11から12.7に限り、データベースのプライマリノード名を更新する必要がある場合があります。 このバグはGitLab 12.8で修正されました。

    この作業が必要かどうかを判断するには、/etc/gitlab/gitlab.rbファイルでgitlab_rails["geo_node_name"] 設定を検索してください。# でコメントアウトされているか、まったく見つからない場合は、データベースでプライマリ・ノードの名前を更新する必要があります。 このように検索できます:

    grep "geo_node_name" /etc/gitlab/gitlab.rb
    

    データベースのプライマリ・ノード名を更新するには

    gitlab-rails runner 'Gitlab::Geo.primary_node.update!(name: GeoNode.current_node_name)'
    
  6. 新しく昇格したプライマリのURLを使用して接続できることを確認します。 プライマリドメインのDNSレコードを更新した場合、以前のDNSレコードのTTLによっては、これらの変更がまだ反映されていない可能性があります。

セカンダリGeoノードを昇格したプライマリノードに追加します。

上記のプロセスを使用してセカンダリノードを プライマリノードに昇格させても、新しいプライマリノードではGeo は有効になりません。

新しいセカンダリノードをオンラインにするには、Geoセットアップ手順に従ってください。

ステップ6(オプション)セカンダリのトラッキングデータベースの削除

すべてのセカンダリにはプライマリからのすべてのアイテムの同期ステータスを保存するために使用される特別な追跡データベースがあります。セカンダリはすでに昇格しているため、追跡データベースのデータはもはや必要ありません。

データは以下のコマンドで削除できます:

sudo rm -rf /var/opt/gitlab/geo-postgresql

gitlab.rbファイルでgeo_secondary[] の設定オプションを有効にしている場合は、コメントアウトするか削除してから GitLab を再設定すると変更が有効になります。

マルチセカンダリ構成におけるセカンダリGeoレプリカの促進

セカンダリノードが複数あり、そのうちの1つを昇格させる必要がある場合は、単一セカンダリ構成におけるセカンダリGeoノードの昇格に従うことをお勧めします。

ステップ1.1つ以上のセカンダリノードにサービスを提供する新しいプライマリノードの準備

  1. 新しいプライマリノードにSSH接続し、rootでログインします:

    sudo -i
    
  2. 編集/etc/gitlab/gitlab.rb

    ## Enable a Geo Primary role (if you haven't yet)
    roles ['geo_primary_role']
    
    ##
    # Allow PostgreSQL client authentication from the primary and secondary IPs. These IPs may be
    # public or VPC addresses in CIDR format, for example ['198.51.100.1/32', '198.51.100.2/32']
    ##
    postgresql['md5_auth_cidr_addresses'] = ['<primary_node_ip>/32', '<secondary_node_ip>/32']
    
    # Every secondary server needs to have its own slot so specify the number of secondary nodes you're going to have
    postgresql['max_replication_slots'] = 1
    
    ##
    ## Disable automatic database migrations temporarily
    ## (until PostgreSQL is restarted and listening on the private address).
    ##
    gitlab_rails['auto_migrate'] = false
    

    (これらの設定の詳細については、プライマリ・サーバーの設定を参照してください。)

  3. ファイルを保存し、データベースのリッスンの変更とレプリケーションスロットの変更が適用されるようにGitLabを再設定します。

    gitlab-ctl reconfigure
    

    変更を有効にするためにPostgreSQLを再起動してください:

    gitlab-ctl restart postgresql
    
  4. PostgreSQLが再起動し、非公開アドレスでリッスンしているため、移行を再度有効にしてください。

    /etc/gitlab/gitlab.rb を編集し、コンフィギュレーションをtrue変更します:

    gitlab_rails['auto_migrate'] = true
    

    ファイルを保存し、GitLabを再設定します:

    gitlab-ctl reconfigure
    

ステップ2.レプリケーションの開始

ここで、各セカンダリノードが新しいプライマリノードの変更をリッスンするようにする必要があります。 そのためには、レプリケーションプロセスを再度開始する必要がありますが、今回は別のプライマリノードに対して行います。 古いレプリケーション設定はすべて上書きされます。

トラブルシューティング

災害復旧の指示に従ったところ、2ファクタ認証が壊れてしまいました。

10.5より前のGeoのセットアップ手順では、データベースに保存された二要素認証の秘密の暗号化に使用されるotp_key_base 秘密の複製に失敗しました。プライマリノードと セカンダリノードでこの秘密が異なる場合、フェイルオーバー後に二要素認証を有効にしたユーザーがログインできなくなります。

古いプライマリノードへのアクセスが残っている場合は、GitLab10.5へのアップグレードセクションの指示に従ってエラーを解決することができます。 そうでない場合は、シークレットが失われ、すべてのユーザーの二要素認証をリセットする必要があります。