クラスタ認証情報をローテーションする


このページでは、Google Kubernetes Engine(GKE)クラスタで認証情報のローテーションを行う方法について説明します。

GKE での認証情報のローテーションについて

クラスタルート認証局(CA)の有効期間は限られています。CA が期限切れになると、この CA によって署名された認証情報は無効になります。これには、クラスタ クライアント証明書(MasterAuth API フィールドから)、API サーバーの鍵と証明書、kubelet クライアント証明書が含まれます。詳細については、クラスタのルート CA の有効期間をご覧ください。

認証情報のローテーションを行うと、クラスタの認証情報を取り消して、新しい認証情報を発行できます。この操作により、クラスタ CA 秘密鍵がローテーションされます。新しい認証情報を使用するにはノードの再作成が必要になります。現在の認証情報の有効期限が切れる前に、クラスタの認証情報のローテーションを開始および完了する必要があります。認証情報のローテーションでは、認証情報のローテーションだけでなく IP のローテーションも行われます。

認証情報のローテーションを行うタイミング

認証情報のローテーションは、現在の認証情報の有効期限よりも前に定期的に行う必要があります。認証情報のローテーションでは、新しい認証情報を使用するためにノードの再作成が必要になります。このため、ワークロードの実行が中断される可能性があります。予期しないワークロードのダウンタイムや、クラスタ外の API クライアントからの応答がない状態を回避するため、メンテナンス期間を計画し、メンテナンスの時間枠内でローテーションを行います。

認証情報の期限切れが近いクラスタまたは期限切れのクラスタを検索する

クラスタの認証情報が 180 日後に期限切れになる場合、またはクラスタの認証情報がすでに期限切れになっている場合、GKE では、このクラスタの認証情報のローテーションを行う必要があることを示す分析情報と推奨事項を含むガイダンスが提供されます。このガイダンスには、認証情報の有効期限が含まれています。このガイダンスは Google Cloud コンソールで確認できます。また、gcloud CLI または Recommender API で CLUSTER_CA_EXPIRATION サブタイプを指定して、このガイダンスを表示することもできます。

クラスタに関する分析情報と推奨事項を受け取った場合は、認証情報のローテーションを行う必要があります。そうしないと、次のセクションで説明するように、現在の CA の有効期限から 30 日以内に認証情報のローテーションが自動的に開始します。

クラスタの停止を防ぐための GKE 自動化ポリシー

現在の認証情報の有効期限が切れた場合にクラスタが復元不能な状態にならないように、GKE は現在の CA の有効期限から 30 日以内に認証情報のローテーションを自動的に開始します。たとえば、クラスタ CA の有効期限が 2024 年 1 月 6 日で、2023 年 12 月 5 日までに認証情報をローテーションしない場合、GKE は 2023 年 12 月 7 日以降に自動ローテーションを開始し、オペレーションを開始してから 7 日後にこのローテーションを完了します。この自動ローテーションは、クラスタの停止を防ぐための最終手段であり、次の点を考慮する必要があります。

  • 自動ローテーションでは、構成されているメンテナンスの時間枠や除外は無視されます。
  • 認証情報のローテーションが完了すると、期限切れとなる認証情報が取り消されます。クラスタ外の Kubernetes API クライアント(ローカル環境の kubectl など)は、新しい認証情報を使用するようにクライアントを構成するまで機能しません。
  • ローテーション中にノードプールが再作成されると、ワークロードの実行が中断される可能性があります。

GKE が開始する自動ローテーションは、サービス停止を防止する最終手段です。自動ローテーションのみに頼らないでください。自動ローテーションは、完全な停止を回避するための緊急の予防的な対策です。

始める前に

始める前に、次の作業が完了していることを確認してください。

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API の有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、gcloud components update を実行して最新のバージョンを取得する。

認証情報の有効期間を確認する

認証情報のローテーションを実行する前と後に、認証情報の有効期間を確認して、クラスタルート CA の有効性を確認することをおすすめします。

単一クラスタの認証情報の有効期間を確認するには、次のコマンドを実行します。

gcloud container clusters describe CLUSTER_NAME \
    --region REGION_NAME \
    --format "value(masterAuth.clusterCaCertificate)" \
    | base64 --decode \
    | openssl x509 -noout -dates

出力は次のようになります。

notBefore=Mar 17 16:45:34 2023 GMT
notAfter=Mar  9 17:45:34 2053 GMT

プロジェクト内のすべてのクラスタの認証情報の有効期間を確認するには、次のコマンドを実行します。

gcloud container clusters list --project PROJECT_ID \
    | awk 'NR>1 {print "echo; echo Validity for cluster " $1 " in location " $2 ":;\
         gcloud container clusters describe --project PROJECT_ID " $1 " --location " $2 " \
         --format \"value(masterAuth.clusterCaCertificate)\" \
         | base64 --decode | openssl x509 -noout -dates"}' \
    | bash

認証情報のローテーションを行う

