使用 Service Extensions 自定义 GKE Gateway 流量


本页介绍了 Google Kubernetes Engine (GKE) 如何使用服务扩展程序将自定义逻辑添加到 Cloud Load Balancing 中。

本页面适用于需要使用 Service Extensions 配置自定义流量管理逻辑的 GKE Identity 和账号管理员以及开发者。

在阅读本页面之前,请确保您熟悉以下内容:

概览

GKE 使用 Service Extensions 将自定义逻辑添加到 Cloud Load Balancing。扩展程序会附加到 Gateway 并引用 ServiceGoogleAPIServiceNameGoogleAPIServiceName 仅适用于 GCPTrafficExtensions

您可以修改请求和响应的 HTTP 标头和载荷,或控制流量路由,而不会影响后端服务选择或安全政策。您可以使用服务扩展来执行高级流量分流、自定义身份验证或请求日志记录等任务。

GKE Gateway Controller 支持以下服务扩展:

  • GCPRoutingExtension:此扩展程序会向 Cloud Load Balancing 添加自定义逻辑,以控制流量路由。区域级外部应用负载平衡器和区域级内部应用负载平衡器均支持此功能。

    `GCPRoutingExtension` 资源会附加到网关,并引用服务。该扩展程序用于控制流量路由。
    :`GCPRoutingExtension` 如何与网关搭配使用
  • GCPTrafficExtension:此扩展程序会将自定义逻辑插入 Cloud Load Balancing。它可让扩展程序服务更改请求和响应的标头和载荷。GCPTrafficExtension 不会影响后端服务选择或后端服务安全政策。

    `GCPTrafficExtension` 资源会附加到网关,并引用服务或 `GoogleAPIServiceName`。该扩展程序会更改请求和响应的标头和载荷。
    :`GCPTrafficExtension` 如何与网关搭配使用

Google Cloud Service Extension 与 GatewayClass 的兼容性

下表介绍了服务扩展与不同 GatewayClass 的兼容性: Google Cloud

GatewayClass GCPRoutingExtension GCPTrafficExtension
gke-l7-rilb 支持 支持
gke-l7-regional-external-managed 支持 支持
gke-l7-global-external-managed 不支持 支持

准备工作

在开始之前,请确保您已执行以下任务:

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

GKE Gateway Controller 要求

限制和局限

下表列出了与 GKE 中网关服务扩展程序的配置相关的限制:

类别 限制和局限
负载平衡器 只有区域级外部应用负载平衡器和区域级内部应用负载平衡器(gke-l7-regional-external-managedgke-l7-rilb 网关类)支持 GCPRoutingExtensiongke-l7-global-external-managed 网关类不支持 GCPRoutingExtension
扩展程序链和规范
  • 对于 GCPTrafficExtension,每个 ExtensionChain 最多可以有 3 个 Extensions
  • 对于 GCPRoutingExtension,每个 ExtensionChain 最多只能有 1 个 Extension
  • GCPTrafficExtensionSpecGCPRoutingExtensionSpec 各自最多可以有 5 个 ExtensionChains
时间和匹配
  • 扩展程序中数据流中每一条消息的超时时间必须介于 10 毫秒到 1,000 毫秒之间。一秒钟的限制也适用于路线和交通延迟扩展程序。
  • ExtensionChain 中的每个 MatchCondition 最多只能包含 10 个 CELExpressions
  • 发送到 GCE 的生成的 MatchCondition 字符串的字符数上限为 512。
  • CELExpression 中的 CELMatcher 字符串的长度不得超过 512 个字符,并且必须遵循特定模式。我们不支持 CELExpression 中的 BackendRefs 字段。
标头和元数据
  • Extension 中的 ForwardHeaders 列表最多可包含 50 个 HTTP 标头名称。
  • Extension 中的 Metadata 映射最多可以有 16 个属性。
  • Metadata 映射中的键的长度必须介于 1 到 63 个字符之间。
  • Metadata 映射中的值必须介于 1 到 1,023 个字符之间。
事件
  • 对于 GCPRoutingExtension,如果未设置 requestBodySendMode,则 supportedEvents 列表只能包含 RequestHeaders 事件。
  • 对于 GCPRoutingExtension,如果 requestBodySendMode 设置为 FullDuplexStreamed,则 supportedEvents 列表只能包含 RequestHeadersRequestBodyRequestTrailers 事件。
