保护网关安全

本页面介绍如何使用各种安全功能保护 Gateway:

  • SSL 政策,可帮助确保 Gateway 使用所需的安全协议和算法

  • 证书,可使用 TLS 保护客户端到网关和网关到后端的流量

  • Google Cloud Armor 安全政策,可保护 Service 免受 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 要求

  • VPC 原生集群支持 Gateway API。
  • 如果您使用的是区域级或跨区域 GatewayClass,则必须启用代理专用子网
  • 集群必须启用 HttpLoadBalancing 插件。
  • 如果您使用的是 Istio,则必须将 Istio 升级到以下版本之一:
    • 1.15.2 或更高版本
    • 1.14.5 或更高版本
    • 1.13.9 或更高版本。
  • 如果您使用的是共享 VPC,则需要在宿主项目中将 Compute Network User 角色分配给服务项目的 GKE 服务账号。

  • 确保您已有 Autopilot 或 Standard 集群。如果需要,请创建 Autopilot 集群

限制和局限

关于 Gateway 安全性,除了 GKE Gateway Controller 的限制和局限之外,还存在以下特定限制:

  • GKE 1.28.4-gke.1083000 版不支持在网关上使用 SSL 证书Certificate Manager 的 TLS 配置。请使用 Kubernetes Secret 作为此 GKE 版本的解决方法。

  • 您不能在同一网关资源上将 networking.gke.io/certmap 注释与 tls.certificateRefs 一起使用。如果您在 Gateway 中引用 CertificateMap,GKE 会将其视为错误。

  • Certificate Manager 支持自行管理和 Google 管理的证书。Google 管理的证书与区域级 Gateway 和全球 Gateway 兼容。

  • 使用 Google 管理的 SSL 证书时,您必须先在 GKE 外部创建 SSL 证书,然后才能将其附加到 Gateway。

  • 如果您在 GCPBackendPolicy 中引用 Google Cloud Armor 后端安全政策,则无法将同一服务用作区域级 Gateway 和全球 Gateway 的后端。您必须为此应用场景创建两个单独的服务和政策。

  • Gateway Controller 不支持 ManagedCertificate 资源。

  • Gateway Controller 不支持 networking.gke.io/managed-certificates 注解。

  • 如果您使用 GKE Gateway 配置 Cloud CDN,则无法通过同一 Gateway 同时启用 IAP 和 Cloud CDN,包括通过 Cloud CDN 启用各个路由。如果您需要为使用 GCPHTTPFilter 资源的路由启用 Cloud CDN,则必须先移除为相应网关配置 IAP 的所有现有 GCPBackendPolicy。

  • TrustConfig 配额。如需了解每个位置中所有 TrustConfig 资源的总大小,请参阅资源配额和限制

  • 位置对齐。所引用的 TrustConfig 资源必须与使用该服务的网关位于同一位置(全球或特定区域)。

  • 命名空间限制。BackendTLSPolicy 资源及其目标资源必须位于同一命名空间中。

如需查看 GKE 上提供的 GatewayClass 资源支持的 Gateway API 字段和功能的列表,请参阅 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 Secret:

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

    GKE 会将证书和密钥保存为 Kubernetes 资源,您可以将其附加到 Gateway。

创建 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 Service。

  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 地址,这意味着任何可以访问互联网的客户端都可以连接到该 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 选项会将域名解析为网关的 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 连接在 Gateway 上终止,并且应用会安全地响应客户端。

使用 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.
    

    此清单描述了具有以下属性的 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 可能需要几分钟时间。

验证 Gateway

  1. 获取 Gateway 的 IP 地址:

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

    输出类似于以下内容:

    203.0.113.12
    

    此输出是一个公共 IP 地址,这意味着任何可以访问互联网的客户端都可以连接到该 IP 地址。

  2. 更新 A 或 AAAA 记录,将您的网域定向到 Gateway 的 IP 地址。

    只有在配置 Google 管理的 SSL 证书时才需要执行此步骤。如果要配置自行管理的证书,则可以跳过此步骤。

    更新 DNS 记录后,负载均衡器最多可能需要 10 分钟才能开始使用 Google 管理的证书。

  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 握手和来自应用的响应。TLS 在 Gateway 上正确终止,并且应用会安全地响应客户端。

使用 Certificate Manager 保护 Gateway 安全

在此示例中,您将使用 Certificate Manager 配置 Gateway。

创建 Certificate

