Kubernetes 入门实战课
罗剑锋
Kong 高级工程师,Nginx/OpenResty 开源项目贡献者
19527 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 41 讲
Kubernetes 入门实战课
15
15
1.0x
00:00/00:00
登录|注册

27|滚动更新:如何做到平滑的应用升级降级?

你好,我是 Chrono。
上次课里我们学习了管理有状态应用的对象 StatefulSet,再加上管理无状态应用的 Deployment 和 DaemonSet,我们就能在 Kubernetes 里部署任意形式的应用了。
不过,只是把应用发布到集群里是远远不够的,要让应用稳定可靠地运行,还需要有持续的运维工作。
如果你还记得在第 18 节课里,我们学过 Deployment 的“应用伸缩”功能就是一种常见的运维操作,在 Kubernetes 里,使用命令 kubectl scale,我们就可以轻松调整 Deployment 下属的 Pod 数量,因为 StatefulSet 是 Deployment 的一种特例,所以它也可以使用 kubectl scale 来实现“应用伸缩”。
除了“应用伸缩”,其他的运维操作比如应用更新、版本回退等工作,该怎么做呢?这些也是我们日常运维中经常会遇到的问题。
今天我就以 Deployment 为例,来讲讲 Kubernetes 在应用管理方面的高级操作:滚动更新,使用 kubectl rollout 实现用户无感知的应用升级和降级。

Kubernetes 如何定义应用版本