GCPTrafficExtension
  • GCPTrafficExtension 支持 responseBodySendMode 字段。
  • GCPTrafficExtension 支持 googleAPIServiceName 字段。
googleAPIServiceNamebackendRef 在扩展程序中引用使用 backendRef 的服务时,您必须满足以下条件:
  • 必须使用 HTTP2 作为其 appProtocol
  • 必须与扩展程序以及扩展程序引用的网关位于同一命名空间中。
  • 无法使用 IAP
  • 无法使用 Google Cloud Armor 安全政策( GCPBackendPolicyConfig 中的 securityPolicy 字段)。
  • 无法使用 Cloud CDN
  • 必须为 Extension 设置 backendRefgoogleAPIServiceName 中的一个。
  • 如果设置了 backendRef,则必须设置 authority
  • 如果设置了 googleAPIServiceName,则必须设置 authority
  • 仅使用 backendRef 为扩展程序配置 requestBodySendMode
  • 仅使用 backendRef 为扩展程序配置 responseBodySendMode

配置 GKE 服务扩展程序

您可以通过配置 GKE 服务扩展程序来自定义流量路由、修改请求或响应载荷,以及与外部服务集成。网关默认没有服务扩展。

如需配置 GKE 服务扩展程序,请执行以下操作:

  1. 部署网关:如需配置 GKE 服务扩展程序,您必须先部署网关,该网关会将外部流量定向到您的集群。这可以是全球外部应用负载平衡器、区域级外部应用负载平衡器或区域级内部应用负载平衡器网关。

    如需详细了解如何部署网关,请参阅部署网关

  2. 部署后端调用服务:创建一个 Kubernetes 服务,用于表示用于执行自定义逻辑的后端服务。负载均衡器会调用此服务。

  3. 配置服务扩展:根据负载平衡器类型和要求配置适当的服务扩展。

    1. 适用于区域级网关的 GCPRoutingExtension:将此扩展程序用于区域级外部应用负载平衡器和区域级内部应用负载平衡器,以便在区域内实现自定义路由逻辑。

    2. GCPTrafficExtension(适用于全球外部网关、区域级外部网关和内部网关):将此扩展程序用于全球外部应用载荷均衡器、区域级外部应用载荷均衡器和区域级内部应用载荷均衡器,以便在各种载荷均衡器类型上执行流量操作,例如标头修改或载荷检查。

部署后端致电服务

标注服务会在 GKE 中为网关服务扩展程序实现自定义逻辑。网关会根据 GCPTrafficExtensionGCPRoutingExtension 配置调用这些后端应用,以修改或路由流量。

您可以部署标注服务,以向网关添加自定义逻辑。此单独的服务会处理自定义处理,例如标头操作、载荷转换或流量路由。

如需部署可用作网关的宣传信息的后端服务,请执行以下步骤:

  1. (可选)为 TLS 创建 Secret:此命令会创建一个类型为 TLS 的 Kubernetes Secret,其中包含您的 TLS 证书和私钥。

    如需为您的致电服务创建 TLS Secret,请替换以下内容:

    • SECRET_NAME:宣传信息服务的 Secret 名称
    • path-to-cert:证书的文件路径
    • path-to-key:密钥的文件路径
  2. 如需验证是否已添加 Secret,请运行以下命令:

    kubectl get secrets SECRET_NAME
    

    SECRET_NAME 替换为您的宣传信息服务的 Secret 名称。

    输出应类似如下所示:

    NAME            TYPE                DATA   AGE
    SECRET_NAME     kubernetes.io/tls   2      12s
    
  3. 定义 Deployment 和 Service 资源。

    您必须定义以下内容:

    • 部署:用于管理包含服务扩展程序的自定义逻辑的应用 pod。
    • Service:将由部署管理的应用 pod 公开为网络服务。
    1. 创建包含部署和服务定义的示例清单 extension-service-app.yaml

      apiVersion: apps/v1
      kind: Deployment
      metadata:
      name: extension-service-app
      spec:
      selector:
          matchLabels:
            app: store
        replicas: 1
        template:
          metadata:
            labels:
              app: store
          spec:
            containers:
            - name: serviceextensions
              image: us-docker.pkg.dev/service-extensions-samples/callouts/python-example-basic:main
              ports:
              - containerPort: 8080
              - containerPort: 443
              volumeMounts:
              - name: certs
                mountPath: "/etc/certs/"
                readOnly: true
              env:
              - name: POD_NAME
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.name
              - name: NAMESPACE
                valueFrom:
                  fieldRef:
                    fieldPath: metadata.namespace
              - name: TLS_SERVER_CERT
                value: "/etc/certs/path-to-cert"
              - name: TLS_SERVER_PRIVKEY
                value: "/etc/certs/path-to-key"
                resources:
                requests:
                  cpu: 10m
            volumes:
            - name: certs
              secret:
                secretName: SECRET_NAME
                optional: false
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: extension-service
      spec:
        ports:
        - port: 443
          targetPort: 443
          appProtocol: HTTP2
        selector:
          app: store
      
    2. 应用 extension-service-app.yaml 清单:

      kubectl apply -f extension-service-app.yaml
      
  4. 验证配置:

    1. 验证应用是否已部署:

      kubectl get pod --selector app=store
      

      应用开始运行后,输出类似于以下内容:

      NAME                                     READY   STATUS    RESTARTS   AGE
      extension-service-app-85f466bc9b-b5mf4   1/1     Running   0          7s
      
    2. 验证 Service 是否已部署:

      kubectl get service extension-service
      

      输出类似于以下内容,其中显示了每个商店部署的 Service:

      NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
      extension-service   ClusterIP   34.118.225.9   <none>        443/TCP   2m40s
      

