Google Cloud での Ingress の構成


概要

このページでは、Google Cloud で Kubernetes Ingress を通じて構成可能な内容について包括的な概要を示します。また、Google Cloud でサポートされている Ingress の機能を比較し、デフォルト コントローラ、FrontendConfig パラメータ、BackendConfig パラメータを使用して Ingress を構成する手順についても説明します。

このページは、組織のネットワークを設計し、ネットワーク機器の設置、構成、サポートを行うネットワーク スペシャリストを対象としています。Google Cloud のコンテンツで参照する一般的なロールとタスク例の詳細については、一般的な GKE Enterprise ユーザーロールとタスクをご覧ください。

機能の比較

Google Cloud でサポートされている Ingress の機能の一覧については、次の表をご覧ください。機能の可用性(一般提供(GA)、ベータ版)も示されています。

Ingress クラス 外部 Ingress 内部 Ingress マルチクラスタ Ingress
Ingress コントローラ Google がホストする Ingress コントローラ
Google Cloud ロードバランサのタイプ 外部 HTTP(S) 負荷分散 内部 HTTP(S) 負荷分散 外部 HTTP(S) 負荷分散
クラスタのスコープ 単一クラスタ 単一クラスタ マルチクラスタ
ロードバランサのスコープ グローバル リージョン グローバル
環境サポート GKE GKE GKE
共有 VPC のサポート 一般提供 一般提供 一般提供
Service アノテーション
コンテナ ネイティブの負荷分散(NEG) 一般提供 一般提供 一般提供
ロードバランサからバックエンドへの HTTPS 一般提供 一般提供 一般提供
HTTP/2 一般提供 一般提供
TLS のみ
一般提供
Ingress アノテーション
静的 IP アドレス 一般提供 一般提供 一般提供
Kubernetes Secret ベースの証明書 一般提供 一般提供 一般提供
セルフマネージド SSL 証明書 一般提供 一般提供 一般提供
Google マネージド SSL 証明書 一般提供 一般提供
FrontendConfig
SSL ポリシー 一般提供 Gateway を使用した一般提供 一般提供
HTTP から HTTPS へのリダイレクト 一般提供
1.17.13-gke.2600+一般提供
一般提供
BackendConfig
バックエンド サービスのタイムアウト 一般提供 一般提供 一般提供
Cloud CDN 一般提供 一般提供
コネクション ドレインのタイムアウト 一般提供 一般提供 一般提供
カスタムのロードバランサのヘルスチェック構成 一般提供 一般提供 一般提供
Google Cloud Armor セキュリティ ポリシー 一般提供
1.19.10-gke.700G
一般提供
HTTP アクセス ロギングの構成 一般提供 一般提供 一般提供
Identity-Aware Proxy(IAP) 一般提供 一般提供 一般提供
セッション アフィニティ 一般提供 一般提供 一般提供
ユーザー定義のリクエスト ヘッダー 一般提供 一般提供
カスタム レスポンス ヘッダー 一般提供
1.25-gke+G
一般提供
1.25-gke+G

B この機能は、指定したバージョン以降のベータ版で利用できます。バージョンが表示されていない機能は、利用可能なすべての GKE のバージョンでサポートされています。

G この機能は、指定したバージョン以降の一般提供リリースとしてサポートされます。

デフォルト コントローラを使用した Ingress の構成

Google Cloud SDK または Google Cloud コンソールを使用して LoadBalancer 機能を手動で構成することはできません。BackendConfig または FrontendConfig Kubernetes リソースを使用する必要があります。

デフォルトのコントローラを使用して Ingress を作成する場合、Ingress オブジェクトのアノテーションを使用して、ロードバランサのタイプ(外部アプリケーション ロードバランサまたは内部アプリケーション ロードバランサ)を選択できます。GKE でゾーン NEG を作成するか、各 Service オブジェクトでアノテーションを使用してインスタンス グループを使用するかを選択できます。

FrontendConfig と BackendConfig のカスタム リソース定義(CRD)を使用することで、ロードバランサをさらにカスタマイズできます。これらの CRD を使用すると、アノテーションよりも構造化された方法で、追加のロードバランサ機能を階層的に定義できます。Ingress とこれらの CRD を使用するには、HTTP 負荷分散アドオンが有効になっている必要があります。GKE クラスタの HTTP 負荷分散はデフォルトで有効になっています。無効にしないでください。

FrontendConfig は Ingress オブジェクトで参照され、外部 Ingress でのみ使用できます。BackendConfig は Service オブジェクトで参照されます。構成の整合性を保つために、複数の Service オブジェクトまたは Ingress オブジェクトで同じ CRD を参照できます。FrontendConfig と BackendConfig CRD は、対応する Ingress リソースと Service リソースと同じライフサイクルを共有し、多くの場合一緒にデプロイされます。

次の図は、その方法を示しています。

  • Ingress または MultiClusterIngress オブジェクトのアノテーションは、FrontendConfig CRD を参照します。FrontendConfig CRD は Google Cloud SSL ポリシーを参照します。

  • Service または MultiClusterService オブジェクトのアノテーションは、BackendConfig CRD を参照します。BackendConfig CRD は、対応するバックエンド サービスのヘルスチェックのカスタム設定を指定します。

BackendConfig と FrontendConfig の概要
図: BackendConfig と FrontendConfig の概要

FrontendConfig と Ingress の関連付け

FrontendConfig は外部 Ingress でのみ使用できます。

FrontendConfig は Ingress または MultiClusterIngress に関連付けることができます。

Ingress

networking.gke.io/v1beta1.FrontendConfig アノテーションを使用します。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    networking.gke.io/v1beta1.FrontendConfig: "FRONTENDCONFIG_NAME"
...

FRONTENDCONFIG_NAME は実際の FrontendConfig 名で置き換えます。

MultiClusterIngress

networking.gke.io/frontend-config アノテーションを使用します。

apiVersion: networking.gke.io/v1
kind: MultiClusterIngress
metadata:
  annotations:
    networking.gke.io/frontend-config: "FRONTENDCONFIG_NAME"
...

FRONTENDCONFIG_NAME は実際の FrontendConfig 名で置き換えます。

BackendConfig と Ingress の関連付け

cloud.google.com/backend-config または beta.cloud.google.com/backend-config アノテーションを使用して、BackendConfig の名前を指定できます。

すべての Service ポートで同じ BackendConfig

すべてのポートに同じ BackendConfig を使用するには、アノテーションで default キーを使用します。Ingress コントローラは、ロードバランサのバックエンド サービスを作成するたびに同じ BackendConfig を使用して、Service のポートの 1 つを参照します。

default キーは、Ingress リソースと MultiClusterIngress リソースの両方に使用できます。
apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/backend-config: '{"default": "my-backendconfig"}'
...

Service ポートごとに一意の BackendConfig

Ingress と MultiClusterIngress の両方で、ポートの名前または番号に一致するキーを使用して、1 つ以上のポートにカスタム BackendConfig を指定できます。Ingress コントローラは、参照される Service ポートのロードバランサ バックエンド サービスを作成するときに、特定の BackendConfig を使用します。

