问题描述
例如一个 istio 服务
istio-ingressgateway LoadBalancer 10.103.19.83 10.160.32.41 15021:30943/TCP,80:32609/TCP,443:30341/TCP,3306:30682/TCP,15443:30302/TCP
这导致了 TCP 内部负载平衡器。前端是端口15021、80、443、3306和15443。
后端基本上就是集群的实例组。
负载均衡器怎么知道前端的443会转发到后端的30341?据我所知,TCP 负载均衡器是在做端口转发吗?魔法是如何/在哪里发生的
解决方法
LoadBalancer Service 类型是NodePort 类型的扩展,它是ClusterIP 类型的扩展。 nodePort 只是在每个工作节点上打开一个 30000-32767 范围内的端口,并使用标签选择器来标识要将流量发送到哪些 Pod。
这意味着内部客户端通过使用节点的内部 IP 地址以及 nodePort 指定的 TCP 端口来调用服务。请求被转发到 targetPort 字段指定的 TCP 端口上的成员 Pod 之一。
这是一个 example
,当在 kubernetes 中创建 Service
时,相应的 Endpoints
对象也随之创建。它也适用于 LoadBalancer
服务类型。
如果你 create a simple nginx deployment 例如通过运行:
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
然后将其公开为 LoadBalancer
服务:
kubectl apply -f https://k8s.io/examples/application/deployment.yaml
除了服务本身,您还将看到 lb-nginx
Endpoints
对象。您可以检查其详细信息:
kubectl get ep lb-nginx -o yaml
如您所见,它会跟踪所有暴露的 pod(在本例中是 Deployment
的一部分),以便相应的 iptables 规则负责将流量转发到特定的 pod,可以一直是最新的,即使它们的数量或它们的 ip 变化。
你可以例如将您的部署扩展到 5 个副本:
kubectl scale deployment nginx-deployment --replicas=5
并再次检查 Endpoints
对象:
kubectl get ep lb-nginx -o yaml
您会看到,在 5 个 Pod 启动并运行后,它也会立即更新。
正如您在 yaml 的 subsets
部分所见:
subsets:
- addresses:
- ip: 10.12.0.3
nodeName: gke-gke-default-pool-75259266-oauz
targetRef:
kind: Pod
name: nginx-deployment-66b6c48dd5-dw9mt
namespace: default
resourceVersion: "22394113"
uid: 8d7e1d3e-64e2-4891-b567-61ee48f61ed1
除了 Pod
的 ip 地址之外,它还维护有关它正在运行的节点的信息。
让我们回到Service
:
kubectl get svc lb-nginx -o yaml
正如您所看到的,LoadBalancer
服务除了其外部 IP 地址之外,还有它的 ClusterIP
和其他所有 Service
(嗯,几乎每个无头服务都没有 ClusterIP):
spec:
clusterIP: 10.16.6.236
clusterIPs:
- 10.16.6.236
externalTrafficPolicy: Cluster
ports:
- nodePort: 31935
port: 80
protocol: TCP
targetPort: 80
因此,您可以想象此外部 IP 以某种方式映射到集群 ip,因此它将流量进一步路由到集群中的相应端点。这种映射是如何完成的并不重要,因为它是由云提供商完成的,并且此类实现细节不是公开共享知识的一部分。您唯一需要知道的是,当您的云提供商提供外部负载均衡器以满足您在 Service
类型的 LoadBalancer
中定义的请求时,除了创建外部负载均衡器之外,它还会处理这个外部 IP 和分配给它的某个标准端口以及一个 kubernetes 服务之间的映射,该服务具有将流量进一步路由到相应 pod 所需的所有信息。如果您想知道这在 GCP 端究竟是如何完成的,即外部(或内部)负载均衡器和 kubernetes LoadBalancer
服务之间的映射/绑定,我担心此类实现细节不会公开披露。