Gateway を保護する

このページでは、次のようなセキュリティ機能を使用して Gateway を保護する方法について説明します。

  • SSL ポリシー。Gateway が必要な安全なプロトコルとアルゴリズムを使用していることを確認します。

  • 証明書。クライアントから Gateway へのトラフィックと Gateway からバックエンドへのトラフィックを TLS で保護するために使用します。

  • Google Cloud Armor セキュリティ ポリシー。DDoS 攻撃からサービスを保護します。

  • Identity-Aware Proxy(IAP)、Service へのアクセスを許可する前に認証と認可のレイヤを提供します。

Gateway のセキュリティの詳細については、Gateway のセキュリティをご覧ください。

始める前に

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

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API を有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。gcloud CLI をインストール済みの場合は、gcloud components update コマンドを実行して最新のバージョンを取得します。以前のバージョンの gcloud CLI では、このドキュメントのコマンドを実行できない場合があります。

GKE Gateway Controller の要件

  • Gateway API は、VPC ネイティブ クラスタでのみサポートされます。
  • リージョンまたはクロスリージョンの GatewayClass を使用している場合は、プロキシ専用サブネットを有効にする必要があります。
  • クラスタで HttpLoadBalancing アドオンが有効になっている必要があります。
  • Istio を使用している場合は、Istio を次のいずれかのバージョンにアップグレードする必要があります。
    • 1.15.2 以降
    • 1.14.5 以降
    • 1.13.9 以降
  • 共有 VPC を使用している場合は、ホスト プロジェクトで、サービス プロジェクトの GKE サービス アカウントに Compute Network User ロールを割り当てる必要があります。

  • すでに Autopilot クラスタまたは Standard クラスタが存在していることを確認する。必要な場合は、Autopilot クラスタを作成します。

制限事項

GKE Gateway Controller の制限事項と制限に加えて、Gateway のセキュリティには次の制限があります。

  • Gateway で SSL 証明書または Certificate Manager を使用する TLS 構成は、GKE バージョン 1.28.4-gke.1083000 ではサポートされていません。この GKE バージョンでは、回避策として Kubernetes Secret を使用してください。

  • 同じ Gateway リソースに対して、tls.certificateRefsnetworking.gke.io/certmap アノテーションを使用することはできません。Gateway で CertificateMap を参照すると、GKE はこれをエラーとして扱います。

  • Certificate Manager は、セルフマネージド証明書と Google マネージド証明書の両方をサポートしています。Google マネージド証明書は、リージョン Gateway およびグローバル Gateway と互換性があります。

  • Google マネージド SSL 証明書を使用する場合は、Gateway に接続する前に GKE の外部で SSL 証明書を作成する必要があります。

  • GCPBackendPolicy で Google Cloud Armor バックエンド セキュリティ ポリシーを参照している場合、同じサービスをリージョン Gateway とグローバル Gateway のバックエンドとして使用することはできません。このユースケースでは、2 つのサービスとポリシーを個別に作成する必要があります。

  • Gateway Controller は ManagedCertificate リソースをサポートしていません。

  • Gateway Controller は networking.gke.io/managed-certificates アノテーションをサポートしていません。

  • GKE Gateway で Cloud CDN を構成する場合、Cloud CDN を使用する個々のルートを含め、同じ Gateway で IAP と Cloud CDN の両方を有効にすることはできません。GCPHTTPFilter リソースを使用するルートで Cloud CDN を有効にする必要がある場合は、まず、その Gateway の IAP を構成する既存の GCPBackendPolicy を削除する必要があります。

  • TrustConfig の割り当て。各ロケーションのすべての TrustConfig リソースの合計サイズについては、リソースの割り当てと上限をご覧ください。

  • 位置合わせ。参照される TrustConfig リソースは、Service を使用する Gateway と同じロケーション(グローバルまたは特定のリージョン)に存在する必要があります。

  • Namespace 制約。BackendTLSPolicy リソースとそのターゲット リソースは、同じ Namespace に存在している必要があります。