应用的版本更新,大家都知道是怎么回事,比如我们发布了 V1 版,过了几天加了新功能,要发布 V2 版。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Kubernetes中的滚动更新是一种高级应用管理操作,通过使用`kubectl rollout`命令实现用户无感知的应用升级和降级。在Kubernetes中,应用的版本更新是通过`template`里Pod的变化来实现的,每次`template`的变动都会形成一个新的版本。通过`kubectl rollout`命令,可以实现应用的滚动更新,即逐个地创建新Pod,同时销毁旧Pod,保证系统里始终有足够数量的Pod在运行,不会中断服务。这种滚动更新的过程由Deployment控制,通过“此消彼长”的方式,实现老版本缩容到0,同时新版本扩容到指定值。通过`kubectl rollout status`命令可以查看应用更新的状态,而使用`kubectl describe`命令可以更清楚地查看Pod的变化情况。滚动更新的过程实际上是两个同步进行的“应用伸缩”操作,通过逐步替换Pod来实现版本更新,保证应用的稳定可靠运行。 Kubernetes的“滚动更新”功能非常便利,不需要人工干预就能简单地将应用升级到新版本,同时不会中断服务。更新过程中,可以随时使用`kubectl rollout pause`暂停更新,检查、修改Pod,或者测试验证,确认无问题后再用`kubectl rollout resume`继续更新。此外,Kubernetes还提供了更新历史功能,可以查看之前的每次更新记录,并且回退到任何位置,类似于Git等版本控制软件。另外,通过在Deployment的`metadata`里加上`annotations`字段,可以为每次更新添加说明信息,使得更新历史更加清晰明了。 总之,Kubernetes的滚动更新功能能够自动缩放新旧版本的Pod数量,实现服务升级或降级,让运维工作变得简单又轻松。文章还介绍了Kubernetes更新应用的滚动更新策略、管理命令以及如何添加更新描述,为读者提供了全面的应用更新管理知识。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Kubernetes 入门实战课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(13)

  • 最新
  • 精选
  • 马以
    思考题: 1: “滚动发布”是能力,“灰度发布”是功能,k8s基于“滚动发布”的能力,可以实现pod的‘水平扩展/收缩’,从而能够提供类似于“灰度发布”、“金丝雀发布”这种功能。 2:其实讨论这个问题前,我们要先了解下k8s的控制器模型,另外还要引入一个概念就是“ReplicaSet”,什么意思呢,其实Deployment并不是直接控制Pod,Pod的归属对象是“ReplicaSet”,也就是说Deployment控制的是“ReplicaSet”(版本这个概念其实我们可以等同于是ReplicaSet),然后“ReplicaSet”控制Pod的数量。我们可以通过 kubectl get rs 来看下具体内容: $ kubectl get rs NAME DESIRED CURRENT READY AGE ngx-deploy-699b5dbd6b 4 4 4 7h42m ngx-deploy-6dfbbccf84 0 0 0 9d ngx-deploy-76c65bc7db 0 0 0 9d ngx-deploy-ffd96c4fc 0 0 0 7h46m 所以这个时候,我们再来理解“版本回退”和“直接部署旧版本的 YAML”的区别就容易了,这里的版本就像是我们平时开发代码库打的tag一样,是类似于我们的快照文件一样,这个快照信息可以正确的帮我们记录当时场景的最原始信息,所以我们通过版本回退的方式能够最大限度的保证正确性(这点是k8s已经为我们保证了这一点),反之如果我们通过旧的yaml部署,就不一定能保证当前这个yaml文件有没有被改动过,这里的变数还是挺大的,所以直接通过yaml部署,极大的增加了我们部署的风险性。

    作者回复: great

    2022-08-24归属地:北京
    31
  • 椰子
    滚动更新时,新版本和旧版本共存的那一小段时间是共同对外提供服务的吗?如果这样的话是不是线上就存在不同版本的问题了

    作者回复: 是这样的,但好处是可以不间断对外提供服务。

    2022-08-24归属地:北京
    4
    5
  • Sports
    第一个问题:灰度发布应该是多个应用版本共存,按一定比例分配; 第二个问题:使用rollout版本回退,保持pod固定数量滚动更新,减轻资源压力,尽量地避免版本冲突。 目前只想到这些,希望老师再补充😁

    作者回复: 说的很好。 如果不用rollout undo,虽然效果是相同的,都是滚动更新,但就没有体现“版本回退”的意思了,仅仅是更新了一个版本,不利于运维管理。

    2022-08-24归属地:北京
    4
  • 菲茨杰拉德
    新老pod同时在线。也就意味着,新功能与旧功能同时在线吗?这样业务无法接受吧。要经过灰度或者验证后,才切换到新pod才比较安全吧。

    作者回复: 这个不是Kubernetes考虑的问题,属于业务层面,所以要用其他的手段来保证平稳过渡。

    2022-11-27归属地:北京
    1
  • Bachue Zhou
    这个滚动更新是否真的能做到用户无感知呢?我有点怀疑。例如用户刚刚发了一个 http 请求到一个 pod,处理了一半,pod 就被关闭了,是否可能造成这个请求最终在用户这边出错了?如果 http 能够处理这种情况,那么 http/2 能吗?grpc 能吗?

    作者回复: 这个当然不可能做到完全无感知,但Kubernetes把原来运维的滚动更新流程给极大地简化了。

    2022-11-20归属地:北京
    1
  • 密码123456
    有个问题,我看公司的项目,直接jenkens打包,k8s就能感知到。那k8s,是如何做到的呢?

    作者回复: 这个就属于CI/CD的范围了,其实并不是Kubernetes直接的能力,而是它们与Kubernetes的集成,我对这方面没有了解过,sorry。

    2022-08-25归属地:上海
    3
    1
  • William
    第一次绑定8080:80 端口后面, 升级了pod, 然后访问curl 127.0.0.1 就会报错: Unable to listen on port 8080: Listeners failed to create with the following errors: [unable to create listener: Error listen tcp4 127.0.0.1:8080: bind: address already in use unable to create listener: Error listen tcp6 [::1]:8080: bind: address already 原因: 因为 ​​kubectl​​​ 没有释放其端口绑定,可以通过以下命令手动终止 ​​pid​​(示例基于尝试向前运行8080端口) lsof -i:8080 (mac电脑) 会显示pid kill -9 pid 然后再重新绑定端口就可以了

    作者回复: good

    2024-01-11归属地:吉林
  • 思绪走了灬光✨
    要想实现滚动更新,是不是pod内的应用应该使用短连接?如果是长连接的应用,那么连接可能一直都不会中断,那在强制中断的时候,还是会造成有损?

    作者回复: 短连接效率低,不应该使用。 这个属于应用层次的问题了,kubernetes管不了,一般来说可以设置一个超时时间,过了就强制关闭。

    2023-06-10归属地:北京
    2
  • 滴流乱转小胖儿
    关于老师提到的“maxSurge、maxUnavailable” 可以移步:https://kubernetes.io/zh-cn/docs/concepts/workloads/controllers/deployment/#max-unavailable

    作者回复: good

    2022-11-13归属地:北京
  • dao
    在实验中的 svc 可以简单实用 `type: ClusterIP` ,这样可以直接使用 ClusterIP 访问,而不需要 port-forward 端口转发了。

    作者回复: service默认就是ClusterIP,用port-forward是因为我们在console机上,集群之外。

    2022-09-23归属地:北京
收起评论
显示
设置
留言
13
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部