服务如何优雅退出
1 | /* |
k8s 如何优雅更新
简单说就是加两个探针并设置 preStop, liveness 用于检测已注册的节点是否可用,readiness 用于检测新创建的节点是否可用。示例如下:
1 | apiVersion: apps/v1 |
以上示例使用 tcp 探测的方式,并设置探测时间间隔为 1 秒。
核心配置探针
主要是设置存活探针和就绪探针。
核心配置 preStop
- 为什么要配置 preStop
- 因为 通知 load balance 将老节点摘除和 向老节点 发送 TERM 信号,是并发的(实际上是先通知load balance 摘掉老节点,然后再异步的发送 TERM 信号),没有保证先后顺序,这就意味着,可能 load balance 还没有将老借点摘除,但是老节点已经接受到了 TERM 信号并且关闭了TCP连接请求,这样部分请求就到了一个已关闭的节点上。
- preStop 是在通知 load balance 摘掉老节点之后的一个操作,这是一个阻塞操作,他会执行指令,直到指令接受,所以,我们在preStop中调用 sleep 函数,给load balance 足够的时间来摘除老节点。然后再‘异步’地发送 TERM 信号。
Kubernetes 在容器结束前立即发送 preStop 事件。除非 Pod 宽限期限超时,Kubernetes 的容器管理逻辑 会一直阻塞等待 preStop 处理函数执行完毕。
This deployment configuration will perform version updates in the following way: It will create one pod with the new version at a time, wait for the pod to start-up and become ready, trigger the termination of one of the old pods, and continue with the next new pod until all replicas have been transitioned. In order to tell Kubernetes when our pods are running and ready to handle traffic we need to configure liveness and readiness probes.
此部署配置将以以下方式执行版本更新:它将一次创建一个具有新版本的Pod,等待Pod启动并准备就绪,触发其中一个旧Pod的终止,然后继续 下一个新的Pod,直到所有副本都已转换。 为了告诉Kubernetes我们的Pod何时运行并准备处理流量,我们需要配置活动和就绪探针。
If our client, that is the zero-downtime test, connects to the
coffee-shop service directly from inside the cluster, it typically uses the service VIP resolved via Cluster DNS and ends up at a Pod instance. This is realized via the kube-proxy that runs on every Kubernetes node and updates iptables that route to the IP addresses of the pods.
如果我们的客户端(即零停机时间测试)直接从群集内部连接到服务,则它通常使用通过群集DNS解析的服务VIP,最终到达Pod实例。 这是通过在每个Kubernetes节点上运行并更新路由到Pod的IP地址的iptables的kube-proxy来实现的。
实现
目前是在公司 gitlab 个人目录下实现了一个 k8s 优雅退出的 模板,经过测试。在 qps 为 1000(更高的qps还没有测试) 可以实现零报错的更新镜像。
gitlab地址:https://gitlab.xiaoduoai.com/zhuyuanbing/grace_shut_example
使用
部署
1 | 项目:https://gitlab.xiaoduoai.com/devops/k8s-app-deploy |
模拟更新镜像
1 | 如在测试环境 |
并发测试工具
TODO
将上线的 http 服务全部替换为平滑更新的方案。
参考
最佳实践文档:https://blog.sebastian-daschner.com/entries/zero-downtime-updates-kubernetes
k8s探针:https://jimmysong.io/kubernetes-handbook/guide/configure-liveness-readiness-probes.html
k8s preStop:https://kubernetes.io/zh/docs/tasks/configure-pod-container/attach-handler-lifecycle-event/