GKE 1.16-gke.3 以降

apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/backend-config: '{"ports": {
    "SERVICE_REFERENCE_A":"BACKENDCONFIG_REFERENCE_A",
    "SERVICE_REFERENCE_B":"BACKENDCONFIG_REFERENCE_B"
    }}'
spec:
  ports:
  - name: PORT_NAME_1
    port: PORT_NUMBER_1
    protocol: TCP
    targetPort: 50000
  - name: PORT_NAME_2
    port: PORT_NUMBER_2
    protocol: TCP
    targetPort: 8080
...

サポートされているすべてのバージョン

apiVersion: v1
kind: Service
metadata:
  annotations:
    cloud.google.com/backend-config: '{"ports": {
      PORT_NAME_1:"BACKENDCONFIG_REFERENCE_A",
      PORT_NAME_2:"BACKENDCONFIG_REFERENCE_B"
    }}'
spec:
  ports:
  - name: PORT_NAME_1
    port: PORT_NUMBER_1
    protocol: TCP
    targetPort: 50000
  - name: PORT_NAME_2
    port: PORT_NUMBER_2
    protocol: TCP
    targetPort: 8080
...

次のように置き換えます。

  • BACKENDCONFIG_REFERENCE_A: 既存の BackendConfig の名前。
  • BACKENDCONFIG_REFERENCE_B: 既存の BackendConfig の名前。
  • SERVICE_REFERENCE_A: PORT_NUMBER_1 または PORT_NAME_1 の値を使用します。これは、Service の BackendConfig アノテーションがポートの名前(spec.ports[].name)またはポートの番号(spec.ports[].port)を参照できるためです。
  • SERVICE_REFERENCE_B: PORT_NUMBER_2 または PORT_NAME_2 の値を使用します。これは、Service の BackendConfig アノテーションがポートの名前(spec.ports[].name)またはポートの番号(spec.ports[].port)を参照できるためです。

Service のポートを数値で参照する場合は、targetPort 値ではなく port 値を使用する必要があります。ここで使用されるポート番号は、BackendConfig のバインドにのみ使用されます。ロードバランサがトラフィックまたはヘルスチェック プローブを送信するポートは制御されません。

  • コンテナ ネイティブの負荷分散を使用する場合、ロードバランサは参照される Service ポート targetPort(サービスを提供する Pod の containerPort と一致する必要があります)のネットワーク エンドポイント グループ(Pod IP アドレスと一致)のエンドポイントにトラフィックを送信します。それ以外の場合、ロードバランサは参照される Service ポートの nodePort でノードの IP アドレスにトラフィックを送信します。

  • BackendConfig を使用してカスタム ロードバランサのヘルスチェックを提供する場合、ロードバランサのヘルスチェックに使用するポート番号は、Service の spec.ports[].port 番号と異なる場合があります。ヘルスチェックのポート番号の詳細については、カスタム ヘルスチェック構成をご覧ください。

FrontendConfig パラメータによる Ingress 機能の構成

次のセクションでは、特定の Ingress 機能を有効にするように FrontendConfig を設定する方法について説明します。

SSL ポリシー

SSL ポリシーを使用すると、ロードバランサがクライアントからの HTTPS トラフィックを終了するために使用する一連の TLS バージョンと暗号を指定できます。まず、GKE の外部で SSL ポリシーを作成する必要があります。作成すると、FrontendConfig CRD で参照できます。

FrontendConfig の sslPolicy フィールドは、GKE クラスタと同じ Google Cloud プロジェクト内の SSL ポリシーの名前を参照します。Ingress によって外部 HTTP(S) ロードバランサ用に作成されたターゲット HTTPS プロキシに SSL ポリシーが追加されます。複数の Ingress リソースで同じ FrontendConfig リソースと SSL ポリシーを参照できます。参照された SSL ポリシーが変更されると、Ingress によって作成された外部 HTTP(S) ロードバランサを実装する Google Front End(GFE)に変更が反映されます。

次の FrontendConfig マニフェストは、gke-ingress-ssl-policy という名前の SSL ポリシーを有効にします。

apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: my-frontend-config
spec:
  sslPolicy: gke-ingress-ssl-policy

HTTP から HTTPS へのリダイレクト

外部 HTTP ロードバランサは、同じ IP アドレスを使用する HTTPS ロードバランサに、暗号化されていない HTTP リクエストをリダイレクトできます。HTTP から HTTPS へのリダイレクトを有効にして Ingress を作成すると、これらの両方のロードバランサが自動的に作成されます。ポート 80 の Ingress の外部 IP アドレスへのリクエストは、ポート 443 の同じ外部 IP アドレスに自動的にリダイレクトされます。この機能は、Cloud Load Balancing の HTTP から HTTPS へのリダイレクトをベースとしています。

HTTP から HTTPS へのリダイレクトをサポートするには、HTTP と HTTPS の両方のトラフィックを処理するように Ingress を構成する必要があります。HTTP と HTTPS のいずれかが無効になっていると、リダイレクトは機能しません。

HTTP から HTTPS へのリダイレクトは、FrontendConfig カスタム リソースの redirectToHttps フィールドを使用して構成されます。Ingress リソース全体に対してリダイレクトが有効になるため、Ingress が参照するすべてのサービスで HTTPS リダイレクトが有効になります。

次の FrontendConfig マニフェストを使用すると、HTTP から HTTPS へのリダイレクトが有効になります。HTTPS リダイレクトを有効にするには、spec.redirectToHttps.enabled フィールドを true に設定します。spec.responseCodeName フィールドは省略可能です。省略されている場合は、301 Moved Permanently リダイレクトが使用されます。

apiVersion: networking.gke.io/v1beta1
kind: FrontendConfig
metadata:
  name: my-frontend-config
spec:
  redirectToHttps:
    enabled: true
    responseCodeName: RESPONSE_CODE

RESPONSE_CODE を次のいずれかに置き換えます。

  • MOVED_PERMANENTLY_DEFAULT は 301 リダイレクト レスポンス コードを返します(responseCodeName が指定されていない場合のデフォルト)。
  • FOUND は 302 リダイレクト レスポンス コードを返します。
  • SEE_OTHER は 303 リダイレクト レスポンス コードを返します。
  • TEMPORARY_REDIRECT は 307 リダイレクト レスポンス コードを返します。
  • PERMANENT_REDIRECT は 308 リダイレクト レスポンス コードを返します。

リダイレクトを有効にすると、Ingress コントローラは、次の図に示すようにロードバランサを作成します。

リダイレクトのみの外部 HTTP ロードバランサ。転送ルール、ターゲット HTTP プロキシ、バックエンド サービスを含む完全な HTTPS ロードバランサへのリダイレクトを含む URL マップで構成される

リダイレクトが機能しているか確認するには、curl コマンドを使用します。

curl http://IP_ADDRESS

IP_ADDRESS は、Ingress の IP アドレスに置き換えます。