配置服务扩展程序

您可以配置 GCPRoutingExtensionGCPTrafficExtension 来自定义流量流。

为区域级网关配置 GCPRoutingExtension

您可以使用 GCPRoutingExtension 来重定向流量。如需配置 GCPRoutingExtension,请更新 HTTPRoute 以指定 service-extensions.com 主机的请求。

  1. 更新 HTTPRoute。修改 HTTPRoute 以添加将触发路由扩展程序的主机名或路径。

    1. 将以下示例清单保存为 store-route.yaml 文件:

      kind: HTTPRoute
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: store
      spec:
        parentRefs:
        - kind: Gateway
          name:GATEWAY_NAME
        hostnames:
        - "store.example.com"
        - "service-extensions.example.com"
        rules:
        - backendRefs:
          - name: store-v1
            port: 8080
        - matches:
          - headers:
            - name: env
              value: canary
          backendRefs:
          - name: store-v2
            port: 8080
        - matches:
          - path:
              value: /de
          backendRefs:
          - name: store-german
            port: 8080
      

      GATEWAY_NAME 替换为网关的名称。

    2. 应用 store-route.yaml 清单:

      kubectl apply -f store-route.yaml
      
  2. 定义 GCPRoutingExtension

    1. GCPRoutingExtension 配置保存在示例 gcp-routing-extension.yaml 文件中:

      kind: GCPRoutingExtension
      apiVersion: networking.gke.io/v1
      metadata:
        name: my-gateway-extension
        namespace: default
      spec:
        targetRefs:
        - group: "gateway.networking.k8s.io"
          kind: Gateway
          name: GATEWAY_NAME
        extensionChains:
        - name: chain1
          matchCondition:
            celExpressions:
            - celMatcher: request.path.contains("serviceextensions")
          extensions:
          - name: ext1
            authority: "myext.com"
            timeout: 1s
              backendRef:
                group: ""
              kind: Service
              name: extension-service
              port: 443
      

      GATEWAY_NAME 替换为网关的名称。

    2. 将示例清单应用到您的集群:

      kubectl apply -f gcp-routing-extension.yaml
      
  3. 验证 GCPRoutingExtension 的配置及其与网关的绑定。

    1. 检查 GCPRoutingExtension 部署:

      kubectl describe gcproutingextension my-gateway-extension
      

      输出类似于以下内容:

      Name:         my-gateway-extension
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPRoutingExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:        1
        Resource Version:  31283253
        UID:               ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Authority:    myext.com
            Backend Ref:
              Group:
              Kind: Service
              Name: extension-service
              Port: 443
            Name:       ext1
            Timeout:    1s
          Match Condition:
            Cel Expressions:
              Cel Matcher: request.path.contains("serviceextensions")
          Name:  chain1
        Target Refs:
          Group: gateway.networking.k8s.io
          Kind: Gateway
          Name: GATEWAY_NAME
      Events:  <none>
      

      输出结果会显示默认命名空间中名为 my-gateway-extensionGCPRoutingExtension 的详细信息。输出显示了 Spec 字段,其中包含扩展程序应如何运行的定义。

    2. 验证网关绑定:

      1. 确认 GCPRoutingExtension 已绑定到网关。这可能需要几分钟时间:

        kubectl describe gateway GATEWAY_NAME
        

        输出类似于以下内容:

        Name:         GATEWAY_NAME
        Namespace:    default
        Labels:       none
        Annotations:  networking.gke.io/addresses: /projects/1234567890/regions/us-central1/addresses/test-hgbk-default-internal-http-5ypwen3x2gcr
                      networking.gke.io/backend-services:
                        /projects/1234567890/regions/us-central1/backendServices/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/re...
                      networking.gke.io/firewalls: /projects/1234567890/global/firewalls/test-hgbk-l7-default-us-central1
                      networking.gke.io/forwarding-rules: /projects/1234567890/regions/us-central1/forwardingRules/test-hgbk-default-internal-http-qn7dk9i9zm73
                      networking.gke.io/health-checks:
                        /projects/1234567890/regions/us-central1/healthChecks/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/regio...
                      networking.gke.io/last-reconcile-time: 2025-03-02T17:15:02Z
                      networking.gke.io/lb-route-extensions:
                        /projects/1234567890/locations/us-central1/lbRouteExtensions/test-hgbk-default-internal-http-lwh0op4qorb0
                      networking.gke.io/lb-traffic-extensions:
                      networking.gke.io/ssl-certificates:
                      networking.gke.io/target-http-proxies:
                        /projects/1234567890/regions/us-central1/targetHttpProxies/test-hgbk-default-internal-http-2jzr7e3xclhj
                      networking.gke.io/target-https-proxies:
                      networking.gke.io/url-maps: /projects/1234567890/regions/us-central1/urlMaps/test-hgbk-default-internal-http-2jzr7e3xclhj
        API Version:  gateway.networking.k8s.io/v1
        Kind:         Gateway
        Metadata:
          Creation Timestamp:  2025-03-02T16:37:50Z
          Finalizers:
          gateway.finalizer.networking.gke.io
          Generation:        1
          Resource Version:  31284863
          UID:               fd512611-bad2-438e-abfd-5619474fbf31
        ...
        

        输出显示了注解,GKE 使用这些注解存储网关与底层Google Cloud 资源之间的链接。networking.gke.io/lb-route-extensions 注解确认了网关与 GCPRoutingExtension 的绑定。

      2. 确认 GCPRoutingExtension 的状态为 Reconciled,原因为 ReconciliationSucceeded,以检查扩展程序状态。此命令可能需要几分钟时间。

        kubectl describe gcproutingextension my-gateway-extension
        

        输出类似于以下内容:

        Name:         my-gateway-extension
        Namespace:    default
        Labels:       <none>
        Annotations:  <none>
        API Version:  networking.gke.io/v1
        Kind:         GCPRoutingExtension
        Metadata:
          Creation Timestamp:  2025-03-02T17:12:30Z
          Generation:          1
          Resource Version:    31284378
          UID:                 ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
        Spec:
          Extension Chains:
            Extensions:
              Authority:  myext.com
              Backend Ref:
                Group:
                Kind:   Service
                Name:   extension-service
                Port:   443
              Name:     ext1
              Timeout:  1s
            Match Condition:
              Cel Expressions:
                Cel Matcher:  request.path.contains("serviceextensions")
            Name:             chain1
          Target Refs:
            Group:  gateway.networking.k8s.io
            Kind:   Gateway
            Name:   GATEWAY_NAME
        Status:
          Ancestors:
            Ancestor Ref:
              Group:      gateway.networking.k8s.io
              Kind:       Gateway
              Name:       GATEWAY_NAME
              Namespace:  default
            Conditions:
              Last Transition Time:  2025-03-02T17:14:15Z
              Message:
              Reason:                Accepted
              Status:                True
              Type:                  Accepted
              Last Transition Time:  2025-03-02T17:14:15Z
              Message:
              Reason:                ReconciliationSucceeded
              Status:                True
              Type:                  Reconciled
            Controller Name:         networking.gke.io/gateway
        Events:
          Type    Reason  Age                From                   Message
          ----    ------  ----               ----                   -------
          Normal  ADD     2m31s              sc-gateway-controller  default/my-gateway-extension
        Normal  SYNC    51s (x2 over 98s)  sc-gateway-controller  Attachment of GCPRoutingExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
          Normal  SYNC    23s           sc-gateway-controller  Reconciliation of GCPRoutingExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
        

        Status.Conditions 字段显示包含 Status: TrueReason: ReconciliationSucceededReconciled 条件。

        正确且原因:ReconciliationSucceeded。此信息确认延期已成功应用。

  4. 将流量发送到您的应用。

    网关、路由和应用在集群中部署完毕后,您可以将流量传递到您的应用。

    1. 如需访问您的应用,您需要找到网关的 IP 地址。

      在终端中,使用以下命令:

      kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
      

      GATEWAY_NAME 替换为网关的名称。

      此命令会输出网关的 IP 地址。在后续命令中,将 GATEWAY_IP_ADDRESS 替换为输出中的 IP 地址。

    2. 转到 store.example.com/serviceextensions 中的 serviceextensions 版商店服务,测试路径更新:

      curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
      

      输出类似于以下内容:

      {
      "cluster_name": "gke1",
      "host_header": "service-extensions.com",
      "metadata": "store-v1",
      "pod_name": "store-v1-5d9554f847-cvxpd",
      "pod_name_emoji": "💇🏼‍♀️",
      "project_id": "gateway-demo",
      "timestamp": "2025-03-15T12:00:00",
      "zone": "us-central1-c"
      }
      