サポートされている Gateway API フィールドと、GKE で使用可能な GatewayClass リソースの機能の一覧については、GatewayClass の機能をご覧ください。

Kubernetes Secret を使用して Gateway を保護する

この例では、Kubernetes Secret を使用して Gateway を構成します。

証明書を Kubernetes Secret に保存する

認証局(CA)によって発行および検証された証明書を使用するか、自己署名証明書を作成できます。次の手順では、自己署名証明書を使用します。

  1. 秘密鍵を作成します。

    openssl genrsa -out PRIVATE_KEY_FILE 2048
    

    PRIVATE_KEY_FILE は、秘密鍵ファイルの名前(private-key.pem など)に置き換えます。詳細については、秘密鍵を選択または作成するをご覧ください。

  2. OpenSSL 構成ファイルを作成します。

    cat <<EOF >CONFIG_FILE
    [req]
    default_bits              = 2048
    req_extensions            = extension_requirements
    distinguished_name        = dn_requirements
    prompt                    = no
    
    [extension_requirements]
    basicConstraints          = CA:FALSE
    keyUsage                  = nonRepudiation, digitalSignature, keyEncipherment
    subjectAltName            = @sans_list
    
    [dn_requirements]
    0.organizationName        = example
    commonName                = store.example.com
    
    [sans_list]
    DNS.1                     = store.example.com
    EOF
    

    CONFIG_FILE は、新しい構成ファイルの名前(config-file.cnf など)に置き換えます。

  3. 証明書署名リクエスト(CSR)ファイルを作成するには、次の操作を行います。

    openssl req -new -key PRIVATE_KEY_FILE \
        -out CSR_FILE \
        -config CONFIG_FILE
    

    CSR_FILE は、新しい CSR ファイル(cert.pem など)の名前に置き換えます。詳細については、CSR を作成するをご覧ください。

  4. CSR に署名します。

    openssl x509 -req \
        -signkey PRIVATE_KEY_FILE \
        -in CSR_FILE \
        -out CERTIFICATE_FILE \
        -extfile CONFIG_FILE \
        -extensions extension_requirements \
        -days 30
    

    CERTIFICATE_FILE は、コマンドによって生成されたファイルのパスと名前(cert-file.pem など)に置き換えます。詳細については、CSR に署名するをご覧ください。

  5. 作成した鍵と証明書ファイルを使用して Kubernetes TLS Secret を作成します。

    kubectl create secret tls store-example-com \
        --cert=CERTIFICATE_FILE \
        --key=PRIVATE_KEY_FILE
    

    GKE は、Gateway に接続できる Kubernetes リソースとして証明書と鍵を保存します。

Gateway と HTTPRoute を作成する

  1. 次のマニフェストを external-gateway.yaml として保存します。

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-http
    spec:
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
        tls:
          mode: Terminate
          certificateRefs: # Directly reference the Kubernetes Secret containing the TLS certificate and private key.
          - name: store-example-com # The name of the TLS secret.
    

    このマニフェストでは、次のプロパティを持つゲートウェイが記述されています。

    • gatewayClassName: gke-l7-global-external-managed: グローバル外部アプリケーション ロードバランサをデプロイします。
    • protocol: HTTPSport: 443: TLS を有効にするために必要です。
    • tls: 前の手順で作成した Kubernetes Secret を参照します。
  2. マニフェストをクラスタに適用します。

    kubectl apply -f external-gateway.yaml
    
  3. 次のマニフェストを store-external-route.yaml として保存します。

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-external
      labels:
        gateway: external-http
    spec:
      parentRefs:
      - name: external-http # Link this route to the 'external-http' Gateway.
      hostnames:
      - "store.example.com" # Match traffic for this hostname.
      rules:
      - backendRefs: # Define where to forward the traffic.
        - name: store-v1
          port: 8080
    

    このマニフェストには、store.example.com へのトラフィックを照合して store-v1 Service に送信する HTTPRoute が記述されています。

  4. マニフェストをクラスタに適用します。

    kubectl apply -f store-external-route.yaml
    