構成したリダイレクト レスポンス コードがレスポンスに表示されます。たとえば、301: MovedPermanently リダイレクトで構成された FrontendConfig は次のようになります。

<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="https://35.244.160.59/">here</A>.</BODY></HTML>

BackendConfig パラメータによる Ingress 機能の構成

次のセクションでは、特定の Ingress 機能を有効にするように BackendConfig を設定する方法について説明します。BackendConfig リソースへの変更は常に調整されるため、Ingress を削除して再作成しなくても BackendConfig の変更が反映されていることを確認できます。

BackendConfig の制限事項については、制限事項のセクションをご覧ください。

バックエンド サービスのタイムアウト

BackendConfig を使用して、バックエンド サービスのタイムアウト期間を秒単位で設定できます。値を指定しない場合、デフォルト値は 30 秒です。

次の BackendConfig マニフェストは、40 秒のタイムアウトを指定します。

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  timeoutSec: 40

Cloud CDN

BackendConfig を使用して、Cloud CDN を有効にできます。

次の BackendConfig マニフェストには、Cloud CDN を有効にするときに使用できるすべてのフィールドが表示されます。

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  cdn:
    enabled: CDN_ENABLED
    cachePolicy:
      includeHost: INCLUDE_HOST
      includeProtocol: INCLUDE_PROTOCOL
      includeQueryString: INCLUDE_QUERY_STRING
      queryStringBlacklist: QUERY_STRING_DENYLIST
      queryStringWhitelist: QUERY_STRING_ALLOWLIST
    cacheMode: CACHE_MODE
    clientTtl: CLIENT_TTL
    defaultTtl: DEFAULT_TTL
    maxTtl: MAX_TTL
    negativeCaching: NEGATIVE_CACHING
    negativeCachingPolicy:
      code: NEGATIVE_CACHING_CODE
      ttl: NEGATIVE_CACHING_TTL
    requestCoalescing: REQ_COALESCING
    serveWhileStale: SERVE_WHILE_STALE
    signedUrlCacheMaxAgeSec: SIGNED_MAX_AGE
    signedUrlKeys:
      keyName: KEY_NAME
      keyValue: KEY_VALUE
      secretName: SECRET_NAME

次のように置き換えます。

  • CDN_ENABLED: true に設定すると、この Ingress バックエンドの Cloud CDN が有効になります。
  • INCLUDE_HOST: true に設定すると、異なるホストへのリクエストは個別にキャッシュされます。
  • INCLUDE_PROTOCOL: true に設定すると、HTTP リクエストと HTTPS リクエストは個別にキャッシュされます。
  • INCLUDE_QUERY_STRING: true に設定すると、queryStringBlacklist または queryStringWhitelist に従ってクエリ文字列パラメータがキャッシュキーに含まれます。どちらも設定されていない場合は、クエリ文字列全体が含まれます。false に設定すると、クエリ文字列全体がキャッシュキーから除外されます。
  • QUERY_STRING_DENYLIST: キャッシュキーから除外するクエリ文字列パラメータの名前を含む文字列配列を指定します。これ以外のパラメータはすべて含まれます。queryStringBlacklist または queryStringWhitelist を指定できますが、両方は指定できません。
  • QUERY_STRING_ALLOWLIST: キャッシュキーに含めるクエリ文字列パラメータの名前を含む文字列配列を指定します。これ以外のパラメータはすべて除外されます。queryStringBlacklist または queryStringWhitelist を使用できますが、両方は使用できません。

次のフィールドは、GKE Ingress を使用する GKE バージョン 1.23.3-gke.900 以降でのみサポートされます。マルチクラスタ Ingress の使用はサポートされません。

Ingress によって Cloud CDN をデプロイし、アプリケーション コンテンツがキャッシュに保存されていることを確認する例を見るには、次のセクションを展開してください。

コネクション ドレインのタイムアウト

コネクション ドレインのタイムアウトは、BackendConfig を使用して構成できます。コネクション ドレインのタイムアウトは、接続がドレインするまで待機する時間(秒)です。指定されたタイムアウト期間の間、除外されたバックエンドに対する既存のリクエストに、完了するまでの時間が与えられます。ロードバランサは、削除されたバックエンドに新しいリクエストを送信しません。タイムアウト時間に達すると、バックエンドに対する残りの接続がすべて閉じます。タイムアウト時間は 0~3,600 秒に設定できます。デフォルト値は 0 で、この場合コネクション ドレインも無効になります。

次の BackendConfig マニフェストは、コネクション ドレインのタイムアウトを 60 秒に指定します。

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  connectionDraining:
    drainingTimeoutSec: 60

カスタム ヘルスチェックの構成

Ingress によってデプロイされるときに、GKE で Google Cloud ロードバランサのヘルスチェックを構成する方法は多岐におよびます。GKE Ingress によるヘルスチェックのデプロイ方法の詳細については、Ingress ヘルスチェックをご覧ください。

BackendConfig を使用すると、ロードバランサのヘルスチェック設定を正確に制御できます。

再利用可能なテンプレートとして同じ BackendConfig を参照するように複数の GKE Service を構成できます。healthCheck パラメータについては、各 GKE Service に対応するバックエンド サービスごとに一意の Google Cloud ヘルスチェックが作成されます。

次の BackendConfig マニフェストは、BackendConfig ヘルスチェックの構成時に使用可能なすべてのフィールドを示します。

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  healthCheck:
    checkIntervalSec: INTERVAL
    timeoutSec: TIMEOUT
    healthyThreshold: HEALTH_THRESHOLD
    unhealthyThreshold: UNHEALTHY_THRESHOLD
    type: PROTOCOL
    requestPath: PATH
    port: PORT

次のように置き換えます。

  • INTERVAL: 各ヘルスチェック プローバーの check-interval を秒単位で指定します。これは、プローバーのチェックを開始してから次のチェックを開始するまでの時間です。このパラメータを省略すると、Google Cloud のデフォルトの 5 秒が使用されます。実装の詳細については、複数のプローブと頻度をご覧ください。
  • TIMEOUT: Google Cloud でプローブへのレスポンスを待機する時間を指定します。TIMEOUT の値は、INTERVAL 以下にする必要があります。単位は秒です。各プローブでは、タイムアウトの前に HTTP 200 (OK) レスポンス コードが配信される必要があります。
  • HEALTH_THRESHOLDUNHEALTHY_THRESHOLD: 正常から異常、または異常から正常に健全性を変更するために、少なくとも 1 つのプローバーについて、プローブの成功または失敗の連続回数を示します。これらのパラメータのいずれかを省略した場合、Google Cloud ではデフォルト値の 2 が使用されます。
  • PROTOCOL: ヘルスチェックのためにプローブ システムで使用されるプロトコルを指定します。BackendConfig は、HTTP、HTTPS、または HTTP2 プロトコルを使用したヘルスチェックの作成のみをサポートします。詳細については、HTTP、HTTPS、HTTP/2 での成功基準をご覧ください。このパラメータは省略できません。
  • PATH: HTTP、HTTPS、または HTTP2 のヘルスチェックの場合は、プローブ システムが接続する request-path を指定します。このパラメータを省略した場合、Google Cloud ではデフォルトの / が使用されます。
  • PORT: BackendConfig では、ポート番号を使用したロードバランサのヘルスチェック ポートの指定のみがサポートされています。このパラメータを省略した場合、Google Cloud ではデフォルト値の 80 が使用されます。

    • コンテナ ネイティブの負荷分散を使用する場合は、containerPort が Service の targetPort によって参照されているかどうかに関係なく、サービスを提供する Pod の containerPort に一致するポートを選択する必要があります。ロードバランサは、Pod の IP アドレスにプローブを直接送信するため、Service の targetPort によって参照される containerPort は制限されません。ヘルスチェック プローブ システムは、指定したポートでサービスを提供する Pod の IP アドレスに接続します。

    • インスタンス グループのバックエンドでは、Service によって公開される nodePort に一致するポートを選択する必要があります。その後、ヘルスチェック プローブ システムがそのポートの各ノードに接続します。

