【Kubernetes系列】控制器(Controller)全解:ReplicaSet、Deployment、DaemonSet、Job 与 CronJob

前言

在上一篇文章中,我们学习了 Pod 的创建、管理与生命周期。但单独使用 kubectl run 创建的"裸 Pod"有一个致命缺陷:它不会自愈、不会扩容、也不会滚动更新。一旦节点宕机,Pod 就永远消失了。

为了解决这个问题,Kubernetes 引入了控制器(Controller)------它们通过「声明期望状态 + 持续调谐(reconcile)」的机制,让集群中的实际状态不断逼近用户期望的状态。这种"声明式 API + 控制循环"正是 Kubernetes 的核心设计哲学。

本文将依次讲解常用的五种控制器:ReplicaSet、Deployment、DaemonSet、Job、CronJob,并重点剖析 Deployment 的滚动更新策略。

实验环境与上一篇一致 :k8s-master / k8s-node1 / k8s-node2 三节点集群,镜像仓库 reg.timinglee.org

五大常用控制器

一、ReplicaSet 控制器

ReplicaSet(简称 RS)的职责只有一个:确保集群中始终运行指定数量的 Pod 副本。它会持续监控 Pod 数量,少了就新建、多了就删除,从而实现自愈。

1.1 创建 ReplicaSet

ReplicaSet 的 YAML 与 Pod 很像,多了一个 replicasselector 字段:

复制代码
# 先用 deployment 模板生成,再把 kind 改为 ReplicaSet
kubectl create deployment webcluster --image myapp:v1 --dry-run=client -o yaml > repset.yml

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  labels:
    app: webcluster
  name: webcluster
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webcluster
  template:
    metadata:
      labels:
        app: webcluster
    spec:
      containers:
      - image: myapp:v1
        name: myapp

kubectl apply -f repset.yml
kubectl get pods --show-labels
# NAME               READY   STATUS    AGE   LABELS
# webcluster-tbxq4   1/1     Running   6m    app=webcluster
# webcluster-jna23   1/1     Running   6m    app=webcluster

1.2 扩缩容测试

修改 replicas 字段即可扩缩容:

复制代码
kubectl scale replicaset webcluster --replicas 4
kubectl scale replicaset webcluster --replicas 2
kubectl scale replicaset webcluster --replicas 0

也可以用 kubectl edit 或修改 YAML 的 replicasapply

⚠️ 注意:日常生产中几乎不直接使用 ReplicaSet,而是使用 Deployment------Deployment 在背后自动创建并管理 ReplicaSet,从而支持滚动更新与回滚。ReplicaSet 本身不支持版本更新历史。


二、Deployment 控制器

Deployment 是生产环境最常用的控制器,它在 ReplicaSet 之上增加了滚动更新、回滚、版本记录等能力,是无状态服务的首选。

2.1 通过 YAML 创建 Deployment

复制代码
kubectl create deployment webcluster --image myapp:v1 --dry-run=client -o yaml > dep.yml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: webcluster
  name: webcluster
spec:
  minReadySeconds: 5     # 新 Pod 就绪后至少等待 5 秒才视为可用(用于平滑切换)
  replicas: 2
  selector:
    matchLabels:
      app: webcluster
  template:
    metadata:
      labels:
        app: webcluster
    spec:
      containers:
      - image: myapp:v1
        name: myapp

kubectl apply -f dep.yml
kubectl get pods --show-labels
kubectl get replicasets.apps   # Deployment 自动创建了 ReplicaSet
# NAME                    DESIRED   CURRENT   READY   AGE
# webcluster-77c87d9946   2         2         2       45s

# 暴露服务并访问
kubectl expose deployment webcluster --port 80 --target-port 80
curl 10.107.142.60
# Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

2.2 滚动升级与回滚(修改镜像)

升级:把镜像版本改成 v2 后重新 apply

