GKE Ingress のルーティングとセキュリティについて

このページでは、GKE Ingress のコア機能とネットワーキング アーキテクチャについて説明します。具体的には、クライアントからロードバランサ、アプリケーション Pod への接続の保護、複数のバックエンド サービスにわたる複雑なルーティングの管理、クラスタ内でのロードバランサのヘルスチェックのオーケストレーション方法について説明します。

このページでは、GKE Ingress の概要で説明されている基本的なコンセプトについて説明します。FrontendConfig や BackendConfig などのカスタム リソースを使用する手順と実装例については、GKE アプリケーションの Ingress 機能を構成するをご覧ください。

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

HTTPS を使用して Ingress を保護する

GKE Ingress は、クライアントとアプリケーション ロードバランサ間、およびロードバランサからアプリケーション Pod へのトラフィックを保護します。

クライアントとロードバランサ間の TLS の構成

HTTP(S) ロードバランサは、クライアントとアプリケーションの間のプロキシとして機能します。クライアントからの HTTPS リクエストを受け入れるには、ロードバランサは証明書を持っていなければなりません。これにより、適切な送信先であることをクライアントに示すことができます。さらに、ロードバランサには、HTTPS handshake を完了するための秘密鍵も必要です。

ロードバランサがクライアントからの HTTPS リクエストを受け入れると、クライアントとロードバランサ間のトラフィックは TLS で暗号化されます。ただし、TLS 暗号化はロードバランサで終端し、アプリケーションへのリクエストの転送は暗号化なしに行われます。詳細については、ロードバランサとアプリケーション間の暗号化を構成するをご覧ください。

SSL 証明書を提供する方法

SSL 証明書を HTTP(S) ロードバランサに指定するには、次の方法を使用します。

  • Google マネージド証明書: ドメイン名に対して Google がプロビジョニング、更新、管理するドメイン認証(DV)証明書です。この証明書は個人 ID や組織 ID を示すものではありません。Google マネージド証明書は、最大 100 個の非ワイルドカード ドメインをサポートします。詳細については、Google マネージド証明書を使用するをご覧ください。

  • Google Cloudと共有されるセルフマネージド証明書: 独自の SSL 証明書をプロビジョニングして、 Google Cloud プロジェクトに証明書リソースを作成できます。その後、証明書リソースを Ingress のアノテーションでリストして、証明書を使用する HTTP(S) ロードバランサを作成します。詳細については、事前共有証明書を使用するをご覧ください。

  • Kubernetes Secret を使用するセルフマネージド証明書: 独自の SSL 証明書をプロビジョニングして、それを保持するための Secret を作成できます。Ingress マニフェストの tls フィールドで Secret を参照して、HTTP(S) ロードバランサを作成できます。詳細については、Kubernetes Secret を使用するをご覧ください。

複数の証明書を使用して HTTPS トラフィックを処理する

最大 15 個の TLS 証明書をクライアントに提示するようにアプリケーション ロードバランサを構成できます。複数の証明書を使用することは、複数のホスト名からコンテンツを配信する必要があり、それぞれに異なる証明書が必要な場合に不可欠です(たとえば、your-store.example と your-experimental-store.example に別々の証明書が必要な場合など)。これらの複数の証明書は、Ingress マニフェスト内で指定します。

証明書の選択と優先度

ロードバランサは、クライアントに提示する証明書を決定するために、Server Name Indication(SNI)を使用します。

  • クライアントが SNI を使用している場合、または使用可能な証明書のいずれかの共通名(CN)と一致するドメイン名を使用している場合、ロードバランサは、クライアントがリクエストしたホスト名に最も近い CN を持つ証明書を使用します。

  • クライアントが SNI をサポートしていない場合、またはリクエストされたドメイン名が使用可能な証明書の CN と一致しない場合、ロードバランサは Ingress マニフェストにリストされている最初の証明書をデフォルトとして使用します。ロードバランサは、次のルールに従ってこの証明書を選択します。

    • tls ブロックに複数の Secret がリストされている場合は、プライマリ証明書は tls ブロックの 1 つ目の Secret になります。
    • pre-shared-cert アノテーションの事前共有証明書の場合: プライマリ証明書は、アノテーションにリストされている最初の証明書です。
    • managed-certificates アノテーションの Google マネージド証明書の場合: すべてのマネージド証明書が名前のアルファベット順に並べ替えられます。プライマリ証明書は、このアルファベット順のリストの先頭にある証明書です。特定の証明書をプライマリとして設定するには、並べ替え順を制御するために、ManagedCertificate オブジェクトに適切な名前を付ける必要があります。たとえば、my-default-certanother-cert よりも優先させるには、0-my-default-cert1-another-cert という名前を付けます。

