本文发表已超过一年。较旧的文章可能包含过时内容。请检查页面中的信息自发布以来是否已不再正确。
使用 EndpointSlice 扩展 Kubernetes 网络
EndpointSlice 是一种令人兴奋的新 API,它提供了一个可扩展且可伸缩的 Endpoints API 替代方案。EndpointSlice 跟踪支持 Service 的 Pod 的 IP 地址、端口、就绪状态和拓扑信息。
在 Kubernetes 1.19 中,此特性默认启用,kube-proxy 从 EndpointSlice 读取,而不是从 Endpoints 读取。虽然这大多是无感知的变化,但在大型集群中应能带来显著的可伸缩性改进。它还将在未来的 Kubernetes 版本中启用重要的新特性,例如拓扑感知路由。
Endpoints API 的可伸缩性限制
使用 Endpoints API 时,一个 Service 只有一个 Endpoints 资源。这意味着它需要能够存储支持该 Service 的每个 Pod 的 IP 地址和端口(网络端点)。这导致了巨大的 API 资源。更糟糕的是,kube-proxy 运行在每个节点上,并监控 Endpoints 资源的任何更新。即使 Endpoints 资源中只有一个网络端点发生变化,整个对象也必须发送到每个 kube-proxy 实例。
Endpoints API 的另一个限制是它限制了可以为一个 Service 跟踪的网络端点数量。etcd 中存储对象的默认大小限制是 1.5MB。在某些情况下,这可能将一个 Endpoints 资源限制为 5,000 个 Pod IP。这对大多数用户来说不是问题,但对于接近此规模的 Service 用户而言,这会成为一个显著问题。
为了说明这些问题在大规模环境中的严重性,一个简单的例子会有所帮助。考虑一个拥有 5,000 个 Pod 的 Service,它最终可能会产生一个 1.5MB 的 Endpoints 资源。即使该列表中只有一个网络端点发生变化,整个 Endpoints 资源也需要分发到集群中的每个节点。在拥有 3,000 个节点的大型集群中,这会成为一个相当大的问题。每次更新都将涉及在集群中发送 4.5GB 的数据(1.5MB Endpoints * 3,000 个节点)。这几乎足够填满一张 DVD,而且每次 Endpoints 变化都会发生。想象一下导致所有 5,000 个 Pod 被替换的滚动更新——那将是超过 22TB(或 5,000 张 DVD)的数据传输量。
使用 EndpointSlice API 分割端点
EndpointSlice API 的设计旨在通过类似于分片的方法来解决这个问题。我们不是用一个单独的 Endpoints 资源来跟踪一个 Service 的所有 Pod IP,而是将它们分割成多个更小的 EndpointSlice。
考虑一个由 15 个 Pod 支持的 Service。最终我们会得到一个跟踪所有这些 Pod 的 Endpoints 资源。如果 EndpointSlice 配置为每个存储 5 个端点,我们将得到 3 个不同的 EndpointSlice:
默认情况下,每个 EndpointSlice 最多存储 100 个端点,尽管这可以通过 kube-controller-manager 上的 `--max-endpoints-per-slice` 标志进行配置。
EndpointSlice 提供 10 倍的可伸缩性改进
这个 API 极大地提高了网络可伸缩性。现在当一个 Pod 被添加或移除时,只需要更新一个小的 EndpointSlice。当单个 Service 支持数百或数千个 Pod 时,这种差异变得相当明显。
更重要的是,现在一个 Service 的所有 Pod IP 无需存储在单个资源中,我们不必担心 etcd 中存储对象的大小限制。EndpointSlice 已被用于将 Service 扩展到超过 100,000 个网络端点。
所有这些都伴随着 kube-proxy 中做出的一些显著性能改进。在大规模使用 EndpointSlice 时,端点更新传输的数据量将显著减少,并且 kube-proxy 更新 iptables 或 ipvs 规则的速度应该会更快。除此之外,Service 现在可以扩展到至少比之前任何限制大 10 倍。
EndpointSlice 启用新功能
作为 Kubernetes v1.16 中的一个 Alpha 特性引入,EndpointSlice 的构建旨在为未来 Kubernetes 版本中的一些令人兴奋的新功能提供支持。这可能包括双栈 Service、拓扑感知路由和端点子集划分。
双栈 Service 是一个令人兴奋的新特性,它与 EndpointSlice 一同开发。它们将为 Service 同时使用 IPv4 和 IPv6 地址,并依赖 EndpointSlice 上的 `addressType` 字段按 IP 系列跟踪这些地址。
拓扑感知路由将更新 kube-proxy 以优先将请求路由到同一可用区或区域内。这利用了 EndpointSlice 中为每个端点存储的拓扑字段。作为进一步的改进,我们正在探索端点子集划分的潜力。这将允许 kube-proxy 只 watch EndpointSlice 的一个子集。例如,这可以与拓扑感知路由结合使用,以便 kube-proxy 只需 watch 包含同一可用区内端点的 EndpointSlice。这将带来另一个非常显著的可伸缩性改进。
这对 Endpoints API 意味着什么?
尽管 EndpointSlice API 提供了一个更新、更具可伸缩性的 Endpoints API 替代方案,但 Endpoints API 将继续被视为正式可用 (GA) 且稳定。为 Endpoints API 计划的最重要的变更将涉及开始截断那些否则会遇到可伸缩性问题的 Endpoints。
Endpoints API 不会消失,但许多新特性将依赖于 EndpointSlice API。为了利用 EndpointSlice 提供的新可伸缩性和功能,目前使用 Endpoints 的应用程序将来可能会考虑支持 EndpointSlice。