复制代码
spec:
  template:
    spec:
      containers:
      - image: myapp:v2   # 升级为版本 2
        name: myapp

kubectl apply -f dep.yml
curl 10.107.142.60
# Hello MyApp | Version: v2 ...

回滚:改回 v1 再 apply 即可(也可以用 kubectl rollout undo):

复制代码
spec:
  template:
    spec:
      containers:
      - image: myapp:v1   # 回滚为版本 1
        name: myapp

kubectl apply -f dep.yml
curl 10.107.142.60
# Hello MyApp | Version: v1 ...

💡 建议把 replicas 调大(如 6)来更直观地观察滚动过程中新旧 Pod 的交替。每次修改 template 都会生成一个新的 ReplicaSet,旧 RS 会被保留以便回滚。


三、Deployment 版本更新策略与优化

3.1 查看默认更新策略

复制代码
kubectl describe deployments.apps webcluster
# RollingUpdateStrategy:  25% max unavailable, 25% max surge

默认采用 RollingUpdate(滚动更新),即先启动新 Pod、再下线旧 Pod,保证服务不中断。默认允许最多 25% 的 Pod 不可用、最多超出期望值 25% 的新 Pod。

3.2 自定义滚动更新策略

复制代码
spec:
  minReadySeconds: 5
  replicas: 6
  strategy:
    rollingUpdate:
      maxSurge: 1          # 更新时 Pod 数量最多比期望值多 1 个
      maxUnavailable: 0     # 更新时不可用 Pod 数量最多为 0(保证零中断)
  template:
    spec:
      containers:
      - image: myapp:v1
        name: myapp
  • maxSurge:更新过程中可超出期望副本数的最大数量(绝对值或百分比)。
  • maxUnavailable:更新过程中允许不可用的最大数量(绝对值或百分比)。

maxUnavailable: 0 配合 maxSurge: 1 可实现"先起新、后删旧"的平滑发布,适合对可用性要求极高的服务。

另一种更新策略是 Recreate:先删除全部旧 Pod,再创建新 Pod,会造成短暂服务中断,适合无法多版本共存的场景。

3.3 更新暂停与恢复(金丝雀发布基础)

有时我们希望先更新一部分,观察没问题再全量。可以暂停滚动更新:

复制代码
kubectl rollout pause deployment webcluster     # 暂停
# 修改镜像为 v2 后 apply,此时更新不会真正推进(仅记录新期望)
kubectl apply -f dep.yml
kubectl rollout history deployment webcluster    # 版本记录不会新增
kubectl rollout resume deployment webcluster     # 恢复,更新真正开始
kubectl rollout history deployment webcluster
# REVISION  CHANGE-CAUSE
# 8         <none>
# 9         <none>

这就是金丝雀发布(Canary)蓝绿部署的基础思路------先小流量验证,再逐步放量。


四、DaemonSet 控制器

DaemonSet 保证集群中每个(或符合选择器条件的)节点上都运行一个 Pod 副本。典型用途:日志采集(Fluentd/Filebeat)、监控代理(node-exporter)、网络插件(CNI)、存储插件。

复制代码
apiVersion: apps/v1
kind: DaemonSet
metadata:
  labels:
    app: daemonset
  name: daemonset
spec:
  selector:
    matchLabels:
      app: daemonset
  template:
    metadata:
      labels:
        app: daemonset
    spec:
      containers:
      - image: myapp:v1
        name: myapp

kubectl apply -f daemonset.yml
# 新节点加入集群后,会自动在该节点上运行 DaemonSet 指定的 Pod

实验验证:新建 node3 并 kubeadm join 加入集群后,node3 上会立刻自动创建该 DaemonSet 的 Pod。也可以通过 nodeSelector / affinity 控制只在特定节点部署。


五、Job 控制器

Job 用于运行一次性任务,任务成功完成(容器退出码为 0)后 Pod 不会再重启,适合批处理、数据迁移、测试等场景。

