NodePort 与 ClusterIP 与 Kubernetes 上的 Headless Service 的性能注意事项

chr*_*vdb 1 kubernetes kubernetes-networking

我们在 AWS EKS 上运行两种类型的服务:

  • 我们使用 aws-alb-ingress-controller 通过应用程序级负载均衡器公开的面向外部的服务
  • 面向内部的服务,我们直接通过服务名称(对于 EKS 应用程序)和通过内部应用程序级负载均衡器使用 aws-alb-ingress-controller(对于非 EKS 应用程序)

我想了解为外部和内部服务选择 Nodeport、ClusterIP 或 Headless Service 对性能的影响。我的设置适用于所有三个选项。

如果我正确理解网络,似乎无头服务需要更少的跳数,因此会(稍微)更快?然而,这篇文章似乎表明,当直接调用无头服务时,将无法正确地进行负载平衡。这样对吗?当通过外部(或内部)ALB 调用时,这仍然成立吗?

NodePort 与 ClusterIP 的性能有什么不同吗?

最后,从集群外部(我们无法访问 Kubernetes DNS)但在同一 VPC 内使用内部服务的最优雅/最高效的方式是什么?是否会使用 ClusterIp 并在服务定义中指定 IP 地址以使其保持稳定?或者有更好的选择吗?

Mat*_*att 5

我已经在下面的标题下提供了关于每种连接转发类型以及服务如何转发的更详细信息,以获取我的答案的上下文。

如果我正确理解网络,似乎无头服务需要更少的跳数,因此会(稍微)更快?

没有明显更快。“额外跃点”是遍历本地查找表的数据包,无论如何它都会遍历它,因此没有明显的差异。目标 Pod 仍将与实际网络跳数相同。

如果您有 1000 个在单个 pod 上运行的服务并且可能是无头的,那么您可以使用它来限制 iptables NAT 规则的数量并加快规则处理速度(请参阅下面的 iptables v ipvs)。

<没有负载平衡的无头服务>是否正确?当通过外部(或内部)ALB 调用时,这仍然成立吗?

是的,这是正确的,客户端(或 ALB)需要跨 Pod IP 实现负载平衡。

NodePort 与 ClusterIP 的性能有什么不同吗?

NodePort 可能有一个额外的网络跃点,从入口节点到运行 Pod 的节点。假设 ClusterIP 范围被路由到正确的节点(并且完全路由)

如果您碰巧使用服务类型:LoadBalancer可以通过将 [ 设置.spec.externalTrafficPolicyLocal][ https://kubernetes.io/docs/concepts/services-networking/service/#aws-nlb-support]来更改此行为,这意味着流量只会被定向到本地 pod。

最后,从集群外部使用内部服务的最优雅/最高效的方式是什么?

我会说使用带有注释的AWS ALB 入口控制器alb.ingress.kubernetes.io/target-type: ip。来自集群的 k8s 配置将通过入口控制器和地址 pod 直接推送到 ALB,而无需遍历任何连接转发或额外的跃点。所有集群重新配置将自动推出。

与集群kube-proxy重新配置相比,配置到达 ALB 有一点延迟。像滚动部署这样的事情可能不像 pod 消失后更新到达那样无缝。ALB 最终能够自行处理中断。

Kubernetes 连接转发

kube-proxy每个节点上都运行着一个进程,用于管理转发连接的方式和位置。这有 3 个选项kube-proxy用户空间代理、iptables 或 IPVS。大多数集群将在 iptables 上,这将满足绝大多数用例。

用户空间代理

转发是通过在用户空间中运行的进程来终止和转发连接。它很慢。你不太可能使用它,不要使用它。

iptables

iptables 通过 NAT 转发内核中的连接,速度很快。这是最常见的设置,将涵盖 90% 的用例。新连接在为服务运行 Pod 的所有节点之间平均共享。

IPVS

在内核中运行,速度快且可扩展。如果您将流量转移到大量应用程序,这可能会提高转发性能。它还支持不同的服务负载均衡模式:

- rr: round-robin
- lc: least connection (smallest number of open connections)
- dh: destination hashing
- sh: source hashing
- sed: shortest expected delay
- nq: never queue
Run Code Online (Sandbox Code Playgroud)

获得服务

我的解释是基于 iptables 的,因为我还没有对 ipvs 集群做过很多详细的工作。我将放弃 ipvs 的复杂性,并说它与 iptables 基本相同,只是随着规则数量在大型集群上的增加(即 pod/服务/网络策略的数量),规则处理速度更快。

我也忽略了描述中的用户空间代理,因为开销只是不使用它。

要理解的基本内容是“服务集群IP”是集群中的一个虚拟结构,它仅作为流量应该去向的规则而存在。每个节点维护所有 ClusterIP/port 到 PodIP/port 的规则映射(通过kube-proxy

节点端口

ALB 路由到任何节点,节点/节点端口将连接转发到处理服务的 pod。这可能是一个远程 pod,涉及通过“线路”将流量发送回。

ALB > 线路 > 节点 > 内核转发到 SVC(如果是远程节点,则为 > 线路)> Pod

集群IP

使用 ClusterIP 进行直接访问取决于路由到正确节点的服务集群 IP 范围。有时它们根本没有路由。

ALB > 连线 > 节点 > 内核转发到 SVC > Pod

可以使用 ALB 注释跳过“Kernel Forward to SVC”步骤,而无需使用无头服务。

无头服务

同样,根据网络设置,Pod IP 并不总是可以从集群外部寻址。你在 EKS 上应该没问题。

ALB > 连线 > 节点 > Pod

笔记

如果将连接转发到 VPC 中的节点,我将使用请求可能会查看 < 1ms 的额外延迟作为后缀。低端的增强型网络实例。可用区间通信可​​能比可用区内通信高一点。如果您碰巧有一个地理上分开的集群,则可能会增加控制流量的重要性。例如,拥有一个实际上跳过许多真实网络的隧道印花布网络。