カスタム HTTP ヘルスチェックを使用して GKE Ingress を設定する方法については、GKE Ingress with custom HTTP health check をご覧ください。

Google Cloud Armor の Ingress セキュリティ ポリシー

Google Cloud Armor セキュリティ ポリシーは、負荷分散されたアプリケーションをウェブベースの攻撃から保護するのに役立ちます。Google Cloud Armor セキュリティ ポリシーを構成すると、BackendConfig を使用して参照できます。

セキュリティ ポリシーの名前を BackendConfig に追加します。次の BackendConfig マニフェストでは、example-security-policy という名前のセキュリティ ポリシーを指定しています。

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  namespace: cloud-armor-how-to
  name: my-backendconfig
spec:
  securityPolicy:
    name: "example-security-policy"

2 つの信頼できる情報源

GKE を介して構成されていても、基盤となる Compute Engine BackendService API を使用して、適用するセキュリティ ポリシーを直接変更できます。これにより、GKE と Compute Engine の 2 つの信頼できる情報源が作成されます。BackendConfig 内の securityPolicy フィールドに対する GKE Ingress コントローラの動作を次の表に示します。競合や予期しない動作を回避するには、GKE BackendConfig を使用して、使用するセキュリティ ポリシーを管理することをおすすめします。

BackendConfig フィールド 動作
spec.securityPolicy.name CloudArmorPolicyName GKE Ingress コントローラにより、CloudArmorPolicyName という名前の Google Cloud Armor ポリシーがロードバランサに設定されます。GKE Ingress コントローラにより、以前に設定されたポリシーが上書きされます。
spec.securityPolicy.name 空の文字列("" GKE Ingress コントローラにより、構成された Google Cloud Armor ポリシーがロードバランサから削除されます。
spec.securityPolicy nil GKE Ingress コントローラでは、Google Cloud コンソール、gcloud CLI、または Terraform を使用して Compute Engine API で構成された BackendService オブジェクトの構成セットを使用します。

Google Cloud Armor による保護を使用して GKE Ingress を設定する方法については、Google Cloud Armor enabled ingress をご覧ください。

HTTP アクセス ロギング

Ingress は、クライアントからのすべての HTTP リクエストを Cloud Logging に記録できます。アクセス ロギングを有効または無効にするには、BackendConfig とアクセス ロギングのサンプリング レートの設定を使用します。

アクセス ロギングを構成するには、BackendConfig の logging フィールドを使用します。logging を省略すると、アクセス ロギングはデフォルトの動作を実行します。これは GKE のバージョンによって異なります。

次のフィールドを構成できます。

  • enable: true に設定した場合、この Ingress のアクセス ロギングが有効になり、ログが Cloud Logging で使用できるようになります。それ以外の場合、この Ingress のアクセス ロギングは無効になります。
  • sampleRate: 0.0 から 1.0 までの値を指定します。0.0 の場合、パケットをまったくログに記録されません。1.0 の場合、すべてのパケットがログに記録されます。このフィールドは、enabletrue に設定されている場合にのみ機能します。sampleRate はオプションのフィールドですが、構成されている場合は enable: true も設定する必要があります。設定しなければ、enable: false と解釈されます。

次の BackendConfig マニフェストは、アクセス ロギングを有効にし、特定の Ingress リソースに対する HTTP リクエストのサンプルレートを 50% に設定します。

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  logging:
    enable: true
    sampleRate: 0.5

Identity-Aware Proxy

Identity-Aware Proxy IAP の BackendConfig を構成するには、BackendConfig の iap ブロックに enabledsecretName の値を指定する必要があります。これらの値を指定するには、compute.backendServices.update 権限が必要です。

次の BackendConfig マニフェストは、Identity-Aware Proxy を有効にします。

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name:  my-backendconfig
spec:
  iap:
    enabled: true
    oauthclientCredentials:
      secretName: my-secret

Google 管理の OAuth クライアントで IAP を有効にする

GKE 1.29.4-gke.1043000 以降では、BackendConfig を使用して Google 管理の OAuth クライアントを使用するように IAP を構成できます。Google OAuth クライアントとカスタム OAuth クライアントのどちらを使用するかを決定するには、IAP ドキュメントのカスタム OAuth 構成を使用するタイミングをご覧ください。

Google 管理の OAuth クライアントで IAP を有効にするには、BackendConfig で OAuthCredentials を指定しないでください。OAuthCredentials を使用して IAP をすでに構成しているユーザーの場合、Google 管理の OAuth クライアントを使用するように切り替える移行パスはなく、バックエンドを再作成する必要があります(Ingress からサービスを削除して再接続します)。このオペレーションはダウンタイムの原因となるため、メンテナンスの時間枠内で行うことをおすすめします。逆の移行パス、つまり Google 管理の OAuthClient から OAuthCredentials への切り替えも可能です。

次の BackendConfig マニフェストは、Google 管理の OAuth クライアントで Identity-Aware Proxy を有効にします。

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name:  my-backendconfig
spec:
  iap:
    enabled: true

詳細な手順については、IAP のドキュメントの GKE での IAP の有効化をご覧ください。

内部 Ingress を持つ Identity-Aware Proxy

IAP に内部 Ingress を構成するには、プレミアム ティアを使用する必要があります。プレミアム ティアを使用しない場合は、Identity-Aware Proxy を使用して内部アプリケーション ロードバランサを表示または作成することはできません。IAP で内部 Ingress を使用するには、Chrome Enterprise Premium サブスクリプションも必要です。

Identity-Aware Proxy ベースの認証を使用して安全な GKE Ingress を設定するには、例として IAP enabled ingress をご覧ください。

セッション アフィニティ

BackendConfig を使用して、セッション アフィニティをクライアント IP または生成された Cookie に設定できます。

クライアント IP アフィニティ

BackendConfig を使用してクライアント IP アフィニティを設定するには、次の例のように affinityType"CLIENT_IP" に設定します。

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  sessionAffinity:
    affinityType: "CLIENT_IP"

BackendConfig を使用して生成された Cookie アフィニティを設定するには、BackendConfig マニフェストで affinityTypeGENERATED_COOKIE に設定します。また、affinityCookieTtlSec を使用して、Cookie を有効のままにしておく期間を設定することもできます。

次のマニフェストでは、アフィニティ タイプを生成された Cookie に設定し、Cookie の TTL を 50 秒に設定します。

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  sessionAffinity:
    affinityType: "GENERATED_COOKIE"
    affinityCookieTtlSec: 50

ユーザー定義のリクエスト ヘッダー

BackendConfig を使用して、ユーザー定義のリクエスト ヘッダーを構成できます。ロードバランサは、指定したヘッダーをバックエンドに転送するリクエストに追加します。

ロードバランサは、カスタム リクエスト ヘッダーをクライアント リクエストにのみ追加します。ヘルスチェック プローブには追加しません。バックエンドで認可に特定のヘッダーが必要であり、ヘルスチェック パケットにヘッダーが含まれていない場合、ヘルスチェックが失敗する可能性があります。

ユーザー定義のリクエスト ヘッダーを有効にするには、BackendConfig リソースの customRequestHeaders プロパティにヘッダーのリストを指定します。各ヘッダーを header-name:header-value 文字列として指定します。

次の BackendConfig マニフェストは、3 つのリクエスト ヘッダーを追加します。

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  customRequestHeaders:
    headers:
    - "X-Client-Region:{client_region}"
    - "X-Client-City:{client_city}"
    - "X-Client-CityLatLong:{client_city_lat_long}"

カスタム レスポンス ヘッダー

カスタム リクエスト ヘッダーを有効にするには、BackendConfig リソースの customResponseHeaders プロパティにヘッダーのリストを指定します。各ヘッダーを header-name:header-value 文字列として指定します。

カスタム レスポンス ヘッダーは、GKE クラスタ バージョン 1.25 以降でのみ使用できます。

次の BackendConfig マニフェストでは、HTTP Strict Transport Security(HSTS)レスポンス ヘッダーを追加する例を示します。

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  customResponseHeaders:
    headers:
    - "Strict-Transport-Security: max-age=28800; includeSubDomains"

演習: バックエンド サービスを使用した Ingress タイムアウトの設定

次の演習では、BackendConfig リソースを使用して Ingress でタイムアウトとコネクション ドレインを構成するために必要な手順を示します。

Ingress のバックエンド プロパティを構成するには、次の操作を行います。

  1. Deployment を作成します
  2. BackendConfig を作成します
  3. Service を作成し、そのポートの 1 つを BackendConfig に関連付けます
  4. Ingress を作成して、その Ingress を(Service、ポート)ペアに関連付けます
  5. バックエンド サービスのプロパティを検証します
  6. クリーンアップします。

Deployment を作成する

BackendConfig と Service を作成する前に、Deployment を作成する必要があります。

次のマニフェストの例では、my-deployment.yaml という Deployment になります。

# my-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      purpose: bsc-config-demo
  replicas: 2
  template:
    metadata:
      labels:
        purpose: bsc-config-demo
    spec:
      containers:
      - name: hello-app-container
        image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0

次のコマンドを実行して Deployment を作成します。

kubectl apply -f my-deployment.yaml

BackendConfig を作成する

BackendConfig を使用して、使用する Ingress 機能を指定します。

この my-backendconfig.yaml という名前の BackendConfig マニフェストでは、以下を指定しています。

  • タイムアウトを 40 秒に設定しています。
  • コネクション ドレイン タイムアウトを 60 秒に設定しています。
# my-backendconfig.yaml
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  timeoutSec: 40
  connectionDraining:
    drainingTimeoutSec: 60

次のコマンドを実行して BackendConfig を作成します。

kubectl apply -f my-backendconfig.yaml

Service の作成

BackendConfig は、Service に複数のポートがある場合でも、単一の Service と Port の組み合わせに対応します。各ポートは、1 つの BackendConfig CRD に関連付けることができます。Ingress が Service ポートを参照し、その Service ポートが BackendConfig に関連付けられている場合、HTTP(S) 負荷分散バックエンド サービスは BackendConfig による構成に影響を与えます。

my-service.yaml という名前の Service マニフェストの例を次に示します。

# my-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: my-service
  labels:
    purpose: bsc-config-demo
  annotations:
    cloud.google.com/backend-config: '{"ports": {"80":"my-backendconfig"}}'
    cloud.google.com/neg: '{"ingress": true}'
spec:
  type: ClusterIP
  selector:
    purpose: bsc-config-demo
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080

cloud.google.com/backend-config アノテーションでは、ポートと BackendConfig オブジェクトの間のマッピングが指定されます。my-service.yaml で:

  • purpose: bsc-config-demo というラベルを持つすべての Pod は Service のメンバーです。
  • Service の TCP ポート 80 が my-backendconfig という名前の BackendConfig に関連付けられています。これは、cloud.google.com/backend-config アノテーションで指定されています。
  • Service のポート 80 に送信されたリクエストは、いずれかのメンバー Pod(ポート 8080)に転送されます。

Service を作成するには、次のコマンドを実行します。

kubectl apply -f my-service.yaml

Ingress を作成する

次の my-ingress.yaml. という名前の Ingress マニフェストの例では、my-service という名前の Service のポート 80 に受信リクエストがルーティングされています。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  rules:
  - http:
      paths:
      - path: /*
        pathType: ImplementationSpecific
        backend:
          service:
            name: my-service
            port:
              number: 80

Ingress を作成するには、次のコマンドを実行します。

kubectl apply -f my-ingress.yaml

Ingress コントローラが外部アプリケーション ロードバランサおよび関連するバックエンド サービスを構成するまで数分待ちます。上記の手順が完了すると、Ingress が 40 秒のタイムアウトと 60 秒のコネクション ドレインのタイムアウトを使用するように構成されます。

バックエンド サービスのプロパティを確認する

BackendConfig を使用して、正しいロードバランサの設定が適用されていることを確認できます。これを行うには、Ingress がデプロイしたバックエンド サービスを特定し、その設定を調べて Deployment マニフェストと一致していることを確認します。

まず、my-ingress リソースを記述し、Ingress に関連付けられたバックエンド サービスを一覧表示するアノテーションをフィルタリングします。例:

kubectl describe ingress my-ingress | grep ingress.kubernetes.io/backends

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

ingress.kubernetes.io/backends: '{"k8s1-27fde173-default-my-service-80-8d4ca500":"HEALTHY","k8s1-27fde173-kube-system-default-http-backend-80-18dfe76c":"HEALTHY"}

出力には、バックエンド サービスに関する情報が表示されます。たとえば、このアノテーションには 2 つのバックエンド サービスが含まれています。

  • "k8s1-27fde173-default-my-service-80-8d4ca500":"HEALTHY" は、my-service Kubernetes Service に関連したバックエンド サービスに関する情報を示しています。
    • k8s1-27fde173 は、クラスタの説明に使用されるハッシュです。
    • default は Kubernetes 名前空間です。
    • HEALTHY は、バックエンドが正常であることを示します。
  • "k8s1-27fde173-kube-system-default-http-backend-80-18dfe76c":"HEALTHY" は、デフォルトのバックエンド(404 サーバー)に関連したバックエンド サービスに関する情報を示しています。
    • k8s1-27fde173 は、クラスタの説明に使用されるハッシュです。
    • kube-system は名前空間です。
    • default-http-backend Kubernetes Service の名前です。
    • 80 はホストのポートです。
    • HEALTHY は、バックエンドが正常であることを示します。

次に、gcloud を使用して、my-service に関連付けられているバックエンド サービスを検査します。"drainingTimeoutSec""timeoutSec" をフィルタリングして、Google Cloud ロードバランサのコントロール プレーンで設定されていることを確認します。例:

# Optionally, set a variable
export BES=k8s1-27fde173-default-my-service-80-8d4ca500

# Filter for drainingTimeoutSec and timeoutSec
gcloud compute backend-services describe ${BES} --global | grep -e "drainingTimeoutSec" -e "timeoutSec"

出力:

  drainingTimeoutSec: 60
  timeoutSec: 40

出力に drainingTimeoutSectimeoutSec が表示されていることで、BackendConfig で値が正しく設定されていることを確認できます。

クリーンアップ

アカウントで不要な料金が発生しないように、この演習用に作成した Kubernetes オブジェクトを削除します。

kubectl delete ingress my-ingress
kubectl delete service my-service
kubectl delete backendconfig my-backendconfig
kubectl delete deployment my-deployment

BackendConfig の制限事項

BackendConfig には次の制限があります。

  • 複数の Ingress オブジェクトが(Service、ポート)を参照する場合でも、1 つの(Service、ポート)ペアが使用できるのは 1 つの BackendConfig だけです。つまり、同じ(Service、ポート)を参照するすべての Ingress オブジェクトで、Google Cloud Armor、IAP、Cloud CDN に対する構成を同一にする必要があります。
  • IAP と Cloud CDN を同じ HTTP(S) ロード バランシング バックエンド サービスで有効にすることはできません。つまり、同じ BackendConfig に IAP と Cloud CDN の両方を構成することはできません。
  • BackendConfig を使用して操作する場合、kubectl 1.7 以降を使用する必要があります。

FrontendConfig または BackendConfig で指定された構成の削除

Ingress 機能を取り消すには、FrontendConfig または BackendConfig CRD で機能構成を明示的に無効にする必要があります。Ingress コントローラは、これらの CRD で指定された構成のみを調整します。

以前に有効にした構成を消去または無効にするには、フィールド タイプに応じてフィールドの値を空の文字列("")または false のブール値に設定します。

次の BackendConfig マニフェストは、Google Cloud Armor セキュリティ ポリシーと Cloud CDN を無効にします。

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: my-backendconfig
spec:
  cdn:
    enabled: false
  securityPolicy:
    name: ""

FrontendConfig または BackendConfig の削除

FrontendConfig

FrontendConfig を削除するには、次の手順に従います。

  1. Ingress マニフェストの networking.gke.io/v1beta1.FrontendConfig アノテーションから FrontendConfig の名前を削除します。

  2. 変更した Ingress マニフェストをクラスタに適用します。たとえば、kubectl apply を使用します。

  3. FrontendConfig を削除します。たとえば、kubectl delete frontendconfig config my-frontendconfig を使用します。

BackendConfig

BackedConfig を削除するには、次の手順に従います。

  1. Service マニフェストの cloud.google.com/backend-config アノテーションから BackendConfig の名前を削除します。

  2. 変更された Service マニフェストをクラスタに適用します。たとえば、kubectl apply を使用します。

  3. BackendConfig を削除します。たとえば、kubectl delete backendconfig my-backendconfig を使用します。

トラブルシューティング

一般的な構成ミスを検出するには、Ingress 診断ツールを使用します。また、ヘルスチェックが正しく構成されていることを確認する必要があります。

BackendConfig が見つからない

このエラーは、Service のアノテーションで Service ポートの BackendConfig が指定されているにもかかわらず BackendConfig リソースが見つからなかった場合に発生します。

Kubernetes イベントを評価するには、次のコマンドを実行します。

kubectl get event

次の出力例は、BackendConfig が見つからなかったことを示します。

KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: error getting BackendConfig for port 80 on service "default/my-service":
no BackendConfig for service port exists

この問題を解決するには、誤った Namespace に BackendConfig リソースが作成されていないことや、Service アノテーションの参照にスペルミスがないことを確認します。

Ingress セキュリティ ポリシーが見つかりません

Ingress オブジェクトが作成された後で、セキュリティ ポリシーが LoadBalancer サービスと適切に関連付けられていない場合は、Kubernetes イベントを検査して構成ミスがないか調べてください。BackendConfig が存在しないセキュリティ ポリシーを指定している場合は、警告イベントが定期的に発生します。

Kubernetes イベントを評価するには、次のコマンドを実行します。

kubectl get event

次の出力例は、セキュリティ ポリシーが見つからなかったことを示します。

KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: The given security policy "my-policy" does not exist.

この問題を解決するには、BackendConfig に正しいセキュリティ ポリシー名を指定します。

GKE でワークロードのスケーリング中に発生した NEG 関連の 500 シリーズエラーへの対処

症状:

GKE でプロビジョニングされた NEG をロード バランシングに使用すると、ワークロードのスケールダウン中にサービスで 502 エラーまたは 503 エラーが発生する可能性があります。502 エラーは既存の接続が閉じる前に Pod が終了した場合に発生します。一方、503 エラーは、削除された Pod にトラフィックが転送された場合に発生します。

Gateway、Ingress、スタンドアロン NEG など、NEG を使用する GKE マネージド ロード バランシング プロダクトを使用している場合、この問題はクラスタに影響する可能性があります。ワークロードを頻繁にスケーリングすると、クラスタが影響を受けるリスクが高くなります。

診断:

エンドポイントをドレインして NEG から削除することなく、Kubernetes で Pod を削除すると、500 シリーズエラーが発生します。Pod の終了時に問題が発生しないようにするには、オペレーションの順序を考慮する必要があります。次の図は、BackendService Drain Timeout が設定されておらず、BackendService Drain TimeoutBackendConfig に設定されている場合のシナリオを示しています。

シナリオ 1: BackendService Drain Timeout が設定されていない。

次の図は、BackendService Drain Timeout が設定されていないシナリオを示しています。

BackendService ドレイン タイムアウトが未設定。

シナリオ 2: BackendService Drain Timeout が設定されている。

次の図は、BackendService Drain Timeout が設定されているシナリオを示しています。

BackendService ドレイン タイムアウトが設定されている。

500 シリーズエラーが発生するタイミングは次の要因によって決まります。

  • NEG API の接続解除レイテンシ: NEG API の接続解除レイテンシは、Google Cloud で接続解除オペレーションが完了するのにかかる時間です。これは、ロードバランサの種類や特定のゾーンなど、Kubernetes 以外のさまざまな要因の影響を受けます。

  • ドレイン レイテンシ: ドレイン レイテンシは、ロードバランサがシステムの特定の部分からトラフィックを送信するのに要する時間を表します。ドレインが開始されると、ロードバランサはエンドポイントへの新しいリクエストの送信を停止しますが、ドレインのトリガーにはレイテンシ(ドレイン レイテンシ)があり、Pod が存在しない場合は一時的な 503 エラーが発生する可能性があります。

  • ヘルスチェックの構成: ヘルスチェックのしきい値の感度を高くすると、接続解除オペレーションが完了していなくてもロードバランサにエンドポイントへのリクエストの送信を停止するように通知できるため、503 エラーの持続を回避できます。

  • 終了猶予期間: 終了猶予期間により、Pod が終了するまでの最大時間が決まります。ただし、終了猶予期間が完了する前に Pod が終了する場合もあります。Pod の存続期間がこの期間よりも長い場合は、この期間の終了時に Pod は強制的に終了します。これは Pod の設定であり、ワークロード定義で構成する必要があります。

考えられる解決策:

このような 5XX エラーを防ぐには、次の設定を適用します。タイムアウト値はあくまでも目安であり、アプリケーションに合わせて調整する必要があります。次のセクションでは、カスタマイズ プロセスについて説明します。

次の図は、preStop フックを使用して Pod を存続させる方法を示しています。

BackendService ドレイン タイムアウトが設定されている。

500 シリーズエラーを回避するには、次の操作を行います。

  1. サービスの BackendService Drain Timeout を 1 分に設定します。

  2. Pod で terminationGracePeriod を拡張します。

    Pod の terminationGracePeriodSeconds を 3.5 分に設定します。推奨設定と組み合わせると、Pod のエンドポイントが NEG から削除されてから、Pod に 30~45 秒の猶予期間が与えられます。正常なシャットダウンにさらに時間が必要な場合は、猶予期間を延長するか、タイムアウトをカスタマイズするの説明に従ってください。

    次の Pod マニフェストでは、コネクション ドレインのタイムアウトを 210 秒(3.5 分)に指定しています。

    spec:
      terminationGracePeriodSeconds: 210
      containers:
      - name: my-app
        ...
      ...
    
  3. すべてのコンテナに preStop フックを適用します。

    preStop フックを適用します。これにより、Pod のエンドポイントがロードバランサでドレインされ、エンドポイントが NEG から削除され、Pod の存続期間が 120 秒に延長されます。

    spec:
      containers:
      - name: my-app
        ...
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sh", "-c", "sleep 120s"]
      ...
    

タイムアウトをカスタマイズする

Pod の継続性を確保しながら 500 シリーズエラーを防ぐには、エンドポイントが NEG から削除されるまで Pod が存続している必要があります。特に 502 エラーと 503 エラーを防ぐには、タイムアウトと preStop フックを組み合わせて実装することを検討してください。

シャットダウン プロセス中に Pod を長く存続させるには、preStop フックを Pod に追加します。Pod に終了シグナルが送信される前に preStop フックを実行することで、preStop フックを使用して、対応するエンドポイントが NEG から削除されるまで Pod を維持できます。

シャットダウン プロセス中に Pod がアクティブである期間を延長するには、次のように Pod 構成に preStop フックを挿入します。

spec:
  containers:
  - name: my-app
    ...
    lifecycle:
      preStop:
        exec:
          command: ["/bin/sh", "-c", "sleep <latency time>"]

タイムアウトと関連設定を構成することで、ワークロードのスケールダウン中に Pod が正常にシャットダウンされるように管理できます。タイムアウトは、特定のユースケースに応じて調整できます。最初の段階ではタイムアウトを長めに設定し、その後、必要に応じて短くすることをおすすめします。タイムアウト関連のパラメータと preStop フックを次のように構成することで、タイムアウトをカスタマイズできます。

Backend Service のドレイン タイムアウト

デフォルトでは、Backend Service Drain Timeout パラメータは設定されておらず、効果はありません。Backend Service Drain Timeout パラメータを設定して有効にすると、ロードバランサはエンドポイントへの新しいリクエストの転送を停止し、タイムアウトを待ってから既存の接続を終了します。

Backend Service Drain Timeout パラメータを設定するには、BackendConfig(Ingress の場合)または GCPBackendPolicy(Gateway の場合)を使用します。スタンドアロン NEG の場合は、BackendService に手動で設定します。タイムアウトは、リクエストの処理時間の 1.5~2 倍にする必要があります。これにより、ドレインが開始される直前にリクエストが到着したときに、タイムアウトの前にリクエストが完了するようになります。Backend Service Drain Timeout パラメータを 0 より大きい値に設定すると、削除が予定されているエンドポイントに新しいリクエストが送信されないため、503 エラーが軽減されます。このタイムアウトを有効にするには、preStop フックと併用し、ドレインが発生している間も Pod がアクティブな状態を維持できるようにする必要があります。この組み合わせを使用しないと、完了しなかった既存のリクエストは 502 エラーを受け取ります。

preStop フック時間

preStop フックには、ドレイン レイテンシとバックエンド サービスのドレイン タイムアウトの両方が完了するまで Pod のシャットダウンを遅らせるのに十分な値を設定する必要があります。これにより、Pod がシャットダウンされる前に適切なコネクション ドレインと NEG からのエンドポイントの削除が確実に行われるようになります。

最適な結果を得るには、preStop フックの実行時間が Backend Service Drain Timeout とドレイン レイテンシの合計と同じか、それよりも長くなるようにします。

理想的な preStop フックの実行時間は、次の式で計算できます。

preStop hook execution time >= BACKEND_SERVICE_DRAIN_TIMEOUT + DRAIN_LATENCY

次のように置き換えます。

  • BACKEND_SERVICE_DRAIN_TIMEOUT: Backend Service Drain Timeout に構成した時間。
  • DRAIN_LATENCY: ドレイン レイテンシの推定時間。推定時間として 1 分を使用することをおすすめします。

500 エラーが引き続き発生する場合は、合計の発生時間を見積もり、その時間の 2 倍をドレイン レイテンシの推定値に追加します。これにより、Pod がサービスから削除される前に、正常にドレインするための十分な時間が確保されます。特定のユースケースでこの値が長すぎる場合は、値を調整します。

Cloud Audit Logs で、Pod から削除されたときのタイムスタンプと、エンドポイントが NEG から削除されたときのタイムスタンプを調べることで、タイミングを見積もることもできます。

終了猶予期間パラメータ

preStop フックが終了し、Pod が正常なシャットダウンを完了するのに十分な時間を確保できるように、terminationGracePeriod パラメータを構成する必要があります。

明示的に設定されていない場合、terminationGracePeriod はデフォルトの 30 秒になります。最適な terminationGracePeriod は次の式で計算できます。

terminationGracePeriod >= preStop hook time + Pod shutdown time

Pod の構成で terminationGracePeriod を定義するには、次のようにします。

  spec:
    terminationGracePeriodSeconds: <terminationGracePeriod>
    containers:
    - name: my-app
      ...
    ...

内部 Ingress リソースの作成時に NEG が見つからない

GKE で内部 Ingress を作成すると、次のエラーが発生することがあります。

Error syncing: error running backend syncing routine: googleapi: Error 404: The resource 'projects/PROJECT_ID/zones/ZONE/networkEndpointGroups/NEG' was not found, notFound

このエラーは、内部アプリケーション ロードバランサ用の Ingress がバックエンドとしてネットワーク エンドポイント グループ(NEG)を必要とするために発生します。

共有 VPC 環境またはネットワーク ポリシーが有効なクラスタでは、アノテーション cloud.google.com/neg: '{"ingress": true}' を Service マニフェストに追加します。

504 Gateway Timeout: アップストリーム リクエストのタイムアウト

GKE の内部 Ingress から Service にアクセスすると、次のエラーが発生することがあります。

HTTP/1.1 504 Gateway Timeout
content-length: 24
content-type: text/plain

upsteam request timeout

このエラーは、内部アプリケーション ロードバランサに送信されたトラフィックが、プロキシ専用サブネット範囲内の Envoy プロキシによってプロキシされるために発生します。

プロキシ専用サブネット範囲からのトラフィックを許可するには、Service の targetPortファイアウォール ルールを作成します。

エラー 400: フィールド「resource.target」の値が無効です

GKE の内部 Ingress から Service にアクセスすると、次のエラーが発生することがあります。

Error syncing:LB_NAME does not exist: googleapi: Error 400: Invalid value for field 'resource.target': 'https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION_NAME/targetHttpProxies/LB_NAME. A reserved and active subnetwork is required in the same region and VPC as the forwarding rule.

この問題を解決するには、プロキシ専用サブネットを作成します。

同期中のエラー: ロードバランサ同期ルーチンの実行中のエラー: ロードバランサが存在しません

GKE コントロール プレーンをアップグレードするか、Ingress オブジェクトを変更すると、次のいずれかのエラーが発生する可能性があります。

"Error during sync: error running load balancer syncing routine: loadbalancer
INGRESS_NAME does not exist: invalid ingress frontend configuration, please
check your usage of the 'kubernetes.io/ingress.allow-http' annotation."

または

Error during sync: error running load balancer syncing routine: loadbalancer LOAD_BALANCER_NAME does not exist:
googleapi: Error 400: Invalid value for field 'resource.IPAddress':'INGRESS_VIP'. Specified IP address is in-use and would result in a conflict., invalid

これらの分析情報を解決するには、次のことを試してください。

  • Ingress マニフェストの tls セクションに hosts フィールドを追加してから、Ingress を削除します。GKE が未使用の Ingress リソースを削除するまで 5 分待ちます。その後、Ingress を再作成します。詳細については、Ingress オブジェクトの hosts フィールドをご覧ください。
  • Ingress に加えた変更を元に戻します。次に、アノテーションまたは Kubernetes Secret を使用して証明書を追加します。

既知の問題

V1 Ingress 命名規則では HTTPS リダイレクトを有効にできません

GKE バージョン 1.16.8-gke.12 以前で作成された GKE Ingress リソースで HTTPS リダイレクトを有効にすることはできません。HTTPS リダイレクトを有効にする前に、Ingress を再作成する必要があります。再作成しないと、エラーイベントが作成され、Ingress は同期されません。

エラーイベント メッセージは次のようになります。

Error syncing: error running load balancer syncing routine: loadbalancer lb-name does not exist: ensureRedirectUrlMap() = error: cannot enable HTTPS Redirects with the V1 Ingress naming scheme. Please recreate your ingress to use the newest naming scheme.

Google Cloud Armor セキュリティ ポリシー フィールドが BackendConfig から削除されました

v1beta1 API を使用して BackendConfig リソースを更新すると、Service からアクティブな Google Cloud Armor セキュリティ ポリシーが削除されるという既知の問題があります。この問題は、次の GKE バージョンに影響します。

  • 1.18.19-gke.1400~1.18.20-gke.5099
  • 1.19.10-gke.700~1.19.14-gke.299
  • 1.20.6-gke.700~1.20.9-gke.899

BackendConfig を使用して Ingress リソースに Google Cloud Armor を構成していない場合、クラスタへの影響はありません。

BackendConfig を使用して Google Cloud Armor を構成する GKE クラスタの場合、v1 API のみを使用して BackendConfig リソースを更新することを強くおすすめします。v1beta1 BackendConfig リソースを使用してクラスタに BackendConfig を適用すると、参照先の Service から Google Cloud Armor セキュリティ ポリシーが削除されます。

この問題を軽減するには、BackendConfig の更新を v1 BackendConfig API のみで行います。v1 BackendConfig は v1beta1 と同じフィールドをすべてサポートしています。互換性を破る変更がないため、API フィールドを透過的に更新できます。アクティブな BackendConfig マニフェストの apiVersion フィールドを cloud.google.com/v1 に置き換え、cloud.google.com/v1beta1 は使用しません。次のサンプル マニフェストは、v1 API を使用する BackendConfig リソースを記述しています。

  apiVersion: cloud.google.com/v1
  kind: BackendConfig
  metadata:
    name: my-backend-config
  spec:
    securityPolicy:
      name: "ca-how-to-security-policy"

BackendConfig リソースを定期的に更新する CI / CD システムまたはツールがある場合は、これらのシステムで cloud.google.com/v1 API グループを使用していることを確認してください。

BackendConfig が v1beta1 API ですでに更新されている場合、Google Cloud Armor セキュリティ ポリシーが削除されている可能性があります。この状態になっているかどうかを確認するには、次のコマンドを実行します。

kubectl get backendconfigs -A -o json | jq -r '.items[] | select(.spec.securityPolicy == {}) | .metadata | "\(.namespace)/\(.name)"'

レスポンスが出力を返す場合、クラスタはこの問題の影響を受けています。このコマンドは、問題の影響を受ける BackendConfig リソース(<namespace>/<name>)のリストを返します。出力が空の場合、問題が発生してから v1beta1 API で BackendConfig が更新されていません。BackendConfig の今後の更新では、v1 のみを使用する必要があります。

Google Cloud Armor セキュリティ ポリシーが削除された場合は、次の Logging クエリを使用して削除されたタイミングを確認できます。

resource.type="gce_backend_service"
protoPayload.methodName="v1.compute.backendServices.setSecurityPolicy"
protoPayload.authenticationInfo.principalEmail:"container-engine-robot.iam.gserviceaccount.com"
protoPayload.response.status = "RUNNING"
NOT protoPayload.authorizationInfo.permission:"compute.securityPolicies.use"

影響を受けるクラスタがある場合は、v1 API を使用する BackendConfig リソースに更新を push することで修正できます。

この問題にパッチを適用して v1beta1 BackendConfig リソースを安全に使用できるようにする、次のいずれかの更新バージョンに GKE コントロール プレーンをアップグレードします。

  • 1.18.20-gke.5100 以降
  • 1.19.14-gke.300 以降
  • 1.20.9-gke.900 以降

次のステップ