ロードバランサが複数の証明書を異なる GKE メソッドで提示する場合、事前共有証明書は Ingress tls ブロックにリストされている Secret よりも優先されます。

次の図は、リクエストで使用されているドメイン名に応じて、複数の異なるバックエンドにトラフィックを送信するロードバランサを示しています。

Ingress システムでの複数の SSL 証明書の使用を示す図

証明書のローテーションのベスト プラクティス

Secret または事前共有証明書のコンテンツをローテーションする場合のベスト プラクティスは次のとおりです。

  • 新しい証明書データが含まれる別の名前の新しい Secret または事前共有証明書を作成します。新しい証明書リソースを使用するように Ingress を更新します。
  • トラフィックの中断を気にしない場合は、Ingress から古いリソースを削除し、同じ名前で内容が異なる新しいリソースをプロビジョニングして、Ingress に再接続します。

証明書のローテーションを自分で管理しないようにするには、Google マネージド SSL 証明書を使用します。

HTTPS のみのトラフィックを適用する

クライアントと HTTP(S) ロードバランサ間のすべてのトラフィックに HTTPS を使用する場合は、Ingress マニフェストに kubernetes.io/ingress.allow-http アノテーションを追加し、値を "false" に設定します。詳細については、HTTP の無効化をご覧ください。

ロードバランサとアプリケーション間の暗号化を構成する

このセクションでは、ロードバランサからアプリケーション Pod への接続を保護する方法について説明します。

HTTPS または HTTP/2 バックエンド プロトコルの有効化

外部アプリケーション ロードバランサは、クライアントと GKE アプリケーションの間のプロキシとして機能します。クライアントは HTTPS(暗号化用)とさまざまなプロトコル(HTTP/1.1 または HTTP/2)を使用してロードバランサに接続できますが、ロードバランサからバックエンド Pod への接続はデフォルトで暗号化されていない HTTP/1.1 になります。

アプリケーションでより高度な構成を処理できる場合は、外部アプリケーション ロードバランサを手動で更新して、次のものを使用できます。

  • HTTP/2: Pod がサポートしている場合にパフォーマンスを最適化します。
  • HTTPS(TLS): ロードバランサ プロキシと Pod 間のトラフィックにエンドツーエンドの暗号化を適用します。

バックエンド接続に使用されるプロトコル(HTTP または HTTPS)と HTTP バージョン(HTTP/1.1 または HTTP/2)の両方を制御するには、Kubernetes Service マニフェストで cloud.google.com/app-protocols アノテーションを使用します。コンテナ ネイティブのロード バランシングを使用しない場合、この Service マニフェストに type: NodePort を含める必要があります。コンテナ ネイティブのロード バランシングを使用する場合は、type: ClusterIP を使用します。

HTTPS ロードバランサの静的 IP アドレス

外部アプリケーション ロードバランサの Ingress オブジェクトを作成すると、クライアントが Service、さらには実行中のコンテナにアクセスするために使用できる固定の外部 IP アドレスを取得できます。この IP アドレスは、Ingress オブジェクトの存続期間にわたって持続するという意味で固定されます。ただし、Ingress を削除して同じマニフェスト ファイルから新しい Ingress を作成しても、同じ外部 IP アドレスが得られる保証はありません。

Ingress を削除して新しい IP アドレスを作成した後も、同じ永続 IP アドレスが必要な場合は、グローバルな静的外部 IP アドレスを予約する必要があります。その後、Ingress マニフェストに、予約した静的 IP アドレスの名前を示すアノテーションを追加します。エフェメラル IP アドレスではなく静的 IP アドレスを使用するように既存の Ingress を変更すると、GKE がロードバランサの転送ルールを再作成するときに、ロードバランサの IP アドレスが変更されることがあります。