Gateway を確認する

インターネット経由でリクエストを送信して、Gateway が動作することを確認します。

  1. Gateway の IP アドレスを取得します。

    kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
    

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

    203.0.113.12
    

    この出力はパブリック IP アドレスです。つまり、インターネットにアクセスできるクライアントであれば、このアドレスに接続できます。

  2. curl を使用して Gateway のドメインにアクセスします。

    curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert CERTIFICATE_FILE -v
    

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

    • GATEWAY_IP_ADDRESS: Gateway ロードバランサの IP アドレス。
    • CERTIFICATE_FILE: 生成した証明書ファイル。Gateway への接続に使用しているマシンに、このファイルを保存する必要があります。Gateway は自己署名証明書を使用するため、Gateway の認証には証明書が必要です。

    --resolve オプションは、ドメイン名を Gateway の IP アドレスに解決します。このドメインには DNS が構成されていないため、これは必須です。

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

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    # This block shows the certificate details presented by the Gateway.
    # The value of the 'common name' field matches the requested hostname.
    * Server certificate:
    *  subject: O=example; CN=store.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: store.example.com (matched)
    *  issuer: O=example; CN=store.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gw",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "store-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08"
      # Several lines of output omitted here.
    }
    

    この出力には、TLS handshake が成功した後のアプリケーションからのレスポンスが含まれます。TLS 接続はゲートウェイで終端し、アプリケーションはクライアントに安全に応答します。

SSL 証明書を使用して Gateway を保護する

この例では、Google マネージド SSL 証明書を使用して Gateway を構成します。

SSL 証明書の作成

  1. Google マネージドのグローバル SslCertificate リソースを作成します。

    gcloud compute ssl-certificates create store-example-com \
        --domains=store.example.com \
        --global
    

Gateway と HTTPRoute を作成する

  1. 次のマニフェストを external-gateway.yaml として保存します。

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-http
    spec:
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
        tls:
          mode: Terminate # Terminate TLS using your SSL certificate.
          options:
            networking.gke.io/pre-shared-certs: store-example-com # Specify the Google Cloud SSL certificate resource name.
    

    このマニフェストでは、次のプロパティを持つゲートウェイが記述されています。

    • gatewayClassName: gke-l7-global-external-managed: グローバル外部アプリケーション ロードバランサをデプロイします。
    • protocol:HTTPSport:443: TLS を有効にするために必要です。
    • tls.mode:Terminate: SSL 証明書を使用して TLS を終端します。
  2. マニフェストをクラスタに適用します。

    kubectl apply -f external-gateway.yaml
    
  3. 次の HTTPRoute マニフェストを store-external-route.yaml として保存します。

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-external
      labels:
        gateway: external-http
    spec:
      parentRefs:
      - name: external-http
      hostnames:
      - "store.example.com"
      rules:
      - backendRefs:
        - name: store-v1
          port: 8080
    
  4. クラスタに HTTPRoute をデプロイします。

    kubectl apply -f store-external-route.yaml
    

    GKE が Gateway をデプロイするまでに数分かかることがあります。

Gateway を確認する

  1. Gateway の IP アドレスを取得します。

    kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
    

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

    203.0.113.12
    

    この出力はパブリック IP アドレスです。つまり、インターネットにアクセスできるクライアントであれば、このアドレスに接続できます。

  2. A レコードまたは AAAA レコードを更新して、ドメインをゲートウェイの IP アドレスにリダイレクトします。

    この手順は、Google マネージド SSL 証明書を構成する場合にのみ必要です。セルフマネージド証明書を構成する場合は、この手順をスキップできます。

    DNS レコードの更新後、ロードバランサが Google マネージド証明書の使用を開始するまでに最大で 10 分かかることがあります。

  3. curl を使用してインターネット経由でリクエストを送信し、Gateway が機能していることを確認します。

    curl https://store.example.com -v
    

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

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=store.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: store.example.com (matched)
    *  issuer: O=example; CN=store.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gw",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "store-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08",
      "zone": "us-west1-a"
    }
    

    この出力には、TLS handshake が成功した後のアプリケーションからのレスポンスが含まれます。ゲートウェイで TLS が正しく終端され、アプリケーションがクライアントに安全に応答します。

