本文档介绍如何使用混合协议外部 LoadBalancer 服务(同时支持 TCP 和 UDP 流量)将 Google Kubernetes Engine (GKE) 集群中运行的应用公开给互联网。
如需详细了解外部直通式网络负载均衡器,请参阅基于后端服务的外部直通式网络负载均衡器。
概览
您可以使用两个单独的 GKE LoadBalancer 服务(具有手动协调的共享 IP 地址)公开同时使用 TCP 和 UDP 协议的应用。不过,这种方法效率不高,因为它需要为单个应用管理多个服务,并且可能会导致配置错误或 IP 地址配额耗尽等问题。
借助混合协议 LoadBalancer 服务,您可以使用单个服务来管理 TCP 和 UDP 的流量。使用单个服务可让您使用单个 IPv4 地址和一组适用于这两种协议的整合转发规则,从而简化配置。外部直通式网络负载均衡器支持此功能。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请通过运行
gcloud components update命令来获取最新版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
- 确保您已有 Autopilot 或 Standard 集群。如需创建新集群,请参阅创建 Autopilot 集群。
要求
如需创建使用混合协议的外部 LoadBalancer 服务,您的集群必须满足以下要求:
- 混合协议负载均衡仅适用于新创建的 1.34.1-gke.2190000 版或更高版本的集群。
- 您必须在集群中启用
HttpLoadBalancing插件。 - 对于新的外部 LoadBalancer 服务,如需实现负载均衡器,请在服务清单中将
spec.loadBalancerClass字段设置为networking.gke.io/l4-regional-external。对于现有服务,您的清单已包含cloud.google.com/l4-rbs: "enabled"注释,您可以将该注释保留原样。
限制
- 混合协议负载均衡器仅支持 IPv4 地址。
您无法在具有以下终结器的服务清单中使用混合协议:
gke.networking.io/l4-ilb-v1gke.networking.io/l4-netlb-v1
如果您的清单包含这些终结器,您必须根据上述要求删除并重新创建服务。
价格
Google Cloud 按转发规则、任何外部 IP 地址和发送的数据量向您收取费用。下表介绍了指定配置所使用的转发规则和外部 IP 地址的数量。如需了解详情,请参阅 VPC 网络价格。
| 类型 | 传输层 | 互联网层 | 转发规则数 | 外部 IP 地址数量 |
|---|---|---|---|---|
| 外部 | 单个(TCP 或 UDP) | IPv4 | 1 | 1 |
| IPv6 | 1 | 1 | ||
| IPv4 和 IPv6(双栈) | 2 | 2 | ||
| 混合(TCP 和 UDP) | IPv4 | 2 | 1 |
部署工作负载
本部分介绍如何部署同时监听 TCP 和 UDP 端口的示例工作负载。请注意,无论您是使用混合协议 LoadBalancer 服务还是两个单独的单协议 LoadBalancer 服务,部署配置都是相同的。
以下清单适用于同时监听 TCP 和 UDP 流量的端口 8080 的示例应用。将以下清单保存为
mixed-app-deployment.yaml:apiVersion: apps/v1 kind: Deployment metadata: name: mixed-app-deployment spec: replicas: 3 selector: matchLabels: app: mixed-app template: metadata: labels: app: mixed-app spec: containers: - image: gcr.io/kubernetes-e2e-test-images/agnhost:2.6 name: agnhost args: ["serve-hostname", "--port=8080", "--tcp=true", "--udp=true", "--http=false"] ports: - name: tcp8080 protocol: TCP containerPort: 8080 - name: udp8080 protocol: UDP containerPort: 8080将清单应用到您的集群:
kubectl apply -f mixed-app-deployment.yaml
创建混合协议负载均衡器
创建类型为 LoadBalancer 的服务,以向 TCP 和 UDP 流量公开部署。
将以下清单保存为
mixed-protocol-lb.yaml:apiVersion: v1 kind: Service metadata: name: mixed-protocol-lb spec: loadBalancerClass: "networking.gke.io/l4-regional-external" type: LoadBalancer selector: app: mixed-app ports: - name: tcp-port protocol: TCP port: 8080 - name: udp-port protocol: UDP port: 8080上述服务有两个端口,一个用于 TCP,一个用于 UDP,两者均位于端口 8080 上。
将清单应用到您的集群:
kubectl apply --server-side -f mixed-protocol-lb.yaml
验证混合协议负载均衡器
创建服务后,验证 GKE 是否已成功创建负载均衡器。
检查 Service:
kubectl describe service mixed-protocol-lb输出显示了负载均衡器的外部 IP 地址以及 TCP 和 UDP 的转发规则。验证输出中的以下详细信息:
status.loadBalancer.ingress.ip字段已填充。- 验证外部负载均衡器是否包含以下注释:
service.kubernetes.io/tcp-forwarding-ruleservice.kubernetes.io/udp-forwarding-rule
Events部分不包含任何错误消息。
更新混合协议负载均衡器
您可以通过修改服务清单来更新混合协议负载均衡器上的端口。要编辑 Service,请运行以下命令:
kubectl edit service SERVICE_NAME
将 SERVICE_NAME 替换为Service的名称。
更新端口
如需更新混合协议负载均衡器上的端口,请修改服务清单的 ports 部分。您可以添加、移除或修改端口。
以下示例添加了用于流式传输的 UDP 端口和用于游戏服务器元数据的 TCP 端口:
apiVersion: v1
kind: Service
metadata:
name: mixed-protocol-lb
spec:
loadBalancerClass: "networking.gke.io/l4-regional-external"
type: LoadBalancer
selector:
app: mixed-app
ports:
- name: tcp-port
protocol: TCP
port: 8080
- name: streaming
protocol: UDP
port: 10100
- name: gameserver-metadata
protocol: TCP
port: 10400
- name: https
protocol: TCP
port: 443
将单协议负载均衡器更新为混合协议负载均衡器
如需将单协议负载均衡器更改为混合协议负载均衡器,请修改服务以包含 TCP 和 UDP 协议的端口。
以下示例向仅限 TCP 的现有负载均衡器添加了 DNS 的 UDP 端口:
apiVersion: v1
kind: Service
metadata:
name: already-existing-single-protocol-lb
spec:
loadBalancerClass: "networking.gke.io/l4-regional-external"
type: LoadBalancer
selector:
app: mixed-app
ports:
- name: http
protocol: TCP
port: 80
- name: https
protocol: TCP
port: 443
- name: dns
protocol: UDP
port: 53
将混合协议负载均衡器更新为单协议负载均衡器
如需将混合协议负载均衡器更改为单协议负载均衡器,请移除其中一种协议的所有端口。
以下示例移除了 DNS 的 UDP 端口,从而将负载均衡器转换为仅限 TCP:
apiVersion: v1
kind: Service
metadata:
name: already-existing-mixed-protocol-lb
spec:
loadBalancerClass: "networking.gke.io/l4-regional-external"
type: LoadBalancer
selector:
app: mixed-app
ports:
- name: http
protocol: TCP
port: 80
- name: https
protocol: TCP
port: 443
删除混合协议 LoadBalancer
如需删除 mixed-protocol-lb 外部 LoadBalancer 服务,请运行以下命令:
kubectl delete service mixed-protocol-lb
GKE 会自动移除为该服务创建的所有负载均衡器资源。
问题排查
本部分介绍了如何解决混合协议 LoadBalancer 服务的常见问题。
检查是否存在错误事件
问题排查的第一步是检查与您的服务相关联的事件。
获取服务的详细信息:
kubectl describe service mixed-protocol-lb查看输出末尾的
Events部分,了解是否有任何错误消息。
错误:LoadBalancer 不支持混合协议
如果您使用 cloud.google.com/l4-rbs: "enabled" 注释创建了服务,则在创建混合协议负载均衡器后,您可能会看到来自原始服务控制器的警告事件:mixed-protocol is not
supported for LoadBalancer。
您可以放心地忽略此消息,因为支持混合协议的新控制器会正确配置负载均衡器。
更新后缺少端口定义
具体情况:
当您更新同时使用 TCP 和 UDP 的同一端口(例如端口 8080)的服务时,更新后的服务会缺少其中一个端口定义。
原因:
这是 Kubernetes 中的已知问题。当您更新在同一端口上具有多个协议的服务时,客户端补丁计算可能会错误地合并端口列表,从而导致其中一个端口定义被移除。此问题会影响使用客户端修补的客户端,例如 kubectl apply 和使用合并补丁的 Go 客户端。
解决方案:
此问题的解决方法取决于您的客户。
对于 kubectl:将
--server-side标志与kubectl apply搭配使用:kubectl apply --server-side -f YOUR_SERVICE_MANIFEST.yaml将
YOUR_SERVICE_MANIFEST替换为您的服务清单的名称。对于 Go 客户端:请勿使用合并补丁。请改用更新调用来替换服务。这需要一个包含整个服务对象规范的 HTTP
PUT请求。
后续步骤
- 详细了解如何使用 Service 公开应用。
- 了解 LoadBalancer Service。