我已经在下面的标题下提供了有关每种连接转发类型以及服务如何向下转发的更详细信息,以获得我的答案的上下文。
如果我正确理解网络,Headless Service 似乎需要更少的跃点,因此会(稍微)更快?
没有明显更快。 “额外跳”是遍历本地查找表的数据包,无论如何它都会遍历,因此没有明显的区别。目标 pod 仍然与实际网络跳数相同。
如果您有 1000 个服务在单个 pod 上运行并且可能是无头的,那么您可以使用它来限制 iptables NAT 规则的数量并加快规则处理速度(请参阅下面的 iptables v ipvs)。
正确吗?当通过外部(或内部)ALB 调用时,这是否仍然有效?
是的,这是正确的,客户端(或 ALB)需要跨 Pod IP 实现负载平衡。
NodePort 与 ClusterIP 的性能有什么不同吗?
NodePort 从入口节点到运行 pod 的节点可能有额外的网络跃点。假设 ClusterIP 范围被路由到正确的节点(并且完全被路由)
如果您碰巧使用了服务类型:LoadBalancer,可以通过将 [.spec.externalTrafficPolicy 设置为 Local][https://kubernetes.io/docs/concepts/services-networking/service/#aws-nlb-support] 来改变这种行为,这意味着流量只会被定向到本地 pod。
最后,从集群外部使用内部服务的最优雅/高性能的方式是什么
我会说将AWS ALB Ingress Controller 与alb.ingress.kubernetes.io/target-type: ip 注释一起使用。集群中的 k8s 配置将通过入口控制器和地址 pod 直接推送到 ALB,而无需遍历任何连接转发或额外的跃点。所有集群重新配置将自动推出。
与集群 kube-proxy 重新配置相比,配置到达 ALB 有一点延迟。滚动部署之类的东西可能不像 pod 消失后更新到达那样无缝。 ALB 有能力最终自行处理中断。
Kubernetes 连接转发
在每个节点上运行一个kube-proxy 进程,该进程管理连接的转发方式和位置。 kube-proxy 如何做到这一点有 3 个选项:Userspace proxy, iptables or IPVS。大多数集群将在 iptables 上,这将满足绝大多数用例。
转发是通过在用户空间中运行的进程来终止和转发连接。它很慢。你不太可能使用它,不要使用它。
iptables 通过 NAT 转发内核中的连接,速度很快。这是最常见的设置,将涵盖 90% 的用例。新连接在所有运行 Pod 服务的节点之间平均共享。
在内核中运行,速度快且可扩展。如果您将流量转移到大量应用程序,这可能会提高转发性能。它还支持不同的服务负载均衡模式:
- rr: round-robin
- lc: least connection (smallest number of open connections)
- dh: destination hashing
- sh: source hashing
- sed: shortest expected delay
- nq: never queue
访问服务
我的解释是基于 iptables,因为我还没有对 ipvs 集群做太多详细的工作。我将放弃 ipvs 的复杂性,并说它与 iptables 基本相同,只是随着大型集群上规则数量的增加(即 Pod/服务/网络策略的数量),规则处理速度更快。
由于开销,我也忽略了描述中的用户空间代理,请不要使用它。
要了解的基本内容是“Service ClusterIP”是集群中的一个虚拟结构,仅作为流量应该去向的规则而存在。每个节点维护所有 ClusterIP/port 到 PodIP/port 的规则映射(通过kube-proxy)
节点端口
ALB 路由到任何节点,节点/节点端口将连接转发到处理服务的 pod。这可能是一个远程 pod,需要通过“电线”将流量发送回。
ALB > 线 > 节点 > 内核转发到 SVC(> 线如果是远程节点) > Pod
集群IP
使用 ClusterIP 进行直接访问取决于将服务集群 IP 范围路由到正确的节点。有时它们根本没有路由。
ALB > 线 > 节点 > 内核转发到 SVC > Pod
可以使用 ALB 注释跳过“内核转发到 SVC”步骤,而无需使用无头服务。
无头服务
同样,根据网络设置,Pod IP 并不总是可以从集群外部寻址。你应该在 EKS 上没问题。
ALB > 电线 > 节点 > Pod
注意
如果将连接转发到 VPC 中的节点,我将在请求后缀上可能会考虑