Certificate Manager を使用して Gateway を保護する

この例では、Certificate Manager を使用して Gateway を構成します。

Certificate を作成する

グローバル Gateway

グローバル Gateway を作成するには、1 つ以上の証明書を含む証明書マップ リソースを参照します。少なくとも 1 つの証明書を作成し、証明書マップへのエントリとして追加する必要があります。

  1. 証明書を作成するには、まず秘密鍵と証明書ファイルを作成します。

  2. セルフマネージド証明書と鍵を読み込んで、Certificate リソースを作成します。

    gcloud certificate-manager certificates create store-example-com-cert \
        --certificate-file="cert.pem" \
        --private-key-file="PRIVATE_KEY_FILE"
    
  3. CertificateMap を作成します。

    gcloud certificate-manager maps create store-example-com-map
    
  4. 証明書を CertificateMap に割り当てる CertificateMapEntry を作成します。

    gcloud certificate-manager maps entries create store-example-com-map-entry \
        --map=store-example-com-map \
        --hostname=store.example.com \
        --certificates=store-example-com-cert
    

リージョン Gateway

リージョン Gateway の場合は、Gateway の作成時に直接指定する Certificate を作成します。グローバル Gateway とは異なり、証明書が割り当てられる CertificateMap を作成する必要はありません。

  1. 秘密鍵と証明書を作成します。

  2. 証明書ファイルと鍵をアップロードして Certificate リソースを作成します。

gcloud certificate-manager certificates create "CERTIFICATE_NAME" \
    --certificate-file="CERTIFICATE_FILE" \
    --private-key-file="PRIVATE_KEY_FILE" \
    --location="REGION"

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

  • CERTIFICATE_NAME: 証明書の名前(例: store-example-com-cert)。
  • CERTIFICATE_FILE: 証明書ファイルの名前(例: cert.pem)。
  • PRIVATE_KEY_FILE: 秘密鍵ファイルの名前(private-key.pem など)。詳細については、秘密鍵を選択または作成するをご覧ください。
  • REGION: Gateway を構成するリージョンの名前(例: us-central1)。

Gateway と HTTPRoute を作成する

グローバル Gateway

グローバル Gateway を作成するには、次の操作を行います。

  1. 次のマニフェストを cert-map-gateway.yaml として保存します。

    kind: Gateway
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: external-http
      annotations:
        networking.gke.io/certmap: store-example-com-map
    spec:
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: https
        protocol: HTTPS
        port: 443
      # No TLS section is included here because TLS is handled by the certmap annotation.
    

    このマニフェストでは、次のプロパティを持つゲートウェイが記述されています。

    • gatewayClassName: gke-l7-global-external-managed: グローバル外部アプリケーション ロードバランサをデプロイします。
    • protocol: HTTPSport: 443: TLS を有効にするために必要です。

    TLS はアノテーション networking.gke.io/certmap を使用して Certificate Manager で構成されるため、TLS セクションはありません。

  2. マニフェストをクラスタに適用します。

    kubectl apply -f cert-map-gateway.yaml
    

    GKE が Gateway をデプロイするまでに数分かかることがあります。

  3. HTTPRoute を作成するには、次のマニフェストを cert-map-http-route.yaml として保存します。

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: foo
      namespace: default
    spec:
      parentRefs:
      - name: external-http
      hostnames:
      - foo.example.com
      rules:
      - matches:
        - path:
            value: /
        backendRefs:
        - name: foo-v1
          port: 8080
    
  4. マニフェストをクラスタに適用します。

    kubectl apply -f cert-map-http-route.yaml
    

