当前位置: 首页 > news >正文

【Kubernetes】使用StatefulSet进行的资源调度,扩缩容,更改配置到版本回滚,三种配置更新方式

StatefulSet实战进阶:从扩缩容到版本回滚的完整操作指南

在Kubernetes中,StatefulSet的优势不仅在于稳定的身份标识,更在于其有序的更新和回滚机制。

一、StatefulSet的扩缩容:有序增减实例

和Deployment不同,StatefulSet的扩缩容有严格的顺序——扩容时从低序号到高序号创建,缩容时从高序号到低序号删除。这对分布式集群(如ZooKeeper)尤为重要,避免核心节点先被删除。

实操过程:从2个副本到5个,再缩回到2个

# 查看初始状态(2个副本)
kubectl get sts
# 输出:NAME   READY   AGE
#       web    2/2     5h47m# 扩容到5个副本
kubectl scale sts web --replicas=5# 观察扩容过程(新Pod按web-2→web-3→web-4顺序创建)
kubectl get po -w
# 输出会看到:
# web-2   0/1     Pending   0               0s
# web-2   1/1     Running   0               10s
# web-3   0/1     Pending   0               0s
# ...(依次创建)# 缩容回2个副本(多余的web-4→web-3→web-2将被删除)
kubectl scale sts web --replicas=2# 查看缩容结果
kubectl get sts
# 输出:NAME   READY   AGE
#       web    2/2     5h58m

关键观察:扩缩容的有序性

从事件日志能清晰看到这个顺序:

kubectl describe sts web | grep "SuccessfulCreate\|SuccessfulDelete"
# 扩容时:先创建web-2,再web-3,最后web-4
# 缩容时:先删除web-4,再web-3,最后web-2

这就是StatefulSet对有状态应用的保护——比如数据库集群,不会先删除主节点(通常是低序号实例)。

二、版本管理:更新、回滚与历史查看

StatefulSet支持像Deployment一样的版本控制,每次修改Pod模板(如镜像版本)都会生成新的修订版本(Revision),方便回滚到历史状态。

1. 如何更新StatefulSet版本?

