LoadBalancer を 1.7.0 から 1.7.2 にアップグレードする場合の注意

Kubernetes バージョン 1.7.0 以降では、type LoadBalancer を指定して新しい Service を作成すると、ノードのヘルスチェックがデフォルトで有効になります(クラスタ内のすべてのノードでバージョン v1.7.0 以降が実行されている場合)。

ただし、Kubernetes バージョン 1.7.0 と 1.7.1 には、GCP ネットワーク ロードバランサからのヘルスチェックにノードが正しく応答しないという既知の問題が存在します。この問題が発生すると、トラフィックはバックエンドに転送されますが、Kubernetes で構成したネットワーク ロードバランサには、すべてのクラスタノードからヘルスチェックの失敗が報告されます。

この問題はバージョン 1.7.2 で修正されていますが、バージョン 1.7.0 または 1.7.1 から 1.7.2 に既存のクラスタをアップグレードするときに操作が必要になる場合があります。アップグレードを実行すると、負荷の不均衡が発生する可能性があります。バージョン 1.7.2 を実行しているノードでヘルスチェックが正常に機能している場合、GCP ロードバランサはこれらのノードにすべてのトラフィックに転送します。ヘルスチェックが失敗しているバージョン 1.7.0 または 1.7.1 のノードには転送されません。この不均衡が発生しているときに、正常の状態のノード(つまり、バージョン 1.7.2 が実行されているノード)の数が十分でなく、クラスタのトラフィックを処理できない場合、サービスが中断する可能性があります。

ノードをバージョン 1.7.2 にアップグレードする前に、影響を受けるすべてのロードバランサからヘルスチェックを手動で削除することで、この問題を回避できます。

クラスタが影響を受けるかどうかの確認

クラスタノードで Kubernetes バージョン 1.7.0 または 1.7.1 が実行され、次のいずれかに当てはまる場合には、クラスタが影響を受ける可能性があります。

  • --type LoadBalancer で新しい Service を作成した。
  • --type LoadBalancer の既存の Service を別のタイプ(ClusterIPExternalName など)に更新した後、LoadBalancer に戻した。
  • 既存の LoadBalancer サービスで sessionAffinity フィールドを更新した。
  • 既存の LoadBalancer サービスで、externalTrafficPolicy フィールドを Cluster に設定した。

クラスタが影響を受けるかどうか確認するには:

  1. Google Cloud Console で、GKE に移動してクラスタを選択します。
  2. [検出と負荷分散] タブをクリックします。
  3. [タイプ] フィールドが LoadBalancerであるサービスを探して、そのサービス名をクリックします。
  4. [サービスの詳細] ペインで、[LoadBalancer] フィールドを探します。これが、クラスタに接続している GCP LoadBalancer リソースになります。
  5. ロードバランサの名前をクリックします。
  6. [負荷分散] ペインが表示されます。ここで、影響を受けるヘルスチェックを探します。k8s-XXX-node という名前のヘルスチェックが付加されている場合は、クラスタが影響を受けます。

クラスタ内のすべてのロードバランサ サービスに関して上記の手順を繰り返します。

対応する Kubernetes Service を特定するには、詳細設定メニューを使用して次の操作を行います。

  1. [転送ルール] タブをクリックします。
  2. ロードバランサのエントリを選択します。
  3. [説明] フィールドにサービス名が {"kubernetes.io/service-name":"$NAMESPACE/$SERVICE_NAME"} の形式で表示されます。

アップグレードに伴うリスクの回避

負荷の不均衡を発生させずにバージョン 1.7.2 に安全にアップグレードするには、次の操作を行います。

  1. アップグレードを開始する前に、クラスタで影響を受けるすべてのロードバランサからヘルスチェックを手動で削除します。
  2. ノードをバージョン 1.7.2 にアップグレードします。
  3. アップグレードの完了後に、クラスタ内の各ロードバランサでヘルスチェックを置換します。

アップグレード前

ロードバランサからノードのヘルスチェックを削除するには:

  1. Google Cloud Console で、GKE に移動してクラスタを選択します。
  2. [検出と負荷分散] タブをクリックします。
  3. 影響を受ける LoadBalancer サービスを探して、サービス名をクリックします。
  4. [サービスの詳細] ペインで、[LoadBalancer] フィールドを探します。これが、クラスタに接続している GCP LoadBalancer リソースになります。
  5. ロードバランサの名前をクリックします。
  6. [負荷分散] ペインで、[詳細設定メニュー] リンクをクリックします。
  7. [詳細設定メニュー] で [ターゲット プール] をクリックします。
  8. 1. ヘルスチェックの名前 k8s-XXX-node をメモします。XXX は、クラスタのハッシュ ID です。この名前は、あとでヘルスチェックを復元するときに必要になります。
  9. ロードバランサに対応するターゲット プールを編集して「ヘルスチェックをしない」に設定します。これは、サービスでダウンタイムを発生させないインプレース更新です。

クラスタで影響を受ける他のロードバランサに関して上記の手順を繰り返します。

ヘルスチェックを削除した後で、トラフィックの不均衡を回避し、ノードをバージョン 1.7.2 に安全にアップグレードできます。 GCP ロードバランサは、ステータスに関係なく、ヘルスチェックを行わずにトラフィックをノードに転送します。この動作は、バージョン 1.6.x 以前の Kubernetes を実行しているクラスタと同じです。

アップグレード後

アップグレード後に、クラスタのロードバランサでノードのヘルスチェックを置換できます。手順は次のとおりです。

  1. Google Cloud Console でクラスタに移動します。
  2. [検出と負荷分散] タブをクリックします。
  3. 影響を受ける LoadBalancer サービスを探して、サービス名をクリックします。
  4. [サービスの詳細] ペインで [LoadBalancer] フィールドを探します。これが、クラスタに接続している GCP LoadBalancer リソースになります。
  5. ロードバランサの名前をクリックします。
  6. [負荷分散] ペインで、[詳細設定メニュー] リンクをクリックします。
  7. [詳細設定メニュー] で [ターゲット プール] をクリックします。
  8. アップグレード前にヘルスチェックを削除するときにメモした k8s-XXX-node 形式の値に一致するように、ロードバランサに対応するターゲット プールを編集します。これは、サービスでダウンタイムを発生させないインプレース更新です。

クラスタで影響を受ける他のロードバランサに関して上記の手順を繰り返します。