リージョン Gateway

リージョン Gateway を作成するときに、Certificate Manager で管理されている証明書と Compute Engine で管理されている証明書を指定できます。

  1. リージョン外部 Gateway を作成するには、次のマニフェストを external-gateway.yaml として保存します。

       kind: Gateway
       apiVersion: gateway.networking.k8s.io/v1
       metadata:
         name: gateway
         namespace: corp
       spec:
         gatewayClassName: gke-l7-regional-external-managed
         listeners:
         - name: gateway-pre-shared-certmap
           protocol: HTTPS
           port: 443
           tls:
             mode: Terminate # TLS is terminated at the Gateway.
             options: # Specifies a comma-separated list of Certificate Manager certificates to use for TLS termination.
               networking.gke.io/cert-manager-certs: store-example-com-cert1, store-example-com-cert2 # These certificates are directly managed by Certificate Manager.
           allowedRoutes:
             kinds:
             - kind: HTTPRoute
             namespaces:
               from: All
    

    このマニフェストでは、次のプロパティを持つ Gateway が記述されています。

    • gatewayClassName: gke-l7-regional-external-managed: リージョン外部アプリケーション ロードバランサをデプロイします。
    • protocol: HTTPSport: 443: TLS を有効にするために必要です。
    • options:
      • networking.gke.io/cert-manager-certs: Certificate Manager で管理されている証明書。

    リージョン内部 Gateway を作成するには、上記の例で gatewayClassName の値を gke-l7-rilb に変更します。これにより、内部アプリケーション ロードバランサがデプロイされます。

  2. マニフェストをクラスタに適用します。

    kubectl apply -f external-gateway.yaml
    
  3. HTTPRoute を作成するには、次のマニフェストを store-external-route.yaml として保存します。

    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: store-external
      labels:
        gateway: external-http
    spec:
      parentRefs:
      - name: external-http
      hostnames:
      - "store.example.com"
      rules:
        backendRefs:
        - name: store-v1
          port: 8080
    

    このマニフェストには、store.example.com のトラフィックを照合して store-v1 Service に転送する HTTPRoute が記述されています。

  4. マニフェストをクラスタに適用します。

    kubectl apply -f store-external-route.yaml
    

Gateway を確認する

  1. Gateway の IP アドレスを取得します。

    kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
    

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

    203.0.113.12
    

    この出力はパブリック IP アドレスです。つまり、インターネットにアクセスできるクライアントであれば、このアドレスに接続できます。

  2. A レコードまたは AAAA レコードを更新して、ドメインをゲートウェイの IP アドレスにリダイレクトします。

    この手順は、Google マネージド SSL 証明書を構成する場合にのみ必要です。セルフマネージド証明書を構成する場合は、この手順をスキップできます。

    DNS レコードの更新後、ロードバランサが Google マネージド証明書の使用を開始するまでに最大で 10 分かかることがあります。

  3. curl を使用して Gateway のドメインにアクセスします。

    curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert CERTIFICATE_FILE -v
    

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

    • GATEWAY_IP_ADDRESS: Gateway ロードバランサの IP アドレス。
    • CERTIFICATE_FILE: 生成した証明書ファイル。Gateway への接続に使用しているマシンに、このファイルを保存する必要があります。Gateway は自己署名証明書を使用するため、Gateway の認証には証明書が必要です。

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

    ...
    * TLSv1.2 (OUT), TLS handshake, Client hello (1):
    * TLSv1.2 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305
    * ALPN, server accepted to use h2
    * Server certificate:
    *  subject: O=example; CN=store.example.com
    *  start date: Apr 19 15:54:50 2021 GMT
    *  expire date: Apr 19 15:54:50 2022 GMT
    *  common name: store.example.com (matched)
    *  issuer: O=example; CN=store.example.com
    *  SSL certificate verify ok.
    ...
    {
      "cluster_name": "gw",
      "host_header": "store.example.com",
      "metadata": "store-v1",
      "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal",
      "pod_name": "store-v1-84b47c7f58-tj5mn",
      "pod_name_emoji": "😍",
      "project_id": "agmsb-k8s",
      "timestamp": "2021-04-19T16:30:08",
      "zone": "us-west1-a"
    }
    

    この出力には、TLS handshake が成功した後のアプリケーションからのレスポンスが含まれます。ゲートウェイで TLS が正しく終端され、アプリケーションがクライアントに安全に応答します。