認証情報のローテーションは、次の手順で行います。

  1. ローテーションを開始する: コントロール プレーンが、元の IP アドレスに加えて新しい IP アドレスでもサービスを開始します。新しい認証情報がワークロードとコントロール プレーンに発行されます。
  2. ノードを再作成する: GKE は、メンテナンスの時間枠と除外から可用性を考慮し、ノードが新しい IP アドレスと認証情報を使用するようにクラスタノードを再作成します。ノードがすでに実行されている GKE バージョンにノードのバージョン アップグレードを実行して、ノードを手動で再作成することもできます。
  3. API クライアントを更新する: ローテーションを開始した後、kubectl を使用して開発マシンなどのクラスタ API クライアントを更新し、新しい IP アドレスを使用してコントロール プレーンと通信します。
  4. ローテーションを完了する: コントロール プレーンが元の IP アドレスでのトラフィックの処理を停止します。Kubernetes ServiceAccounts の既存の静的認証情報を含め、古い認証情報が取り消されます。

認証情報のローテーションを開始すると、GKE によってノードが再作成されます。ただし、Google Cloud Next などの大規模なイベントの期間中は、中断が発生しないように自動ノード再作成を一時停止することがあります。開始から 7 日以内に認証情報のローテーションが完了しない場合、GKE はローテーションを完了しようとします。クラスタ内のノードが以前の認証情報を使用している場合、自動完了は失敗しています。ローテーションを開始した後、認証情報のローテーションを手動で追跡して完了する計画を立ててください。自動完了はベスト エフォートであり、自動完了に依存しないでください。

ローテーションを開始する

認証情報のローテーションを開始するには、次のコマンドを実行します。

gcloud container clusters update CLUSTER_NAME \
    --region REGION_NAME \
    --start-credential-rotation

このコマンドは、新しい認証情報を作成してコントロール プレーンに発行し、2 つの IP アドレス(元の IP アドレスと新しい IP アドレス)でサービスを提供するようにコントロール プレーンを構成します。

ノードを再作成する

新しい IP アドレスでサービスを提供するように API サーバーを再構成すると、メンテナンスが利用可能であれば、GKE はノードを自動的に更新して新しい IP アドレスと認証情報を使用します。GKE は、すべてのノードを、ノードですでに実行されている GKE バージョンにアップグレードします。これにより、ノードが再作成されます。詳細については、ノードプールのアップグレードをご覧ください。

デフォルトでは、GKE はオペレーションの開始から 7 日後に認証情報のローテーションを自動的に完了します。クラスタ内のアクティブなメンテナンスの時間枠またはメンテナンスの除外により、この 7 日間に GKE が一部のノードを再作成できない場合、認証情報のローテーションは完了しません。

  • メンテナンスの除外またはメンテナンスの時間枠を使用すると、ローテーションが失敗する可能性がある場合は、クラスタを手動でアップグレードして、ノードを強制的に再作成します。

    gcloud container clusters upgrade CLUSTER_NAME \
        --location=LOCATION \
        --cluster-version=VERSION
    

    VERSION は、クラスタがすでに使用している GKE バージョンに置き換えます。

    詳細については、メンテナンス時間枠の注意点をご覧ください。

ノードプールの再作成の進行状況を確認する

  1. ローテーションのオペレーションをモニタリングするには、次のコマンドを実行します。

    gcloud container operations list \
        --filter="operationType=UPGRADE_NODES AND status=RUNNING" \
        --format="value(name)"
    

    このコマンドは、ノードのアップグレード オペレーションのオペレーション ID を返します。

  2. オペレーションをポーリングするには、オペレーション ID を次のコマンドに渡します。

    gcloud container operations wait OPERATION_ID
    

ノードプールは 1 つずつ再作成され、それぞれに固有のオペレーションがあります。複数のノードプールがある場合は、次の手順に沿って各オペレーションをポーリングします。

API クライアントを更新する

認証情報のローテーションを開始したら、新しい認証情報を使用してコントロール プレーンの新しい IP アドレスを参照するように、クラスタ外のすべての API クライアント(デベロッパー マシンの kubectl など)を更新する必要があります。

API クライアントを更新するには、クライアントごとに次のコマンドを実行します。

gcloud container clusters get-credentials CLUSTER_NAME \
    --region REGION_NAME

Kubernetes ServiceAccount 認証情報を更新する

クラスタ内の ServiceAccounts に静的認証情報を使用している場合は、有効期間の短い認証情報に切り替えます。ローテーションが完了すると、既存の ServiceAccount 認証情報が無効になります。有効期間の短い認証情報を使用しない場合は、ローテーションの完了後に、クラスタ内のすべての ServiceAccount の静的認証情報を再作成します。

ハードコードされた IP アドレスとファイアウォール ルールを更新する

使用環境でコントロール プレーンの IP アドレスをハードコードした場合、またはコントロール プレーンの IP アドレスをターゲットとするファイアウォール ルールがある場合は、アドレスを新しい IP アドレスに更新します。アプリケーションとファイアウォール ルールの IP アドレスを更新せずにローテーションを完了すると、GKE が以前のコントロール プレーン IP アドレスに対するサービスを停止したときに、それらのリソースで中断が発生する可能性があります。

ローテーションを完了する

クラスタの外部で API クライアントを更新したら、新しい認証情報と新しい IP アドレスのみでサービスを提供するように、コントロール プレーンを構成します。

gcloud container clusters update CLUSTER_NAME \
    --region=REGION_NAME \
    --complete-credential-rotation

認証情報のローテーションが完了せず、次のようなエラー メッセージが返される場合は、トラブルシューティングを参照してください。

ERROR: (gcloud.container.clusters.update) ResponseError: code=400, message=Node pool "test-pool-1" requires recreation.

次のステップ