本页面介绍如何通过创建 Kubernetes Ingress 对象来配置外部应用负载均衡器。
在阅读本页内容之前,您应该先熟悉 GKE 网络概念。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行
gcloud components update
以获取最新版本。
启用 HttpLoadBalancing
插件
集群必须启用 HttpLoadBalancing
插件。默认情况下,此插件处于启用状态。在 Autopilot 集群中,您无法停用此插件。
您可以使用 Google Cloud 控制台或 Google Cloud CLI 启用 HttpLoadBalancing
插件。
控制台
转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。
点击要修改的集群的名称。
在网络下的 HTTP 负载均衡字段中,点击 edit 修改 HTTP 负载均衡。
选中启用 HTTP 负载均衡复选框。
点击保存更改。
gcloud
gcloud container clusters update CLUSTER_NAME --update-addons=HttpLoadBalancing=ENABLED
将 CLUSTER_NAME
替换为您的集群名称。
创建静态 IP 地址
外部应用负载均衡器提供一个稳定的 IP 地址,您可以使用该 IP 地址将请求路由到一个或多个 Service。如果您需要永久的 IP 地址,则必须在创建 Ingress 之前预留一个全球静态外部 IP 地址。
如果您修改现有 Ingress 以使用静态 IP 地址而不是临时 IP 地址,则 GKE 可能会在重新创建负载均衡器的转发规则时更改负载均衡器的 IP 地址。
创建外部应用负载均衡器
在本练习中,您将配置外部应用负载均衡器,以根据网址路径将请求路由到不同的 Service。
如需在 Google Cloud 控制台中直接遵循有关此任务的分步指导,请点击操作演示:
创建 Deployment 和 Service
使用名为 hello-world-1
和 hello-world-2
的 Service 创建两个 Deployment:
将以下清单保存为
hello-world-deployment-1.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: hello-world-deployment-1 spec: selector: matchLabels: greeting: hello version: one replicas: 3 template: metadata: labels: greeting: hello version: one spec: containers: - name: hello-app-1 image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0" env: - name: "PORT" value: "50000"
此清单描述了一个包含三个副本的示例 Deployment。
将清单应用于集群:
kubectl apply -f hello-world-deployment-1.yaml
将以下清单保存为
hello-world-service-1.yaml
:apiVersion: v1 kind: Service metadata: name: hello-world-1 spec: type: NodePort selector: greeting: hello version: one ports: - protocol: TCP port: 60000 targetPort: 50000
此清单描述了具有以下属性的 Service:
- 同时具有
greeting: hello
标签和version: one
标签的任何 Pod 都是 Service 的成员。 - GKE 会将发送到 TCP 端口 60000 上的 Service 的请求转发到 TCP 端口 50000 上的其中一个成员 Pod。
- Service 类型为
NodePort
,除非您使用容器原生负载均衡功能,否则必须使用该类型。如果使用容器原生负载均衡功能,则服务类型不存在限制。建议使用type: ClusterIP
。
- 同时具有
将清单应用于集群:
kubectl apply -f hello-world-service-1.yaml
将以下清单保存为
hello-world-deployment-2.yaml
:apiVersion: apps/v1 kind: Deployment metadata: name: hello-world-deployment-2 spec: selector: matchLabels: greeting: hello version: two replicas: 3 template: metadata: labels: greeting: hello version: two spec: containers: - name: hello-app-2 image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0" env: - name: "PORT" value: "8080"
此清单描述了一个包含三个副本的示例 Deployment。
将清单应用于集群:
kubectl apply -f hello-world-deployment-2.yaml
将以下清单保存为
hello-world-service-2.yaml
:apiVersion: v1 kind: Service metadata: name: hello-world-2 spec: type: NodePort selector: greeting: hello version: two ports: - protocol: TCP port: 80 targetPort: 8080
此清单描述了具有以下属性的 Service:
- 同时具有
greeting: hello
标签和version: two
标签的任何 Pod 都是 Service 的成员。 - GKE 会将发送到 TCP 端口 80 上的 Service 的请求转发到 TCP 端口 8080 上的其中一个成员 Pod。
- 同时具有
将清单应用于集群:
kubectl apply -f hello-world-service-2.yaml
创建 Ingress
创建一个 Ingress,指定根据请求中的网址路径路由请求的规则。当您创建 Ingress 时,GKE Ingress 控制器会创建并配置外部应用负载均衡器。
将以下清单保存为
my-ingress.yaml
:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress annotations: # If the class annotation is not specified it defaults to "gce". kubernetes.io/ingress.class: "gce" spec: rules: - http: paths: - path: /* pathType: ImplementationSpecific backend: service: name: hello-world-1 port: number: 60000 - path: /v2 pathType: ImplementationSpecific backend: service: name: hello-world-2 port: number: 80
此清单描述了具有以下属性的 Ingress:
有两个 GKE Ingress 类。指定 Ingress 类必须使用
kubernetes.io/ingress.class
注解。您不能使用spec.ingressClassName
指定 GKE Ingress。gce
类会部署外部应用负载均衡器。gce-internal
类会部署内部应用负载均衡器。当您部署不带注解
spec.ingressClassName
和kubernetes.io/ingress.class
的 Ingress 资源时,GKE 会创建一个外部应用负载均衡器。这与指定kubernetes.io/ingress.class: gce
注解时发生的行为相同。如需了解详情,请参阅 GKE Ingress 控制器行为。GKE 会为每个
backend.service
创建一个 Google Cloud 后端 Service。当客户端将请求发送到网址路径为
/
的负载均衡器时,GKE 会将请求转发到端口 60000 上的hello-world-1
Service。当客户端将请求发送到网址路径为/v2
的负载均衡器时,GKE 会将请求转发到端口 80 上的hello-world-2
Service。如需详细了解path
和pathType
属性,请参阅网址路径。
将清单应用于集群:
kubectl apply -f my-ingress.yaml
测试外部应用负载均衡器
请等待 5 分钟,让负载均衡器完成配置,然后测试外部应用负载均衡器:
查看 Ingress:
kubectl get ingress my-ingress --output yaml
输出结果会显示外部应用负载均衡器的 IP 地址:
status: loadBalancer: ingress: - ip: 203.0.113.1
测试
/
路径:curl LOAD_BALANCER_IP_ADDRESS/
将
LOAD_BALANCER_IP_ADDRESS
替换为负载均衡器的外部 IP 地址。输出类似于以下内容:
Hello, world! Version: 1.0.0 Hostname: ...
如果输出包含 404 错误,请等待几分钟。
测试
/v2
路径:curl load-balancer-ip/v2
输出类似于以下内容:
Hello, world! Version: 2.0.0 Hostname: ...
适用于外部负载均衡的 Ingress 的工作原理
外部应用负载均衡器充当您的客户端和应用之间的代理。如果您想要接受来自客户端的 HTTPS 请求,则负载均衡器必须具有证书,这样才能向客户端证明其身份。 负载均衡器还必须具有私钥才能完成 HTTPS 握手。 有关详情,请参阅:
网址路径
Ingress 的 path
字段唯一支持的通配符是 *
字符。*
字符必须紧跟在正斜线 (/
) 之后,并且必须是格式中的最后一个字符。例如,/*
、/foo/*
、/foo/bar/*
是有效格式,但 *
、/foo/bar*
、/foo/*/bar
不是有效格式。
较具体的格式优先于不太具体的格式。如果您同时拥有 /foo/*
和 /foo/bar/*
,则选择 /foo/bar/bat
来匹配 /foo/bar/*
。 如需详细了解路径限制和格式匹配,请参阅网址映射文档。
对于运行低于 1.21.3-gke.1600 的版本的 GKE 集群,pathType
字段唯一支持的值为 ImplementationSpecific
。对于运行 1.21.3-gke.1600 版或更高版本的集群,pathType
还支持 Prefix
和 Exact
值。
停用 HTTP
如果希望客户端和负载均衡器之间的所有流量都使用 HTTPS,则可以停用 HTTP。如需了解详情,请参阅停用 HTTP。
负载均衡器和应用之间的 HTTPS
如果在 GKE Pod 中运行的应用能够接收 HTTPS 请求,您可以将负载均衡器配置成使用 HTTPS 将请求转发给应用。如需了解详情,请参阅负载均衡器和应用之间的 HTTPS (TLS)。
客户端和负载均衡器之间的 HTTP/2
客户端可以使用 HTTP/2 向负载均衡器发送请求。无需配置。
负载均衡器和应用之间的 HTTP/2
如果在 GKE Pod 中运行的应用能够接收 HTTP/2 请求,则可以将负载均衡器配置为在将请求转发给应用时使用 HTTP/2。如需了解详情,请参阅 HTTP/2 与 Ingress 搭配使用实现负载均衡。
网络端点组
如果您的集群支持容器原生负载均衡,则建议使用网络端点组 (NEG)。对于 GKE 集群 1.17 和更高版本,以及在特定条件下,容器原生负载均衡是默认负载均衡,不需要明确的 cloud.google.com/neg: '{"ingress": true}'
Service 注释。
共享 VPC
如果要在其中部署 Ingress 资源的 GKE 集群位于某个服务项目中,并且您希望由 GKE 控制层面来管理宿主项目中的防火墙资源,则必须按照为具有共享 VPC 的集群管理防火墙资源中的要求,为该服务项目的 GKE 服务账号在宿主项目中授予适当的 IAM 权限。这样,Ingress 控制器便可创建防火墙规则,允许用于 Google Cloud 健康检查的入站流量及普通流量。
以下是 Ingress 资源日志中可能存在的事件示例。如果 Ingress 控制器由于未正确配置权限而无法创建防火墙规则来允许用于 Google Cloud 健康检查的入站流量,则会发生此错误。
Firewall change required by security admin: `gcloud compute firewall-rules update <RULE_NAME> --description "GCE L7 firewall rule" --allow tcp:<PORT> --source-ranges 130.211.0.0/22,35.191.0.0/16 --target-tags <TARGET_TAG> --project <HOST_PROJECT>
如果您希望从宿主项目手动预配防火墙规则,则可以将 networking.gke.io/suppress-firewall-xpn-error: "true"
注释添加到 Ingress 资源,以忽略 firewallXPNError
事件。
外部 Ingress 注释摘要
Ingress 注释
注解 | 说明 |
---|---|
kubernetes.io/ingress.allow-http | 指定是否允许客户端与 HTTP(S) 负载均衡器之间的 HTTP 流量。可能的值为“true”和“false”。默认为“true”。 请参阅停用 HTTP。 |
ingress.gcp.kubernetes.io/pre-shared-cert | 使用此注释将证书资源附加到 GKE Ingress 资源。如需了解详情,请参阅将多个 SSL 证书与外部应用负载均衡器搭配使用。 |
kubernetes.io/ingress.global-static-ip-name | 使用此注释指定负载均衡器应使用先前创建的静态外部 IP 地址。请参阅 HTTP(S) 负载均衡器的静态 IP 地址。 |
networking.gke.io/v1beta1.FrontendConfig | 使用此注释可以自定义负载均衡器面向客户端的配置。如需了解详情,请参阅 Ingress 配置。 |
networking.gke.io/suppress-firewall-xpn-error | 对于 Ingress 负载均衡器,如果 Kubernetes 由于权限不足而无法更改防火墙规则,则系统会每隔几分钟创建一次 firewallXPNError 事件。在 GLBC 1.4 及更高版本中,您可以通过将 networking.gke.io/suppress-firewall-xpn-error: "true" 注释添加到 Ingress 资源,忽略 firewallXPNError 事件。您可以随时移除此注释以取消忽略。可能的值有 true 和 false 。默认值为 false 。 |
与 Ingress 相关的服务注释
注解 | 说明 |
---|---|
cloud.google.com/app-protocols | 使用此注释可设置负载均衡器与应用之间的通信协议。可能的协议有 HTTP、HTTPS 和 HTTP2。 请参阅负载均衡器与应用之间的 HTTPS 和使用 Ingress 进行负载均衡的 HTTP/2。 |
cloud.google.com/backend-config | 使用此注解配置与 Service 关联的后端服务。如需了解详情,请参阅 Ingress 配置。 |
cloud.google.com/neg | 使用此注释指定负载均衡器应使用网络端点组。请参阅使用容器原生负载均衡。 |
后续步骤
- 阅读 GKE 中适用于外部应用负载均衡器的 Ingress 的概念性概览。
- 完成使用 Ingress 设置外部应用负载均衡器的教程。
阅读 GKE 中 Service 的概念性概览。
实现基本外部 Ingress。