Kubernetes之服务优雅升级

mokeyWie 2020/10/14 14:33:43

前言k8s本身就支持服务滚动升级,但是如果程序没有正确的处理退出信号时,就会导致部分请求直接被中断从而影响用户体验。滚动升级步骤每个pod代表一个集群中的节点,在 k8s 做rolling-update的时候默认会向旧的pod发生一个SIGTERM信号,如果应用没有对SIGTERM信号做处理的…

前言

k8s本身就支持服务滚动升级,但是如果程序没有正确的处理退出信号时,就会导致部分请求直接被中断从而影响用户体验。

滚动升级步骤

每个pod代表一个集群中的节点,在 k8s 做rolling-update的时候默认会向旧的pod发生一个SIGTERM信号,如果应用没有对SIGTERM信号做处理的话,会立即强制退出程序,这样的话会导致有些请求还没处理完,前端应用请求错误。

先来回顾下 k8s 的滚动升级步骤:

  1. 启动一个新的 pod
  2. 等待新的 pod 进入 Ready 状态
  3. 创建 Endpoint,将新的 pod 纳入负载均衡
  4. 移除与老 pod 相关的 Endpoint,并且将老 pod 状态设置为 Terminating,此时将不会有新的请求到达老 pod
  5. 给老 pod 发送 SIGTERM 信号,并且等待 terminationGracePeriodSeconds 这么长的时间。(默认为 30 秒)
  6. 超过 terminationGracePeriodSeconds 等待时间直接强制 kill 进程并关闭旧的 pod

这里要注意,SIGTERM信号如果进程没有处理的话也其实也就会导致进程被强杀,如果处理了但是超过terminationGracePeriodSeconds配置的时间也一样会被强杀,所以这个时间可以根据具体的情况去设置。

SpringBoot 处理 SIGTERM 信号

SpringBoot中处理 SIGTERM 信号非常简单,只需要一个@PreDestroy注解就可以监听到:

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @PreDestroy
    public void shutdown() {
       System.out.println("shutdown")
    }
}

通过容器生命周期 hook 来优雅停止

在 pod 中容器将停止前,会执行PreStop hook,hook 可以执行一个HTTP GET请求或者exec命令,并且它们执行是阻塞的,可以利用这个特性来做优雅停止。

  • 调用HTTP GET

    "lifecycle": {
        "preStop": {
        "httpGet": {
                "path": "/shutdown",
                "port": 3000,
                "scheme": "HTTP"
            }
        }
    }
  • 调用exec

    "lifecycle": {
        "preStop": {
            "exec": {
                "command": ["/bin/sh", "-c", "sleep 30"]
            }
        }
    }

这样的好处是可以在 k8s 层面来解决优雅停机的问题,而不需要应用程序对SIGTERM信号做处理。

关于 PreStop 和 terminationGracePeriodSeconds

  1. 如果有PreStop hook会执行PreStop hook
  2. PreStop hook执行完成后会向 pod 发送SIGTERM信号。
  3. 如果在terminationGracePeriodSeconds时间限制内,PreStop hook没有执行完的话,一样会直接发送SIGTERM信号,并且时间延长 2 秒。

即在有PreStop hook的情况下,也是在terminationGracePeriodSeconds时间限制内,在超过这个时间点之后,还会给出 2 秒进程处理SIGTERM信号的时间,最后直接强杀。

以上情况已经过 k8s 上验证过,参考:https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods

我是MonkeyWie,欢迎扫码👇👇关注!不定期在公众号中分享JAVAGolang前端dockerk8s等干货知识。

wechat

随时随地学软件编程-关注百度小程序和微信小程序
关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。
本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。
[Kubernetes之服务优雅升级]http://www.zyiz.net/tech/detail-148012.html

上一篇:K8S环境的Jenkin性能问题处理

下一篇:K8S节点异常怎么办?TKE"节点健康检查和自愈"来帮忙

赞(0)

共有 条评论 网友评论

验证码: 看不清楚?
    关注微信小程序
    程序员编程王-随时随地学编程

    扫描二维码或查找【程序员编程王】

    可以随时随地学编程啦!

    技术文章导航 更多>
    扫一扫关注最新编程教程