我们在多节点 Kubernetes 集群上部署了有状态的 Redis。 (v1.27.15)
有两个名为“redis”和“redis-headless”的服务
集群中有3个节点。当我们关闭其中一个节点时,该节点上的 redis 就会终止:
kubectl get pods -A -o wide | grep redis
mynamespace redis-node-0 3/3 Running 0 8m 10.244.248.4 ha3-node2
mynamespace redis-node-1 3/3 Terminating 0 68m 10.244.230.119 ha3-node1
mynamespace redis-node-2 3/3 Running 0 67m 10.244.192.208 ha3-node3
但是对于 redis-headless 服务 10.244.230.119 仍然在端点中
kubectl describe endpoints -n mynamespace redis-headless
Name: redis-headless
Namespace: mynamespace
Subsets:
Addresses: 10.244.192.208,10.244.230.119,10.244.248.4
对于 redis 服务(clusterIP)端点没问题。 (10.244.230.119 已从端点中删除)
这种行为对于无头服务来说是否正常,如果不是,解决方案是什么?
问候,
严尊
这正在按预期工作,这就是 Kubernetes 的工作原理。
pod deletion
和 endpoint
切片更新过程是并行的,不能保证其中一个会先于另一个更新。除此之外,还有所有ingress/load balancer
后端需要使用新的端点切片信息进行更新,这也不能保证在 Pod 停止之前发生。这就是我们建议在 prestop hook
中使用 sleep 的原因;这应该可以解决问题。
如果在容器收到
endpoint
之前删除 term signal
,则在容器 terminating
期间不会有新请求到达。如果容器在端点被删除之前启动 terminating
,那么 pod 将继续接收请求。然后这些请求将得到 “Connection timeout” or “Connection refused”
错误作为响应。 由于端点删除必须在完成之前传播到集群中的每个节点,因此 pod 驱逐过程很可能首先完成。
来自此文档,其中包含详细信息。
如果您使用 Headless 类型的服务,CoreDNS 将必须订阅端点的更改,并在每次添加或删除端点时重新配置自身。