配置 GCPTrafficExtension

您可以使用 GCPTrafficExtension 在 Google Cloud 环境中使用高级流量管理功能。您可以在全球外部应用负载平衡器、区域外部应用负载平衡器和区域级内部应用负载平衡器中配置此扩展程序。您可以使用 GCPTrafficExtension 实现自定义请求和响应逻辑、复杂的路由、转换和安全政策。

  1. 更新 HTTPRoute。修改您的 HTTPRoute,以添加将触发流量延长的主机名或路径。

    1. 将以下示例清单保存为 store-route.yaml 文件:

      kind: HTTPRoute
      apiVersion: gateway.networking.k8s.io/v1
      metadata:
        name: store
      spec:
        parentRefs:
        - kind: Gateway
          name: GATEWAY_NAME
        hostnames:
        - "store.example.com"
        - "service-extensions.example.com"
        rules:
        - backendRefs:
          - name: store-v1
            port: 8080
        - matches:
          - headers:
            - name: env
              value: canary
          backendRefs:
          - name: store-v2
            port: 8080
        - matches:
          - path:
              value: /de
          backendRefs:
          - name: store-german
            port: 8080
      

      GATEWAY_NAME 替换为网关的名称,例如 internal-httpexternal-httpglobal-external-http

    2. store-route.yaml 清单应用到您的集群:

      kubectl apply -f store-route.yaml
      
  2. 定义 GCPTrafficExtension

    1. GCPTrafficExtension 配置保存到示例 gcp-traffic-extension.yaml 文件中:

      kind: GCPTrafficExtension
      apiVersion: networking.gke.io/v1
      metadata:
        name: my-traffic-extension
        namespace: default
      spec:
        targetRefs:
        - group: "gateway.networking.k8s.io"
          kind: Gateway
          name: GATEWAY_NAME
        extensionChains:
        - name: chain1
          matchCondition:
            celExpressions:
            - celMatcher: request.path.contains("serviceextensions")
          extensions:
          - name: ext1
            authority: "myext.com"
            timeout: 1s
            backendRef:
              group: ""
              kind: Service
              name: extension-service
              port: 443
      

      GATEWAY_NAME 替换为网关的名称,例如 internal-httpexternal-httpglobal-external-http

    2. 将示例清单应用到您的集群:

      kubectl apply -f gcp-traffic-extension.yaml
      
  3. 验证 GCPTrafficExtension 的配置及其与网关的绑定。

    1. 检查 GCPTrafficExtension 部署:

      kubectl describe gcptrafficextension my-traffic-extension
      

      输出类似于以下内容:

      Name:         my-traffic-extension
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPTrafficExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:        1
        Resource Version:  31283253
        UID:               ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Authority:    myext.com
            Backend Ref:
              Group:
              Kind: Service
              Name: extension-service
              Port: 443
            Name:       ext1
            Timeout:    1s
          Match Condition:
            Cel Expressions:
              Cel Matcher: request.path.contains("serviceextensions")
          Name:  chain1
        Target Refs:
          Group: gateway.networking.k8s.io
          Kind: Gateway
          Name: GATEWAY_NAME
      Events:  <none>
      

      输出结果会显示默认命名空间中名为 my-traffic-extensionGCPTrafficExtension 的详细信息。它会显示 Spec 字段,其中包含扩展程序应如何运行的定义。

    2. 验证网关绑定:

      确认 GCPTrafficExtension 已绑定到网关。此命令可能需要几分钟才能完成:

      kubectl describe gateway GATEWAY_NAME
      

      输出类似于以下内容:

      Name:         GATEWAY_NAME
      Namespace:    default
      Labels:       <none>
      Annotations:  networking.gke.io/addresses: /projects/1234567890/regions/us-central1/addresses/test-hgbk-default-internal-http-5ypwen3x2gcr
                    networking.gke.io/backend-services:
                      /projects/1234567890/regions/us-central1/backendServices/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/re...
                    networking.gke.io/firewalls: /projects/1234567890/global/firewalls/test-hgbk-l7-default-us-central1
                    networking.gke.io/forwarding-rules: /projects/1234567890/regions/us-central1/forwardingRules/test-hgbk-default-internal-http-qn7dk9i9zm73
                    networking.gke.io/health-checks:
                      /projects/1234567890/regions/us-central1/healthChecks/test-hgbk-default-extension-service-443-rduk21fwhoj0, /projects/1234567890/regio...
                    networking.gke.io/last-reconcile-time: 2025-03-02T17:15:02Z
                    networking.gke.io/lb-traffic-extensions:
                      /projects/1234567890/locations/us-central1/lbTrafficExtensions/test-hgbk-default-internal-http-lwh0op4qorb0
                    networking.gke.io/ssl-certificates:
                    networking.gke.io/target-http-proxies:
                      /projects/1234567890/regions/us-central1/targetHttpProxies/test-hgbk-default-internal-http-2jzr7e3xclhj
                    networking.gke.io/target-https-proxies:
                    networking.gke.io/url-maps: /projects/1234567890/regions/us-central1/urlMaps/test-hgbk-default-internal-http-2jzr7e3xclhj
      API Version:  gateway.networking.k8s.io/v1
      Kind:         Gateway
      Metadata:
        Creation Timestamp:  2025-03-02T16:37:50Z
        Finalizers:
          gateway.finalizer.networking.gke.io
        Generation:        1
        Resource Version:  31284863
        UID:               fd512611-bad2-438e-abfd-5619474fbf31
      ...
      

      输出显示了注解,GKE 使用这些注解来存储网关与底层资源之间的链接。 Google Cloud networking.gke.io/lb-traffic-extensions 注解确认了绑定。

    3. 检查扩展程序状态:

      确认 GCPTrafficExtension 的状态为 Reconciled,原因为 ReconciliationSucceeded。此命令可能需要几分钟时间才能完成。

      kubectl describe gcptrafficextension my-traffic-extension
      

      输出类似于以下内容:

      Name:         my-traffic-extension
      Namespace:    default
      Labels:       <none>
      Annotations:  <none>
      API Version:  networking.gke.io/v1
      Kind:         GCPTrafficExtension
      Metadata:
        Creation Timestamp:  2025-03-02T17:12:30Z
        Generation:          1
        Resource Version:    31284378
        UID:                 ec8efaa0-d8e7-4e1b-9fd4-0ae0ef3c74d0
      Spec:
        Extension Chains:
          Extensions:
            Authority:  myext.com
            Backend Ref:
              Group:
              Kind:   Service
              Name:   extension-service
              Port:   443
            Name:     ext1
            Timeout:  1s
          Match Condition:
            Cel Expressions:
              Cel Matcher:  request.path.contains("serviceextensions")
          Name:             chain1
        Target Refs:
          Group:  gateway.networking.k8s.io
          Kind:   Gateway
          Name:   GATEWAY_NAME
      Status:
        Ancestors:
          Ancestor Ref:
            Group:      gateway.networking.k8s.io
            Kind:       Gateway
            Name:       GATEWAY_NAME
            Namespace:  default
          Conditions:
            Last Transition Time:  2025-03-02T17:14:15Z
            Message:
            Reason:                Accepted
            Status:                True
            Type:                  Accepted
            Last Transition Time:  2025-03-02T17:14:15Z
            Message:
            Reason:                ReconciliationSucceeded
            Status:                True
            Type:                  Reconciled
          Controller Name:         networking.gke.io/gateway
      Events:
        Type    Reason  Age                From                   Message
        ----    ------  ----               ----                   -------
        Normal  ADD     2m31s              sc-gateway-controller  default/my-traffic-extension
        Normal  SYNC    51s (x2 over 98s)  sc-gateway-controller  Attachment of GCPTrafficExtension "default/my-gateway-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
        Normal  SYNC    23s           sc-gateway-controller  Reconciliation of GCPTrafficExtension "default/my-traffic-extension" to AncestorRef {Group:       "gateway.networking.k8s.io",
        Kind:        "Gateway",
        Namespace:   "default",
        Name:        "GATEWAY_NAME",
        SectionName: nil,
        Port:        nil} was a success
      

      Status.Conditions 字段显示包含 Status: TrueReason: ReconciliationSucceededReconciled 条件。此信息确认延期已成功应用。

  4. 将流量发送到您的应用。

    网关、路由和应用在集群中部署完毕后,您可以将流量传递到您的应用。

    1. 如需访问您的应用,您需要找到网关的 IP 地址。

      在终端中,使用以下命令:

      kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
      

      GATEWAY_NAME 替换为网关的名称。

      此命令会输出网关的 IP 地址。在后续命令中,将 GATEWAY_IP_ADDRESS 替换为输出中的 IP 地址。

    2. 转到 store.example.com/serviceextensions 中的 serviceextensions 版商店服务,测试路径更新:

      curl http://store.example.com/serviceextensions --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v
      

      输出类似于以下内容:

      {
      *   Request completely sent off
      < HTTP/1.1 200 OK
      < server: Werkzeug/2.3.7 Python/3.11.3
      < date: Sun, 02 Mar 2025 16:58:10 GMT
      < content-type: application/json
      < access-control-allow-origin: *
      < hello: service-extensions
      < via: 1.1 google
      < transfer-encoding: chunked
      }
      

