本文档介绍了如何使用混合协议外部或内部 LoadBalancer Service 处理 TCP 和 UDP 流量,以公开在 Google Kubernetes Engine (GKE) 集群中运行的应用。
如需详细了解 L4 负载平衡器,请参阅 LoadBalancer Service 简介。
概览
您可以使用两个单独的 GKE LoadBalancer Service(具有手动协调的共享 IP 地址)公开同时使用 TCP 和 UDP 协议的应用。不过,这种方法效率不高,因为它需要为单个应用管理多个 Service,并且可能会导致配置错误或 IP 地址配额耗尽等问题。
借助混合协议 LoadBalancer Service,您可以使用单个 Service 来管理 TCP 和 UDP 的流量。使用单个 Service 可让您为这两种协议使用单个 IP 地址和一组整合的转发规则,从而简化配置。区域级外部直通式网络负载平衡器和内部直通式网络负载平衡器都支持此功能。
GKE 支持具有 IPv4、IPv6 和双栈配置的混合协议 Service。混合协议 Service 使用第 3 层 (L3) 转发规则。按照设计,这些规则会将到达负载平衡器的虚拟 IP (VIP) 地址的所有流量直接转发到集群节点。
为了确保安全性,GKE 会自动创建和管理优先级为 999 的防火墙规则,这些规则仅允许在 Service 清单中定义的特定 TCP 和 UDP 流量。所有其他未经授权的流量 (定向到负载均衡器的 VIP 地址)都会被 GKE 管理的防火墙规则(使用优先级 1000)阻止。如果您创建了优先级更高的防火墙规则,请确保这些规则不会意外允许未经授权的流量到达您的节点。 如需了解详情,请参阅 GKE Service 防火墙 规则。
准备工作
在开始之前,请确保您已完成以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如需使用 Google Cloud CLI 执行此任务,
请安装并
初始化
gcloud CLI。如果您之前安装了 gcloud CLI,请通过运行
gcloud components update命令来获取最新 版本。较早版本的 gcloud CLI 可能不支持运行本文档中的命令。
- 确保您已有 Autopilot 或 Standard 集群。如需创建新集群,请参阅创建 Autopilot 集群。
要求
如需创建使用混合协议的 LoadBalancer Service,您的集群必须满足以下要求:
- 混合协议负载均衡在 GKE 1.36.2-gke.1498000 版及更高版本中正式发布。正式版支持具有 IPv4、IPv6 和双栈配置的外部和内部负载平衡器。
- 对于 1.34.1-gke.2190000 到 1.36.2-gke.1498000 版本,混合协议负载均衡仅适用于使用 IPv4 地址的外部负载均衡器。
- 您必须在集群上启用
HttpLoadBalancing插件。 - 对于内部负载平衡器,集群必须启用 GKE 子集化 。
- 对于新的内部 LoadBalancer Service,请在 Service 清单中将
spec.loadBalancerClass字段的值设置为networking.gke.io/l4-regional-internal。对于现有的内部 Service, 您的清单已包含networking.gke.io/load-balancer-type: "Internal"注解,您可以保留该注解。 - 对于新的外部 LoadBalancer Service,请在 Service 清单中将
spec.loadBalancerClass字段设置为networking.gke.io/l4-regional-external。 对于现有的外部 Service,您的清单已包含cloud.google.com/l4-rbs: "enabled"注解,您可以保留该 注解。
限制
- 在 1.34.1-gke.2190000 到 1.36.2-gke.1498000 版本中,混合协议负载平衡器仅支持 IPv4 地址。
- 具有
gke.networking.io/l4-ilb-v1或gke.networking.io/l4-netlb-v1终止器的现有 Service 不能用于混合协议负载均衡。如果您想在这些 Service 上使用混合协议,则必须根据上述要求删除并重新创建 Service。 - 更新 Service 上的端口可能会导致通过负载均衡器路由的所有流量短暂中断。
- 您无法将 Private Service Connect 附加到混合协议 Service。
价格
Cloud de Confiance 会针对每个转发规则、任何外部 IP 地址和发送的数据向您收费。下表介绍了用于指定配置的转发规则数和外部 IP 地址数。如需了解详情,请参阅 VPC 网络价格。
| 类型 | 传输层 | 互联网层 | 转发规则数 | 外部 IP 地址数 |
|---|---|---|---|---|
| 内部 | 单个或混合(TCP、UDP 或两者) | IPv4 | 1 | 0 |
| IPv6 | 1 | 0 | ||
| IPv4 和 IPv6(双栈) | 2 | 0 | ||
| 外部 | 单个或混合(TCP、UDP 或两者) | IPv4 | 1 | 1 |
| IPv6 | 1 | 1 | ||
| IPv4 和 IPv6(双栈) | 2 | 2 |
部署工作负载
本部分介绍了如何部署同时监听 TCP 和 UDP 端口的示例工作负载。请注意,无论您使用的是混合协议 LoadBalancer Service 还是两个单独的单协议 LoadBalancer Service,Deployment 配置都是相同的。
以下清单适用于同时监听 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 的 Service,以向 TCP 和 UDP 流量公开部署。您可以创建外部或内部负载均衡器。
如需创建外部负载均衡器,请将以下清单保存为
mixed-protocol-lb.yaml:apiVersion: v1 kind: Service metadata: name: mixed-protocol-external-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如需创建内部负载均衡器,请将
spec.loadBalancerClass字段的值设置为networking.gke.io/l4-regional-internal。上述 Service 有两个端口,一个用于 TCP,一个用于 UDP,都在端口 8080 上。
将清单应用到您的集群:
kubectl apply --server-side -f mixed-protocol-lb.yaml
验证混合协议负载均衡器
创建服务后,验证 GKE 是否已成功创建负载均衡器。
检查 Service:
kubectl describe service SERVICE_NAME将
SERVICE_NAME替换为 Service 的名称(例如mixed-protocol-lb)。输出结果会显示负载均衡器的 IP 地址和转发规则。验证输出结果中的以下详细信息:
status.loadBalancer.ingress.ip字段已填充。- 对于 1.34.1-gke.2190000 到 1.36.2-gke.1498000 版本的集群,请验证是否存在以下外部负载均衡器注解:
service.kubernetes.io/tcp-forwarding-ruleservice.kubernetes.io/udp-forwarding-rule
- 对于在 1.36.2-gke.1498000 之后的版本上创建的集群,请根据您的配置验证是否存在以下负载均衡器注解:
- 对于 IPv4:
service.kubernetes.io/l3-forwarding-rule - 对于 IPv6:
service.kubernetes.io/l3-forwarding-rule-ipv6 - 对于双栈:这两个注解。
- 对于 IPv4:
- “
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" # for internal LB, use: "networking.gke.io/l4-regional-internal"
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" # for internal LB, use: "networking.gke.io/l4-regional-internal"
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" # for internal LB, use: "networking.gke.io/l4-regional-internal"
type: LoadBalancer
selector:
app: mixed-app
ports:
- name: http
protocol: TCP
port: 80
- name: https
protocol: TCP
port: 443
删除混合协议负载平衡器
如需删除混合协议 LoadBalancer Service,请运行以下命令:
kubectl delete service SERVICE_NAME
将 SERVICE_NAME 替换为 Service 的名称(例如 mixed-protocol-external-lb)。
GKE 会自动移除为该服务创建的所有负载均衡器资源。
问题排查
本部分介绍了如何解决混合协议 LoadBalancer Service 的常见问题。
检查错误事件
问题排查的第一步是检查与您的 Service 关联的事件。
获取 Service 的详细信息:
kubectl describe service SERVICE_NAME将
SERVICE_NAME替换为 Service 的名称。查看输出结果末尾的
Events部分,了解是否有任何错误 消息。
错误:负载平衡器不支持混合协议
如果您使用 cloud.google.com/l4-rbs: "enabled" 注释创建了服务,则在创建混合协议负载均衡器后,您可能会看到来自原始服务控制器的警告事件:mixed-protocol is not
supported for LoadBalancer。
您可以放心地忽略此消息,因为支持混合协议的新控制器会正确配置负载均衡器。
更新后缺少端口定义
具体情况:
当您更新同时使用 TCP 和 UDP 的同一端口(例如端口 8080)的 Service 时,更新后的 Service 中缺少其中一个端口定义。
原因:
这是 Kubernetes 中的已知问题。当您更新在同一端口上具有多个协议的 Service 时,客户端补丁计算可能会错误地合并端口列表,从而导致其中一个端口定义被移除。
此问题会影响使用客户端补丁的客户端,例如 kubectl apply 和使用合并补丁的 Go 客户端。
解决方案:
此问题的解决方法取决于您的客户端。
对于 kubectl:将
--server-side标志与kubectl apply搭配使用:kubectl apply --server-side -f YOUR_SERVICE_MANIFEST.yaml将
YOUR_SERVICE_MANIFEST替换为 Service 清单的名称。对于 go-client:请勿使用合并补丁。请改用更新调用来替换 Service。这需要使用整个 Service 对象规范发出 HTTP
PUT请求。