最常见的更新是修改镜像版本,这里我用kubectl patch直接修改(也可以编辑配置文件后apply也可以直接 kubect edit:(文末给出三种更新方式)

# 将镜像从nginx:1.7.9更新为nginx:1.9.1
kubectl patch sts web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:1.9.1"}]'

更新会按顺序进行:先更新web-0,确认就绪后再更新web-1(这就是RollingUpdate策略)。

2. 查看版本历史:知道自己改了什么

每次更新后,Kubernetes会记录版本信息,用rollout history查看:

# 查看所有版本
kubectl rollout history sts web
# 输出:
# REVISION  CHANGE-CAUSE
# 1         <none>  # 初始版本(nginx:1.7.9)
# 2         <none>  # 第一次更新(nginx:1.9.1)# 查看指定版本的详细配置
kubectl rollout history sts web --revision=2
# 输出会显示该版本使用的镜像、端口等信息

3. 回滚到历史版本:遇到问题时的救星

我更新到nginx:1.9.1后,web-1一直卡在ImagePullBackOff(镜像拉取失败),这时回滚到上一个可用版本是最佳选择:

# 回滚到指定版本(这里回滚到版本1)
kubectl rollout undo sts web --to-revision=1

但回滚后可能遇到一个问题:部分Pod仍沿用旧镜像配置(比如web-1还在尝试拉取nginx:1.9.1)。这是因为Kubernetes有时会缓存旧配置,解决办法很简单——删除有问题的Pod,StatefulSet会自动用新配置重建:

# 删除卡住的Pod
kubectl delete pod web-1# 查看重建后的状态(会使用版本1的镜像)
kubectl get po web-1
# 输出:web-1   1/1     Running   0               4s

三、实战踩坑与解决方案

坑1:回滚后Pod仍用旧镜像

现象:执行rollout undo后,web-1状态还是ImagePullBackOff,仍在拉取旧镜像。

原因:kubelet节点缓存了旧的Pod配置,未及时更新。

解决:手动删除Pod触发重建(StatefulSet会自动按最新配置创建新Pod):

kubectl delete pod web-1

坑2:版本历史中找不到旧版本

现象:回滚后执行kubectl rollout history sts web --revision=1,提示“unable to find the specified revision”。

原因:每次回滚或更新都会生成新的修订版本(比如回滚到版本1后,会生成版本3),旧版本编号会被覆盖。

解决:无需纠结旧编号,直接查看当前历史:

# 查看最新历史
kubectl rollout history sts web
# 找到目标版本的新编号(比如版本3是nginx:1.7.9),再回滚
kubectl rollout undo sts web --to-revision=3

坑3:rollout status一直显示“Waiting for pods”

现象:执行kubectl rollout status sts web后,长时间显示“Waiting for 1 pods to be ready”。

原因:部分Pod未就绪(比如镜像拉取失败、健康检查未通过)。

解决

  1. 查看Pod具体状态:kubectl describe pod web-1
  2. 针对性解决(如镜像拉取失败就换镜像,或删除Pod重建)

四、StatefulSet版本管理核心命令总结

操作命令说明
查看版本历史kubectl rollout history sts <名称>列出所有修订版本
查看指定版本详情kubectl rollout history sts <名称> --revision=<编号>查看某版本的配置(如镜像)
回滚到上一版本kubectl rollout undo sts <名称>无需指定编号,回滚到最近一次更新前
回滚到指定版本kubectl rollout undo sts <名称> --to-revision=<编号>精确回滚到目标版本
查看更新/回滚状态kubectl rollout status sts <名称>确认是否所有Pod都完成更新
强制重建Podkubectl delete pod <pod名称>解决缓存导致的配置不生效问题

五、总结:StatefulSet版本管理的核心原则

  1. 有序性是核心:无论扩缩容还是更新,StatefulSet都按“先低后高”或“先高后低”的顺序操作,避免有状态应用出现混乱。
  2. 版本即配置快照:每次修改Pod模板(如镜像)都会生成新修订版本,这是回滚的基础。
  3. 回滚后需验证:回滚命令执行成功不代表所有Pod都已更新,需通过get porollout status确认状态。
  4. 缓存问题:遇到配置不生效时,删除Pod是简单有效的解决办法(StatefulSet会自动重建)。

一、三种更新方式对比

方式适用场景难度特点
kubectl apply -f <文件>修改配置文件后批量更新最安全,支持重复执行,需先编辑文件
kubectl edit <资源类型> <名称>临时修改单个资源,快速验证直接编辑运行中的资源,无需保存文件
kubectl patch <资源类型> <名称>脚本化、自动化更新,修改单个字段使用JSON Patch语法,适合CI/CD

二、用 kubectl edit 更新 StatefulSet

这是最直观的交互式编辑方式,适合初学者:

# 编辑名为web的StatefulSet
kubectl edit sts web# 执行后会打开默认编辑器(如vi),显示当前StatefulSet的YAML配置
# 找到并修改镜像版本(通常在 spec.template.spec.containers[0].image 路径下)
# 保存并退出编辑器,Kubernetes会自动应用修改
优点:
  • 无需记住复杂的字段路径,直接查看完整配置
  • 所见即所得,修改后立即生效
  • 适合临时调整或测试
缺点:
  • 不适合批量或自动化操作
  • 多人协作时可能覆盖他人修改
  • 编辑大文件时可能眼花缭乱

三、用 kubectl patch 更新 StatefulSet

这是更精确的字段级修改方式,适合脚本化操作:

# 方式1:使用JSON Patch格式(官方推荐)
kubectl patch sts web --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value": "nginx:1.9.1"}]'# 方式2:使用merge格式(更简单,但有局限性)
kubectl patch sts web -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx","image":"nginx:1.9.1"}]}}}}'
JSON Patch语法解释:
  • op: 操作类型(replace/add/remove
  • path: JSON路径,指向要修改的字段(如 /spec/template/spec/containers/0/image
  • value: 新值
优点:
  • 适合自动化脚本(如CI/CD流水线)
  • 可精确控制修改内容
  • 支持原子性操作(多个patch一起执行)
缺点:
  • 需要熟悉JSON路径语法
  • 命令很长,容易写错
  • 调试困难(出错时难以定位问题)

四、用 kubectl apply 更新 StatefulSet

这是最推荐的“声明式”更新方式:

# 1. 编辑本地配置文件
vim web.yaml
# 修改其中的镜像版本# 2. 应用修改
kubectl apply -f web.yaml
优点:
  • 配置可追踪(版本控制工具如Git可管理)
  • 支持增量更新(只修改变化的部分)
  • 可重复执行,幂等性设计
  • 适合团队协作(所有人使用同一配置文件)
缺点:
  • 需要先保存配置文件
  • 不适合紧急修改(需先找到并编辑文件)

五、初学者应该选哪种方式?

  1. 推荐顺序
    kubectl applykubectl editkubectl patch

  2. 具体场景建议

    • 日常开发:用 apply,保持配置文件与集群状态一致
    • 临时调试:用 edit,快速修改验证
    • 自动化更新:用 patch,集成到CI/CD流程
  3. 避免踩坑

    • 不要混用多种方式(如用 edit 修改后又用 apply),可能导致配置冲突
    • patch 适合简单字段修改,复杂修改建议用 apply
    • 修改前先用 kubectl get <资源> -o yaml 查看当前配置,避免意外覆盖

六、常见问题解答

1. 如何找到要修改的字段路径?
  • kubectl get sts web -o yaml 查看完整配置
  • 使用工具如 jq 提取路径:
    kubectl get sts web -o json | jq '.spec.template.spec.containers[0].image'
    
2. patch 报错 “field is immutable” 怎么办?

StatefulSet的某些字段(如 serviceName)不可修改,需删除重建:

kubectl delete sts web
kubectl apply -f web.yaml
3. 如何验证修改是否成功?
# 查看StatefulSet状态
kubectl get sts web# 查看Pod使用的镜像
kubectl get po web-0 -o jsonpath='{.spec.containers[0].image}'# 查看事件日志
kubectl describe sts web | grep Events -A 20

http://www.dtcms.com/a/299448.html

相关文章:

  • c#中让图片显示清晰
  • 三、平衡桥电路
  • 060_泛型擦除与边界限定
  • MySQL数据库SQL语句进阶篇——连接查询与子查询详解
  • Traffic Lights set的使用
  • CSS变量与Houdini自定义属性:解锁样式编程新维度
  • Go 语言函数设计原则:避免修改传入参数
  • MCU中的GPIO(通用输入/输出)是什么?
  • [Qt]QString隐式拷贝
  • 利用DeepSeek解决kdb+x进行tpch测试的几个问题及使用感受
  • 系统架构设计师-【2025年上半年案例题】-真题分享
  • unittest 案例执行顺序详解
  • [SAP ABAP] ALV报表练习4
  • FreeRTOS-事件组
  • Cortex-M3内核SysTick定时器介绍
  • `munmap`系统调用及示例
  • 柔性智造:华控智能的垂直整合定制方案
  • 微服务springcloud http客户端feign
  • 伟淼科技李志伟:破解二代接班传承困局,系统性方案破除三代魔咒
  • Redis缓存策略以及bigkey的学习(九)
  • C语言——学习笔记
  • 数据结构(4)单链表算法题(上)
  • Linux DNS 服务器正反向解析
  • 深入分析计算机网络传输层和应用层面试题
  • 从压缩到加水印,如何实现一站式图片处理
  • 编程语言Java——核心技术篇(四)集合类详解
  • 从0开始学linux韦东山教程Linux驱动入门实验班(5)
  • C语言中:形参与实参的那些事
  • 分类预测 | MATLAB实现CPO-SVM冠豪猪算法优化支持向量机分类预测
  • 分类预测 | MATLAB实现DBO-SVM蜣螂算法优化支持向量机分类预测