前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >K8S 滚动更新如何优雅停止 Pod

K8S 滚动更新如何优雅停止 Pod

作者头像
YP小站
发布2020-06-04 15:28:45
5.4K0
发布2020-06-04 15:28:45
举报
文章被收录于专栏:YP小站YP小站YP小站

何谓优雅停止?

优雅停止(Graceful shutdown) 这个说法来自于操作系统,我们执行关机之后都得 OS 先完成一些清理操作,而与之相对的就是硬中止(Hard shutdown),比如拔电源。

到了分布式系统中,优雅停止就不仅仅是单机上进程自己的事了,往往还要与系统中的其它组件打交道。比如说我们起一个微服务,网关把一部分流量分给我们,这时:

  • 假如我们一声不吭直接把进程杀了,那这部分流量就无法得到正确处理,部分用户受到影响。不过还好,通常来说网关或者服务注册中心会和我们的服务保持一个心跳,过了心跳超时之后系统会自动摘除我们的服务,问题也就解决了;这是硬中止,虽然我们整个系统写得不错能够自愈,但还是会产生一些抖动甚至错误;
  • 假如我们先告诉网关或服务注册中心我们要下线,等对方完成服务摘除操作再中止进程,那不会有任何流量受到影响;这是优雅停止,将单个组件的启停对整个系统影响最小化;

按照惯例,SIGKILL 是硬终止的信号,而 SIGTERM 是通知进程优雅退出的信号,因此很多微服务框架会监听 SIGTERM 信号,收到之后去做反注册等清理操作,实现优雅退出。[4]

什么是Pod?

Pod 就像是豌豆荚一样,它由一个或者多个容器组成(例如Docker容器),它们共享容器存储、网络和容器运行配置项。Pod中的容器总是被同时调度,有共同的运行环境。你可以把单个Pod想象成是运行独立应用的“逻辑主机”——其中运行着一个或者多个紧密耦合的应用容器——在有容器之前,这些应用都是运行在几个相同的物理机或者虚拟机上。[1]

滚动更新会出现的问题

在 k8s 执行 Rolling-Update 的时,默认会向旧的 pod 发生一个 SIGTERM 信号,如果业务应用没有对 SIGTERM 信号做处理的话,有可能导致程序退出后也没有处理完请求,引起客户端访问异常。

简述滚动更新步骤

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

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

滚动更新图解 [3]

绿色Pod 为当前已运行Pod , 紫色Pod 为新创建Pod

  • 当前 Service A 把流量分给4个 绿色Pod
  • 管理员更新完 Deployment 部署文件,触发 Rolling-Update 操作,根据 k8s 调度算法选出一个 Node ,在这台 Node上创建一个 紫色Pod
  • 当第一个 紫色Pod 创建完开始服务,k8s 会继续停止一个 绿色Pod,并创建一个 紫色Pod
  • 循环替换,直到把所有 绿色Pod 替换成 紫色Pod,紫色Pod 达到 Deployment 部署文件中定义的副本数,则滚动更新完成

滚动更新允许以下操作:

  • 将应用程序从准上线环境升级到生产环境(通过更新容器镜像)
  • 回滚到以前的版本
  • 持续集成和持续交付应用程序,无需停机

解决方法

  • 通过容器生命周期 hook 来优雅停止 Pod 停止前,会执行 PreStop hook,hook 可以执行一个 HTTP GET请求 或者 exec命令,并且它们执行是阻塞的,可以利用这个特性来做优雅停止。
  • 调用 HTTP GET
spec:
  contaienrs:
  - name: my-container
    lifecycle:
      preStop:
        httpGet:
          path: "/stop"
          port: 8080
          scheme: "HTTP"
  • 调用 exec
spec:
  contaienrs:
  - name: my-container
    lifecycle:
      preStop:
        exec:
          command: ["/bin/sh","-c","/pre-stop.sh"]
  • 关于 PreStop 和 terminationGracePeriodSeconds
  • 如果有 PreStop hook 会执行 PreStop hookPreStop hook 执行完成后会向 pod 发送 SIGTERM 信号。
  • 如果在 terminationGracePeriodSeconds 时间限制内,PreStop hook 还没有执行完,一样会直接发送 SIGTERM 信号,并且时间延长 2秒,最后强制 Kill 。

参考链接

  • [1]https://jimmysong.io/kubernetes-handbook/concepts/pod.html
  • [2]https://monkeywie.github.io/2019/07/11/k8s-graceful-shutdown/
  • [3]https://kubernetes.io/docs/tutorials/kubernetes-basics/update/update-intro/
  • [4]https://aleiwu.com/post/tidb-opeartor-webhook/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 YP小站 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 何谓优雅停止?
  • 什么是Pod?
  • 滚动更新会出现的问题
  • 简述滚动更新步骤
  • 滚动更新图解 [3]
  • 解决方法
  • 参考链接
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档