保護閘道

本頁說明如何使用各種安全防護功能保護 Gateway:

  • 安全資料傳輸層 (SSL) 政策,確保閘道使用必要的安全通訊協定和演算法

  • 使用 TLS 保護用戶端到閘道,以及閘道到後端之間的流量

  • Google Cloud Armor 安全性政策,可保護服務免於遭受 DDoS 攻擊

  • Identity-Aware Proxy (IAP),在允許存取服務前提供驗證和授權層

如要進一步瞭解閘道安全性,請參閱「閘道安全性」。

事前準備

開始之前,請確認您已完成下列工作:

  • 啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 如要使用 Google Cloud CLI 執行這項工作,請安裝初始化 gcloud CLI。如果您先前已安裝 gcloud CLI,請執行 gcloud components update 指令,取得最新版本。舊版 gcloud CLI 可能不支援執行本文中的指令。

GKE Gateway 控制器需求

  • 閘道 API 僅支援 VPC 原生叢集。
  • 如果您使用區域或跨區域 GatewayClass,則必須啟用僅限 Proxy 的子網路
  • 叢集必須啟用 HttpLoadBalancing 外掛程式。
  • 如果您使用 Istio,請務必將 Istio 升級至下列其中一個版本:
    • 1.15.2 以上版本
    • 1.14.5 以上版本
    • 1.13.9 以上版本。
  • 如果您使用 Shared VPC,則須在代管專案中,將 Compute Network User 角色指派給服務專案的 GKE 服務帳戶。

  • 確認您有現有的 Autopilot 或 Standard 叢集。如需叢集,請建立 Autopilot 叢集

規定與限制

除了 GKE Gateway 控制器的限制,Gateway 安全性還受到下列限制:

  • 在閘道上使用 SSL 憑證Certificate Manager的 TLS 設定,不支援 GKE 1.28.4-gke.1083000 版。如要解決這個問題,請使用 Kubernetes 密鑰

  • 您無法在同一個 Gateway 資源中,同時使用 networking.gke.io/certmap 註解和 tls.certificateRefs。如果在 Gateway 中參照 CertificateMap,GKE 會將此視為錯誤。

  • Certificate Manager 支援自行管理和 Google 代管的憑證。Google 代管的憑證與區域和全域閘道相容。

  • 使用 Google 代管的 SSL 憑證時,您必須在 GKE 外部建立 SSL 憑證,才能將憑證附加至 Gateway。

  • 如果您在 GCPBackendPolicy 中參照 Google Cloud Armor 後端安全政策,就無法將同一項服務做為區域和全域閘道的後端。您必須為這個用途建立兩項不同的服務和政策。

  • Gateway 控制器不支援 ManagedCertificate 資源。

  • Gateway 控制器不支援 networking.gke.io/managed-certificates 註解。

  • 如果您使用 GKE Gateway 設定 Cloud CDN,就無法透過同一個 Gateway 同時啟用 IAP 和 Cloud CDN,包括使用 Cloud CDN 的個別路徑。如要為使用 GCPHTTPFilter 資源的路徑啟用 Cloud CDN,請先移除為該 Gateway 設定 IAP 的所有現有 GCPBackendPolicy。

  • TrustConfig 配額。如要瞭解每個位置中所有 TrustConfig 資源的總大小,請參閱「資源配額和限制」。

  • 位置對齊。參考的 TrustConfig 資源必須與使用該服務的 Gateway 位於相同位置 (全域或特定區域)。

  • 命名空間限制。BackendTLSPolicy 資源及其目標資源必須位於相同命名空間。

如需 GKE 支援的 Gateway API 欄位和 GatewayClass 資源功能清單,請參閱 GatewayClass 功能

使用 Kubernetes Secret 保護閘道安全

在本範例中,您將使用 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 密鑰:

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

    GKE 會將憑證和金鑰儲存為 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.
    

    這個資訊清單說明具有下列屬性的 Gateway:

    • 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
    

    這個資訊清單說明 HTTPRoute,該路徑會比對流量與 store.example.com,並將流量傳送至 store-v1 服務。

  4. 將資訊清單套用至叢集:

    kubectl apply -f store-external-route.yaml
    

