K8s 运维系列 | 第 4 天:工作负载——Deployment、ReplicaSet 与滚动更新

在前面的文章中,我们已经了解了 Kubernetes 的核心对象 Pod、Label、Selector 与命名空间。Pod 是 K8s 中最小的调度单位,但在生产环境中,我们几乎不会直接创建裸 Pod,因为裸 Pod 一旦被删除或节点宕机,它不会自动恢复。为了让应用具备自愈、扩容和滚动更新能力,Kubernetes 提供了「工作负载(Workload)」这一层抽象,其中最常见、最核心的就是 Deployment。今天我们就来深入拆解 Deployment、ReplicaSet 与滚动更新的关系,并通过实战掌握它们的用法。

K8s 运维 第4天

什么是 Deployment 与 ReplicaSet

在 Kubernetes 中,Deployment 是一种高级工作负载控制器,它负责声明应用的期望状态:要运行多少个 Pod 副本、使用哪个镜像版本、如何更新等。而 ReplicaSet(简称 RS)则是 Deployment 底层的执行者,它的职责非常单一:始终维持指定数量的 Pod 副本在运行。

可以用一句话概括它们的关系:Deployment 管理 ReplicaSet,ReplicaSet 管理 Pod。当你创建一个 Deployment 时,Deployment 控制器会自动创建对应的 ReplicaSet,ReplicaSet 再根据模板创建并维持 Pod 副本数量。这种「控制器分层」的设计让 K8s 能够实现声明式管理:你只需告诉它「我想要 3 个 Nginx 副本」,剩下的由控制器自动完成。

Deployment 的声明式 YAML

下面是一个最典型的 Deployment 配置示例,我们部署一个 Nginx 应用,维持 3 个副本:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.24
        ports:
        - containerPort: 80

需要特别注意的是 selector.matchLabelstemplate.metadata.labels 必须保持一致,否则 Deployment 无法正确管理它创建的 Pod。replicas 字段则声明了期望的副本数量。

实战:创建与管理 Deployment

1. 创建 Deployment 并查看状态

使用 kubectl apply 创建上面的 Deployment,并观察它的运行情况:

kubectl apply -f nginx-deployment.yaml

# 查看 Deployment 状态
kubectl get deployment nginx-deployment

# 查看对应的 ReplicaSet 与 Pod
kubectl get replicaset
kubectl get pods -l app=nginx

执行后你会看到,一个 ReplicaSet 被自动创建,名称类似 nginx-deployment-xxxxxx,同时 3 个 Pod 正在运行。这验证了我们前面提到的分层关系。

2. 手动扩容与缩容

假设业务流量上涨,我们需要把副本数从 3 提升到 5:

kubectl scale deployment nginx-deployment --replicas=5

Kubernetes 会立即创建两个新的 Pod,直到副本数达到 5。反之,缩容时它会优先删除多余的 Pod。整个过程无需人工干预,这正是声明式管理带来的便利。

3. 查看更新历史与详情

Deployment 会记录每一次变更的历史,方便我们回滚:

kubectl rollout history deployment/nginx-deployment
kubectl describe deployment nginx-deployment

滚动更新:零停机发布的核心

滚动更新(Rolling Update)是 Deployment 最强大的能力之一。传统的发布方式往往需要停掉旧版本再启动新版本,造成服务中断;而滚动更新会逐步用新版本的 Pod 替换旧版本的 Pod,在整个过程中始终有可用的副本对外提供服务,从而实现零停机发布。

下面演示一次镜像升级,把 Nginx 从 1.24 升级到 1.25:

kubectl set image deployment/nginx-deployment nginx=nginx:1.25
# 或者直接编辑 YAML 修改 image 字段后 apply
kubectl rollout status deployment/nginx-deployment

更新过程中,Deployment 会创建一个新的 ReplicaSet,新旧两个 ReplicaSet 会同时存在一段时间:新 RS 的 Pod 数量逐渐增加,旧 RS 的 Pod 数量逐渐减少,直到新版本完全接管。

更新策略与回滚

Deployment 的 strategy 字段控制更新策略,默认就是 RollingUpdate,并支持 maxUnavailablemaxSurge 两个关键参数:

spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1        # 更新期间最多可多出的 Pod 数量
      maxUnavailable: 0  # 更新期间最多不可用的 Pod 数量

如果更新后发现新版本有问题,可以快速回滚到上一个版本:

# 查看历史版本
kubectl rollout history deployment/nginx-deployment

# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment

# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2

常见问题与排查

  1. Pod 一直处于 Pending 状态:通常是资源不足或节点调度问题,可以用 kubectl describe pod <pod-name> 查看 Events 定位原因。
  2. 镜像拉取失败(ImagePullBackOff):检查镜像名称、tag 是否正确,以及节点是否能访问镜像仓库。
  3. 滚动更新卡住:如果 maxUnavailable=0 且新旧版本 readiness 探针配置不当,可能导致更新停滞,可检查 kubectl rollout status 的反馈。
  4. 误删了 ReplicaSet:不必担心,只要 Deployment 还在,控制器会自动重新创建 RS 和 Pod。

总结

今天我们从概念到实战完整梳理了 Kubernetes 中最常用的工作负载对象:Deployment、ReplicaSet 与滚动更新。理解这三者的关系是使用 K8s 的关键一步——Deployment 声明期望状态,ReplicaSet 维持副本数量,滚动更新保证零停机发布。掌握了这些,你就能够以声明式的方式从容管理应用的生命周期。

下期预告:第 5 天我们将讲解 Service 与 Ingress——服务发现与流量接入,看看这些随时可能被替换的 Pod 是如何被稳定地访问到的。敬请期待!

微信二维码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容