排查网关上的流量扩展问题

本部分提供有关在网关上配置流量扩展的问题排查提示。

找不到网关

以下错误表示 GCPTrafficExtensionGCPRoutingExtension 资源的 targetRefs 字段中指定的网关资源不存在:

error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.gatewayRef: gateway "my-gateway" not found in namespace "default"

如需解决此问题,请确保在 GCPTrafficExtensionGCPRoutingExtension 资源的 targetRefs 字段中指定的网关资源在指定命名空间中存在。

找不到服务或服务端口

以下错误表示 GCPTrafficExtensionGCPRoutingExtension 资源的 backendRef 字段中指定的 Service 或 Service 端口不存在:

error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.service: service "callout-service" not found in namespace "default"

如需解决此问题,请确保在 GCPTrafficExtensionGCPRoutingExtension 资源的 backendRef 字段中指定的 Service 和 Service 端口存在于指定的命名空间中。

NEG 中没有网络端点

以下错误表示 NEG 中没有与 GCPTrafficExtensionGCPRoutingExtension 资源的 backendRef 字段中指定的服务相关联的网络端点:

error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.service: no network endpoints found for service "callout-service"

如需解决此问题,请确保在 GCPTrafficExtensionGCPRoutingExtension 资源的 backendRef 字段中指定的 Service 具有网络端点。

发送请求时没有回复或回复时出错

如果您未收到回复,或者在发送请求时收到包含错误的回复,则可能表示宣传信息服务无法正常运行。

如需解决此问题,请检查宣传信息服务的日志,看看是否有任何错误。

JSON 载荷中显示错误代码 404

以下错误表示未找到宣传信息服务或服务未响应请求:

{
  "error": {
    "code": 404,
    "message": "Requested entity was not found.",
    "status": "NOT_FOUND"
  }
}

如需解决此问题,请确保通话服务正在运行,正在监听正确的端口,并且在 GCPTrafficExtensionGCPRoutingExtension 资源中正确配置了该服务。

JSON 载荷中显示错误代码 500

以下错误表示宣传信息服务出现内部服务器错误:

{
  "error": {
    "code": 500,
    "message": "Internal server error.",
    "status": "INTERNAL"
  }
}

如需解决此问题,请检查致电服务的日志,找出内部服务器错误的原因。

后续步骤