驗證閘道

透過網際網路傳送要求,確認閘道是否正常運作。

  1. 取得閘道的 IP 位址:

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

    輸出結果會與下列內容相似:

    203.0.113.12
    

    這個輸出內容是公開 IP 位址,表示任何可存取網際網路的用戶端都能連線。

  2. 使用 curl 存取閘道的網域:

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

    更改下列內容:

    • GATEWAY_IP_ADDRESS:閘道負載平衡器的 IP 位址。
    • CERTIFICATE_FILE:您產生的憑證檔案。您必須將這個檔案儲存在用來連線至閘道的電腦上。由於閘道使用自行簽署的憑證,因此需要憑證來驗證閘道。

    --resolve 選項會將網域名稱解析為閘道的 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 握手,以及應用程式的回應。TLS 連線會在閘道終止,應用程式則會安全地回應用戶端。

使用 SSL 憑證保護 Gateway

在本範例中,您將使用 Google 代管的 SSL 憑證設定閘道。

建立 SSL 憑證

  1. 建立 Google 代管的通用 SslCertificate 資源:

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

建立閘道和 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.
    

    這個資訊清單說明具有下列屬性的 Gateway:

    • 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。

驗證閘道

  1. 取得閘道的 IP 位址:

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

    輸出結果會與下列內容相似:

    203.0.113.12
    

    這個輸出內容是公開 IP 位址,表示任何可存取網際網路的用戶端都能連線。

  2. 更新 A 或 AAAA 記錄,將網域導向閘道的 IP 位址。

    只有在設定 Google 代管的 SSL 憑證時,才需要執行這個步驟。如果設定的是自行管理的憑證,可以略過這個步驟。

    更新 DNS 記錄後,負載平衡器最多需要 10 分鐘,才會開始使用 Google 代管憑證。

  3. 透過網際網路傳送要求 (使用 curl),確認閘道是否正常運作:

    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 握手,以及來自應用程式的回應。TLS 在閘道正確終止,且應用程式安全地回應用戶端。

使用 Certificate Manager 保護閘道安全

在本範例中,您將使用 Certificate Manager 設定 Gateway。

建立 Certificate

Global Gateway

如要建立全域閘道,請參照包含一或多個憑證的憑證對應資源。您必須建立至少一個憑證,並將其新增為憑證對應組合中的項目。

  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. 建立 CertificateMapEntry,將憑證指派給 CertificateMap

    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
    

區域閘道

如果是地區閘道,請建立 Certificate,並在建立閘道時直接指定。與全球閘道不同,您不需要建立指派憑證的 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

建立閘道和 HTTPRoute

Global 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.
    

    這個資訊清單說明具有下列屬性的 Gateway:

    • 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
    

區域閘道

建立區域閘道時,您可以指定由 Certificate Manager 管理的憑證,以及由 Compute Engine 管理的憑證。

  1. 如要建立地區外部閘道,請將下列資訊清單儲存為 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:

    • gatewayClassNamegke-l7-regional-external-managed:部署區域性外部應用程式負載平衡器。
    • protocol: HTTPSport: 443:啟用 TLS 時必須提供。
    • options
      • networking.gke.io/cert-manager-certs:由 Certificate Manager 管理的憑證。

    如要在上述範例中建立區域性內部閘道,請將 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
    

    這個資訊清單說明 HTTPRoute,該路徑會比對 store.example.com 的流量,並將流量轉送至 store-v1 服務。

  4. 將資訊清單套用至叢集:

    kubectl apply -f store-external-route.yaml
    

驗證閘道

  1. 取得閘道的 IP 位址:

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

    輸出結果會與下列內容相似:

    203.0.113.12
    

    這個輸出內容是公開 IP 位址,表示任何可存取網際網路的用戶端都能連線。

  2. 更新 A 或 AAAA 記錄,將網域導向閘道的 IP 位址。

    只有在設定 Google 代管的 SSL 憑證時,才需要執行這個步驟。如果設定的是自行管理的憑證,可以略過這個步驟。

    更新 DNS 記錄後,負載平衡器最多需要 10 分鐘,才會開始使用 Google 代管憑證。

  3. 使用 curl 存取閘道的網域:

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

    更改下列內容:

    • GATEWAY_IP_ADDRESS:閘道負載平衡器的 IP 位址。
    • CERTIFICATE_FILE:您產生的憑證檔案。您必須將這個檔案儲存在用來連線至閘道的電腦上。由於閘道使用自行簽署的憑證,因此需要憑證來驗證閘道。

    輸出結果會與下列內容相似:

    ...
    * 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 握手,以及來自應用程式的回應。TLS 在閘道正確終止,且應用程式安全地回應用戶端。

