本页面介绍了 Google Kubernetes Engine (GKE) 如何使用 Service Extensions 将自定义逻辑添加到 Cloud Load Balancing。
本页面适用于需要使用 Service Extensions 配置自定义流量管理逻辑的 GKE 身份和账号管理员及开发者。
在阅读本页面之前,请确保您熟悉以下内容:
概览
GKE 使用 Service Extensions 将自定义逻辑添加到 Cloud Load Balancing。您可以使用 Service Extensions 执行高级流量分配、自定义身份验证或请求日志记录等任务。
GKE Gateway Controller 支持以下 Service Extensions:
GCPRoutingExtension
:此扩展程序可将自定义逻辑添加到 Cloud Load Balancing,以控制流量路由。GCPTrafficExtension
:此扩展程序可将自定义逻辑插入到 Cloud Load Balancing,以修改流量。此逻辑在选择服务后应用于流量。负载均衡器可以添加或更改 HTTP 请求和响应的标头和载荷。GCPTrafficExtension
不会影响服务选择或服务安全政策。
扩展程序会附加到网关,并引用 Service
、GCPWasmPlugin
或 googleAPIServiceName
。
引用服务:在此模型中,您将自定义逻辑部署为单独的后端应用,并将其公开为 Kubernetes 服务。负载平衡器会对此服务进行调用,以处理流量。此方法用途广泛,可让您实现自定义路由逻辑或执行流量操纵,例如标头修改或载荷检查。您可以使用
GCPRoutingExtension
或GCPTrafficExtension
引用服务。引用
GCPWasmPlugin
资源:对于高性能使用情形,您可以使用 WebAssembly (Wasm) 模块将自定义的用户编写逻辑直接注入到Google Cloud 负载均衡器的数据路径中。您可以定义一个GCPWasmPlugin
资源,该资源指向 Artifact Registry 中 Wasm 模块的映像。此方法仅与GCPTrafficExtension
和全球外部应用负载平衡器搭配使用。引用 Google API 服务:您还可以使用
GCPTrafficExtension
中的googleAPIServiceName
字段直接引用 Google API 服务。
在下图中,GCPRoutingExtension
资源附加到网关并引用多项服务。此扩展程序可控制流向服务的流量路由。
在下图中,GCPTrafficExtension
资源会附加到网关并引用服务、GoogleAPIServiceName
或 GCPWasmPlugin
。扩展程序会更改请求和响应的标头和载荷。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行
gcloud components update
命令以获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
根据需要启用 Compute Engine API、Network Services API 和 Model Armor API。
前往启用对 API 的访问,然后按照说明操作。
如需详细了解 Google Cloud Service Extensions 的价格,请参阅价格。
在 Service Extensions 访问权限控制中查看所需的角色和权限。
熟悉 Service Extensions 配额中的配额和限制。
如果您打算使用通用表达式语言 (CEL) 匹配器,请查看 CEL 匹配器语言参考文档中支持的属性和运算符。
查看 Service Extensions 的限制和局限。
GKE Gateway Controller 要求
- 您的集群必须使用 GKE 1.33 版或更高版本。
- 如需使用
GCPWasmPlugin
,您的集群必须使用 GKE 1.33.3 版或更高版本。 - 集群必须已启用 Gateway API。
- 您必须已配置网关资源。此资源可以是全球外部应用负载平衡器、区域级外部应用负载平衡器或区域级内部应用负载平衡器网关。如果您使用
GCPWasmPlugin
资源,则必须仅部署全球外部应用负载平衡器网关。 - 您必须具有已配置的 HTTPRoute 资源。
限制和局限
下表列出了与 GKE 中网关 Service Extensions 的配置关联的限制:
类别 | 限制和局限 |
---|---|
负载均衡器 |
以下负载平衡器支持 GCPRoutingExtension :
GCPTrafficExtension :
|
扩展程序链和规范 |
|
时间安排和匹配 |
|
标头和元数据 |
|
事件 |
|
GCPTrafficExtension |
|
GCPWasmPlugin |
|
googleAPIServiceName 和 backendRef |
在扩展程序中引用使用 backendRef 的服务时,您必须满足以下条件:
|
引用服务
在 Service Extensions 中,您可以引用托管自定义逻辑的服务,并让负载均衡器执行该逻辑。默认情况下,网关没有 Service Extensions。
如需配置 GKE Service Extensions,请按以下步骤操作:
部署后端调用服务:创建 Kubernetes 服务,用于表示执行自定义逻辑的后端服务。负载均衡器会调用此服务。
配置服务扩展程序:根据负载均衡器类型使用相应的扩展程序。
适用于区域级网关的
GCPRoutingExtension
:将此扩展程序用于区域级外部应用负载平衡器和区域级内部应用负载平衡器,以在区域内实现自定义路由逻辑。适用于全球外部网关、区域级外部网关和内部网关的
GCPTrafficExtension
:将此扩展程序用于全球外部应用载荷均衡器、区域级外部应用载荷均衡器和区域级内部应用载荷均衡器,以跨各种载荷均衡器类型执行流量操控,例如标头修改或载荷检查。
部署后端调用服务
调用服务可在 GKE 中实现网关 Service Extensions 的自定义逻辑。网关会根据 GCPTrafficExtension
或 GCPRoutingExtension
配置调用这些后端应用,以修改或路由流量。
您可以部署调用服务,以向网关添加自定义逻辑。此独立服务可处理自定义处理,例如标头操纵、载荷转换或流量路由。
如需部署可作为网关调用的服务,请执行以下步骤:
(可选)为 TLS 创建 Secret:此命令会创建一个 TLS 类型的 Kubernetes Secret,其中包含您的 TLS 证书和私钥。
如需为调用服务创建 TLS Secret,请替换以下内容:
SECRET_NAME
:您的调用服务的 Secret 名称path-to-cert
:您的证书的文件路径path-to-key
:您的密钥的文件路径
如需验证是否已添加 Secret,请运行以下命令:
kubectl get secrets SECRET_NAME
将
SECRET_NAME
替换为调用服务的 Secret 名称。输出应类似如下所示:
NAME TYPE DATA AGE SECRET_NAME kubernetes.io/tls 2 12s
定义 Deployment 和 Service 资源。
您必须定义以下内容:
- Deployment:用于管理包含 Service Extensions 自定义逻辑的应用 Pod。
- 服务:用于将由 Deployment 管理的应用 Pod 公开为网络服务。
创建包含 Deployment 和 Service 定义的示例清单
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
应用
extension-service-app.yaml
清单:kubectl apply -f extension-service-app.yaml
验证配置:
验证是否已部署应用:
kubectl get pod --selector app=store
应用开始运行后,输出类似于以下内容:
NAME READY STATUS RESTARTS AGE extension-service-app-85f466bc9b-b5mf4 1/1 Running 0 7s
验证是否已部署 Service:
kubectl get service extension-service
输出类似于以下内容,其中显示了每个存储区 Deployment 的 Service:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE extension-service ClusterIP 34.118.225.9 <none> 443/TCP 2m40s
配置 Service Extensions
您可以配置 GCPRoutingExtension
或 GCPTrafficExtension
来自定义流量。
为区域级网关配置 GCPRoutingExtension
您可以使用 GCPRoutingExtension
重新路由流量。如需配置 GCPRoutingExtension
,请更新 HTTPRoute 以指定 service-extensions.com
主机的请求。
更新 HTTPRoute。修改 HTTPRoute 以包含将触发路由扩展程序的主机名或路径。
将以下示例清单保存为
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
替换为您的网关名称。应用
store-route.yaml
清单:kubectl apply -f store-route.yaml
定义
GCPRoutingExtension
。将
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
替换为您的网关名称。将示例清单应用到您的集群:
kubectl apply -f gcp-routing-extension.yaml
验证
GCPRoutingExtension
的配置及其与网关的绑定。检查
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-extension
的GCPRoutingExtension
的详细信息。输出显示了Spec
字段,其中包含扩展程序的行为方式定义。验证网关绑定:
确认
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
的绑定。通过确认
GCPRoutingExtension
具有Programmed
状态和ProgrammingSucceeded
原因来检查扩展程序状态。此命令可能需要几分钟时间。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: ProgrammingSucceeded Status: True Type: Programmed 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: True
和Reason: ProgrammingSucceeded
的Programmed
条件。此信息确认已成功应用扩展程序。
将流量发送到应用。
在集群中部署网关、路由和应用后,您可以将流量传递到您的应用。
如需访问您的应用,您需要查找网关的 IP 地址。
在终端中,使用以下命令:
kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
将
GATEWAY_NAME
替换为您的网关名称。此命令会输出网关的 IP 地址。在后续命令中,将
GATEWAY_IP_ADDRESS
替换为输出中的 IP 地址。通过前往位于
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
实施自定义 HTTP 请求和响应逻辑、复杂的路由、转换和安全政策。
更新 HTTPRoute。修改 HTTPRoute 以包含将触发流量扩展程序的主机名或路径。
将以下示例清单保存为
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-http
、external-http
或global-external-http
。将
store-route.yaml
清单应用到您的集群:kubectl apply -f store-route.yaml
定义
GCPTrafficExtension
。将
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-http
、external-http
或global-external-http
。将示例清单应用到您的集群:
kubectl apply -f gcp-traffic-extension.yaml
验证
GCPTrafficExtension
的配置及其与网关的绑定。检查
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-extension
的GCPTrafficExtension
的详细信息。它显示了Spec
字段,其中包含扩展程序的行为方式定义。验证网关绑定:
确认
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
注解会确认绑定。检查扩展程序状态:
确认
GCPTrafficExtension
具有Programmed
状态和ProgrammingSucceeded
原因。此命令可能需要几分钟时间才能完成。如需检查
GCPTrafficExtension
的扩展程序状态,请运行以下命令:kubectl describe gcptrafficextension my-traffic-extension
GCPTrafficExtension
资源输出类似于以下内容: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: ProgrammingSucceeded Status: True Type: Programmed 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: True
和Reason: ProgrammingSucceeded
的Programmed
条件。此信息确认已成功应用扩展程序。
将流量发送到应用。
在集群中部署网关、路由和应用后,您可以将流量传递到您的应用。
如需访问您的应用,您需要查找网关的 IP 地址。
在终端中,使用以下命令:
kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
将
GATEWAY_NAME
替换为您的网关名称。此命令会输出网关的 IP 地址。在后续命令中,将
GATEWAY_IP_ADDRESS
替换为输出中的 IP 地址。通过前往位于
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 }
引用 GCPWasmPlugin
资源
您可以使用包含 GCPTrafficExtension
的 GCPWasmPlugin
将自定义逻辑直接注入负载均衡器的数据路径中。此方法可让您部署打包为 Wasm 模块的自定义流量管理功能。
如需配置 GKE Service Extensions,请按以下步骤操作:
部署
GCPWasmPlugin
:创建并部署包含 Wasm 模块自定义代码的GCPWasmPlugin
自定义资源定义 (CRD)。您只能将GCPWasmPlugin
与gke-l7-global-external-managed
GatewayClass 的GCPTrafficExtension
搭配使用。配置 Service Extensions:为全球外部应用负载平衡器使用
GCPTrafficExtension
。
部署 GCPWasmPlugin
借助 GCPWasmPlugin
,您可以将自定义的用户编写的逻辑直接注入 Google Cloud 负载均衡器的数据路径中。GCPWasmPlugin
资源指向 Artifact Registry 中的 Wasm 模块映像,然后由负载均衡器执行该映像。
在继续执行以下步骤之前,请确保您已将 Wasm 模块上传到 Artifact Registry 代码库。如需了解详情,请参阅准备插件代码。
如需部署 GCPWasmPlugin
资源,请完成以下步骤:
将以下清单保存为
wasm-plugin.yaml
:kind: GCPWasmPlugin apiVersion: networking.gke.io/v1 metadata: name: gcp-wasm-plugin spec: versions: - name: wasm-plugin-version description: "Test wasm plugin version" image: "us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main" weight: 1000000 logConfig: enabled: true # Configures the sampling rate of activity logs. # The value of the field must be in range [0, 1e6]. sampleRate: 1000000 # Specifies the lowest level of logs that are exported to Cloud Logging. minLogLevel: INFO
请注意以下几点:
spec.versions.name
:版本名称在GCPWasmPlugin
资源中必须是唯一的。您最多可以列出 10 个版本,但只能有一个版本的权重不为零。spec.versions.image
:引用存储在 Artifact Registry 中的包含插件代码的映像。spec.versions.weight
:指定插件版本的权重。权重必须是介于 0 到 1,000,000 之间的数字(含边界值)。spec.logConfig
:指定是否为此插件启用 Cloud Logging。如果未指定值,则默认情况下会停用 Cloud Logging。spec.logConfig.sampleRate
:配置活动日志的采样率。该比率必须是介于 0 到 1,000,000 之间的数字(含边界值)。如果启用 Cloud Logging 时未指定,则默认值为1,000,000
(记录 100% 的请求)。spec.logConfig.minLogLevel
:指定导出到 Cloud Logging 的最低日志级别。如果在启用 Cloud Logging 时未指定该值,则该字段默认设置为INFO
。
应用
wasm-plugin.yaml
清单:kubectl apply -f wasm-plugin.yaml
验证插件是否已部署:
kubectl describe gcpwasmplugins.networking.gke.io gcp-wasm-plugin
输出类似于以下内容:
Name: gcp-wasm-plugin Namespace: default Labels: <none> Annotations: <none> API Version: networking.gke.io/v1 Kind: GCPWasmPlugin Metadata: Creation Timestamp: 2025-08-08T19:54:18Z Generation: 1 Resource Version: 44578 UID: 549a12c7-91d1-43ad-a406-d6157a799b79 Spec: Log Config: Enabled: true Min Log Level: INFO Sample Rate: 1000000 Versions: Description: Test wasm plugin version Image: us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main Name: wasm-plugin-version Weight: 1000000 Events: <none>
配置 Service Extensions
如需向全球外部应用负载平衡器添加自定义逻辑,您可以配置 GCPTrafficExtension
以使用 GCPWasmPlugin
。您可以使用 GCPTrafficExtension
在 Google Cloud 环境中使用高级流量管理功能。您可以跨全球外部应用负载平衡器配置此扩展程序。
如需配置 GCPTrafficExtension
以使用 GCPWasmPlugin
,请完成以下步骤:
定义
GCPTrafficExtension
。将
GCPTrafficExtension
配置保存为gcp-traffic-extension-with-plugin.yaml
:kind: GCPTrafficExtension apiVersion: networking.gke.io/v1 metadata: name: gcp-traffic-extension-with-plugin 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 supportedEvents: - RequestHeaders - ResponseHeaders backendRef: group: "networking.gke.io" kind: GCPWasmPlugin name: gcp-wasm-plugin
将
GATEWAY_NAME
替换为您的网关名称,例如global-external-http
。将示例清单应用于集群:
kubectl apply -f gcp-traffic-extension-with-plugin.yaml
验证
GCPTrafficExtension
的配置及其与网关的绑定。检查
GCPTrafficExtension
部署:kubectl describe gcptrafficextensions.networking.gke.io gcp-traffic-extension-with-plugin
输出类似于以下内容:
Name: gcp-traffic-extension-with-plugin 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: Backend Ref: Group: networking.gke.io Kind: GCPWasmPlugin Name: gcp-wasm-plugin Name: ext1 Supported Events: RequestHeaders ResponseHeaders 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>
输出会显示默认命名空间中名为
gcp-traffic-extension-with-plugin
的GCPTrafficExtension
的详细信息。它显示了Spec
字段,其中包含扩展程序的行为方式定义。验证网关绑定:
确认
GCPTrafficExtension
已绑定到网关。此命令可能需要几分钟时间才能完成:kubectl describe gateway GATEWAY_NAME
输出类似于以下内容:
Name: GATEWAY_NAME Namespace: default Labels: <none> Annotations: networking.gke.io/addresses: /projects/922988411345/global/addresses/test-k18j-default-external-http-2jfqxrkgd0fm networking.gke.io/backend-services: /projects/922988411345/global/backendServices/test-k18j-default-gw-serve404-80-8zjp3d8cqfsu, /projects/922988411345/global/backendServices... networking.gke.io/certmap: store-example-com-map networking.gke.io/firewalls: /projects/922988411345/global/firewalls/test-k18j-l7-default-global networking.gke.io/forwarding-rules: /projects/922988411345/global/forwardingRules/test-k18j-default-external-http-wt1tl0cwi6zr networking.gke.io/health-checks: /projects/922988411345/global/healthChecks/test-k18j-default-gw-serve404-80-8zjp3d8cqfsu, /projects/922988411345/global/healthChecks/test-... networking.gke.io/last-reconcile-time: 2025-08-08T20:27:35Z networking.gke.io/lb-route-extensions: networking.gke.io/lb-traffic-extensions: projects/922988411345/locations/global/lbTrafficExtensions/test-k18j-default-external-http-0tdum40yts35 networking.gke.io/ssl-certificates: networking.gke.io/target-http-proxies: networking.gke.io/target-https-proxies: /projects/922988411345/global/targetHttpsProxies/test-k18j-default-external-http-jy9mc97xb5yh networking.gke.io/url-maps: /projects/922988411345/global/urlMaps/test-k18j-default-external-http-jy9mc97xb5yh networking.gke.io/wasm-plugin-versions: projects/922988411345/locations/global/wasmPlugins/test-k18j-default-gcp-wasm-plugin-itle20jj9nyk/versions/test-k18j-wasm-plugin-version-i... networking.gke.io/wasm-plugins: projects/922988411345/locations/global/wasmPlugins/test-k18j-default-gcp-wasm-plugin-itle20jj9nyk 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 Spec: Gateway Class Name: gke-l7-global-external-managed Listeners: Allowed Routes: Namespaces: From: Same Name: https Port: 443 Protocol: HTTPS ...
输出显示了注解,GKE 使用这些注解来存储网关与底层 Google Cloud资源之间的链接。
networking.gke.io/lb-traffic-extensions
、networking.gke.io/wasm-plugin-versions
和networking.gke.io/wasm-plugins
注解会确认绑定。检查扩展程序状态:
确认
GCPTrafficExtension
具有Programmed
状态和ProgrammingSucceeded
原因。此命令可能需要几分钟时间才能完成。kubectl describe gcptrafficextensions.networking.gke.io gcp-traffic-extension-with-plugin
输出类似于以下内容:
Name: gcp-traffic-extension-with-plugin Namespace: default Labels: <none> Annotations: <none> API Version: networking.gke.io/v1 Kind: GCPTrafficExtension Metadata: Creation Timestamp: 2025-08-08T20:08:09Z Generation: 1 Resource Version: 56528 UID: 1389f790-9663-45ca-ac4e-a2c082f43359 Spec: Extension Chains: Extensions: Backend Ref: Group: networking.gke.io Kind: GCPWasmPlugin Name: gcp-wasm-plugin Name: ext1 Supported Events: RequestHeaders ResponseHeaders Match Condition: Cel Expressions: Cel Matcher: request.path.contains("serviceextensions") Name: chain1 Target Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Status: Ancestors: Ancestor Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Namespace: default Conditions: Last Transition Time: 2025-08-08T20:16:13Z Message: Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2025-08-08T20:16:13Z Message: Observed Generation: 1 Reason: ResolvedRefs Status: True Type: ResolvedRefs Last Transition Time: 2025-08-08T20:16:13Z Message: Observed Generation: 1 Reason: ProgrammingSucceeded Status: True Type: Programmed Controller Name: networking.gke.io/gateway Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 19m sc-gateway-controller default/gcp-traffic-extension-with-plugin Normal SYNC 3m25s (x4 over 11m) sc-gateway-controller Attachment of GCPTrafficExtension "default/gcp-traffic-extension-with-plugin" to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: "external-http", SectionName: nil, Port: nil} was a success Normal SYNC 3m25s (x4 over 11m) sc-gateway-controller All the object references were able to be resolved for GCPTrafficExtension "default/gcp-traffic-extension-with-plugin" bound to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: "external-http", SectionName: nil, Port: nil} Normal SYNC 3m25s (x4 over 11m) sc-gateway-controller Programming of GCPTrafficExtension "default/gcp-traffic-extension-with-plugin" to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: "external-http", SectionName: nil, Port: nil} was a success
检查插件状态。
确认
GCPWasmPlugin
资源具有Programmed
状态和ProgrammingSucceeded
原因。此命令可能需要几分钟时间才能完成。kubectl describe gcpwasmplugins.networking.gke.io gcp-wasm-plugin
输出类似于以下内容:
Name: gcp-wasm-plugin Namespace: default Labels: <none> Annotations: <none> API Version: networking.gke.io/v1 Kind: GCPWasmPlugin Metadata: Creation Timestamp: 2025-08-08T19:54:18Z Generation: 1 Resource Version: 44578 UID: 549a12c7-91d1-43ad-a406-d6157a799b79 Spec: Log Config: Enabled: true Min Log Level: INFO Sample Rate: 1000000 Versions: Description: Test wasm plugin version Image: us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main Name: wasm-plugin-version Weight: 1000000 Status: Ancestors: Ancestor Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Namespace: default Conditions: Last Transition Time: 2025-08-08T19:59:06Z Message: Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2025-08-08T19:59:06Z Message: Observed Generation: 1 Reason: ResolvedRefs Status: True Type: ResolvedRefs Last Transition Time: 2025-08-08T19:59:06Z Message: Observed Generation: 1 Reason: ProgrammingSucceeded Status: True Type: Programmed Controller Name: networking.gke.io/gateway Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 31m sc-gateway-controller default/gcp-wasm-plugin Normal SYNC 2m1s (x7 over 26m) sc-gateway-controller Attachment of WasmPlugin "default/gcp-wasm-plugin" to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: "external-http", SectionName: nil, Port: nil} was a success Normal SYNC 2m1s (x7 over 26m) sc-gateway-controller All the object references were able to be resolved for WasmPlugin "default/gcp-wasm-plugin" bound to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: "external-http", SectionName: nil, Port: nil} Normal SYNC 2m1s (x7 over 26m) sc-gateway-controller Programming of WasmPlugin "default/gcp-wasm-plugin" to AncestorRef {Group: "gateway.networking.k8s.io", Kind: "Gateway", Namespace: "default", Name: "external-http", SectionName: nil, Port: nil} was a success
将流量发送到应用。
在集群中部署网关、路由和应用后,您可以将流量传递到您的应用。
如需访问您的应用,您需要查找网关的 IP 地址。
在终端中,使用以下命令:
kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
将
GATEWAY_NAME
替换为您的网关名称。此命令会输出网关的 IP 地址。在后续命令中,将
GATEWAY_IP_ADDRESS
替换为输出中的 IP 地址。通过前往位于
store.example.com/serviceextensions
的serviceextensions
版本的存储区服务来测试路径更新:curl https://store.example.com/serviceextensions --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v
输出返回
Hello World
。
管理 GCPWasmPlugin
资源
您可以更新 GCPWasmPlugin
CRD 并监控插件。
更新 GCPWasmPlugin
如需更新 GCPWasmPlugin
资源,请按以下步骤操作:
在
GCPWasmPlugin
清单中进行更改,然后按照部署GCPWasmPlugin
中所述的步骤操作。例如,如需拥有两个版本的插件,其中一个版本用于提供流量,另一个版本不用于提供流量,请将
wasm-plugin.yaml
文件更新为以下内容:kind: GCPWasmPlugin apiVersion: networking.gke.io/v1 metadata: name: gcp-wasm-plugin spec: versions: - name: wasm-plugin-version-v1 description: "Serving Wasm Plugin version" image: "us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main" weight: 1000000 - name: wasm-plugin-version-v2 description: "Non serving Wasm Plugin version" image: "us-docker.pkg.dev/service-extensions-samples/plugins/local-reply:main" weight: 0 logConfig: enabled: true sampleRate: 1000000 minLogLevel: INFO
在此示例中,适用以下情况:
wasm-plugin-version-v1
的weight
为1000000
,表示它可处理所有流量。wasm-plugin-version-v2
的weight
为0
,表示它不提供任何流量。
如需确保网关已更新,请运行以下命令。此命令可能需要几分钟时间才能完成:
kubectl describe gateway GATEWAY_NAME
将
GATEWAY_NAME
替换为您的网关名称。
监控 GCPWasmPlugin
如需在 Google Cloud 控制台中查看 GCPWasmPlugin
的指标,请参阅从插件的角度进行监控。
当您按照指南中的步骤操作,需要从插件版本过滤条件列表中选择一个值时,请查找 prefix−WASM_PLUGIN_VERSION_NAME_FROM_FILE−suffix
格式,其中 WASM_PLUGIN_VERSION_NAME_FROM_FILE
是您在 GCPWasmPlugin
配置文件中定义的特定版本名称。
排查网关上的流量扩展程序问题
本部分提供有关在网关上配置流量扩展程序的问题排查提示。
找不到网关
以下错误表示 GCPTrafficExtension
或 GCPRoutingExtension
资源的 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"
如需解决此问题,请确保 GCPTrafficExtension
或 GCPRoutingExtension
资源的 targetRefs
字段中指定的网关资源存在于指定的命名空间中。
未找到服务或服务端口
以下错误表示 GCPTrafficExtension
或 GCPRoutingExtension
资源的 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"
如需解决此问题,请确保 GCPTrafficExtension
或 GCPRoutingExtension
资源的 backendRef
字段中指定的 Service 和 Service 端口存在于指定的命名空间中。
NEG 中没有网络端点
以下错误表示 NEG 中没有网络端点与 GCPTrafficExtension
或 GCPRoutingExtension
资源的 backendRef
字段中指定的 Service 关联:
error: failed to create resource: GCPTrafficExtension.networking.gke.io "my-traffic-extension" is invalid: spec.service: no network endpoints found for service "callout-service"
如需解决此问题,请确保 GCPTrafficExtension
或 GCPRoutingExtension
资源的 backendRef
字段中指定的 Service 具有网络端点。
发送请求时未回复或回复出错
如果您没有收到回复,或者在发送请求时收到包含错误的回复,这可能表明调用服务无法正常运行。
如需解决此问题,请检查调用服务的日志中是否有任何错误。
JSON 载荷中的错误代码 404
以下错误表示找不到调用服务或调用服务未响应请求:
{
"error": {
"code": 404,
"message": "Requested entity was not found.",
"status": "NOT_FOUND"
}
}
如需解决此问题,请确保调用服务正在运行,正在监听正确的端口,并且已在 GCPTrafficExtension
或 GCPRoutingExtension
资源中正确配置该服务。
JSON 载荷中的错误代码 500
以下错误表示调用服务遇到了内部服务器错误:
{
"error": {
"code": 500,
"message": "Internal server error.",
"status": "INTERNAL"
}
}
如需解决此问题,请检查调用服务的日志,以确定内部服务器错误的原因。
GCPWasmPlugin
不存在
以下错误表示您的项目中不存在 GCPWasmPlugin
资源:
Status:
Ancestors:
Ancestor Ref:
Group: gateway.networking.k8s.io
Kind: Gateway
Name: external-http
Namespace: default
Conditions:
Last Transition Time: 2025-03-06T16:27:57Z
Message:
Reason: Accepted
Status: True
Type: Accepted
Last Transition Time: 2025-03-06T16:27:57Z
Message: error cause: invalid-wasm-plugin: GCPWasmPlugin default/my-wasm-plugin in GCPTrafficExtension default/my-gateway-plugin-extension does not exist
Reason: GCPWasmPluginNotFound
Status: False
Type: ResolvedRefs
Controller Name: networking.gke.io/gateway
如需解决此问题,请在 Google Cloud 项目中创建相应的GCPWasmPlugin
,或将扩展程序指向现有的GCPWasmPlugin
。
后续步骤
- 了解 GKE 推理网关。
- 了解如何使用 GKE 推理网关部署 LLM。
- 了解如何查看可观测性指标。