トラフィックのルーティング

GKE Ingress は、URL マップを使用して、受信リクエストが特定のバックエンド サービスにルーティングされる方法を定義します。ホスト名、URL パス、またはその両方の組み合わせに基づいてルーティング ルールを構成し、単一のロードバランサを介して複数のアプリケーションのトラフィックを管理できます。

複数のバックエンド サービス

各外部アプリケーション ロードバランサまたは内部アプリケーション ロードバランサは、1 つ以上のバックエンド サービスを参照する単一の URL マップを使用します。1 つのバックエンド サービスが、Ingress によって参照される各 Service に対応します。

たとえば、URL パスに応じてリクエストを異なるバックエンド サービスにルーティングするようにロードバランサを構成できます。つまり、your-store.example に送信されたリクエストは、正価の商品を表示するバックエンド サービスにルーティングされ、your-store-example/discounted に送信されたリクエストは、値引き対象商品を表示するバックエンド サービスにルーティングされるようにできます。

ホスト名に応じてリクエストをルーティングするように、ロードバランサを構成することもできます。つまり、your-store.example に送信されたリクエストはあるバックエンド サービスに送信され、your-experimental-store.example に送信されたリクエストは別のバックエンド サービスに送信されるようにできます。

GKE クラスタでは、Kubernetes Ingress オブジェクトを作成して HTTP(S) ロードバランサの作成と構成を行います。1 つの Ingress オブジェクトは 1 つ以上の Service オブジェクトに関連付けられている必要があります。それぞれの Service オブジェクトは、Pod のセットに関連付けられます。

同じホストに複数のバックエンドを持つ GKE Ingress を構成する場合は、単一のホストと複数のパスを備えた単一のルールが必要です。それ以外の場合、GKE Ingress コントローラは 1 つのバックエンド サービスのみをプロビジョニングします。

my-ingress という名前の Ingress のマニフェストを次に示します。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
 rules:
  - host: your-store.example
    http:
      paths:
      - path: /products
        pathType: ImplementationSpecific
        backend:
          service:
            name: my-products
            port:
              number: 60000
      - path: /discounted
        pathType: ImplementationSpecific
        backend:
          service:
            name: my-discounted-products
            port:
              number: 80

Ingress を作成すると、GKE Ingress コントローラで、Ingress とそれに関連する Service の情報に従って、外部アプリケーション ロードバランサまたは内部アプリケーション ロードバランサが作成されて構成されます。また、ロードバランサには、ドメイン名に関連付けることのできる固定 IP アドレスが与えられます。

上記の例で、ロードバランサの IP アドレスをドメイン名 your-store.example に関連付けたと仮定します。クライアントが your-store.example/products にリクエストを送信すると、そのリクエストはポート 60000 の my-products という名前の Kubernetes Service にルーティングされます。クライアントが your-store.example/discounted にリクエストを送信すると、そのリクエストはポート 80 の my-discounted-products という名前の Kubernetes Service にルーティングされます。