為閘道設定前端 mTLS

您可以為 GKE Gateway 設定用戶端憑證驗證,也就是前端 mTLS。gke-l7-global-external-managedgke-l7-regional-external-managedgke-l7-rilb GatewayClass 支援前端 mTLS,可讓 Gateway 驗證用戶端提供的憑證。前端 mTLS 設定適用於使用 Terminate 模式的 HTTPS 接聽程式。

您可以透過下列任一方式設定前端 mTLS:

  • 使用 Gateway API 設定 (建議)。
  • 在閘道上使用自行管理的 TrustConfig 註解 (進階)。

使用 Gateway API 設定設定前端 mTLS (建議)

建議使用 Gateway API 設定用戶端憑證驗證。這個方法包括將信任來源儲存在 Kubernetes ConfigMap 中,並在 Gateway 規格中參照這個 ConfigMap。

  1. 建立信任來源。

    信任來源會建立並驗證提供給負載平衡器的用戶端憑證信任根。GKE Gateway 支援以根憑證為準的信任來源。

    如要建立憑證,請參閱「建立根憑證和中繼憑證」。

  2. 建立 ConfigMap。

    將信任來源儲存在 Kubernetes ConfigMap 中。ConfigMap 中的每個金鑰都必須包含一個有效的 x509 格式 PEM 編碼 CA 憑證。除非使用 ReferenceGrant,否則您必須在與 Gateway 資源相同的命名空間中建立這個 ConfigMap。如要在不同命名空間中參照 ConfigMap,請參閱 ReferenceGrant

    將憑證資料放在 ca.crt 金鑰下方:

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

    如要使用憑證建立 ConfigMap,請執行下列指令:

    kubectl create configmap my-config \
        --from-file=ca.crt=ROOT_CERT_PATH
    

    請將 ROOT_CERT_PATH 替換為憑證檔案的路徑,ConfigMap 只能包含一個憑證。

  3. 設定閘道。

    將 ConfigMap 附加至 Gateway,方法是在 Gateway 規格中新增包含 frontendValidation 欄位的 tls 區段。default 設定為必要項目,且適用於使用 Terminate 模式的所有 HTTPS 監聽器,除非您指定每個通訊埠的設定。以下範例顯示包含伺服器憑證 (使用 certmap 註解) 和用戶端憑證驗證 (使用 tls.frontendValidation 欄位) 的端對端 Gateway 設定:

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: mtls-example
      annotations:
        networking.gke.io/certmap: store-example-com-map
    spec:
      gatewayClassName: gke-l7-global-external-managed
      tls:
        frontendValidation:
          default:
            caCertificateRefs:
            - kind: ConfigMap
              group: ""
              name: my-config
      listeners:
      - name: foo-https
        protocol: HTTPS
        port: 443
        hostname: foo.example.com
        tls:
          mode: Terminate
          # No certificateRefs needed when using the certmap annotation
    
  4. 覆寫每個通訊埠的設定。

    您也可以為個別連接埠指定專屬信任來源。每個連接埠的設定都會覆寫為該連接埠設定的所有接聽程式的預設設定。

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: mtls-port-override
      annotations:
        networking.gke.io/certmap: store-example-com-map
    spec:
      gatewayClassName: gke-l7-global-external-managed
      tls:
        frontendValidation:
          default:
            caCertificateRefs:
            - kind: ConfigMap
              group: ""
              name: global-ca-config
          perPort:
          - port: 8443
            tls:
              validation:
                caCertificateRefs:
                - kind: ConfigMap
                  group: ""
                  name: port-specific-ca-config
      listeners:
      - name: https-default
        protocol: HTTPS
        port: 443
        tls:
          mode: Terminate
      - name: https-override
        protocol: HTTPS
        port: 8443
        tls:
          mode: Terminate
    
  5. 選用:設定用戶端驗證模式。

    根據預設,GKE Gateway 會強制執行嚴格的用戶端憑證驗證 (AllowValidOnly)。如要允許無效或缺少的用戶端憑證,請在 frontendValidation.default 設定中,將 mode 鍵的值設為 AllowInsecureFallback

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: mtls-example
      annotations:
        networking.gke.io/certmap: store-example-com-map # Add this annotation
    spec:
      gatewayClassName: gke-l7-global-external-managed
      tls:
        frontendValidation:
          default:
            caCertificateRefs:
            - kind: ConfigMap
              group: ""
              name: my-config
            mode: AllowInsecureFallback
      listeners:
      - name: foo-https
        protocol: HTTPS
        port: 443
        hostname: foo.example.com
        tls:
          mode: Terminate
          # No certificateRefs needed when using the certmap annotation
    