复制代码
kubectl create job job --image perl:5.34.0 --dry-run=client -o yaml > job.yml

apiVersion: batch/v1
kind: Job
metadata:
  name: testjob
spec:
  completions: 6      # 总共需要成功完成 6 次
  parallelism: 2      # 最大并行运行 2 个 Pod
  backoffLimit: 4     # 失败重试上限为 4 次
  template:
    spec:
      containers:
      - image: busybox
        name: testjob
        command: ["/bin/sh","-c"]
        args:
        - |
          echo this is testjob message
          sleep 10
      restartPolicy: Never

kubectl apply -f job.yml
kubectl logs pods/testjob-4cdlr
# this is testjob message

关键字段:

  • completions:Job 需要成功完成的 Pod 总数。
  • parallelism:同时运行的 Pod 上限。
  • backoffLimit:失败重试次数上限。
  • restartPolicy:Job 中通常为 NeverOnFailure(不能用默认的 Always)。

六、CronJob 控制器

CronJob 在 Job 之上增加了基于时间的调度,类似 Linux 的 crontab,用于周期性任务(如定时备份、定时报表、缓存清理)。

复制代码
kubectl create cronjob cronjob --image busybox --schedule "* * * * *" --dry-run=client -o yaml > cronjob.yml

apiVersion: batch/v1
kind: CronJob
metadata:
  name: cronjob
spec:
  schedule: '* * * * *'    # 分 时 日 月 周,这里表示每分钟执行一次
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - image: busybox
            name: cronjob
            command:
            - /bin/sh
            - -c
            - echo "hello timinglee"
          restartPolicy: OnFailure

kubectl apply -f cronjob.yml
kubectl get cronjobs.batch
# NAME      SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
# cronjob   * * * * *   False     0        17s             70s
kubectl logs cronjob-29598241-pxggh
# hello timinglee

调度格式为标准的 5 段 cron 表达式(分 时 日 月 周)。也可设置 startingDeadlineSeconds(错过调度的最大容忍时间)、concurrencyPolicy(并发策略:Allow/Forbid/Replace)。


总结

本文介绍了 Kubernetes 中五种最常用的控制器:

控制器 适用场景 核心特点
ReplicaSet 维持 Pod 副本数 自愈、扩缩容(通常被 Deployment 间接使用)
Deployment 无状态服务 在 RS 之上支持滚动更新、回滚、版本管理
DaemonSet 节点级守护进程 每个节点运行一个副本
Job 一次性任务 任务完成即结束,支持并发与重试
CronJob 周期性任务 基于 cron 表达式定时触发 Job

此外,官方还提供 StatefulSet (有状态服务,如数据库,提供稳定网络标识与持久存储)、HorizontalPodAutoscaler(HPA) (基于 CPU/内存等指标自动扩缩容)以及 Operator 模式(针对复杂有状态应用的扩展控制器),后续可深入学习。

相关推荐
nxb5561 小时前
云原生:控制器
java·开发语言·云原生
UseLessQQ1 小时前
云原生 kubenetes 控制器管理
云原生·kubernetes
是枚小菜鸡儿吖4 小时前
把视频教程变成可复习的笔记:Docker 部署 BiliNote,自动转写与总结
笔记·docker·容器
浪兎兎11 小时前
【Kubernetes 实战】(二)部署 Ruoyi-Cloud —— 部署服务
云原生·容器·kubernetes
淼澄研学12 小时前
Proliferate开源框架技术解析与Docker部署实操
docker·容器·开源
浪兎兎13 小时前
Docker 容器技术笔记
笔记·docker·容器
Zhu75814 小时前
在Docker环境离线部署最新版Harbor
运维·docker·容器
大大大大晴天14 小时前
K8S 在大数据里的真正价值:适用场景、收益边界与不适合的地方
大数据·云原生
众人皆醒我独醉15 小时前
流量路由:Istio 与 Knative 的集成
面试·kubernetes·llm