五分钟 k8s 实战-滚动更新与优雅停机

当我们在生产环境发布应用时,必须要考虑到当前系统还有用户正在使用的情况,所以尽量需要做到不停机发版。

所以在发布过程中理论上之前的 v1 版本依然存在,必须得等待 v2 版本启动成功后再删除历史的 v1 版本。

如果 v2 版本启动失败 v1 版本不会做任何操作,依然能对外提供服务。

滚动更新

这是我们预期中的发布流程,要在 kubernetes 使用该功能也非常简单,只需要在 spec 下配置相关策略即可:

yaml 复制代码
spec:
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate

这个配置的含义是:

  • 使用滚动更新,当然还有 Recreate 用于删除旧版本的 Pod,我们基本不会用这个策略。
  • maxSurge:滚动更新过程中可以最多超过预期 Pod 数量的百分比,当然也可以填整数。
  • maxUnavailable:滚动更新过程中最大不可用 Pod 数量超过预期的百分比。

这样一旦我们更新了 Pod 的镜像时,kubernetes 就会先创建一个新版本的 Pod 等待他启动成功后再逐步更新剩下的 Pod。

优雅停机

滚动升级过程中不可避免的又会碰到一个优雅停机的问题,毕竟是需要停掉老的 Pod。

这时我们需要注意两种情况:

  • 停机过程中,已经进入 Pod 的请求需要执行完毕才能退出。
  • 停机之后不能再有请求路由到已经停机的 Pod

第一个问题如果我们使用的是 Go,可以使用一个钩子来监听 kubernetes 发出的退出信号:

go 复制代码
quit := make(chan os.Signal)  
signal.Notify(quit, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGPIPE)  
go func() {  
    <-quit  
    log.Printf("quit signal received, exit \n")  
    os.Exit(0)  
}()

在这里执行对应的资源释放。

如果使用的是 spring boot 也有对应的配置:

yaml 复制代码
server: 
	shutdown: "graceful"
spring: 
	lifecycle: 
		timeout-per-shutdown-phase: "20s"	

当应用收到退出信号后,spring boot 将不会再接收新的请求,并等待现有的请求处理完毕。

但 kubernetes 也不会无限等待应用将 Pod 将任务执行完毕,我们可以在 Pod 中配置

yaml 复制代码
terminationGracePeriodSeconds: 30

来定义需要等待多长时间,这里是超过 30s 之后就会强行 kill Pod。

具体值大家可以根据实际情况配置


yaml 复制代码
spec:
  containers:
  - name: example-container
    image: example-image
    lifecycle:
      preStop:
        exec:
          command: ["sh", "-c", "sleep 10"]

同时我们也可以配置 preStop 做一个 sleep 来确保 kubernetes 将准备删除的 Pod 在 Iptable 中已经更新了之后再删除 Pod。

这样可以避免第二种情况:已经删除的 Pod 依然还有请求路由过来。 具体可以参考 spring boot 文档: docs.spring.io/spring-boot...

回滚

回滚其实也可以看作是升级的一种,只是升级到了历史版本,在 kubernetes 中回滚应用非常简单。

shell 复制代码
# 回滚到上一个版本
 k rollout undo deployment/abc
# 回滚到指定版本
k rollout undo daemonset/abc --to-revision=3

同时 kubernetes 也能保证是滚动回滚的。

优雅重启

在之前的 如何优雅重启 kubernetes 的 Pod 那篇文章中写过,如果想要优雅重启 Pod 也可以使用 rollout 命令,它也也可以保证是滚动重启。

shell 复制代码
k rollout restart deployment/nginx

使用 kubernetes 的滚动更新确实要比我们以往的传统运维简单许多,就几个命令的事情之前得写一些复杂的运维脚本才能实现。

本文的所有源码在这里可以访问: github.com/crossoverJi...

相关推荐
专业程序开发源9 分钟前
django新闻推荐系统70655-计算机课程设计、毕业设计
java·javascript·spring boot·后端·python·django·课程设计
打工仔折腾 AI21 分钟前
把 AI Agent 托管到家里电脑:UU远程端口映射与CLI实测记录
人工智能·后端·python·langchain·电脑·ai agent 实战
vx_Biye_Design25 分钟前
springboot一站式旅游管理平台81037-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·课程设计·express·旅游
嵌入式学习菌34 分钟前
ESP32 ModbusTCP 分片缓存
java·后端·spring
程序员小杰@41 分钟前
Spring Boot 常用注解分类速记
java·spring boot·后端
挖掘狂人1 小时前
Git 从 0 到 1:用一个小项目走完 add / commit / reset / merge / rebase / push
git·后端·github
vx_Biye_Design1 小时前
springboot小学生英语学习APP62773-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·python·学习·课程设计
打工仔折腾 AI1 小时前
用UU远程把家里电脑变成AI Agent常驻服务器:CLI、端口映射与代理实测
运维·服务器·人工智能·后端·python·电脑·ai agent 实战
明月_清风1 小时前
AI Agent 进入系统层:现在有哪些开源项目在解决这个问题?
人工智能·后端
弈栈录2 小时前
MySQL 事务、索引与锁:后端开发必须掌握的数据库基础
数据库·后端