使用自行管理的 TrustConfig (進階)

或者,您也可以使用 TrustConfig 資源為 Gateway 加上註解,設定用戶端憑證驗證。如需更多彈性,或設定超出標準 Gateway API 限制,請使用這個自行管理的方法。這個方法與 Gateway API 設定方法互斥,且適用於 Gateway 上的所有 HTTPS 監聽器 (不支援每個連接埠的覆寫)。

  1. 建立 TrustConfig 資源。如需操作說明,請參閱「建立信任設定資源」。

    建立 TrustConfig 資源時,請為全域閘道 (gke-l7-global-external-managed) 指定 global,或為區域閘道 (gke-l7-regional-external-managedgke-l7-rilb) 指定適當區域 (例如 us-central1)。

  2. 使用 networking.gke.io/frontend-trust-config 註解,將 TrustConfig 附加至 Gateway。

    以下範例顯示端對端 Gateway 設定,其中包含伺服器憑證 (使用 certmap 註解) 和用戶端憑證驗證 (使用 TrustConfig 註解):

    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: mtls-example
      annotations:
        networking.gke.io/frontend-trust-config: my-trust-config
        networking.gke.io/certmap: store-example-com-map # Add this annotation
    spec:
      gatewayClassName: gke-l7-global-external-managed
      listeners:
      - name: foo-https
        protocol: HTTPS
        port: 443
        hostname: foo.example.com
        tls:
          mode: Terminate
          # Remove certificateRefs and replace with the comment
          # No certificateRefs needed when using the certmap annotation
    
  3. 選用:設定用戶端驗證模式。

    根據預設,GKE Gateway 會強制執行嚴格的用戶端憑證驗證 (REJECT_INVALID)。如要允許無效或缺少的用戶端憑證,請將 networking.gke.io/allow-invalid-or-missing-client-cert 註解設為 true

設定閘道的後端 TLS

後端 TLS 可讓 GKE Gateway 負載平衡器驗證所連線後端的身分。後端 TLS 會在閘道和後端 Pod 之間的 TLS 交握期間,新增明確的驗證步驟。閘道會做為 TLS 用戶端,根據您設定的一組信任憑證授權單位 (CA),驗證後端伺服器的憑證。建立新連線時會進行這項驗證,確保閘道只與受信任的後端通訊,進而提升整體安全性。

您可以透過附加至 Service、InferencePool、ServiceImport 或 GCPInferencePoolImport 的 BackendTLSPolicy 資源,設定後端驗證 TLS。BackendTLSPolicy 必須與目標資源位於相同命名空間。

下列 GatewayClass 支援後端 TLS:

  • gke-l7-global-external-managed
  • gke-l7-regional-external-managed
  • gke-l7-rilb

使用 Kubernetes ConfigMap (標準)

使用這個方法時,您會直接在 Kubernetes ConfigMap 中提供 CA 憑證。

  1. 建立包含 PEM 編碼 CA 憑證的 ConfigMap 資源。詳情請參閱憑證規定。每個 ConfigMap 只能包含一個 CA 憑證。您必須在與 BackendTLSPolicy 資源相同的命名空間中建立這個 ConfigMap。BackendTLSPolicy 不支援跨命名空間參照 ConfigMap 資源。

    憑證資料必須放在 ca.crt 金鑰下方:

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

    PEM_DATA 替換為 CA 憑證的 Base64 編碼 PEM 格式內容。

  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 (進階)