Gateway のバックエンド TLS を構成する

バックエンド TLS を使用すると、GKE Gateway ロードバランサは接続先のバックエンドの ID を検証できます。バックエンド TLS は、Gateway とバックエンド Pod 間の TLS handshake 中に明示的な検証ステップを追加します。Gateway は TLS クライアントとして機能し、構成した信頼できる認証局(CA)のセットに対してバックエンド サーバーの証明書を検証します。この検証は新しい接続が確立されたときに行われ、Gateway が信頼できるバックエンドとのみ通信することを保証し、全体的なセキュリティを強化します。

バックエンド認証済み TLS は、Service、InferencePool、ServiceImport、または GCPInferencePoolImport に関連付けられた BackendTLSPolicy リソースを使用して構成できます。BackendTLSPolicy は、ターゲット リソースと同じ Namespace に存在する必要があります。

バックエンド TLS は、次の GatewayClass でサポートされています。

  • gke-l7-global-external-managedgke-l7-global-external-managed-mc (Service と ServiceImport バックエンドのみをサポート)
  • gke-l7-regional-external-managedgke-l7-regional-external-managed-mc
  • gke-l7-rilbgke-l7-rilb-mc
  • gke-l7-cross-regional-internal-managed-mc

Kubernetes ConfigMap を使用する(標準)

この方法では、CA 証明書を Kubernetes ConfigMap で直接指定します。

  1. PEM エンコードされた CA 証明書を含む ConfigMap リソースを作成します。詳細については、証明書の要件をご覧ください。各 ConfigMap には、1 つの CA 証明書のみを含める必要があります。この ConfigMap は、BackendTLSPolicy リソースと同じ Namespace に作成する必要があります。BackendTLSPolicy は、ConfigMap リソースへのクロス名前空間参照をサポートしていません。

    証明書データは ca.crt キーの下に配置する必要があります。

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: my-backend-ca
    data:
      ca.crt: |
        -----BEGIN CERTIFICATE-----
        PEM_DATA
        -----END CERTIFICATE-----
    

    PEM_DATA は、Base64 でエンコードされた PEM 形式の CA 証明書の内容に置き換えます。

  2. ConfigMap を参照する BackendTLSPolicy を使用して、Service、InferencePool、ServiceImport、または GCPInferencePoolImport をターゲットにします。

    サービス

    次のマニフェストは、Service をターゲットとする BackendTLSPolicy を示しています。

    apiVersion: gateway.networking.k8s.io/v1
    kind: BackendTLSPolicy
    metadata:
      name: secure-backend-policy
    spec:
      targetRefs:
      - group: "" # empty group means Core API.
        kind: Service
        name: my-service-name
      validation:
        hostname: "backend.example.com"
        caCertificateRefs:
        - group: "" # empty group means Core API.
          kind: ConfigMap
          name: my-backend-ca
    

    InferencePool

    次のマニフェストは、InferencePool をターゲットとする BackendTLSPolicy を示しています。

    apiVersion: gateway.networking.k8s.io/v1
    kind: BackendTLSPolicy
    metadata:
      name: secure-backend-policy-inferencepool
    spec:
      targetRefs:
      - group: "inference.networking.k8s.io" # For InferencePool
        kind: InferencePool
        name: my-inference-pool
      validation:
        hostname: "backend.example.com"
        caCertificateRefs:
        - group: "" # empty group means Core API.
          kind: ConfigMap
          name: my-backend-ca
    

    ServiceImport

    次のマニフェストは、ServiceImport をターゲットとする BackendTLSPolicy を示しています。

    apiVersion: gateway.networking.k8s.io/v1
    kind: BackendTLSPolicy
    metadata:
      name: secure-backend-policy-serviceimport
    spec:
      targetRefs:
      - group: "net.gke.io" # For ServiceImport
        kind: ServiceImport
        name: my-service-import
      validation:
        hostname: "backend.example.com"
        caCertificateRefs:
        - group: "" # empty group means Core API.
          kind: ConfigMap
          name: my-backend-ca
    

    GCPInferencePoolImport

    次のマニフェストは、GCPInferencePoolImport をターゲットとする BackendTLSPolicy を示しています。

    apiVersion: gateway.networking.k8s.io/v1
    kind: BackendTLSPolicy
    metadata:
      name: secure-backend-policy-gcpinferencepoolimport
    spec:
      targetRefs:
      - group: "networking.gke.io" # For GCPInferencePoolImport
        kind: GCPInferencePoolImport
        name: my-gcp-inference-pool-import
      validation:
        hostname: "backend.example.com"
        caCertificateRefs:
        - group: "" # empty group means Core API.
          kind: ConfigMap
          name: my-backend-ca
    

