部署 Kubernetes Gateway 资源,以管理外部流量到达单个 Google Kubernetes Engine (GKE) 集群内应用的方式。配置 GKE 网关可灵活而有力地控制入站流量,从而提高应用的可伸缩性和可靠性。例如,GKE Gateway 提供优化的路由和自动扩缩功能。这些功能对于低延迟在线服务至关重要,可确保响应迅速的用户体验,同时有助于控制成本。
如需跨多个集群或舰队部署网关,请参阅部署多集群网关。如需了解具体的网关配置(例如跨命名空间路由和 HTTP 流量分配),请参阅 Gateway API 用户指南。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。如果您之前安装了 gcloud CLI,请通过运行
gcloud components update命令来获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
确保您已有 Autopilot 或 Standard 集群。如需创建新集群,请参阅创建 Autopilot 集群。
确保您的用户账号具有 Certificate Manager 编辑者 (
roles/certificatemanager.editor) 角色,以便您创建必要的证书映射。
GKE Gateway Controller 要求
- 仅 VPC 原生集群支持 Gateway API。
- 如果您使用的是区域级或跨区域 GatewayClass,则必须启用代理专用子网。
- 集群必须启用
HttpLoadBalancing插件。 - 如果您使用的是 Istio,则必须将 Istio 升级到以下版本之一:
- 1.15.2 或更高版本
- 1.14.5 或更高版本
- 1.13.9 或更高版本。
- 如果您使用的是共享 VPC,则需要在宿主项目中将
Compute Network User角色分配给服务项目的 GKE 服务账号。
限制和局限
使用 GKE 网关时,请了解以下局限性和限制:
GKE GatewayClass 支持不同的功能,具体取决于它们使用的负载均衡器。如需详细了解每个 GatewayClass 支持的不同功能,请参阅 GatewayClass 功能。
最佳实践: 为获得最佳性能,请将网关数量限制为最多 100 个。超出此限制可能会影响性能或导致延迟时间增加。
GKE Gateway 仅支持 Gateway API 标准发布渠道。
GKE Gateway 始终在 Autopilot 集群上处于启用状态。您无法在 Autopilot 集群上安装 Gateway API 实验性发布渠道 CRD。
您不能使用 FrontendConfig 或 BackendConfig 配置网关,必须使用政策。
GKE 网关的行为与 Ingress 不同,因为网关不会推断健康检查参数。如果您的 Service 没有为
GET /请求返回 200,或者您有其他调整的 Pod 就绪性检查,则需要为 Service 配置 HealthCheckPolicy。您无法直接在主机名中指定端口号(例如 web.example.com:80)以进行流量路由。
您可以在 Cloud de Confiance 控制台中查看 GKE 为网关创建的负载均衡器资源,但这些资源不会引用它们所连接的网关或 GKE 集群。
您无法使用网关自动生成 Google 管理的 SSL 证书,但可以手动创建和引用 Google 管理的 SSL 证书。如需了解详情,请参阅保护网关安全。
HTTPRoute 是唯一受支持的路由类型。不支持 TCPRoute、UDPRoute 和 TLSRoute。如需查看 GKE Gateway Controller 支持的字段列表,请参阅 GatewayClass 功能。
使用网关或路径重定向的自定义请求和响应标头以及使用网关的网址重写仅适用于 GKE 1.27 版或更高版本。
对于使用网关和路径重定向的自定义请求和响应标头以及使用网关的网址重写,不支持 GatewayClass
gke-l7-gxlb。在配置 HTTPRoute 自定义请求和响应标头时,不支持以下 Cloud de Confiance变量:
origin_request_header(GKE 网关不支持跨域资源共享 [CORS] 政策)
Cloud de Confiance by S3NS 传统应用负载均衡器限制适用于 GKE 网关。此外,您不能在后端服务中配置自定义主机响应标头。
路径重定向和网址重写是互斥的,您不能在同一规则中同时使用这两个过滤条件。
Cloud Load Balancing 不支持将流量重定向到其他端口。如需查看 GKE Gateway Controller 支持的字段列表,请参阅 GatewayClass 功能。
GKE 网关不支持通配符、正则表达式和动态网址。
如果您指定具有区域级外部网关类的网关,则控制器会预配内部 IP 地址而不是外部地址。如需了解如何将已命名的地址与区域级外部应用负载平衡器结合使用,请参阅部署区域级外部网关。
网关使用独立 NEG 来配置网络端点组。为了确保网关控制器正确协调负载均衡器配置,您无法修改作为网关一部分的 Service 的
cloud.google.com/neg注解。GKE 网关不支持引用同时被 GKE Ingress 引用的 Service。
将
Gateway配置为预配 IP 地址时,不支持更改Gateway.spec.gatewayClass。为确保网关控制器正确协调负载均衡器,请删除现有网关,并使用更新后的gatewayClass值重新部署清单。不支持
networking.gke.io/app-protocols注解。改用appProtocol字段即可实现相同的结果。如果您将 GKE 网关与
external-dns搭配使用,并且网关的健康状况不佳,则默认情况下,与网关关联的所有 DNS 记录都会从您的 DNS 区域中删除。最佳实践: 运行
external-dns时,设置policy=upsert-only标志。 此配置有助于防止删除现有 DNS 记录。如果从 GKE 网关通过路由(Service 上的独立 NEG 注解)引用的
Service中移除端口,您还必须更新该 Service 上的独立 NEG 控制器才能移除该端口。否则,NEG 控制器最终会停止同步此 Service 的 Pod 端点。如需了解详情,请参阅从 Service 中移除端口后,NEG 控制器停止管理端点。使用可用区级集群的多集群网关 (MCG) 部署在集群升级期间容易发生服务中断故障。出现此问题的原因是,当可用区级集群的控制平面暂时不可用时,旧版网络端点组 (NEG) 发现机制可能会错误地报告零个后端。我们正在努力解决此问题,以便从长远来看,此问题不会再出现。为避免出现此单点故障,请使用具有 MCG 的区域级 GKE 集群。
在集群中启用 Gateway API
在 GKE 中使用网关资源之前,您的集群必须启用 Gateway API。
在更新现有 GKE 集群以启用 Gateway API 之前,请先确保满足所需的最低要求,然后再继续更新。
如需在现有 GKE 集群(Autopilot 或 Standard)上启用 Gateway API,请使用以下命令。集群最多可能需要 45 分钟来协调和安装 CustomResourceDefinition。
gcloud container clusters update CLUSTER_NAME \
--location=CLUSTER_LOCATION\
--gateway-api=standard
替换以下内容:
CLUSTER_NAME:现有集群的名称。CLUSTER_LOCATION:集群的 Compute Engine 区域或可用区。
--gateway-api=standard 标志指示 GKE 使用集群安装 Gateway API 标准渠道的 CRD。
验证集群
创建或升级集群后,GKE Gateway Controller 会自动安装 GatewayClass。控制器可能需要几分钟时间才能识别 CRD 并安装 GatewayClass。
确认已在 GKE 控制平面中启用 Gateway API:
gcloud container clusters describe CLUSTER_NAME \ --location=CLUSTER_LOCATION \ --format json输出类似于以下内容:如果此输出为空,请再次运行集群更新命令。
"networkConfig": { ... "gatewayApiConfig": { "channel": "CHANNEL_STANDARD" }, ... },确认您的集群中安装了 GatewayClass:
kubectl get gatewayclass输出类似于以下内容:
NAME CONTROLLER ACCEPTED AGE gke-l7-global-external-managed networking.gke.io/gateway True 16h gke-l7-regional-external-managed networking.gke.io/gateway True 16h gke-l7-gxlb networking.gke.io/gateway True 16h gke-l7-rilb networking.gke.io/gateway True 16h
如需了解每个 GatewayClass 的功能,请参阅 GatewayClass 功能。
系统只会自动安装单集群 GatewayClass。如需安装和使用多集群 GatewayClass 以实现内部和外部多集群负载均衡,请参阅启用多集群网关。
部署内部网关
内部网关公开只能从 VPC 或连接到 VPC 的网络访问的应用。
部署区域级内部网关
以下示例展示了如何部署区域性内部网关,以便实现在特定地理区域内服务之间的高效安全通信。
配置代理专用子网
您必须先配置代理专用子网,然后才能创建使用内部应用负载均衡器的网关。在使用内部应用负载均衡器的 VPC 中,每个区域都必须具有一个代理专用子网。此子网为负载均衡器代理提供了内部 IP 地址。
创建代理专用子网:
gcloud compute networks subnets create SUBNET_NAME \ --purpose=REGIONAL_MANAGED_PROXY \ --role=ACTIVE \ --region=COMPUTE_REGION \ --network=VPC_NETWORK_NAME \ --range=CIDR_RANGE替换以下内容:
SUBNET_NAME:代理专用子网的名称。COMPUTE_REGION:代理专用子网的区域。VPC_NETWORK_NAME:您用于创建此代理专用子网的 VPC 网络的名称。确保这是与您的 GKE 集群所在的 VPC 网络和您部署网关的 VPC 网络相同。这对于负载均衡器与后端服务之间的无缝通信非常重要。CIDR_RANGE:子网的主要 IP 地址范围。使用的子网掩码长度不得超过/26,以确保至少有 64 个 IP 地址可用于该区域中的代理。建议的子网掩码为/23。
验证代理专用子网:
gcloud compute networks subnets describe SUBNET_NAME \ --region=COMPUTE_REGION输出类似于以下内容:
... gatewayAddress: 10.1.1.1 ipCidrRange: 10.1.1.0/24 kind: compute#subnetwork name: proxy-subnet network: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/global/networks/default privateIpGoogleAccess: false privateIpv6GoogleAccess: DISABLE_GOOGLE_ACCESS purpose: REGIONAL_MANAGED_PROXY region: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION role: ACTIVE selfLink: https://www.googleapis.com/compute/v1/projects/PROJECT_NAME/regions/REGION/subnetworks/proxy-subnet state: READY
创建网关
网关资源表示在 Kubernetes 中路由流量的数据层面。网关可表示许多不同类型的负载均衡和路由,具体取决于派生网关的 GatewayClass。如需详细了解网关资源,请参阅网关资源说明或 API 规范。
在这种情况下,GKE 集群的管理员需要创建一个网关,可供不同团队用于在内部公开其应用。管理员部署网关,应用团队独立部署其路由并将路由连接到此网关。
将以下网关清单保存到名为
gateway.yaml的文件中:kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: internal-http spec: # Specify an existing GatewayClass. gatewayClassName: gke-l7-rilb listeners: # Listen for HTTP traffic on port 80. - name: http protocol: HTTP port: 80此清单包含以下字段:
gatewayClassName: gke-l7-rilb:指定派生此网关的 GatewayClass。gke-l7-rilb对应于内部应用负载均衡器。port: 80指定网关仅开放端口 80 来监听 HTTP 流量。
此网关配置为仅处理端口 80 上的 HTTP 流量。默认情况下,不支持 HTTPS(端口 443),如果您尝试通过 HTTPS 进行连接,请求可能会失败。
在您的集群中部署网关:
kubectl apply -f gateway.yaml验证网关是否已正确部署。部署其所有资源可能需要几分钟时间。
kubectl describe gateways.gateway.networking.k8s.io internal-http输出类似于以下内容:
Name: internal-http Namespace: default Spec: Gateway Class Name: gke-l7-rilb Listeners: Allowed Routes: Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute Namespaces: From: Same Name: http Port: 80 Protocol: HTTP Status: Addresses: Type: IPAddress Value: 192.168.1.14 Conditions: Last Transition Time: 2025-03-19T19:53:46Z Message: The OSS Gateway API has deprecated this condition, do not depend on it. Observed Generation: 1 Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2025-03-19T19:53:46Z Message: Observed Generation: 1 Reason: Accepted Status: True Type: Accepted Last Transition Time: 2025-03-19T19:53:46Z Message: Observed Generation: 1 Reason: Programmed Status: True # Indicates that the Gateway is ready. Type: Programmed Last Transition Time: 2025-03-19T19:53:46Z Message: The OSS Gateway API has altered the "Ready" condition semantics and reserved it for future use. GKE Gateway will stop emitting it in a future update, use "Programmed" instead. Observed Generation: 1 Reason: Ready Status: True Type: Ready Last Transition Time: 2025-03-19T19:53:46Z Message: Observed Generation: 1 Reason: Healthy Status: True Type: networking.gke.io/GatewayHealthy Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 92s networking.gke.io/gateway test/internal-http Normal UPDATE 45s (x3 over 91s) networking.gke.io/gateway test/internal-http Normal SYNC 45s networking.gke.io/gateway SYNC on test/internal-http was a success在此输出中,
Programmed条件的状态为True,表示 Gateway 已准备就绪。此时,您的集群中部署了一个网关,该网关已预配负载均衡器和 IP 地址。但是,该网关没有路由,因此它还不知道应该如何将流量发送到后端。如果没有路由,所有流量都会流向默认后端,这会返回 HTTP 404。接下来,您将部署应用和路由,告知网关如何到达应用后端。
部署演示应用
应用团队可以独立于网关的部署部署他们的应用和路由。在某些情况下,应用团队可能还希望拥有网关,并自行将其部署为专用于应用的资源。如需了解网关和路由的不同所有权模型,请参阅路由绑定。不过在此示例中,商店团队会部署其应用以及通过在上一部分中创建的 internal-http 网关公开其应用的附带 HTTPRoute。
HTTPRoute 资源有许多可配置的字段可用于流量匹配。如需了解 HTTPRoute 字段的说明,请参阅 API 规范。
将商店应用(store-v1、store-v2 和 store-german 部署)部署到您的集群:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yaml这将创建三个 Deployment 和三个 Service,分别名为 store-v1、store-v2 和 store-german。
验证应用已成功部署:
kubectl get pod应用运行后,输出类似于以下内容:
NAME READY STATUS RESTARTS AGE store-german-66dcb75977-5gr2n 1/1 Running 0 38s store-v1-65b47557df-jkjbm 1/1 Running 0 14m store-v2-6856f59f7f-sq889 1/1 Running 0 14m验证 Service 已部署:
kubectl get service输出会显示每个商店 Deployment 的 Service:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE store-german ClusterIP 10.48.3.183 <none> 8080/TCP 4s store-v1 ClusterIP 10.48.2.224 <none> 8080/TCP 5s store-v2 ClusterIP 10.48.4.48 <none> 8080/TCP 5s
部署 HTTPRoute
路由资源定义了用于将流量从网关映射到 Kubernetes 后端的特定于协议的规则。HTTPRoute 资源会执行 HTTP 和 HTTPS 流量匹配和过滤,并且受所有 gke-l7 GatewayClass 支持。
在本部分中,您将部署一个 HTTPRoute,它会使用访问您的商店应用所需的路由规则对网关进行编程。
将以下 HTTPRoute 清单保存到名为
store-route.yaml的文件中:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: store spec: # Attach the HTTPRoute to a Gateway. parentRefs: - kind: Gateway name: internal-http # Route requests that have `store.example.com` in the Host header. hostnames: - "store.example.com" rules: # Send requests with the `env: canary` header to the `store-v2` Service. - matches: - headers: - name: env value: canary backendRefs: - name: store-v2 port: 8080 # Send requests with `/de` in the path to the `store-german` Service. - matches: - path: value: /de backendRefs: - name: store-german port: 8080 # Send unmatched requests to the store-v1 Service. - backendRefs: - name: store-v1 port: 8080在集群中部署 HTTPRoute:
kubectl apply -f store-route.yamlstoreHTTPRoute 使用parentRefs属性绑定到internal-http网关:这些路由规则在底层的负载均衡器上配置,如下图所示:这些路由规则通过以下方式处理 HTTP 流量:
- 发送到
store.example.com/de的流量路由到 Servicestore-german。 - 发送到
store.example.com且具有 HTTP 标头"env: canary"的流量路由到 Servicestore-v2。 - 发送到
store.example.com的其余流量路由到 Servicestore-v1。
- 发送到
验证 HTTPRoute 已部署:
kubectl describe httproute store输出类似于以下内容:
Name: store Namespace: default Labels: <none> Annotations: <none> API Version: gateway.networking.k8s.io/v1 Kind: HTTPRoute # Multiple lines are omitted here. Spec: Hostnames: store.example.com Parent Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: internal-http Rules: Backend Refs: Group: Kind: Service Name: store-v1 Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-v2 Port: 8080 Weight: 1 Matches: Headers: Name: env Type: Exact Value: canary Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-german Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: /de Status: Parents: Conditions: Last Transition Time: 2022-11-01T04:18:52Z Message: Reason: Accepted Status: True Type: Accepted Last Transition Time: 2022-11-01T04:18:52Z Message: Reason: ReconciliationSucceeded Status: True Type: Reconciled Controller Name: networking.gke.io/gateway Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: internal-http Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 24m sc-gateway-controller default/store Normal SYNC 16m (x4 over 23m) sc-gateway-controller Bind of HTTPRoute "default/store" to ParentRef {Group: gateway.networking.k8s.io", # Multiple lines are omitted here.验证 HTTPRoute 已绑定到网关:
kubectl describe gateway输出类似于以下内容:
Name: internal-http Namespace: default Labels: <none> <...> Status: Addresses: Type: IPAddress Value: 10.128.15.203 Conditions: Last Transition Time: 2022-11-01T03:47:01Z Message: Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2022-11-01T03:47:01Z Message: Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2022-11-01T03:47:01Z Message: Reason: Ready Status: True Type: Ready Name: http Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute <...>
将流量发送到应用
现在,网关、路由和应用已在集群中部署,您可以将流量传递到您的应用。 网关配置为仅在端口 80 上传送 HTTP 流量。除非已单独配置 TLS,否则通过 HTTPS 发出的请求可能会失败。
从网关检索 IP 地址,以便将流量发送到您的应用:
kubectl get gateways.gateway.networking.k8s.io internal-http -o=jsonpath="{.status.addresses[0].value}"输出为一个 IP 地址。
在与集群连接的虚拟机 (VM) 实例上,将流量发送到此 IP 地址。这是必要的操作,因为网关具有内部 IP 地址,并且只能从 VPC 网络内部访问。由于
internal-http是区域级负载均衡器,因此客户端虚拟机必须与 GKE 集群位于同一区域。在同一 VPC 网络和区域中创建测试虚拟机:
gcloud compute instances create test-vm \ --zone=COMPUTE_ZONE \ --network=VPC_NETWORK_NAME使用 SSH 连接到虚拟机:
gcloud compute ssh test-vm --zone=COMPUTE_ZONE在虚拟机的 shell 中,向
store.example.com发出请求:curl http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v将
GATEWAY_IP_ADDRESS替换为上一步中的 IP 地址。演示应用的输出显示了应用运行位置的相关信息:
{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v1", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v1-84b47c7f58-pmgmk", "pod_name_emoji": "💇🏼♀️", "project_id": "gateway-demo-243723", "timestamp": "2022-10-25T13:31:17", "zone": "ZONE_NAME" }转到
store.example.com/de中的德语版商店服务,测试路径匹配:curl http://store.example.com/de --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v输出会确认请求已由
store-germanPod 处理:{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "Gutentag!", "node_name": "gke-gke1-pool-2-bd121936-n3xn.c.gateway-demo-243723.internal", "pod_name": "store-german-5cb6474c55-lq5pl", "pod_name_emoji": "🧞♀", "project_id": "gateway-demo-243723", "timestamp": "2022-10-25T13:35:37", "zone": "ZONE_NAME" }最后,使用
env: canaryHTTP 标头将流量发送到 Canary 版商店服务:curl -H "env: canary" http://store.example.com --resolve store.example.com:80:GATEWAY_IP_ADDRESS -v输出会确认请求已由
store-v2Pod 处理:{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v2", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v2-5788476cbd-s9thb", "pod_name_emoji": "🦰", "project_id": "gateway-demo-243723", "timestamp": "2022-10-25T13:38:26", "zone": "ZONE_NAME" }
部署外部网关
外部网关公开可从互联网或 VPC 网络的外部网络访问的应用。外部网关部署与内部网关部署类似,但您必须保护应用的安全,因为公共互联网可以访问网关。
您可以通过两种方式创建外部网关:全球级外部网关或区域级外部网关。
- 区域级外部网关:此网关使用区域级 IP 地址作为网关的前端。此网关的行为取决于您选择的网络服务层级:
- 如果您选择标准网络服务层级(默认),系统仅在部署区域级外部网关的本地 Cloud de Confiance by S3NS 计算区域中通告区域级 IP 地址。将流量发送到此 IP 地址的客户端会由其本地 ISP 和公共互联网进行路由,然后再到达通告该 IP 地址的 Google 区域。
- 如果您选择高级网络服务层级,系统会在 Google 的全球网络中通告区域级 IP 地址。这意味着,即使目标是区域 IP 地址,客户端流量也会在离客户端最近的 Google 边缘对接点进入 Google 的高品质全球主干网。此位置可最大限度地缩短流量在公共互联网上的传输距离,从而显著缩短延迟时间并提高性能。
- 全球外部网关:此网关使用全球 IP 地址(或任播 IP 地址)作为网关的前端。此 IP 地址在所有 Cloud de Confiance by S3NS 计算区域中均会公布。将流量发送到此任播 IP 地址的客户端会路由到通告该 IP 地址的最近 Google 位置。全球外部网关仅在高级网络服务层级提供。
部署区域级外部网关
以下示例展示了如何使用自行管理的证书和 HTTPRoute 公开具有附加到区域外部网关的多份证书的商店应用。
为区域级网关创建代理子网
您必须先配置代理专用子网,然后才能创建使用区域级外部应用负载平衡器的网关。在使用区域级外部应用负载平衡器的 VPC 中,每个区域都必须具有一个 external_managed_proxy 子网。此子网为负载均衡器代理提供了内部 IP 地址。
创建证书以保护您的客户端流量
您可以使用证书授权机构 (CA) 颁发并验证的证书,也可以创建自签名证书。如需详细了解如何创建证书,请参阅将证书存储在 Kubernetes Secret 中。
如需保护客户端与区域网关之间的流量,您可以使用以下方法:
- Google 管理的或自行管理的 Certificate Manager 证书
- 自行管理的区域性 SSL 证书
- Kubernetes Secret
CertificateMap 或 Google 管理的 SSL 证书与区域级网关不兼容。
如需了解详情,请参阅证书和 Cloud de Confiance by S3NS 负载平衡器。
创建区域级外部 HTTP(S) 网关
为外部负载均衡器创建区域级静态 IP 地址。
gcloud compute addresses create IP_ADDRESS_NAME \ --region=COMPUTE_REGION \ --network-tier=STANDARD替换以下内容:
IP_ADDRESS_NAME:新的静态 IP 地址的名称。COMPUTE_REGION:集群在其中运行的 Compute Engine 区域。
使用自行管理的证书创建区域级外部应用负载均衡器网关,如下所示,并将清单保存为
regional-gateway.yaml:kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: external-regional-http spec: # Name of an existing GatewayClass. gatewayClassName: gke-l7-regional-external-managed # Listen for HTTPS traffic on port 443 listeners: - name: https protocol: HTTPS port: 443 tls: # Terminate the TLS session with the client at the Gateway. mode: Terminate # Certificates for the Gateway to use to create a new TLS session. certificateRefs: - name: store-example-com # The name of the static IP address of the external load balancer. # You can also use the `IPAddress` type to specify the actual IP address. addresses: - type: NamedAddress value: IP_ADDRESS_NAME应用
regional-gateway清单:kubectl apply -f regional-gateway.yaml验证配置。
kubectl get gateway输出类似于以下内容:
NAME CLASS ADDRESS READY AGE external-http gke-l7-regional-external-managed 35.118.32.224 True 49s如需了解更多详情,请使用 describe 命令:
kubectl describe gateway输出类似于以下内容:
Name: external-regional-http Namespace: default Labels: <none> ... Spec: Gateway Class Name: gke-l7-regional-external-managed Listeners: Allowed Routes: Namespaces: From: Same Name: https Port: 443 Protocol: HTTPS Tls: Certificate Refs: Group: Kind: Secret Name: store-example-com Mode: Terminate ...
部署演示应用
应用团队可以独立于网关的部署部署他们的应用和路由。在某些情况下,应用团队可能还希望拥有网关,并自行将其部署为专用于其应用的资源。如需了解网关和路由的不同所有权模型,请参阅路由绑定。在此示例中,商店团队会部署应用和附带的 HTTPRoute,以通过在上一部分中创建的 external-http 网关公开应用。
如需详细了解 HTTPRoute 字段,请参阅 API 规范。
将示例应用部署到您的集群:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/store.yaml此示例应用创建了三个 Deployment 和三个 Service,分别名为
store-v1、store-v2和store-german。验证应用已成功部署:
kubectl get pod输出类似于以下内容:
NAME READY STATUS RESTARTS AGE store-german-66dcb75977-5gr2n 1/1 Running 0 38s store-v1-65b47557df-jkjbm 1/1 Running 0 14m store-v2-6856f59f7f-sq889 1/1 Running 0 14m验证 Service 已成功部署:
kubectl get service输出类似于以下内容:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE store-german ClusterIP 10.48.3.183 <none> 8080/TCP 4s store-v1 ClusterIP 10.48.2.224 <none> 8080/TCP 5s store-v2 ClusterIP 10.48.4.48 <none> 8080/TCP 5s
创建 HTTPRoute
路由资源定义了用于将流量从网关映射到 Kubernetes 后端的特定于协议的规则。HTTPRoute 资源会执行 HTTP 和 HTTPS 流量匹配和过滤,并且受所有 gke-l7-* GatewayClass 支持。
在本部分中,您将部署 HTTPRoute,它会使用访问示例应用所需的路由规则来配置网关。
将以下清单保存到名为
store-route-external.yaml的文件中:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: store-external spec: parentRefs: # Bind the route to the 'external-http' Gateway. - kind: Gateway name: external-http hostnames: - "store.example.com" rules: # Default rule for store.example.com that sends traffic to the store-v1 service. - backendRefs: - name: store-v1 port: 8080 # Match requests with the "env: canary" header and send them to the store-v2 service. - matches: - headers: - name: env value: canary backendRefs: - name: store-v2 port: 8080 # Match requests with the path "/de" and sends them to the store-german service. - matches: - path: value: /de backendRefs: - name: store-german port: 8080此清单描述了引用
external-http网关的 HTTPRoute。将清单应用到您的集群:
kubectl apply -f store-route-external.yamlstoreHTTPRoute 使用parentRefs属性绑定到external-http网关:下图展示了在底层负载均衡器上配置的路由规则:路由规则对 HTTP 流量的处理方式如下:
- 发送到
store.example.com/de的流量路由到 Servicestore-german。 - 发送到
store.example.com且具有 HTTP 标头"env: canary"的流量路由到 Servicestore-v2。 - 发送到
store.example.com的其余流量路由到 Servicestore-v1。
- 发送到
验证 HTTPRoute 已部署:
kubectl describe httproute store-external输出类似于以下内容:
Name: store-external Namespace: default Labels: <none> Annotations: <none> API Version: gateway.networking.k8s.io/v1 Kind: HTTPRoute # Multiple lines are omitted here. Spec: Hostnames: store.example.com Parent Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Rules: Backend Refs: Group: Kind: Service Name: store-v1 Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-v2 Port: 8080 Weight: 1 Matches: Headers: Name: env Type: Exact Value: canary Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-german Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: /de Status: Parents: # This section shows the status of this route in relation to each Gateway attached. Conditions: Last Transition Time: 2022-11-01T05:42:31Z Message: Reason: Accepted Status: True # Means that the Gateway has validated and accepted this route's configuration. Type: Accepted Last Transition Time: 2022-11-01T05:43:18Z Message: Reason: ReconciliationSucceeded Status: True Type: Reconciled Controller Name: networking.gke.io/gateway Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 2m48s sc-gateway-controller default/store-external Normal SYNC 61s (x3 over 2m27s) sc-gateway-controller Bind of HTTPRoute "default/store-external" to ParentRef Group: "gateway.networking.k8s.io", ...验证 HTTPRoute 已绑定到网关:
kubectl describe gateway external-http输出类似于以下内容:
Name: external-http Namespace: default Labels: <none> # Multiple lines are omitted here. Status: Addresses: Type: IPAddress Value: 34.149.207.45 Conditions: Last Transition Time: 2022-11-01T05:37:21Z Message: Reason: Scheduled Status: True Type: Scheduled Last Transition Time: 2022-11-01T05:43:18Z Message: Reason: Ready Status: True Type: Ready Listeners: Attached Routes: 1 Conditions: Last Transition Time: 2022-11-01T05:43:18Z Message: Reason: Ready Status: True Type: Ready Name: https Supported Kinds: Group: gateway.networking.k8s.io Kind: HTTPRoute # Multiple lines are omitted here.
将流量发送到应用
现在,网关、路由和应用已在集群中部署,您可以将流量传递到您的应用。
获取网关的 IP 地址:
kubectl get gateways.gateway.networking.k8s.io external-http -o=jsonpath="{.status.addresses[0].value}"输出为一个 IP 地址。
创建一个虚拟机:
gcloud cloud-shell ssh将流量从虚拟机发送到网关 IP 地址。 您必须手动设置主机标头,因为您不拥有
example.com主机名。curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v将
GATEWAY_IP_ADDRESS替换为上一步中网关的 IP 地址。cacert.pem:您生成的证书文件。您必须将此文件保存在用于连接到网关的机器上。
输出显示来自演示版应用有关应用运行位置的信息:
{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v1", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v1-84b47c7f58-pmgmk", "pod_name_emoji": "💇🏼♀️", "project_id": "gateway-demo-243723", "timestamp": "2022-09-25T13:31:17", "zone": "us-central1-a" }转到
store.example.com/de中的德语版store服务,以测试路径匹配:curl https://store.example.com/de --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v输出会确认请求已由
store-germanPod 处理:{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "Gutentag!", "node_name": "gke-gke1-pool-2-bd121936-n3xn.c.gateway-demo-243723.internal", "pod_name": "store-german-5cb6474c55-lq5pl", "pod_name_emoji": "🧞♀", "project_id": "gateway-demo-243723", "timestamp": "2022-09-25T13:35:37", "zone": "us-central1-a" }使用
env: canaryHTTP 标头将流量发送到store服务的 Canary 版本:curl -H "env: canary" https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert cacert.pem -v输出会确认请求已由
store-v2Pod 处理:{ "cluster_name": "gke1", "host_header": "store.example.com", "metadata": "store-v2", "node_name": "gke-gke1-pool-2-bd121936-5pfc.c.gateway-demo-243723.internal", "pod_name": "store-v2-5788476cbd-s9thb", "pod_name_emoji": "👩🏿", "project_id": "gateway-demo-243723", "timestamp": "2022-09-25T13:38:26", "zone": "us-central1-a" }
部署全球外部网关
以下示例展示了如何将多个证书附加到全球外部网关并将证书分组到证书映射,并使用 Certificate Manager 和 HTTPRoute 公开商店应用。
创建证书映射
如果每个网关需要 15 个或更多证书或者您需要使用通配符证书,Google 建议使用 Certificate Manager 来管理证书。
您还可以使用 Kubernetes Secret 或 Google 管理的 SSL 证书来保护外部网关。如需了解详情,请参阅网关安全性。
在本部分中,您将使用 Certificate Manager 创建证书,以保护集群上运行的应用。
启用 Certificate Manager API:
gcloud services enable certificatemanager.googleapis.com创建证书映射:
gcloud beta certificate-manager maps create store-example-com-map将 Google 管理的证书和密钥加载到证书中:
gcloud beta certificate-manager certificates create store-example-com-cert \ --certificate-file="CERTIFICATE_FILE" \ --private-key-file="PRIVATE_KEY_FILE"替换以下内容:
CERTIFICATE_FILE:证书文件的名称。该文件必须具有.pem扩展名。例如cert.pem。PRIVATE_KEY_FILE:您的私钥文件的名称。
如需了解详情,请参阅创建私钥和证书。
创建将证书分配给证书映射的
CertificateMapEntry:gcloud beta certificate-manager maps entries create store-example-com-map-entry \ --map=store-example-com-map \ --hostname=store.example.com \ --certificates=store-example-com-cert
如需了解如何使用其他证书来源(例如 Kubernetes Secret 或 SSL 证书)保护网关,请参阅保护网关安全。
创建网关
网关资源表示在 Kubernetes 中路由流量的数据层面。网关可以表示许多不同类型的负载均衡和路由,具体取决于其使用的 GatewayClass。
在本部分中,您将创建一个网关。应用团队可以独立部署路由并将其安全地附加到网关,从而使用网关将应用公开给互联网。
将以下清单保存到名为
gateway.yaml的文件中:kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: external-http annotations: networking.gke.io/certmap: store-example-com-map spec: # This GatewayClass uses a global external Application Load Balancer. gatewayClassName: gke-l7-global-external-managed listeners: - name: https protocol: HTTPS port: 443此清单描述了具有以下字段的网关:
gatewayClassName: gke-l7-global-external-managed:指定此网关的 GatewayClass。此网关类使用全球外部应用负载均衡器。protocol: HTTPS和port: 443:指定网关为 HTTPS 流量开放端口 443。这些字段会启用 TLS。networking.gke.io/certmap: store-example-com-map:指定 Certificate Manager 中证书映射的名称。
没有 TLS 部分,因为 TLS 是使用注解
networking.gke.io/certmap以及使用 Certificate Manager 配置的。将清单应用到您的集群:
kubectl apply -f gateway.yamlGKE 可能需要几分钟时间来部署资源。
验证网关已成功部署:
kubectl describe gateway输出类似于以下内容:
Name: external-http Namespace: default Labels: <none> ... Spec: Gateway Class Name: gke-l7-global-external-managed Listeners: Allowed Routes: Namespaces: From: Same Name: https Port: 443 Protocol: HTTPS Tls: Certificate Refs: Group: Kind: Secret Name: store-example-com Mode: Terminate ...此输出显示集群中部署的网关具有负载均衡器和公共 IP 地址。该网关没有路由,这意味着它无法将流量发送到后端。如果没有路由,所有流量都会流向默认后端,这会返回 HTTP 404 响应。在下一部分中,您将部署路由,以指示网关将流量发送到后端。
部署演示应用
您可以独立于 Gateway 的部署来部署应用和路由。
如需详细了解如何部署演示应用,请参阅部署演示应用。
创建 HTTPRoute
您必须创建 HTTPRoute 才能执行 HTTP 和 HTTPS 流量匹配和过滤。
将流量发送到应用
部署应用并创建 HTTPRoute 后,您可以将流量传递给应用。
如需详细了解如何将流量发送到您的应用,请参阅将流量发送到应用。
部署区域级外部网关
以下示例展示了如何使用自行管理的证书和 HTTPRoute 公开具有附加到区域外部网关的多份证书的商店应用。
为区域级网关创建代理子网
您必须先配置代理专用子网,然后才能创建使用区域级外部应用负载均衡器的网关。在使用区域级外部应用负载均衡器的 VPC 中,每个区域都必须具有一个 external_managed_proxy 子网。此子网为负载均衡器代理提供了内部 IP 地址。
创建证书以保护您的客户端流量
您可以使用证书授权机构 (CA) 颁发并验证的证书,也可以创建自签名证书。如需详细了解如何创建证书,请参阅将证书存储在 Kubernetes Secret 中。
如需保护客户端与区域网关之间的流量,您可以使用以下方法:
- Google 管理的或自行管理的 Certificate Manager 证书
- 自行管理的区域性 SSL 证书
- Kubernetes Secret
CertificateMap 或 Google 管理的 SSL 证书与区域级网关不兼容。
如需了解详情,请参阅证书和 Cloud de Confiance by S3NS 负载均衡器
创建区域级外部 HTTP(S) 网关
为外部负载均衡器创建区域级静态 IP 地址。
gcloud compute addresses create IP_ADDRESS_NAME \ --region=COMPUTE_REGION \ --network-tier=STANDARD替换以下内容:
IP_ADDRESS_NAME:新的静态 IP 地址的名称。COMPUTE_REGION:集群在其中运行的 Compute Engine 区域。
使用自行管理的证书创建区域级外部应用负载均衡器网关,如下所示,并将清单保存为
regional-gateway.yaml:kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: external-regional-http spec: # Name of an existing GatewayClass. gatewayClassName: gke-l7-regional-external-managed # Listen for HTTPS traffic on port 443 listeners: - name: https protocol: HTTPS port: 443 tls: # Terminate the TLS session with the client at the Gateway. mode: Terminate # Certificates for the Gateway to use to create a new TLS session. certificateRefs: - name: store-example-com # The name of the static IP address of the external load balancer. # You can also use the `IPAddress` type to specify the actual IP address. addresses: - type: NamedAddress value: IP_ADDRESS_NAME应用
regional-gateway清单:kubectl apply -f regional-gateway.yaml验证配置。
kubectl get gateway输出类似于以下内容:
NAME CLASS ADDRESS READY AGE external-http gke-l7-regional-external-managed 35.118.32.224 True 49s如需了解更多详情,请使用 describe 命令:
kubectl describe gateway输出类似于以下内容:
Name: external-regional-http Namespace: default Labels: <none> ... Spec: Gateway Class Name: gke-l7-regional-external-managed Listeners: Allowed Routes: Namespaces: From: Same Name: https Port: 443 Protocol: HTTPS Tls: Certificate Refs: Group: Kind: Secret Name: store-example-com Mode: Terminate ...
部署演示应用
您可以独立于 Gateway 的部署来部署应用和路由。
如需详细了解如何部署演示应用,请参阅部署演示应用。
创建 HTTPRoute
您必须创建 HTTPRoute 才能执行 HTTP 和 HTTPS 流量匹配和过滤。
将流量发送到应用
部署应用并创建 HTTPRoute 后,您可以将流量传递给应用。
如需详细了解如何将流量发送到您的应用,请参阅将流量发送到应用。
使用共享 Gateway
Gateway API 使用单独的资源(网关和路由资源)来部署负载均衡器和路由规则。这与 Ingress 不同,Ingress 会将所有内容组合到一个资源中。通过在资源之间拆分责任,网关可让负载均衡器及其路由规则单独部署,并由不同用户或团队进行部署。这样一来,网关即可成为共享网关,这些网关与多个不同路由连接,可以完全由独立团队拥有和管理,甚至可以跨不同命名空间。
针对共享网关部署路由
此示例基于部署内部 Gateway中部署的 internal-http Gateway。
在此示例中,网站团队将部署其应用、Service 和HTTPRoute,以将来自 Gateway 的流量与这些 Service 匹配。
部署示例应用:
kubectl apply -f https://raw.githubusercontent.com/GoogleCloudPlatform/gke-networking-recipes/main/gateway/gke-gateway-controller/app/site.yaml将以下清单保存到名为
site-route-internal.yaml的文件中:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: site-internal spec: # Attach the HTTPRoute to the `internal-http` Gateway. parentRefs: - kind: Gateway name: internal-http # Route requests that have `site.example.com` in the Host header. hostnames: - "site.example.com" # Send all requests to the `site-v1` Service. rules: - backendRefs: - name: site-v1 port: 8080此清单描述了一个与
site.example.com的所有流量匹配并将其路由到site-v1Service 的 HTTPRoute。将清单应用到您的集群:
kubectl apply -f site-route-internal.yaml验证 HTTPRoute 是否已连接到 Gateway:
kubectl describe httproute.gateway.networking.k8s.io site-internal输出类似于以下内容:
Status: Parents: Conditions: Last Transition Time: 2023-01-09T15:05:43Z Message: Reason: Accepted Status: True Type: Accepted Last Transition Time: 2023-01-09T15:05:43Z Message: Reason: ReconciliationSucceeded Status: True Type: Reconciled Controller Name: networking.gke.io/gateway Parent Ref: Group: gateway.networking.k8s.io Kind: Gateway Name: internal-http ...如果 Gateway 的
Accepted条件为True,则表示 HTTPRoute 已成功绑定到 Gateway。如需详细了解状态字段,请参阅路由状态。验证流向 Gateway 的流量是否已正确路由:
curl -H "host: site.example.com" GATEWAY_IP_ADDRESS curl -H "host: store.example.com" GATEWAY_IP_ADDRESS将
GATEWAY_IP_ADDRESS替换为内部网关的 IP 地址。您必须在 Gateway 所在的 VPC 中使用虚拟机 (VM)。
输出类似于以下内容:
{ "cluster_name": "CLUSTER_NAME", "host_header": "site.example.com", "metadata": "site-v1", "pod_name": "site-v1-5d64fc4d7d-fz6f6", "pod_name_emoji": "👩🏼🍳", "project_id": "PROJECT_ID", "timestamp": "2022-11-02T19:07:01", "zone": "ZONE_NAME" } ... { "cluster_name": "CLUSTER_NAME", "host_header": "store.example.com", "metadata": "store-v1", "pod_name": "store-v1-6d8d58d78-vz8pn", "pod_name_emoji": "🧝🏻♂️", "project_id": "PROJECT_ID", "timestamp": "2022-11-02T19:07:01", "zone": "ZONE_NAME" }此输出表明,带有
site.example.comHost 标头的请求会到达site-v1服务,而带有store.example.comHost 标头的请求会到达store-v1服务。
配置网络层级
您可以使用网关定义中 addresses[] 数组内的 type 字段,为区域级外部应用负载均衡器的监听器地址指定网络层级。如果您未指定网络层级,则网关默认使用标准层级的临时 IP 地址。
请将以下值用于 type 字段:
networking.gke.io/premium-ephemeral-ipv4-address:分配高级层级 IP 地址。networking.gke.io/standard-ephemeral-ipv4-address:分配标准层级 IP 地址。
如需分配来自这两个网络层级的 IP 地址,请在 addresses 字段中指定这两种类型。
以下示例展示了如何 Cloud de Confiance by S3NS 为网关分配高级层级 IP 地址。如需预配标准层级 IP 地址,请使用 networking.gke.io/standard-ephemeral-ipv4-address。
将以下示例清单保存为
external-regional-http.yaml:kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: external-regional-http spec: # Name of an existing GatewayClass. gatewayClassName: gke-l7-regional-external-managed # Listen for HTTPS traffic on port 443. listeners: - name: https protocol: HTTPS port: 443 tls: # Terminate the TLS session with the client at the Gateway. mode: Terminate # Certificates for the Gateway to use to create a new TLS session. certificateRefs: - name: store-example-com addresses: # Request a Premium Tier ephemeral IPv4 address for the Gateway. - type: networking.gke.io/premium-ephemeral-ipv4-address应用示例清单:
kubectl apply -f external-regional-http.yaml
配置 Gateway 默认后端
所有 gke-l7-* GatewayClass 都会向不匹配的流量返回 HTTP 404。您可以使用显式默认 Route 配置默认后端,该路由会将不匹配的流量发送到用户提供的 Service。
即使没有明确的后端定义,网关也会配置为处理 404(未找到)和 500(服务器错误)等错误代码。默认行为可能因网关实现而异。如需更好地控制错误处理,请考虑配置自定义后端。
以下 HTTPRoute 示例演示了如何自定义默认后端。如果您应用与以下内容类似的 HTTPRoute,则其优先于隐式默认后端:
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: custom-default-backend
spec:
parentRefs:
- kind: Gateway
name: my-internal-gateway
# Omit the `hostnames` field to route all unmatched traffic from the
# attached Gateway.
rules:
- backendRefs:
- name: my-custom-default-backend-service
port: 8080
此 HTTPRoute 匹配来自特定网关的所有流量。每个 Gateway 只能有一个规则,否则规则会发生冲突并且优先顺序适用。
您可以使用默认后端来阻止他人创建路由所有 Gateway 流量的默认路由后端。显式 HTTPRoute 始终优先于具有冲突路由规则的新 HTTPRoute。
为 Gateway 配置静态 IP 地址
每个 Gateway 都有一个 IP 地址,用于监听流量。如果您未在网关上指定 IP 地址,则网关控制器会自动提供 IP 地址。您还可以创建静态 IP 地址,以使 IP 地址的存在与 Gateway 生命周期无关。
部署网关后,其 IP 地址会显示在状态字段中:
kind: Gateway
...
status:
addresses:
- value: 10.15.32.3
根据 GatewayClass,IP 地址是从以下子网分配的:
| GatewayClass | 默认 IP 地址池 |
|---|---|
|
|
主节点 IPv4/IPv6 地址范围中的区域专用 IP 地址 |
|
|
Google 的区域外部 IPv4/IPv6 范围中的区域公共 IP 地址 |
|
|
Google 的全球外部 IPv4/IPv6 范围中的全球公共 IP 地址 |
addresses.NamedAddress 字段可让您指定独立于网关的 IP 地址。您可以在网关部署之前创建静态 IP 地址资源,并且 NamedAddress 会引用该资源。即使网关已删除,您也可以重复使用静态 IP 地址。
使用已命名的 IP 地址
您可以通过指定 NamedAddress 来配置 IPv4 或 IPv6 地址。您必须先预配静态 IP 地址,然后才能创建网关。
创建静态 IP 地址资源:
gcloud compute addresses create IP_ADDRESS_NAME \ --purpose=SHARED_LOADBALANCER_VIP \ --region=COMPUTE_REGION \ --subnet=SUBNET \ --project=PROJECT_ID替换以下内容:
IP_ADDRESS_NAME:新的静态 IP 地址的名称COMPUTE_REGION:对于区域级 Gateway,是集群在其中运行的 Compute Engine 区域。对于全球级外部网关,不需要此标志。SUBNET:IP 地址的子网。对于全球级外部网关,不需要此标志。PROJECT_ID:GKE 集群在其中运行的项目。
将以下清单保存到名为
named-ip-gateway.yaml的文件中:kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: internal-http spec: gatewayClassName: gke-l7-rilb listeners: - name: http protocol: HTTP port: 80 addresses: - type: NamedAddress value: IP_ADDRESS_NAME此清单描述了一个引用已命名的 IP 地址的 Gateway。
将清单应用到您的集群:
kubectl apply -f named-ip-gateway.yaml验证 Gateway IP 地址:
kubectl describe gateway internal-http输出类似于以下内容:
Name: internal-http Namespace: default Labels: <none> ... Spec: Addresses: Type: NamedAddress Value: IP_ADDRESS_NAME Gateway Class Name: gke-l7-rilb Listeners: Allowed Routes: Namespaces: From: Same Name: http Port: 80 Protocol: HTTP Status: Addresses: Type: IPAddress Value: 10.15.32.103
配置从 HTTP 到 HTTPS 的重定向
Cloud Load Balancing 提供从 HTTP 到 HTTPS 的重定向功能。外部应用负载均衡器将未加密的 HTTP 请求重定向到使用相同 IP 地址的 HTTPS 负载均衡器。当您创建启用 HTTP 到 HTTPS 重定向的网关时,系统会自动创建这两个负载均衡器。对端口 80 上网关的外部 IP 地址的请求会自动重定向到端口 443 上的同一外部 IP 地址。
默认情况下,网关上未定义 HTTP 到 HTTPS 重定向。
如需将 HTTP 流量重定向到 HTTPS,请配置网关以同时处理 HTTP 和 HTTPS 流量。如果您停用 HTTP 或 HTTPS,则网关不会重定向流量。
以下示例展示了如何使用 HTTP 到 HTTPS 重定向来帮助确保从客户端发送到 Web 应用的流量始终重定向到安全页面。
gke-l7-gxlb 和 gke-l7-gxlb-mc GatewayClass 不支持从 HTTP 到 HTTPS 的重定向。如需详细了解每个 GatewayClass 支持的不同功能,请参阅 GatewayClass 功能。
请注意,HTTPRoute 中的 hostnames 部分是可选的。您可以省略 hostnames 部分,为特定 HTTP 端口上的所有主机名创建全方位重定向。此外,您还可以使用通配符重定向,例如:
...
hostnames:
- "*.example.com" # Matches all subdomains of example.com
...
重定向来自基础架构命名空间的 HTTP 流量
在某些情况下,基础架构或平台管理团队与应用团队之间没有明显的区别,因此防止网关滥用可能成为一个难题。
以下示例进一步限制了 HTTP 监听器的使用,以防止应用团队意外使用非安全协议。此示例将网关配置为仅当 HTTPRoute 位于具有 otherInfra: httpToHttps 标签的命名空间中时才允许其使用 HTTP 监听器。不过,网关允许任何命名空间中的 HTTPRoute 使用 HTTPS 监听器。您可以使用 Kubernetes RBAC 限制 http-redirect 命名空间,这样应用团队就不会错误地在此命名空间中创建 HTTPRoute。
创建网关的命名空间。将清单保存为
gateway-namespace.yaml:apiVersion: v1 kind: Namespace metadata: name: gateway-infra应用清单:
kubectl apply -f gateway-namespace.yaml创建网关的命名空间,并将清单保存为
redirect-namespace.yaml:apiVersion: v1 kind: Namespace metadata: name: http-redirect labels: otherInfra: httpToHttps此
http-redirect命名空间具有otherInfra: httpToHttps标签。应用清单:
kubectl apply -f redirect-namespace.yaml如需限制 HTTP 监听器的使用,请使用以下清单创建网关。将清单保存为
external-gateway.yaml:kind: Gateway apiVersion: gateway.networking.k8s.io/v1 metadata: name: external-http namespace: gateway-infra spec: # Name of an existing GatewayClass. gatewayClassName: gke-l7-global-external-managed listeners: - name: http protocol: HTTP port: 80 # Allow only HTTPRoutes from namespaces that have the # `otherInfra: httpToHttps` label to use this listener. allowedRoutes: kinds: - kind: HTTPRoute namespaces: from: Selector selector: matchLabels: otherInfra: httpToHttps - name: https protocol: HTTPS port: 443 # Allow HTTPRoutes from any namespace to use this listener. allowedRoutes: kinds: - kind: HTTPRoute namespaces: from: All tls: mode: Terminate options: networking.gke.io/pre-shared-certs: store-example-comnamespace字段指定在gateway-infra命名空间中创建网关。allowedRoutes部分中的namespaces字段将 HTTP 监听器限制为与标签otherInfra: httpToHttps匹配的命名空间。
应用清单:
kubectl apply -f external-gateway.yaml如需强制进行 HTTPS 重定向,请使用以下清单创建默认 HTTPRoute。将清单保存为
http-redirect.yaml:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: redirect # Create the HTTPRoute in the `http-redirect` namespace. namespace: http-redirect spec: # Attach the HTTPRoute to the `http` listener in the `external-http` # Gateway. parentRefs: - namespace: gateway-infra name: external-http sectionName: http rules: # Respond to the request with an HTTPS redirection. - filters: - type: RequestRedirect requestRedirect: scheme: httpssectionName字段指示网关仅在 HTTP 监听器上匹配。RequestRedirect过滤条件会强制重定向到 HTTPS 监听器。
应用清单:
kubectl apply -f http-redirect.yaml使用以下清单为应用创建 Service。将清单保存为
service-deployment.yaml:apiVersion: v1 kind: Service metadata: name: store-v1 spec: selector: app: store version: v1 ports: - port: 8080 targetPort: 8080 --- apiVersion: apps/v1 kind: Deployment metadata: name: store-v1 spec: replicas: 2 selector: matchLabels: app: store version: v1 template: metadata: labels: app: store version: v1 spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1 ports: - containerPort: 8080 env: - name: METADATA value: "store-v1"应用清单:
kubectl apply -f service-deployment.yaml使用以下清单为仅允许 HTTPS 的应用创建 HTTPRoute。将清单保存为
http-route.yaml:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1 metadata: name: store-external labels: gateway: external-http spec: # Attach the HTTPRoute to the HTTPS listener in the `external-http` # Gateway. parentRefs: - name: external-http namespace: gateway-infra sectionName: https # Match requests that have the `store.example.com` Host header. hostnames: - "store.example.com" # Route requests to the `store-v1` Service. rules: - backendRefs: - name: store-v1 port: 8080应用清单:
kubectl apply -f http-route.yaml
配置路径重定向和网址重写
路径重定向涉及将传入请求从一个网址路径重定向到另一个网址路径。借助路径重定向,您可以在需要处理过期或已弃用的网址时更改网址结构。
网址重写有助于在服务器上处理传入网址之前修改该网址。它允许您更改网址的结构或格式,而无需实际更改底层内容或文件结构。网址重写对创建方便记忆且易于理解的人性化和搜索引擎优化 (SEO) 型网址非常有用。默认情况下,系统不会配置路径重定向和网址重写,您需要使用 HTTPRoute 中的过滤条件明确配置这些重定向或重写。
GKE Gateway 支持路径重定向和网址重写。如需了解详情,请参阅 HTTP 路径重定向和重写。
配置路径重定向
您可以将路径重定向配置为替换整个路径,也可以仅替换网址中的前缀。
替换整个路径
如需替换整个路径,请在 HTTPRoute 中配置过滤条件,以将网址路径中包含前缀
/any-path的任何网址替换为严格值/new-path。如下所示创建
HTTPRoute清单,并将其命名为store.yaml:apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: store spec: parentRefs: - kind: Gateway name: external-http hostnames: - store.example.com rules: - matches: - path: # Match requests by a prefix, like `/any-path` and `/any-path/home`. type: PathPrefix value: /any-path filters: - type: RequestRedirect requestRedirect: path: # Replace the full path with `/new-path`. For example, both # `/any-path/home` and `/any-path` become `/new-path`. type: ReplaceFullPath replaceFullPath: /new-path statusCode: 302例如,此清单为 HTTPRoute 设置路由规则,如下所示:到网址
https://store.example.com/any-path/...的任意路由应重定向到新位置https://store.example.com/new-path/(严格)。应用清单:
kubectl apply -f store.yaml
此路由规则遵循严格的重定向规则,这意味着浏览器不会尝试缓存重定向,而是重定向到最新版本。
仅替换前缀
如需仅替换前缀,请在 HTTPRoute 中配置过滤条件,以将网址路径中包含前缀
/any-prefix的任何网址替换为严格值/new-prefix。如下所示创建
HTTPRoute清单,并将其命名为store.yaml:apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: store spec: parentRefs: - kind: Gateway name: external-http hostnames: - store.example.com rules: - matches: - path: # Match requests by prefix, like `/any-prefix` and # `/any-prefix/home`. type: PathPrefix value: /any-prefix filters: - type: RequestRedirect requestRedirect: path: # Replace the matched prefix with `/new-prefix`. For example, # `/any-prefix` becomes `/new-prefix` and `/any-prefix/home` # becomes `/new-prefix/home`. type: ReplacePrefixMatch replacePrefixMatch: /new-prefix statusCode: 302例如,此清单为 HTTPRoute 设置路由规则,如下所示:到网址
https://store.example.com/any-path/v1/...的任意路由应重定向到新位置https://store.example.com/new-path/v1/...(唯一)。应用清单:
kubectl apply -f store.yaml
此路由规则遵循唯一的重定向规则,可确保浏览器始终将您重定向到相同的预期页面。
配置网址重写
设置网址重写可更改网址对用户的显示方式。您可以使用网址重写功能,让网址更加方便用户使用,改进搜索引擎优化 (SEO),或将用户重定向到新网页。
重写整个主机名
要重写整个主机名,请执行以下操作:
在 HTTPRoute 中配置过滤条件,指示网关先将请求标头中的
Host信息从www.example.com替换为store.example.com,然后再将请求转发到后端服务。如下所示创建
HTTPRoute清单,并将其命名为www.yaml:apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: www spec: parentRefs: - kind: Gateway name: external-http hostnames: - www.example.com rules: - filters: - type: URLRewrite # Replace the hostname in the URL with `store.example.com`. urlRewrite: hostname: store.example.com backendRefs: - name: store-v1 port: 8080例如,通过上述配置,任何对
https://www.example.com的请求都将转发到带有Host: store.example.com标头(而不是Host: www.example.com)的后端服务。应用清单:
kubectl apply -f www.yaml
使用路径修饰符进行重写
您可以将重写与路径修饰符结合使用,以在将请求中继到后端服务之前提供高级网址和路径修改。
如需使用路径修饰符进行重写,请执行以下操作:
在 HTTPRoute 中配置过滤条件,指示网关先将请求标头中的“主机”信息从 www.example.com 替换为
to store.example.com,并将/store值替换为/,然后再将请求转发到后端服务。如下所示创建
HTTPRoute清单,并将其命名为www.yaml:apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: www spec: parentRefs: - kind: Gateway name: external-http hostnames: - www.example.com rules: - matches: - path: type: PathPrefix value: /store filters: - type: URLRewrite # For URLs that have `/store` in the path, replace the hostname with # store.example.com and replace the `/store` prefix with `/de`. urlRewrite: hostname: store.example.com path: type: ReplacePrefixMatch replacePrefixMatch: /de backendRefs: - name: store-german port: 8080例如,通过上述配置,任何对
https://www.example.com/store/...的请求都将转发到请求标头中带有Host: store.example.com(而不是Host: www.example.com)的后端服务,并且/store将被重写为/de。应用清单:
kubectl apply -f www.yaml
验证配置
如需在使用网址重写或路径重定向过滤条件创建 HTTPRoute 后验证过滤条件是否已应用,请执行以下操作:
kubectl get httproute www -o yaml
输出类似于以下内容:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"gateway.networking.k8s.io/v1","kind":"HTTPRoute","metadata":{"annotations":{},"name":"www","namespace":"default"},"spec":{"hostnames":["www.example.com"],"parentRefs":[{"kind":"Gateway","name":"external-http"}],"rules":[{"backendRefs":[{"name":"store-german","port":8080}],"filters":[{"type":"URLRewrite","urlRewrite":{"hostname":"store.example.com","path":{"replacePrefixMatch":"/de","type":"ReplacePrefixMatch"}}}],"matches":[{"path":{"type":"PathPrefix","value":"/store"}}]}]}}
creationTimestamp: "2023-06-22T01:00:42Z"
generation: 3
name: www
namespace: default
resourceVersion: "51268631"
uid: e516493e-806d-44d6-ae0d-1c9ff25682cf
spec:
hostnames:
- www.example.com
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: external-http
rules:
- backendRefs:
- group: ""
kind: Service
name: store-german
port: 8080
weight: 1
filters:
- type: URLRewrite
urlRewrite:
hostname: store.example.com
path:
replacePrefixMatch: /de
type: ReplacePrefixMatch
matches:
- path:
type: PathPrefix
value: /store
status:
parents:
- conditions:
- lastTransitionTime: "2023-06-22T01:11:26Z"
message: ""
observedGeneration: 2
reason: Accepted
status: "True"
type: Accepted
- lastTransitionTime: "2023-06-22T01:11:26Z"
message: ""
observedGeneration: 2
reason: ReconciliationSucceeded
status: "True"
type: Reconciled
controllerName: networking.gke.io/gateway
parentRef:
group: gateway.networking.k8s.io
kind: Gateway
name: external-http
如需了解更多详情,请使用 describe 命令:
kubectl describe httproute
配置自定义请求和响应标头
使用自定义请求和响应标头,您可以为 HTTP(S) 请求和响应指定其他标头。根据负载均衡器检测到的信息,这些标头可以包含以下信息:
- 客户端的延迟时间
- 客户端 IP 地址的地理位置
- TLS 连接的参数
默认情况下,向后端服务发送/从后端服务接收的请求不会添加自定义标头,您需要使用 HTTPRoute 中的过滤条件明确配置自定义标头。
您可以通过在 HTTPRoute 的规则中添加过滤条件部分来配置自定义标头,如下所示:
配置自定义请求标头
使用 RequestHeaderModifier 过滤条件创建 HTTPRoute 清单,然后将其保存为 http-route-request.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store
spec:
<...>
rules:
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
<...>
应用清单:
kubectl apply -f http-route-request.yaml
配置自定义响应标头
使用 ResponseHeaderModifier 过滤条件创建 HTTPRoute 清单,并将其保存为 http-route-response.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store
spec:
<...>
rules:
filters:
- type: ResponseHeaderModifier
responseHeaderModifier:
<...>
应用清单:
kubectl apply -f http-route-response.yaml
您可以按照 Gateway API 实现中的说明添加、设置和移除标头。您可以使用 Cloud de Confiance 支持的变量通过自定义标头配置 HTTPRoute。
示例 1:
如需配置在将客户端位置信息发送到后端服务之前将该信息添加到 HTTP 请求的 HTTPRoute,请创建 HTTPRoute 清单并将其命名为 external-http-request.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store
spec:
parentRefs:
- kind: Gateway
name: external-http
hostnames:
- store.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /fr
filters:
# Add custom headers to requests that have `/fr` in the path.
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Client-Geo-Location
value: "{client_region},{client_city}"
backendRefs:
- name: store-french
port: 8080
例如,对于位于法国特拉斯堡的客户端,网关会将标头添加为 X-Client-Geo-Location:FR,Strasbourg。
示例 2:
如需配置添加自定义响应标头以支持 HTTP 严格传输安全协议的 HTTPRoute,请创建 HTTPRoute 清单并将其命名为 external-http-response.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: store
spec:
parentRefs:
- kind: Gateway
name: external-http
hostnames:
- store.example.com
rules:
- matches:
- path:
type: PathPrefix
value: /de
filters:
# Add custom headers to responses to requests that have `/de` in the
# path.
- type: ResponseHeaderModifier
responseHeaderModifier:
add:
- name: Strict-Transport-Security
value: max-age=63072000
backendRefs:
- name: store-german
port: 8080
验证配置
如需在配置自定义请求和响应标头后验证配置,请执行以下操作:
kubectl get httproute输出类似于以下内容:
NAME HOSTNAMES AGE store ["store.example.com"] 4d23h如需了解更多详情,请使用 describe 命令:
kubectl describe httproute输出类似于以下内容:
Name: store Namespace: default Labels: <none> Annotations: <none> API Version: gateway.networking.k8s.io/v1 Kind: HTTPRoute Metadata: Creation Timestamp: 2023-05-27T00:51:01Z Generation: 5 Resource Version: 25418887 UID: 2e07a1b8-420b-41b4-acd1-cecbfcd39f42 Spec: Hostnames: store.example.com Parent Refs: Group: gateway.networking.k8s.io Kind: Gateway Name: external-http Rules: Backend Refs: Group: Kind: Service Name: store-v1 Port: 8080 Weight: 1 Matches: Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-v2 Port: 8080 Weight: 1 Matches: Headers: Name: env Type: Exact Value: canary Path: Type: PathPrefix Value: / Backend Refs: Group: Kind: Service Name: store-german Port: 8080 Weight: 1 Filters: Request Header Modifier: Add: Name: X-Client-Geo-Location Value: {client_region},{client_city} Type: RequestHeaderModifier Matches: Path: Type: PathPrefix Value: /de Status: <...>
配置前端 mTLS
为了启用客户端证书身份验证,Google 应用负载平衡器提供了前端 mTLS。对于 GKE Gateway,前端 mTLS 可让您为所有受支持的 GatewayClass 资源(无论是全球级还是区域级)配置和应用客户端证书验证。如需了解详情,请参阅为网关配置前端 mTLS。
配置后端 TLS
后端经过身份验证的 TLS 是一项安全功能,可让 GKE 网关负载均衡器验证其连接到的后端的身份。对于 GKE 网关,此功能可让您为受支持的 GatewayClass(例如全球或区域级外部托管负载平衡器和区域级内部负载平衡器)配置和应用后端证书验证。
如需了解详情,请参阅保护网关安全。
如需让网关也向后端验证自己的身份(双向 TLS),您应在网关资源上使用客户端证书。如需了解相关说明,请参阅为网关配置后端双向 TLS (mTLS)。
路由状态
HTTPRoute 资源会发出条件和事件,以帮助用户了解 HTTPRoute 是否已成功与一个或多个 Gateway 绑定,或者 HTTPRoute 是否被拒绝。
HTTPRoute 条件
HTTPRoute 条件指示 Route 的状态及其绑定到的 Gateway。由于一个 Route 可以绑定到多个 Gateway,因此这是一个 Gateway 以及 Route 与每个 Gateway 之间的各个条件的列表。
Accepted=True表示 HTTPRoute 已成功绑定到 Gateway。Accepted=False表示 HTTPRoute 已被拒绝与此 Gateway 绑定。
如果 Gateway bindings 标题下未列出任何 Gateway,则 HTTPRoute 标签和 Gateway 标签选择器可能不匹配。如果 Route 未被任何 Gateway 选择,则可能会发生这种情况。
HTTPRoute 事件
HTTPRoute 事件提供有关 HTTPRoute 状态的详细信息。事件分组的原因如下:
ADD事件由添加的资源触发。UPDATE事件由更新的资源触发。SYNC事件由定期协调触发。
路由合并、优先权和验证
路由优先权
Gateway API 针对具有重叠路由规则的路由应如何匹配流量定义了严格的优先权规则。两个重叠 HTTPRoute 之间的优先权如下所示:
- 主机名合并:最长/最具体的主机名匹配。
- 路径合并:最长/最具体的路径匹配。
- 标头合并:匹配的 HTTP 标头的最大数。
- 冲突:如果前三个规则未确立优先权,则优先权转给时间戳最早的 HTTPRoute 资源。
路由合并
对于 gke-l7 GatewayClass,给定网关的所有 HTTPRoutes 都会合并到同一个网址映射资源中。HTTPRoute 的合并在一起的方式取决于 HTTPRoute 之间的重叠类型。来自前面的示例的 HTTPRoute 可以拆分为三个单独的 HTTPRoute,用于说明路由合并和优先权:
- 路由合并:所有三个 HTTPRoute 都与同一
internal-http网关连接,因此它们会合并在一起。 - 主机名合并:对于
store.example.com,所有三个路由都匹配,因此它们的主机名规则会合并。 - 路径合并:store-german-route 具有更具体的路径
/de,因此不会进一步合并。store-v1-route 和 store-v2-route 同样与同一/*路径匹配,因此它们会在该路径上合并。 - 标头合并:store-v2-route 具有一组比 store-v1-route 更具体的 HTTP 标头匹配项,因此不会进一步合并。
- 冲突:由于路由可以按主机名、路径和标头进行合并,因此不会发生冲突,并且所有路由规则都应用于流量。
前面的示例中使用的单个 HTTPRoute 相当于这三个单独的路由:
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: store-v1-route
spec:
parentRefs:
- kind: Gateway
name: internal-http
hostnames:
- "store.example.com"
rules:
- backendRefs:
- kind: Service
name: store-v1
port: 8080
---
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: store-v2-route
spec:
parentRefs:
- kind: Gateway
name: internal-http
hostnames:
- "store.example.com"
rules:
- matches:
- headers:
- type: Exact
name: env
value: canary
backendRefs:
- kind: Service
name: store-v2
port: 8080
---
kind: HTTPRoute
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: store-german-route
spec:
parentRefs:
- kind: Gateway
name: internal-http
hostnames:
- "store.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: /de
backendRefs:
- kind: Service
name: store-german
port: 8080
Kubernetes 网关和 Istio 网关
请注意,Kubernetes Gateway API 和 Istio API 都有一个名为 Gateway 的资源。虽然它们执行类似的功能,但并不是相同的资源。如果您在同一 Kubernetes 集群中同时使用 Istio 和 Gateway API,则当您在命令行中使用 kubectl 时,这些名称将重叠。kubectl get gateway 可能会返回 Kubernetes 网关资源,但不会返回 Istio 网关资源,反之亦然。
$ kubectl api-resources
NAME SHORTNAMES APIGROUP NAMESPACED KIND
gateways gw networking.istio.io/v1beta1 true Gateway
gateways gtw networking.k8s.io/v1beta1 true Gateway
如果您使用的是 Istio 并升级到 GKE 1.20 及更高版本,则建议开始使用网关资源简称或指定 API 组。Kubernetes 网关的简称为 gtw,Istio 网关的简称为 gw。以下命令会分别返回 Kubernetes 网关资源和 Istio 网关资源。
# Kubernetes Gateway
$ kubectl get gtw
NAME CLASS
multi-cluster-gateway gke-l7-global-external-managed-mc
$ kubectl get gateway.networking.x-k8s.io
NAME CLASS
multi-cluster-gateway gke-l7-global-external-managed-mc
# Istio Gateway
$ kubectl get gw
NAME AGE
bookinfo-gateway 64m
$ kubectl get gateway.networking.istio.io
NAME AGE
bookinfo-gateway 64m
问题排查
区域中缺少代理专用子网
具体情况:
创建区域级 Gateway(内部或外部)时,可能会出现以下问题:
generic::invalid_argument: error ensuring load balancer: Insert: Invalid value for field 'resource.target': 'regions/[REGION_NAME]/targetHttpProxies/gkegw-x5vt-default-internal-http-[ID]'. A reserved managed proxy subnetwork with purpose REGIONAL_MANAGED_PROXY is required.
原因:
此错误消息表示,您的网关所在的区域不存在代理专用子网。
临时解决方法:
如需解决此问题,请配置代理专用子网。
区域中已存在用途错误的代理专用子网
具体情况:
为区域级 Gateway(内部或外部)创建代理专用子网时,可能会出现以下问题:
ERROR: (gcloud.compute.networks.subnets.create) Could not fetch resource:
- The resource 'projects/[PROJECT_NAME]/regions/[REGION_NAME]/subnetworks/[PROXY_ONLY_SUBNET_NAME]' already exists
原因:
此错误消息表示,您尝试在已存在代理专用子网的区域中创建区域代理专用子网。
临时解决方法:
如需解决此问题,请按照以下步骤操作:
检查该区域中是否已存在代理专用子网,并验证其用途是否正确:
列出您的子网,以查找该区域中的代理专用子网:
gcloud compute networks subnets list --regions=COMPUTE_REGION将
COMPUTE_REGION替换为您要在其中创建区域级 Gateway 的 Compute Engine 区域。描述该区域中的代理专用子网,以确定其用途:
gcloud compute networks subnets describe PROXY_ONLY_SUBNET \ --region COMPUTE_REGION | grep -E 'name|purpose'将
PROXY_ONLY_SUBNET替换为代理专用子网。
GKE Gateway 仅支持区域级网关(内部或区域级)的
REGIONAL_MANAGED_PROXY代理专用子网。如果该区域中现有的代理专用子网是以
INTERNAL_HTTPS_LOAD_BALANCER用途创建的,请将其用途迁移到REGIONAL_MANAGED_PROXY。
没有健康的上行
具体情况:
创建网关但无法访问后端服务(503 响应代码)时,可能会出现以下问题:
no healthy upstream
原因:
此错误消息表示健康检查探测器找不到健康状况良好的后端服务。您的后端服务可能处于健康状况良好状态,但您可能需要自定义健康检查。
临时解决方法:
如需解决此问题,请使用 HealthCheckPolicy 根据应用的要求自定义监控状况检查(例如 /health)。
删除集群后出现孤立的网关资源
具体情况:
尝试重新创建网关时,GKE 管理的负载均衡器资源仍会在 Cloud de Confiance 控制台中显示,但无法使用界面将其删除,界面会显示类似于以下内容的消息:
This load balancing service is read-only. It is managed by GKE and can be modified only by GKE.
原因:
如果 Gateway 控制器在集群或网关删除和重新创建期间未能清理过时的底层 Cloud de Confiance by S3NS 资源,则会出现此问题。
临时解决方法:
如需解决此问题,请使用 Google Cloud CLI 命令删除孤立的负载均衡资源,如下所示:
gcloud compute forwarding-rules delete FORWARDING_RULE_NAME
# For HTTP proxies
gcloud compute target-http-proxies delete PROXY_NAME
# For HTTPS proxies
gcloud compute target-https-proxies delete PROXY_NAME
gcloud compute url-maps delete URL_MAP_NAME
# For global backend services
gcloud compute backend-services delete BACKEND_SERVICE_NAME --global
# For regional backend services
gcloud compute backend-services delete BACKEND_SERVICE_NAME --region=REGION
gcloud compute health-checks delete HEALTH_CHECK_NAME
gcloud compute network-endpoint-groups delete NEG_NAME --zone=ZONE
替换以下内容:
FORWARDING_RULE_NAME:转发规则的名称。PROXY_NAME:目标代理的名称。URL_MAP_NAME:网址映射的名称。BACKEND_SERVICE_NAME:后端服务的名称。HEALTH_CHECK_NAME:健康检查的名称。NEG_NAME:网络端点组的名称。REGION:区域后端服务的区域。ZONE:网络端点组的可用区。
后续步骤
- 详细了解 Gateway Controller。
- 了解如何使用政策配置网关资源。
- 请参阅 Gateway API 文档了解其他网关配置。