這個方法可讓您參照在 Certificate Manager 中獨立管理的 TrustConfig 資源。 Google Cloud

  1. 在 Certificate Manager 中建立 TrustConfig 資源。TrustConfig 必須與 Gateway 建立在相同的專案和位置。

    • 如為全域多叢集閘道 (包括區域多叢集) 和跨區域閘道,請使用 global location。
    • 如果是區域單一叢集閘道,請使用與閘道相同的區域。
    • 如果您的服務是由不同位置的多個閘道使用,您必須在每個位置建立同名的 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 這項政策適用的後端資源。支援服務 (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,僅支援服務和 ServiceImport 後端。
validation.hostname 閘道在與後端 Pod 進行 TLS 握手期間使用的主機名稱 (SNI)。
validation.subjectAltNames 選用。定義一或多個主體別名 (SAN),用來驗證後端的憑證。支援 HostnameURI (例如 SPIFFE ID)。
validation.caCertificateRefs 標準方法。參照相同命名空間中的 ConfigMap 資源清單 (最多八個)。每個 ConfigMap 都必須在 ca.crt 鍵底下包含單一 PEM 編碼的 CA 憑證。不支援跨命名空間參照。
validation.wellKnownCACertificates 進階方法:使用自行管理的 TrustConfig 時,請將值設為 System
options GKE 專用選項的地圖。使用 networking.gke.io/backend-trust-config 設定參照外部 TrustConfig 資源。

驗證後端 TLS 設定

套用 BackendTLSPolicy 後,請檢查政策狀態,確認 Gateway 控制器已接受設定:

kubectl describe backendtlspolicy POLICY_NAME

POLICY_NAME 替換為政策名稱。

如果政策包含 AcceptedResolvedRefs 條件,且 Status.Ancestors 區段中含有 Status: "True",即表示政策已成功套用:

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

如果這些條件中有任何一項為 Status,則表示政策尚未套用。如需更多詳細資料,請查看 ReasonMessage 欄位。常見錯誤包括在 caCertificateRefs 中參照不存在的 ConfigMap,或是缺少 ca.crt 鍵。False

這個狀態表示 Gateway 已成功驗證政策,並將 TLS 設定套用至目標服務或 InferencePool 的後端。BackendTLSPolicy 資源必須與目標資源位於相同命名空間。

使用 TLS 保護負載平衡器與應用程式之間的流量

您可以使用 ports[].appProtocol 欄位,加密從負載平衡器到後端 Pod 的流量。appProtocol 支援的欄位包括:HTTPHTTPSHTTP2kubernetes.io/h2c

下列資訊清單說明 Service,其中指定負載平衡器必須使用 HTTPS 流量與後端 Pod 通訊:

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 政策,確保用戶端到負載平衡器的流量安全無虞。

如要進一步瞭解可附加至閘道的 SSL 政策,以及如何建立這些政策,請參閱「設定 SSL 政策,確保用戶端到負載平衡器之間的流量安全無虞」。

使用 Google Cloud Armor 保護後端

Google Cloud Armor 安全性政策可協助您保護負載平衡應用程式,防範網路攻擊。設定 Google Cloud Armor 安全性政策後,您可以在套用至 Kubernetes 服務的 GCPBackendPolicy 中參照該政策。

如要透過 Gateway 設定 Google Cloud Armor 政策,請參閱「設定 Google Cloud Armor 安全性政策,保護後端服務」。

使用 Identity-Aware Proxy 驗證對後端的請求

Identity-Aware Proxy 會驗證傳送應用程式要求的用戶端,並強制執行以角色為準的流量授權,協助您防範後端受到惡意流量攻擊。為 GKE 啟用 Identity-Aware Proxy 後,您可以在套用至 Kubernetes 服務的 GCPBackendPolicy 中參照 OAuth 憑證。

如要透過閘道設定 Identity-Aware Proxy,請參閱「設定 Identity-Aware Proxy」。

後續步驟