Ingress の path フィールドでサポートされているワイルドカード文字は「*」のみです。「*」はスラッシュ(「/」)の直後に置かれる必要があり、パターンの最後の文字でなければなりません。たとえば、/*/foo/*/foo/bar/* は有効なパターンですが、*/foo/bar*/foo/*/bar は有効ではありません。

より具体的なパターンのほうが、そうでないものよりも優先されます。/foo/*/foo/bar/* の両方を使用すると、/foo/bar/bat/foo/bar/* と比較されます。

パスの制限とパターン マッチングの詳細については、URL マップのドキュメントをご覧ください。

my-products Service のマニフェストは次のようになります。

apiVersion: v1
kind: Service
metadata:
  name: my-products
spec:
  type: NodePort
  selector:
    app: products
    department: sales
  ports:
  - protocol: TCP
    port: 60000
    targetPort: 50000

上記のマニフェストでは、次の点に注意してください。

  • spec.type フィールドは、使用するロード バランシング方法によって異なります。

  • selector フィールドでは、app: products ラベルと department: sales ラベルの両方を持つ Pod がこの Service のメンバーであることを示しています。

  • リクエストがポート 60000 で Service に到達すると、そのリクエストは TCP ポート 50000 の 1 つのメンバーポッドにルーティングされます。

  • メンバーポッドごとに、TCP ポート 50000 でリッスンするコンテナが必要です。

my-discounted-products Service のマニフェストは次のようになります。

apiVersion: v1
kind: Service
metadata:
  name: my-discounted-products
spec:
  type: NodePort
  selector:
    app: discounted-products
    department: sales
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

上記のマニフェストでは、次の点に注意してください。

  • selector フィールドでは、app: discounted-products ラベルと department: sales ラベルの両方を持つ Pod がこの Service のメンバーであることを示しています。

  • リクエストがポート 80 で Service に到達すると、そのリクエストは TCP ポート 8080 の 1 つのメンバーポッドにルーティングされます。

  • メンバーポッドごとに、TCP ポート 8080 でリッスンするコンテナが必要です。

デフォルトのバックエンド

Ingress のデフォルトのバックエンドを指定するには、Ingress マニフェストで spec.defaultBackend フィールドを指定します。これにより、rules フィールドで定義されたパスと一致しないリクエストがすべて処理されます。たとえば、次の Ingress では、/discounted と一致しないリクエストが my-products という Service のポート 60001 に送信されます。

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

デフォルトのバックエンドを指定しない場合、GKE は 404 を返すバックエンドをデフォルトにします。これは、kube-system Namespace のクラスタ上に default-http-backend NodePort Service として作成されます。

404 HTTP レスポンスは次のようになります。

response 404 (backend NotFound), service rules for the path non-existent

カスタム デフォルト バックエンドを使用して GKE Ingress を設定するには、カスタム デフォルト バックエンドを使用した GKE Ingress をご覧ください。

ヘルスチェック

デフォルトの Ingress コントローラを使用して Ingress によって 1 つ以上の Service を公開すると、GKE によって従来のアプリケーション ロードバランサまたは内部アプリケーション ロードバランサが作成されます。こうしたロードバランサでは、いずれも 1 つの URL マップで複数のバックエンド サービスがサポートされます。各バックエンド サービスは 1 つのKubernetes Service に対応し、各バックエンド サービスは Google Cloud ヘルスチェックを 1 つ参照する必要があります。このヘルスチェックはクラスタの外部で実装されるため、Kubernetes の liveness プローブまたは readiness プローブとは異なります。

ロードバランサのヘルスチェックは、バックエンド サービスごとに指定されます。ロードバランサのすべてのバックエンド サービスに同じヘルスチェックを実施できますが、ロードバランサ全体に対してはヘルスチェック リファレンスが(Ingress オブジェクト自体では)指定されません。

GKE は、次のいずれかの方法に基づいてヘルスチェックを作成します。

  • BackendConfig CRD: Service がロードバランサとやり取りする方法を正確に制御できるカスタム リソース定義(CRD)。BackendConfig CRD を使用すると、対応するバックエンド サービスに関連付けられたヘルスチェックのカスタム設定を指定できます。こうしたカスタム設定により、従来のアプリケーション ロードバランサと Ingress によって作成された内部アプリケーション ロードバランサの両方のヘルスチェックをより柔軟に制御できます。
  • readiness プローブ: Pod 内のコンテナがトラフィックを処理する準備ができているかどうかを判断する診断チェック。GKE Ingress コントローラは、その Service のサービング Pod で使用されている readiness プローブ に基づいて、Service のバックエンド サービスのヘルスチェックを作成します。パス、ポート、プロトコルなどのヘルスチェック パラメータは、readiness プローブの定義から導出できます。
  • デフォルト値: BackendConfig CRD を構成しない場合や、readiness プローブの属性を定義しない場合のパラメータ。
ベスト プラクティス:

BackendConfig CRD を使用して、ロードバランサのヘルスチェック設定を細かく制御します。

GKE は、次の手順を使用して、Kubernetes Service に対応する各バックエンド サービスのヘルスチェックを作成します。

  • Service が healthCheck 情報を使用して BackendConfig CRD を参照する場合、GKE はそれを使用してヘルスチェックを作成します。このヘルスチェックの作成方法は、GKE Enterprise Ingress コントローラと GKE Ingress コントローラの両方でサポートされます。

  • Service が BackendConfig CRD を参照していない場合:

    • サービング Pod が使用するPod テンプレートに、ヘルスチェック パラメータとして解釈できる属性がある readiness プローブを持つコンテナがある場合、GKE でヘルスチェックのパラメータの一部またはすべてを推定できます。実装の詳細については、readiness プローブからのパラメータ、ヘルスチェック パラメータの作成に使用できる属性のリストについては、デフォルト パラメータと推定パラメータをご覧ください。readiness プローブからのパラメータの推定は、GKE Ingress コントローラでのみサポートされています。

    • Service のサービング Pod の Pod テンプレートに、ヘルスチェック パラメータとして解釈できる属性がある readiness プローブを持つコンテナがない場合、デフォルト値を使用してヘルスチェックが作成されます。GKE Enterprise Ingress コントローラと GKE Ingress コントローラの両方で、デフォルト値のみを使用してヘルスチェックを作成できます。

デフォルト パラメータと推定パラメータ

以下のパラメータは、BackendConfig CRD を使用して対応する Service のヘルスチェック パラメータを指定しない場合に使用されます。

ヘルスチェック パラメータ デフォルト値 推論可能な値
プロトコル HTTP Service のアノテーション cloud.google.com/app-protocols に存在している場合
リクエストパス / サービング Pod の spec に存在している場合:
containers[].readinessProbe.httpGet.path
リクエスト ホスト ヘッダー Host: backend-ip-address サービング Pod の spec に存在している場合:
containers[].readinessProbe.httpGet.httpHeaders
想定されるレスポンス HTTP 200 (OK) HTTP 200 (OK)
変更できません
チェック間隔
  • コンテナ ネイティブのロード バランシングの場合: 15 秒
  • インスタンス グループの場合: 60 秒
サービング Pod の spec に存在している場合:
  • コンテナネイティブのロード バランシングの場合:
    containers[].readinessProbe.periodSeconds
  • インスタンス グループの場合:
    containers[].readinessProbe.periodSeconds + 60 seconds
チェックのタイムアウト 5 秒 サービング Pod の spec に存在している場合:
containers[].readinessProbe.timeoutSeconds
正常しきい値 1 1
変更できません
異常しきい値
  • コンテナネイティブのロード バランシングの場合: 2
  • インスタンス グループの場合: 10
デフォルトと同じ:
  • コンテナネイティブのロード バランシングの場合: 2
  • インスタンス グループの場合: 10
ポートの指定
  • コンテナ ネイティブのロード バランシングの場合: Service の port
  • インスタンス グループの場合: Service の nodePort
次の条件も満たしている限り、ヘルスチェック プローブは spec.containers[].readinessProbe.httpGet.port で指定されたポート番号に送信されます。
  • readiness プローブのポート番号が、サービング Pod の containers[].spec.ports.containerPort と一致する。
  • サービング Pod の containerPort が、Service の targetPort と一致する。
  • Ingress のサービス バックエンド ポートの仕様では、Service の spec.ports[] の有効なポートを参照しています。次の 2 つの方法があります。
    • Ingress の spec.rules[].http.paths[].backend.service.port.name は、対応する Service で定義された spec.ports[].name と一致します。
    • Ingress の spec.rules[].http.paths[].backend.service.port.number は、対応する Service で定義された spec.ports[].port と一致します。
宛先 IP アドレス
  • コンテナ ネイティブのロード バランシングの場合: Pod の IP アドレス
  • インスタンス グループの場合: ノードの IP アドレス
デフォルトと同じ:
  • コンテナ ネイティブのロード バランシングの場合: Pod の IP アドレス
  • インスタンス グループの場合: ノードの IP アドレス

readiness プローブからのパラメータ

GKE で Service のバックエンド サービスのヘルスチェックが作成されると、その Service のサービング Pod で使用されている 1 つのコンテナの readiness プローブから特定のパラメータをコピーできます。このオプションは、GKE Ingress コントローラのみでサポートされています。

ヘルスチェック パラメータとして解釈できるサポートされている readiness プローブの属性は、デフォルト パラメータと推定パラメータでデフォルト値とともに一覧表示されています。readiness プローブに指定されていない属性、または readiness プローブがまったく指定されていない場合は、デフォルト値が使用されます。

Service のサービング Pod に複数のコンテナが含まれている場合や、GKE Enterprise Ingress コントローラを使用している場合は、BackendConfig CRD を使用してヘルスチェック パラメータを定義する必要があります。詳しくは、代わりに BackendConfig CRD を使用する場合をご覧ください。

代わりに BackendConfig CRD を使用する場合

次の場合は、Pod の readiness プローブのパラメータに依存せずに、Service の BackendConfig CRD を作成して、バックエンド サービスのヘルスチェック パラメータを明示的に定義する必要があります。

  • GKE Enterprise を使用している場合: GKE Enterprise Ingress コントローラは、サービング Pod の readiness プローブからのヘルスチェック パラメータの取得をサポートしていません。ヘルスチェックの作成には、暗黙的パラメータを使用するか、BackendConfig CRD での定義に従います。

  • サービング Pod に複数のコンテナがある場合: GKE には、ヘルスチェック パラメータを推測するコンテナの readiness プローブを選択する方法がありません。各コンテナには独自の readiness プローブがあり、readiness プローブはコンテナに必要なパラメータではないため、対応する Service のBackendConfig CRD を参照して、対応するバックエンド サービスのヘルスチェックを定義する必要があります。

  • ロードバランサのヘルスチェックに使用するポートを制御する必要がある場合: GKE では、そのポートが Ingress spec.rules[].http.paths[].backend.servicePort で参照される Service のサービスポートと一致している場合、バックエンド サービスのヘルスチェックに対して、readiness プローブの containers[].readinessProbe.httpGet.port のみを使用します。

BackendConfig CRD からのパラメータ

対応する Service により参照される BackendConfig CRD の healthCheck パラメータを使用して、バックエンド サービスのヘルスチェック パラメータを指定できます。これにより、従来のアプリケーション ロードバランサまたは Ingress によって作成された内部アプリケーション ロードバランサのヘルスチェックをより柔軟に制御できるようになります。GKE のバージョンの互換性については、Ingress の構成をご覧ください。

この BackendConfig CRD の例では、spec.healthCheck 属性でヘルスチェック プロトコル(タイプ)、リクエストパス、ポート、チェック間隔を定義します。

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: http-hc-config
spec:
  healthCheck:
    checkIntervalSec: 15
    port: 15020
    type: HTTPS
    requestPath: /healthz

BackendConfig ヘルスチェックを構成するときに使用可能なすべてのフィールドを構成するには、カスタム ヘルスチェックの構成の例を使用します。

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

Pod の readiness(準備完了)

上記のいずれかの方法でロードバランサのヘルスチェックを構成すると、GKE Ingress コントローラはバックエンド エンドポイントのヘルスステータスを使用して Pod の準備状況を判断します。これは、ローリング アップデートと全体的なトラフィックの安定性を管理するうえで重要です。

関連する Pod について、対応する Ingress コントローラは、cloud.google.com/load-balancer-neg-ready タイプの readiness ゲートを管理します。Ingress コントローラは、NEG 内のすべてのエンドポイントの健全性を含む、ロードバランサのヘルスチェック ステータスをポーリングします。ロードバランサのヘルスチェック ステータスが、特定の Pod に対応するエンドポイントが正常であることを示す場合、Ingress コントローラは Pod の readiness ゲート値を True に設定します。各ノードで実行されている kubelet は、この readiness ゲート値と、定義されている場合は Pod の readiness プローブの両方を考慮して、Pod の有効な準備完了状況を計算します。

Ingress でコンテナネイティブのロード バランシングを使用すると、Pod の readiness ゲートが自動的に有効になります。

readiness ゲートは、ローリング アップデートのレートを制御します。ローリング アップデートを開始すると、GKE で新しい Pod が作成され、新しい Pod ごとのエンドポイントが NEG に追加されます。ロードバランサから見てエンドポイントが正常な場合、Ingress コントローラは readiness ゲートを True に設定します。GKE が古い Pod を削除する前に、新しく作成された Pod は少なくとも readiness ゲートを通過する必要があります。これにより、Pod に対応するエンドポイントにロードバランサのヘルスチェックを通過させ、バックエンド容量が維持されるようにします。

コンテナ イメージが不適切であるか、ロードバランサのヘルスチェックが正しく構成されていないため、Pod の readiness ゲートが準備完了であることを示さない場合、ロードバランサは新しい Pod にトラフィックを転送しません。更新した Deployment をロールアウトする際にこのようなエラーが発生した場合、新しいポッドを作成しようとすると、そのポッドの readiness ゲートが True にならないことによりロールアウトが停滞します。この状況を検出して修正する方法については、トラブルシューティングをご覧ください。

コンテナネイティブのロード バランシングと readiness ゲートを使用しなければ、GKE は、Pod を準備完了としてマークする前に、ロードバランサのエンドポイントが正常かどうかを検出できません。以前の Kubernetes バージョンでは、遅延の期間(Deployment の仕様の minReadySeconds)を指定することで、Pod を削除して置換するレートを指定していました。

次のいずれかの条件が満たされた場合、GKE は Pod の cloud.google.com/load-balancer-neg-ready の値を True に設定します。

  • いずれの Pod の IP アドレスも、GKE コントロール プレーンによって管理される GCE_VM_IP_PORT NEG のエンドポイントではない。
  • Pod の 1 つ以上の IP アドレスが、GKE コントロール プレーンで管理されている GCE_VM_IP_PORT NEG のエンドポイントである。NEG がバックエンド サービスに接続されている。バックエンド サービスで、ロードバランサのヘルスチェックに成功している。
  • Pod の 1 つ以上の IP アドレスが、GKE コントロール プレーンで管理されている GCE_VM_IP_PORT NEG のエンドポイントである。NEG がバックエンド サービスに接続されている。バックエンド サービスに関するロードバランサのヘルスチェックがタイムアウトしている。
  • 1 つ以上の Pod の IP アドレスが 1 つ以上の GCE_VM_IP_PORT NEG のエンドポイントである。いずれの NEG もバックエンド サービスに接続されていない。ロードバランサのヘルスチェック データを利用できない。

WebSocket のサポート

外部アプリケーション ロードバランサでは、WebSocket プロトコルは構成なしで機能します。

WebSocket プロトコルを使用する場合は、デフォルトの 30 秒よりも長いタイムアウト値を使用することをおすすめします。Google Cloud 外部アプリケーション ロードバランサ経由で送信される WebSocket トラフィックでは、バックエンド サービスのタイムアウトは、アイドル状態かどうかにかかわらず、WebSocket 接続をオープン状態に保てる最長時間として解釈されます。

バックエンド サービスのタイムアウト値を設定するには、バックエンド レスポンスのタイムアウトをご覧ください。

高度なネットワーキングのシナリオ

GKE Ingress は、プロジェクト間でのネットワーク リソースの共有やカスタム Ingress コントローラの使用など、高度なネットワーキング構成をサポートしています。

共有 VPC

Ingress リソースと MultiClusterIngress リソースは共有 VPC でサポートされていますが、追加の準備が必要です。

Ingress コントローラは GKE コントロール プレーンで動作し、クラスタのプロジェクトの GKE サービス アカウントを使用して Google Cloud API 呼び出しを行います。デフォルトでは、共有 VPC サービス プロジェクトにあるクラスタが共有 VPC ネットワークを使用している場合、Ingress コントローラはホスト プロジェクトでサービス プロジェクトの GKE サービス アカウントを使用して、上り(内向き)許可ファイアウォール ルールの作成と更新を実行できません。

ホスト プロジェクトで VPC ファイアウォール ルールを作成および管理する権限をサービス プロジェクトの GKE サービス アカウントに付与できます。これらの権限を付与することで、GKE は次のものに対して上り(内向き)許可ファイアウォール ルールを作成します。

セキュリティ ポリシーによって、ホスト プロジェクトからのファイアウォール管理のみが許可される場合は、これらのファイアウォール ルールを手動でプロビジョニングできます。共有 VPC に Ingress をデプロイすると、Ingress リソース イベントにより、アクセスを提供するために必要な特定のファイアウォール ルールが提供されます。

ルールを手動でプロビジョニングするには:

  1. Ingress リソース イベントを表示します。

    kubectl describe ingress INGRESS_NAME
    

    INGRESS_NAME は実際の Ingress 名で置き換えます。

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

    Events:
    Type    Reason  Age                    From                     Message
    ----    ------  ----                   ----                     -------
    Normal  Sync    9m34s (x237 over 38h)  loadbalancer-controller  Firewall change required by security admin: `gcloud compute firewall-rules update k8s-fw-l7--6048d433d4280f11 --description "GCE L7 firewall rule" --allow tcp:30000-32767,tcp:8080 --source-ranges 130.211.0.0/22,35.191.0.0/16 --target-tags gke-l7-ilb-test-b3a7e0e5-node --project <project>`
    

    推奨されるファイアウォール ルールが Message 列に表示されます。

  2. ホスト プロジェクトから提案されたファイアウォール ルールをコピーして適用します。ルールを適用すると、ロードバランサと Google Cloud  ヘルス チェッカーから Pod にアクセスできるようになります。

ホスト コントローラのファイアウォール ルールを管理する権限を Ingress コントローラに与える

サービス プロジェクトの GKE クラスタで、ホスト プロジェクトのファイアウォール リソースを作成して管理するには、次のいずれかの方法で、サービス プロジェクトの GKE サービス アカウントに適切な IAM 権限を付与する必要があります。

  • サービス プロジェクトの GKE サービス アカウントに、ホスト プロジェクトに対する Compute セキュリティ管理者のロールを付与します。次の例は、この方法を示しています。

  • より細かく設定する場合は、カスタム IAM ロールを作成し、compute.networks.updatePolicycompute.firewalls.listcompute.firewalls.getcompute.firewalls.createcompute.firewalls.updatecompute.firewalls.deletecompute.subnetworks.list 権限のみを含めます。サービス プロジェクトの GKE サービス アカウントに、ホスト プロジェクトに対するこのカスタムロールを付与します。

複数のサービス プロジェクトにクラスタがある場合は、いずれかの方法を選択して、サービス プロジェクトの GKE サービス アカウントごとに繰り返す必要があります。

gcloud projects add-iam-policy-binding HOST_PROJECT_ID \
  --member=serviceAccount:service-SERVICE_PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com \
  --role=roles/compute.securityAdmin

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

カスタム Ingress コントローラの使用

HttpLoadBalancing アドオンを無効にすると、カスタム Ingress コントローラを実行できます。これにより、GKE Ingress コントローラにより Ingress リソースが処理されなくなります。

HttpLoadBalancing アドオンを有効にしたカスタム Ingress コントローラを実行する場合、サブセット化Private Service Connect などの機能を利用するには、次のいずれかの方法を使用できます。

プロセスによって spec.ingressClassName が誤って上書きされないようにする必要があります。spec.IngressClassName を有効値から空の文字列("")に変更する更新オペレーションによって、GKE Ingress コントローラで Ingress が処理されます。

ingressClassName フィールドを構成する

Ingress マニフェストで ingressClassName フィールドを設定することで、カスタム Ingress コントローラを使用できます。次のマニフェストでは、cilium Ingress コントローラを指定する Ingress が記述されています。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: cafe-ingress
spec:
 ingressClassName: cilium
 tls:
 - hosts:
   - cafe.example.com
   secretName: cafe-secret
 rules:
 - host: cafe.example.com

デフォルトの Ingress クラスを構成する

アノテーション ingressclass.kubernetes.io/is-default-classtrue に設定して IngressClass リソースを作成すると、クラスタ内のすべての Ingress リソースにデフォルトの Ingress クラスを構成できます。

apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: gce
  annotations:
    ingressclass.kubernetes.io/is-default-class: "true"
spec:
  controller: k8s.io/ingress-gce

GKE Ingress コントローラの動作の概要

GKE バージョン 1.18 以降を実行しているクラスタの場合、GKE Ingress コントローラで Ingress が処理されるかどうかは、Ingress マニフェストの kubernetes.io/ingress.class アノテーションと ingressClassName フィールドの値によって決まります。詳細については、GKE Ingress コントローラの動作をご覧ください。

Ingress 構成のテンプレート