セルフマネージド TrustConfig を使用する(詳細)

この方法では、 Google CloudCertificate Manager で個別に管理する TrustConfig リソースを参照できます。

  1. Certificate Manager で TrustConfig リソースを作成します。TrustConfig は、Gateway と同じプロジェクトとロケーションに作成する必要があります。

    • グローバルまたはマルチクラスタ Gateway(リージョン マルチクラスタを含む)とクロスリージョン Gateway の場合は、global ロケーションを使用します。
    • リージョン単一クラスタ Gateway の場合は、Gateway と同じリージョンを使用します。
    • Service が異なるロケーションの複数の Gateway で使用されている場合は、各ロケーションで同じ名前の TrustConfig リソースを作成する必要があります。
  2. options フィールドを介して外部 TrustConfig リソースを参照する BackendTLSPolicy を使用して Service をターゲットにします。

    apiVersion: gateway.networking.k8s.io/v1
    kind: BackendTLSPolicy
    metadata:
      name: secure-backend-policy
    spec:
      targetRefs:
      - group: "" # empty group means Core API.
        kind: Service
        name: my-service-name
      validation:
        wellKnownCACertificates: "System"
        hostname: "backend.example.com"
        options:
          networking.gke.io/backend-trust-config: "my-trust-config-name"
    

BackendTLSPolicy フィールド リファレンス

次の表に、BackendTLSPolicy リソースのキーフィールドを示します。

フィールド 説明
targetRefs このポリシーが適用されるバックエンド リソース。Service(group: "")、InferencePool(group: "inference.networking.k8s.io")、ServiceImport(group: "net.gke.io")、GCPInferencePoolImport(group: "networking.gke.io")をサポートします。注: gke-l7-global-external-managedgke-l7-global-external-managed-mc の GatewayClass では、Service と ServiceImport のバックエンドのみがサポートされます。
validation.hostname バックエンド Pod との TLS handshake 中に Gateway で使用されるホスト名(SNI)。
validation.subjectAltNames 省略可。バックエンドの証明書に対して検証する 1 つ以上のサブジェクト代替名(SAN)を定義します。HostnameURI(SPIFFE ID など)をサポートします。
validation.caCertificateRefs 標準的な方法。同じ Namespace 内の ConfigMap リソースのリスト(最大 8 個)を参照します。各 ConfigMap には、ca.crt キーの下に 1 つの PEM エンコードされた CA 証明書が含まれている必要があります。Namespace をまたぐ参照はサポートされていません。
validation.wellKnownCACertificates 高度な方法。セルフマネージド TrustConfig を使用する場合は、値を System に設定します。
options GKE 固有のオプションのマップ。networking.gke.io/backend-trust-config 設定を使用して、外部の TrustConfig リソースを参照します。

