本文档介绍了如何在 GKE 中创建外部直通式网络负载平衡器和内部直通式网络负载平衡器
资源,以将多网络 Pod 公开给内部或外部
客户端。 Cloud de Confiance by S3NS 它介绍了多网络 LoadBalancer Service 的必要配置、功能和限制。
如果您将工作负载连接到多个 VPC 网络,请使用 LoadBalancer 类型的 Kubernetes Service 将流量路由到特定辅助网络上的 Pod。创建 Service 时,GKE 会创建一个直通式网络负载平衡器来管理此流量。
如需详细了解 GKE 中的多网络,请参阅关于 Pod 的多网络支持。
多网络 LoadBalancer Service 的工作原理
如需公开多网络工作负载,请创建 type: LoadBalancer 的 Service。
该 Service 必须包含一个特殊选择器,该选择器根据 Pod 的辅助接口的网络来定位 Pod。添加注解以指定是创建内部负载均衡器还是外部负载均衡器。
选择器中的 networking.gke.io/network 标签按网络过滤端点。此标签可确保负载均衡器仅将流量发送到连接到指定网络的 Pod 接口。
限制
多网络负载平衡器具有以下限制:
- 不支持使用
externalTrafficPolicy: Cluster的 Service。 - 不支持以
hostNetworkPod 为目标的 Service。 - 不支持 IPv6 和双栈网络。
- 您无法更改现有 Service 的网络。
- 仅支持第 3 层网络。
- 不支持基于目标池或实例组后端的负载平衡器。
- 辅助(非默认)网络不支持 ClusterIP 和 NodePort Service。
准备工作
在开始之前,请完成以下任务:
- 按照为 Pod 设置多网络支持 中的步骤操作, 准备 VPC 网络并创建具有额外网络的 GKE 集群。
- 确保您的集群已为第 4 层内部负载平衡器启用子集分配。如需启用此功能,请在创建或更新集群时使用
--enable-l4-ilb-subsetting标志。 - 确保您的集群运行的是 GKE 版本 1.36 或更高版本。
部署多网络 Pod
如需将 Pod 附加到其他网络,请使用 networking.gke.io/interfaces 注解创建 Deployment。此注解指定了 Pod 的网络和接口。
将以下清单保存为
web-app-deployment.yaml:apiVersion: apps/v1 kind: Deployment metadata: name: web-app labels: app: web-app spec: replicas: 3 selector: matchLabels: app: web-app template: metadata: labels: app: web-app annotations: networking.gke.io/default-interface: 'eth1' networking.gke.io/interfaces: '[ {"interfaceName":"eth0","network":"default"}, {"interfaceName": "eth1","network": "dmz"} ]' spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1 ports: - containerPort: 8080此清单会创建一个名为
web-app的 Deployment,其中包含三个 Pod。这些 Pod 有两个接口:eth0连接到default网络,eth1连接到dmz网络。networking.gke.io/default-interface注解将eth1设置为 Pod 的默认接口。将清单应用到您的集群:
kubectl apply -f web-app-deployment.yaml
如果您为 Service 使用非默认接口,则必须在 Pod 内配置路由。如需配置路由,请向具有 NET_ADMIN 功能的 Pod 规范添加 initContainer。
以下示例展示了为 eth1 接口添加默认路由的 initContainer:
initContainers:
- name: init-routes-busybox
image: busybox
command: ['sh', '-c', 'ip route add default dev eth1 table 200 && ip rule add from 172.16.1.0/24 table 200']
securityContext:
capabilities:
add: ["NET_ADMIN"]
在 initContainer 命令中,将 172.16.1.0/24 替换为 Pod 网络的辅助 IP 地址范围。
部署内部 LoadBalancer Service
如需在 dmz 网络上公开 web-app Deployment,请创建内部 LoadBalancer Service。
将以下清单保存为
internal-lb-service.yaml:apiVersion: v1 kind: Service metadata: name: web-app-internal-lb namespace: default annotations: networking.gke.io/load-balancer-type: "Internal" spec: externalTrafficPolicy: Local ports: - port: 80 protocol: TCP targetPort: 8080 selector: networking.gke.io/network: dmz app: web-app type: LoadBalancer此清单会创建一个具有以下属性的 Service:
networking.gke.io/load-balancer-type: "Internal":指定 内部直通式网络负载平衡器。selector:选择具有标签app: web-app且连接到dmz网络的 Pod。
将清单应用到您的集群:
kubectl apply -f internal-lb-service.yaml
部署外部 LoadBalancer Service
如需将 web-app Deployment 公开给外部客户端,请创建外部 LoadBalancer Service。
将以下清单保存为
external-lb-service.yaml:apiVersion: v1 kind: Service metadata: name: web-app-external-lb namespace: default annotations: cloud.google.com/l4-rbs: "enabled" spec: externalTrafficPolicy: Local ports: - port: 80 protocol: TCP targetPort: 8080 selector: networking.gke.io/network: dmz app: web-app type: LoadBalancer此清单会创建一个具有以下属性的 Service:
cloud.google.com/l4-rbs: "enabled":指定基于后端服务的 外部直通式网络负载平衡器。selector:选择具有标签app: web-app且连接到dmz网络的 Pod。
将清单应用到您的集群:
kubectl apply -f external-lb-service.yaml
验证 Service
部署 Service 后,请验证负载平衡器是否已正确创建和配置。
检查 Service 的状态:
kubectl get services输出类似于以下内容:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE web-app-external-lb LoadBalancer 10.8.47.77 35.239.57.231 80:31550/TCP 5m web-app-internal-lb LoadBalancer 10.8.43.251 172.16.0.43 80:32628/TCP 6m kubernetes ClusterIP 10.8.32.1 <none> 443/TCP 43h内部负载均衡器的
EXTERNAL-IP地址属于dmz网络。列出项目中的转发规则:
gcloud compute forwarding-rules list输出类似于以下内容:
NAME REGION IP_ADDRESS IP_PROTOCOL TARGET af901673cc0f24907a6aa8c3ce4afc21 us-central1 35.239.57.231 TCP us-central1/backendServices/k8s2-xhvzqabw-default-web-app-external-lb-u4xbs4ot k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a us-central1 172.16.0.43 TCP us-central1/backendServices/k8s2-xhvzqabw-default-web-app-internal-lb-vp1x1d6a描述内部负载均衡器的转发规则,以验证其是否已附加到正确的网络:
gcloud compute forwarding-rules describe k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a --region=$REGION将
REGION替换为集群的区域。输出类似于以下内容。验证
network和subnetwork字段是否与dmz网络的详细信息匹配。IPAddress: 172.16.0.43 IPProtocol: TCP ... loadBalancingScheme: INTERNAL name: k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a network: https://www.googleapis.com/compute/v1/projects/projectId/global/networks/dmz-vpc ... subnetwork: https://www.googleapis.com/compute/v1/projects/projectId/regions/us-central1/subnetworks/dmz-subnet
测试负载平衡器
如需测试外部负载均衡器,请向其外部 IP 地址发送请求:
curl EXTERNAL_LB_IP:80将
EXTERNAL_LB_IP替换为web-app-external-lbService 的外部 IP 地址。如需测试内部负载均衡器,请从与负载均衡器位于同一 VPC 中的主机发送请求:
curl INTERNAL_LB_IP:80将
INTERNAL_LB_IP替换为web-app-internal-lbService 的 IP 地址。
问题排查
本部分介绍了如何排查多网络负载平衡器的问题。
负载平衡器创建失败
如果负载均衡器创建失败,请检查 Service 事件以查找错误消息:
kubectl describe service SERVICE_NAME
将 SERVICE_NAME 替换为 Service 的名称。
类似 network some-other-network does not exist 的错误消息表示 Service 选择器中指定的网络未在集群中定义。
验证网络是否存在:
kubectl get networks
如果网络存在,请验证 Network 对象是否正确引用了
有效的 GKENetworkParamSet 资源。如需检查配置错误,请检查 Network 资源状态:
kubectl get networks NETWORK_NAME -o yaml
将 NETWORK_NAME 替换为您的网络名称。
在有效配置中,ParamsReady 和 Ready 条件均为
True。如果 ParamsReady 不是 True,请确保
Network 规范中的 parametersRef 与现有
GKENetworkParamSet 资源的名称、种类和群组正确匹配。
如果 Network 资源正确但仍未就绪,请检查引用的 GKENetworkParamSet 的状态是否存在错误,例如缺少子网:
kubectl get gkenetworkparamsets GNP_NAME -o yaml
将 GNP_NAME 替换为 GKENetworkParamSet 的名称。
负载平衡器没有后端
如果负载均衡器已预配但没有运行正常的后端,请执行以下操作:
- 验证是否存在节点池,该节点池在 Service 使用的网络中具有网络接口。
- 验证 Service 选择的 Pod 是否正在运行。
检查 Service 的端点:
kubectl describe endpointslice -l kubernetes.io/service-name=SERVICE_NAMEmultinet-endpointslice-controller.gke.io控制器会创建多网络端点。EndpointSlice 中列出的 Pod IP 地址属于 Service 使用的网络。如果 EndpointSlice 没有端点,请验证 Service 选择器标签是否与正在运行的 Pod 匹配,以及网络选择器是否与 Pod 的网络匹配。
后续步骤
- 了解 Pod 的多网络支持。
- 了解多网络 Service。