全球 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. 创建用于将证书分配给 CertificateMapCertificateMapEntry

    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,您需要创建一个 Certificate,并在创建 Gateway 时直接指定。与全球 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

如需创建全球网关,请完成以下步骤:

  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 部分,因为 TLS 是使用注释 networking.gke.io/certmap 来配置 Certificate Manager 的。

  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:

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

    此清单描述了一个 HTTPRoute,与 store.example.com 的流量匹配并将流量转发到 store-v1 Service。

  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 地址,这意味着任何可以访问互联网的客户端都可以连接到该 IP 地址。

  2. 更新 A 或 AAAA 记录,将您的网域定向到 Gateway 的 IP 地址。

    只有在配置 Google 管理的 SSL 证书时才需要执行此步骤。如果要配置自行管理的证书,则可以跳过此步骤。

    更新 DNS 记录后,负载均衡器最多可能需要 10 分钟才能开始使用 Google 管理的证书。

  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 握手和来自应用的响应。TLS 在 Gateway 上正确终止,并且应用会安全地响应客户端。

为网关配置后端 TLS

借助后端 TLS,GKE Gateway 负载均衡器可以验证其连接到的后端的身份。后端 TLS 在网关与后端 Pod 之间的 TLS 握手期间添加了显式验证步骤。网关充当 TLS 客户端,根据您配置的一组可信证书授权机构 (CA) 验证后端服务器的证书。此验证会在建立新连接时进行,以确保网关仅与受信任的后端通信,从而提高整体安全性。

您可以使用附加到 Service、InferencePool、ServiceImport 或 GCPInferencePoolImport 的 BackendTLSPolicy 资源来配置后端经过身份验证的 TLS。BackendTLSPolicy 必须与目标资源位于同一命名空间中。

以下 GatewayClass 支持后端 TLS:

  • 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(标准)

在此方法中,您直接在 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 位于同一项目和位置。

    • 对于全球多集群 Gateway(包括区域级多集群)和跨区域 Gateway,请使用 global 位置。
    • 对于区域级单集群网关,请使用与网关相同的区域。
    • 如果您的服务由不同位置的多个网关使用,您必须在每个位置创建具有相同名称的 TrustConfig 资源。
  2. 通过 options 字段,使用引用外部 TrustConfig 资源的 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:
        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 握手期间使用的主机名 (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 后,通过检查政策状态来验证网关控制器是否已接受该配置:

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

如果 Status 对于上述任何条件均为 False,则表示相应政策尚未应用。如需了解详情,请查看 ReasonMessage 字段。 常见错误包括引用 caCertificateRefs 中不存在或缺少 ca.crt 键的 ConfigMap

此状态确认网关已成功验证政策,并将 TLS 设置应用于目标服务或 InferencePool 的后端。BackendTLSPolicy 资源必须与目标资源位于同一命名空间中。

使用 TLS 保护负载均衡器到应用的流量

您可以使用 ports[].appProtocol 字段加密从负载均衡器到后端 Pod 的流量。支持的 appProtocol 字段值为:HTTPHTTPSHTTP2kubernetes.io/h2c

以下清单描述了一个指定负载均衡器必须使用 HTTPS 流量与后端 Pod 通信的 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 的外部 Gateway 公开时,请务必使用最新协议或指定最低 SSL 或 TLS 版本。您可以使用 SSL 政策保护客户端到负载均衡器的流量。

如需详细了解可附加到 Gateway 的 SSL 政策以及如何创建这些政策,请参阅配置 SSL 政策以保护客户端到负载均衡器的流量

使用 Google Cloud Armor 保护后端

Google Cloud Armor 安全政策可帮助保护您的负载均衡应用免遭 Web 攻击。配置 Google Cloud Armor 安全政策后,您可以在应用于 Kubernetes Service 的 GCPBackendPolicy 中引用该政策。

如需使用 Gateway 配置 Google Cloud Armor 政策,请参阅配置 Google Cloud Armor 安全政策以保护后端服务

使用 Identity-Aware Proxy 对发送至后端的请求进行身份验证

Identity-Aware Proxy 通过验证向应用发送请求的客户端的身份并强制执行基于角色的流量授权,可帮助您保护后端免受不必要流量的影响。启用 Identity-Aware Proxy for GKE 后,您可以在应用于 Kubernetes Service 的 GCPBackendPolicy 中引用您的 OAuth 凭据。

如需使用 Gateway 配置 Identity-Aware Proxy,请参阅配置 Identity-Aware Proxy

后续步骤