バックエンド TLS 構成を確認する

BackendTLSPolicy を適用したら、ポリシーのステータスを確認して、Gateway コントローラが構成を受け入れたことを確認します。

kubectl describe backendtlspolicy POLICY_NAME

POLICY_NAME は、ポリシーの名前に置き換えます。

ポリシーが正常に適用されるのは、Status.Ancestors セクションに Status: "True" が含まれ、AcceptedResolvedRefs の条件が含まれている場合です。

Status:
  Ancestors:
  - Ancestor Ref:
      Group: gateway.networking.k8s.io
      Kind: Gateway
      Name: my-gateway-name
      Namespace: default
    Conditions:
    - Last Transition Time: "2026-02-17T15:19:26Z"
      Message: ""
      Reason: Accepted
      Status: "True"
      Type: Accepted
    - Last Transition Time: "2026-02-17T15:19:26Z"
      Message: ""
      Reason: ResolvedRefs
      Status: "True"
      Type: ResolvedRefs
    Controller Name: networking.gke.io/gateway

これらの条件のいずれかで StatusFalse の場合、ポリシーが適用されていないことを示します。詳しくは、Reason フィールドと Message フィールドを確認してください。一般的なエラーとしては、存在しない ConfigMapcaCertificateRefs で参照している、または ca.crt キーが欠落しているなどがあります。

このステータスは、Gateway がポリシーを正常に検証し、ターゲット Service または InferencePool のバックエンドに TLS 設定を適用したことを確認します。BackendTLSPolicy リソースは、ターゲット リソースと同じ Namespace に存在する必要があります。

TLS を使用してロードバランサからアプリケーションへのトラフィックを保護する

ports[].appProtocol フィールドを使用して、ロードバランサからバックエンド Pod へのトラフィックを暗号化できます。appProtocol でサポートされているフィールドは、HTTPHTTPSHTTP2kubernetes.io/h2c です。

次のマニフェストでは、ロードバランサがバックエンド Pod との通信に HTTPS トラフィックを使用する必要があることを指定する Service を記述しています。

apiVersion: v1
kind: Service
metadata:
  name: store-v2
spec:
  selector:
    app: store
    version: v2
  ports:
  - port: 8080
    targetPort: 8080
    appProtocol: HTTPS

ロードバランサは、バックエンド Pod で使用される証明書を確認しません。バックエンド Pod で使用される証明書が有効であることの確認は、お客様の責任で行っていただきます。

SSL ポリシーを使用してクライアントからロードバランサへのトラフィックを保護する

アプリケーションが HTTPS を使用する外部ゲートウェイを介して公開される場合は、最新のプロトコルを使用するか、最小の SSL または TLS バージョンを指定することが重要です。SSL ポリシーを使用することで、クライアントからロードバランサのトラフィックを保護できます。

Gateway に接続できる SSL ポリシーとその作成方法の詳細については、クライアントからロードバランサのトラフィックを保護する SSL ポリシーの構成をご覧ください。

Google Cloud Armor を使用してバックエンドを保護する

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

Gateway で Google Cloud Armor ポリシーを構成するには、バックエンド サービスを保護する Google Cloud Armor セキュリティ ポリシーを構成するをご覧ください。

Identity-Aware Proxy を使用してバックエンドへのリクエストを認証する

Identity-Aware Proxy は、アプリケーションにリクエストを送信するクライアントを認証し、ロールベースのトラフィック認可を適用することで、不要なトラフィックからバックエンドを保護します。GKE 用 Identity-Aware Proxy を有効にすると、Kubernetes Service に適用された GCPBackendPolicy で OAuth 認証情報を参照できます。

Gateway を使用して Identity-Aware Proxy を構成するには、Identity-Aware Proxy を構成するをご覧ください。

次のステップ