K8S v1.26 服务滚动更新期间流量损失优化
Kubernetes v1.26 包括网络流量工程方面的重大进步,其中两个功能(服务内部流量策略支持和 EndpointSlice 终止条件)升级为 GA,第三个功能(代理终止端点 Proxy terminating endpoints)升级为测试版。这些增强功能的组合旨在解决当今人们在 traffic 工程中面临的缺点,并为未来解锁新功能。
滚动更新期间负载均衡器的流量损失
在 Kubernetes v1.26 之前,当将该字段 externalTrafficPolicy 设置为 Local 时,集群可能会在滚动更新期间遇到来自服务负载均衡器的流量丢失。
这里有很多活动部件在起作用,因此快速了解 Kubernetes 如何管理负载均衡器可能会有所帮助!
在 Kubernetes 中,您可以创建一个type: LoadBalancer
服务来使用负载均衡器向外部公开应用程序。负载均衡器的实现因集群和平台而异,但该服务提供了一个通用抽象来表示在所有 Kubernetes 安装中保持一致的负载均衡器。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app.kubernetes.io/name: my-app
ports:
- protocol: TCP
port: 80
targetPort: 9376
type: LoadBalancer
在底层,Kubernetes 为服务分配一个 NodePort,然后 kube-proxy 使用它来提供从 NodePort 到 Pod 的网络数据路径。然后,控制器会将集群中的所有可用节点添加到负载均衡器的后端池中,使用为服务指定的 NodePort 作为后端目标端口。
通常,为服务设置externalTrafficPolicy: Local
是有益的,以避免在未运行支持该服务的健康 Pod 的节点之间进行额外的跳跃。使用 externalTrafficPolicy: Local
时,会分配一个额外的 NodePort 用于健康检查,这样不包含健康 Pod 的节点将被排除在负载均衡器的后端池之外。
一种可能丢失流量的场景是节点丢失了服务的所有 Pod,但外部负载均衡器尚未探测健康检查 NodePort。这种情况的可能性在很大程度上取决于负载均衡器上配置的健康检查间隔。间隔越大,发生这种情况的可能性就越大,因为即使在 kube-proxy 已删除该服务的转发规则后,负载均衡器仍会继续向节点发送流量。当 Pod 在滚动更新期间开始终止时,也会发生这种情况。由于 Kubernetes 不会将终止 Pod 视为“就绪”,因此在滚动更新期间,当任何给定节点上只有终止 Pod 时,流量可能会丢失。
从 Kubernetes v1.26 开始,kube-proxy 默认启用ProxyTerminatingEndpoints
该功能,在流量会被丢弃的情况下添加自动故障转移和路由到终止端点。更具体地说,当存在滚动更新并且节点仅包含终止 Pod 时,kube-proxy 将根据它们的就绪情况将流量路由到终止 Pod。此外,如果只有终止 Pod 可用,kube-proxy 将主动使 NodePort 健康检查失败。通过这样做,kube-proxy 会提醒外部负载均衡器新连接不应发送到该节点,但会优雅地处理对现有连接的请求。
EndpointSlice 条件
为了支持 kube-proxy 中的这一新功能,EndpointSlice API 为 endpoints 引入了新条件:serving
和terminating
.
该serving
条件在语义上与 ready
相同,除了当一个 Pod 终止时它可以是 true 或 false,不像 ready,由于兼容性原因终止 Pod 时它总是 false。terminating 条件对于正在终止的 Pods 为 true (非空的 deltionTimestamp) ,否则为 false。
添加这两个条件使此 API 的使用者能够理解以前不可能的 Pod 状态。例如,我们现在可以跟踪同时终止的“就绪”和“未就绪”Pod。
EndpointSlice API 的使用者,例如 Kube-proxy 和 Ingress Controller,现在可以使用这些条件来协调连接耗尽事件,方法是继续为现有连接转发流量,但将新连接重新路由到其他非终止端点。
优化内部节点本地流量
与服务如何设置 externalTrafficPolicy: Local
以避免外部来源流量的额外跃点类似,Kubernetes 现在支持 internalTrafficPolicy: Local
,以对源自集群内部的流量启用相同的优化,特别是针对使用 Service Cluster IP 作为目标地址的流量。此功能在 Kubernetes v1.24 中升级为 Beta,并在 v1.26 中升级为 GA。
服务默认该 internalTrafficPolicy
字段为Cluster
,其中流量随机分配到所有端点。
当internalTrafficPolicy
设置为 Local
时,只有当有一个可用的端点位于同一节点的本地时,kube-proxy 才会转发服务的内部流量。