什么是 Pod 控制器?

Pod 是 Kubernetes 中最小的部署单元,但 Pod 本身是 “临时性” 的(比如节点故障会导致 Pod 消失)。Pod 控制器的作用是:管理 Pod 的生命周期,确保 Pod 始终按照预期状态运行(比如维持指定数量的副本、处理故障重启等)。

一、ReplicaSet(副本集)

作用

保证集群中始终运行指定数量的 Pod 副本,通过 “标签选择器” 关联 Pod,当 Pod 故障时会自动重建。

适用场景

一般不直接使用,主要作为 Deployment 的底层组件(Deployment 通过管理 ReplicaSet 实现更复杂的功能)。

实操步骤
1. 编写 YAML 配置(replicaset-demo.yaml)
# API 版本:apps/v1(ReplicaSet 属于 apps 组,版本 v1)
apiVersion: apps/v1
# 资源类型:ReplicaSet
kind: ReplicaSet
metadata:
  # ReplicaSet 的名称(自定义,需唯一)
  name: rs-demo
  # 可选:给控制器打标签(用于分类或筛选)
  labels:
    controller: replicaset
spec:
  # 核心配置:期望的 Pod 副本数(这里指定 2 个)
  replicas: 2
  # 标签选择器:控制器只管理带有这些标签的 Pod(必须与 Pod 模板的标签匹配)
  selector:
    matchLabels:
      app: nginx  # 匹配 Pod 的标签(关键:类似“身份证”)
  # Pod 模板:定义要创建的 Pod 的规格
  template:
    metadata:
      # Pod 的标签(必须与 selector.matchLabels 一致,否则控制器不识别)
      labels:
        app: nginx
    spec:
      # 容器配置(Pod 中运行的容器)
      containers:
      - name: nginx-container  # 容器名称(自定义)
        image: nginx:1.25      # 容器镜像(nginx 官方镜像,版本 1.25)
        ports:
        - containerPort: 80    # 容器内暴露的端口(nginx 默认监听 80 端口)
2. 创建 ReplicaSet

执行命令:

kubectl apply -f replicaset-demo.yaml
3. 验证创建结果
  • 查看 ReplicaSet:

    kubectl get replicaset
    -----------------------------------------------------------------------------------------------------
    # 输出示例:
    [root@k8s-master Pod-controller]# kubectl get replicasets
    NAME      DESIRED   CURRENT   READY   AGE
    rs-demo   2         2         2       37s
    
  • 查看由 ReplicaSet 管理的 Pod:

    kubectl get pods --show-labels
    -----------------------------------------------------------------------------------------------------
    # 输出示例:
    [root@k8s-master Pod-controller]# kubectl get pods --show-labels 
    NAME            READY   STATUS    RESTARTS   AGE   LABELS
    rs-demo-h2rrx   1/1     Running   0          85s   app=nginx
    rs-demo-pck6t   1/1     Running   0          85s   app=nginx
    
4. 测试故障自愈能力

手动删除一个 Pod,观察是否会自动重建:

# 删除其中一个 Pod(替换为实际 Pod 名称)
kubectl delete pod rs-demo-h2rrx
# 再次查看 Pod,会发现新的 Pod 被创建(名称不同,但标签相同)
kubectl get pods
------------------------------------------------------------------------------------------------------------
#验证
[root@k8s-master Pod-controller]# kubectl get pods -o wide 
NAME            READY   STATUS    RESTARTS   AGE    IP               NODE        NOMINATED NODE   READINESS GATES
rs-demo-h2rrx   1/1     Running   0          2m6s   10.244.36.76     k8s-node1   <none>           <none>
rs-demo-pck6t   1/1     Running   0          2m6s   10.244.169.139   k8s-node2   <none>           <none>
[root@k8s-master Pod-controller]# kubectl delete pod rs-demo-h2rrx 
pod "rs-demo-h2rrx" deleted
[root@k8s-master Pod-controller]# kubectl get pods --show-labels 
NAME            READY   STATUS              RESTARTS   AGE     LABELS
rs-demo-kc7xk   0/1     ContainerCreating   0          21s     app=nginx
rs-demo-pck6t   1/1     Running             0          3m21s   app=nginx
[root@k8s-master Pod-controller]# kubectl get pods -o wide 
NAME            READY   STATUS    RESTARTS   AGE     IP               NODE        NOMINATED NODE   READINESS GATES
rs-demo-kc7xk   1/1     Running   0          45s     10.244.107.204   k8s-node3   <none>           <none>
rs-demo-pck6t   1/1     Running   0          3m45s   10.244.169.139   k8s-node2   <none>           <none>
5. 清理资源(重要!避免环境混乱)
kubectl delete -f replicaset-demo.yaml
# 验证是否删除:kubectl get replicaset 和 kubectl get pods 应无相关资源

二、Deployment(部署)

作用

基于 ReplicaSet 实现,除了维持 Pod 副本数,还支持滚动更新(不中断服务更新 Pod)、版本回滚(更新出错时恢复旧版本),是无状态应用的首选控制器。

适用场景

无状态服务(如 Web 服务器、API 服务等,多个副本完全相同,无依赖关系)。

实操步骤
1. 编写 YAML 配置(deployment-demo.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-demo  # Deployment 名称
  labels:
    controller: deployment
spec:
  replicas: 3  # 期望 3 个 Pod 副本
  # 标签选择器:匹配 Pod 的标签(与 Pod 模板标签一致)
  selector:
    matchLabels:
      app: nginx-deploy
  # 更新策略(核心配置:控制如何更新 Pod)
  strategy:
    type: RollingUpdate  # 滚动更新(默认,逐步替换旧 Pod,不中断服务)
    rollingUpdate:
      maxSurge: 1        # 更新时最多可超出期望副本数的数量(1 个或 25%)
      maxUnavailable: 0  # 更新时最多不可用的副本数(0 表示不允许服务中断)
  # Pod 模板(与 ReplicaSet 类似)
  template:
    metadata:
      labels:
        app: nginx-deploy  # 必须与 selector.matchLabels 一致
    spec:
      containers:
      - name: nginx
        image: nginx:1.25  # 初始镜像版本
        ports:
        - containerPort: 80
2. 创建 Deployment
kubectl apply -f deployment-demo.yaml
3. 验证创建结果
  • 查看 Deployment:

    kubectl get deployment
    -----------------------------------------------------------------------------------------------------
    # 输出示例:
    [root@k8s-master Pod-controller]# kubectl get deployment
    NAME          READY   UP-TO-DATE   AVAILABLE   AGE
    deploy-demo   3/3     3            3           18s
    [root@k8s-master Pod-controller]# kubectl get deployment deploy-demo
    NAME          READY   UP-TO-DATE   AVAILABLE   AGE
    deploy-demo   3/3     3            3           31s
    [root@k8s-master Pod-controller]# kubectl get pods --show-labels 
    NAME                           READY   STATUS    RESTARTS   AGE   LABELS
    deploy-demo-847bcc67cf-62wdw   1/1     Running   0          51s   app=nginx-deploy,pod-template-hash=847bcc67cf
    deploy-demo-847bcc67cf-l2gw2   1/1     Running   0          51s   app=nginx-deploy,pod-template-hash=847bcc67cf
    deploy-demo-847bcc67cf-nsbp2   1/1     Running   0          51s   app=nginx-deploy,pod-template-hash=847bcc67cf
    
  • 查看底层 ReplicaSet(Deployment 会自动创建 ReplicaSet):

    kubectl get replicaset
    -----------------------------------------------------------------------------------------------------
    #验证
    [root@k8s-master Pod-controller]# kubectl get replicasets.apps 
    NAME                     DESIRED   CURRENT   READY   AGE
    deploy-demo-847bcc67cf   3         3         3       2m7s
    
4. 测试滚动更新

更新 Pod 镜像版本(模拟应用升级):

  • 编辑 YAML 文件,将 image: nginx:1.25 改为 image: nginx:1.26

  • 执行更新:

    kubectl apply -f deployment-demo.yaml
    
  • 观察更新过程(旧 Pod 逐步删除,新 Pod 逐步创建):

    kubectl get pods -w  # -w 表示实时监控
    -----------------------------------------------------------------------------------------------------
    #验证
    [root@k8s-master Pod-controller]# kubectl get pod -w
    NAME                           READY   STATUS              RESTARTS   AGE
    deploy-demo-5577f674f8-z6pfw   0/1     ContainerCreating   0          18s
    deploy-demo-847bcc67cf-62wdw   1/1     Running             0          3m54s
    deploy-demo-847bcc67cf-g7cqm   1/1     Running             0          18s
    deploy-demo-847bcc67cf-l2gw2   1/1     Running             0          3m54s
    deploy-demo-847bcc67cf-nsbp2   1/1     Running             0          3m54s
    deploy-demo-847bcc67cf-xqs64   1/1     Running             0          18s
    deploy-demo-847bcc67cf-xsxmv   1/1     Running             0          18s
    deploy-demo-5577f674f8-z6pfw   1/1     Running             0          56s
    deploy-demo-847bcc67cf-xqs64   1/1     Terminating         0          56s
    deploy-demo-5577f674f8-bs2tn   0/1     Pending             0          0s
    deploy-demo-5577f674f8-bs2tn   0/1     Pending             0          0s
    deploy-demo-5577f674f8-bs2tn   0/1     ContainerCreating   0          0s
    deploy-demo-847bcc67cf-xqs64   1/1     Terminating         0          57s
    deploy-demo-5577f674f8-bs2tn   0/1     ContainerCreating   0          1s
    deploy-demo-847bcc67cf-xqs64   0/1     Terminating         0          57s
    deploy-demo-847bcc67cf-xqs64   0/1     Terminating         0          57s
    deploy-demo-847bcc67cf-xqs64   0/1     Terminating         0          57s
    
    [root@k8s-master Pod-controller]# kubectl get pods
    NAME                           READY   STATUS    RESTARTS   AGE
    deploy-demo-5577f674f8-5f889   1/1     Running   0          76s
    deploy-demo-5577f674f8-bs2tn   1/1     Running   0          3m
    deploy-demo-5577f674f8-kh4fj   1/1     Running   0          75s
    deploy-demo-5577f674f8-n28ws   1/1     Running   0          78s
    deploy-demo-5577f674f8-tz8vk   1/1     Running   0          2m21s
    deploy-demo-5577f674f8-z6pfw   1/1     Running   0          3m56s
    
    [root@k8s-master Pod-controller]# kubectl get pods -o wide 
    NAME                           READY   STATUS    RESTARTS   AGE     IP               NODE        NOMINATED NODE   READINESS GATES
    deploy-demo-5577f674f8-5f889   1/1     Running   0          95s     10.244.107.208   k8s-node3   <none>           <none>
    deploy-demo-5577f674f8-bs2tn   1/1     Running   0          3m19s   10.244.36.79     k8s-node1   <none>           <none>
    deploy-demo-5577f674f8-kh4fj   1/1     Running   0          94s     10.244.169.143   k8s-node2   <none>           <none>
    deploy-demo-5577f674f8-n28ws   1/1     Running   0          97s     10.244.36.80     k8s-node1   <none>           <none>
    deploy-demo-5577f674f8-tz8vk   1/1     Running   0          2m40s   10.244.169.142   k8s-node2   <none>           <none>
    deploy-demo-5577f674f8-z6pfw   1/1     Running   0          4m15s   10.244.107.207   k8s-node3   <none>           <none>
    
    [root@k8s-master Pod-controller]# curl 10.244.107.208
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    [root@k8s-master Pod-controller]# 
    
    
    
5. 测试版本回滚

如果更新后出现问题,回滚到上一版本:

# 查看 Deployment 历史版本
kubectl rollout history deployment/deploy-demo
------------------------------------------------------------------------------------------------------------
#验证
[root@k8s-master Pod-controller]# kubectl get deployments
NAME          READY   UP-TO-DATE   AVAILABLE   AGE
deploy-demo   6/6     6            6           10m
[root@k8s-master Pod-controller]# kubectl get deployments deploy-demo 
NAME          READY   UP-TO-DATE   AVAILABLE   AGE
deploy-demo   6/6     6            6           10m
[root@k8s-master Pod-controller]# kubectl rollout history deployment deploy-demo 
deployment.apps/deploy-demo 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>
#<none> 原因是升级时未加注释
------------------------------------------------------------------------------------------------------------

# 回滚到上一版本
kubectl rollout undo deployment/deploy-demo
# 验证回滚结果(Pod 镜像应变回 nginx:1.25)
kubectl describe pod <pod 名称> | grep Image:
------------------------------------------------------------------------------------------------------------
#验证版本
[root@k8s-master Pod-controller]# kubectl describe pod deploy-demo-847bcc67cf | grep Image:
    Image:          nginx:1.25
    Image:          nginx:1.25
    Image:          nginx:1.25
    Image:          nginx:1.25
    Image:          nginx:1.25
    Image:          nginx:1.25
------------------------------------------------------------------------------------------------------------
6. 清理资源
kubectl delete -f deployment-demo.yaml
# 验证:kubectl get deployment、replicaset、pods 均无相关资源

三、DaemonSet(守护进程集)

作用

确保集群中所有节点(或指定节点)上都运行且只运行一个相同的 Pod,节点新增时会自动在新节点创建 Pod,节点删除时 Pod 也会被删除。

适用场景

节点级服务(如日志收集器、监控代理、网络插件等,需要在每个节点运行)。

实操步骤
1. 编写 YAML 配置(daemonset-demo.yaml)
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ds-demo  # DaemonSet 名称
  labels:
    controller: daemonset
spec:
  selector:
    matchLabels:
      app: log-collector  # 匹配 Pod 的标签
  template:
    metadata:
      labels:
        app: log-collector
    spec:
      # 容忍度(可选:允许 Pod 调度到有污点的节点,如 master 节点)
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
        operator: Exists
      containers:
      - name: log-collector
        image: busybox:1.36  # 用 busybox 模拟日志收集器
        # 容器启动命令:循环打印日志到文件(模拟收集日志)
        command: ["/bin/sh", "-c", "while true; do echo '收集节点日志...' >> /var/log/ds-demo.log; sleep 10; done"]
        # 挂载节点的日志目录到容器(让容器能访问节点的日志文件)
        volumeMounts:
        - name: node-log-dir  # 挂载名称(与下面 volumes.name 对应)
          mountPath: /var/log  # 容器内的挂载路径
      # 定义存储卷(关联节点的实际目录)
      volumes:
      - name: node-log-dir
        hostPath:
          path: /var/log  # 节点上的日志目录(容器会读取这里的文件)
2. 创建 DaemonSet
kubectl apply -f daemonset-demo.yaml
3. 验证创建结果
  • 查看 DaemonSet:

    kubectl get daemonset
    # 输出示例:NAME      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   AGE
    #          ds-demo   2         2        2       2            2           30s
    # DESIRED:节点总数(每个节点 1 个 Pod)
    
  • 查看 Pod(每个节点 1 个):

kubectl get pods -o wide # -o wide 显示 Pod 所在节点

输出示例:

[root@k8s-master Pod-controller]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ds-demo-6phjm 1/1 Running 0 40s 10.244.36.83 k8s-node1
ds-demo-9x6c5 1/1 Running 0 40s 10.244.235.199 k8s-master
ds-demo-p79qn 1/1 Running 0 40s 10.244.169.146 k8s-node2
ds-demo-zgdfv 1/1 Running 0 40s 10.244.107.211 k8s-node3



##### 4. 验证节点日志收集(可选)

登录其中一个节点,查看容器写入的日志文件:

```bash
# 在节点上执行(需有节点访问权限)
cat /var/log/ds-demo.log
------------------------------------------------------------------------------------------------------------
# 应看到类似 "收集节点日志..." 的内容
[root@k8s-master Pod-controller]# cat /var/log/ds-demo.log 
收集节点日志...
收集节点日志...
收集节点日志...
收集节点日志...
收集节点日志...
收集节点日志...
收集节点日志...
收集节点日志...
收集节点日志...
收集节点日志...
收集节点日志...
收集节点日志...
收集节点日志...
收集节点日志...
收集节点日志...
收集节点日志...
5. 清理资源
kubectl delete -f daemonset-demo.yaml
# 验证:kubectl get daemonset 和 pods 均无相关资源

四、StatefulSet(有状态集)

作用

管理有状态应用,为 Pod 提供固定的名称(如 web-0、web-1)、固定的网络标识(通过 DNS 访问)和独立的持久化存储(每个 Pod 数据不共享)。

适用场景

有状态服务(如数据库、分布式系统:MySQL、ZooKeeper 等,需要稳定的身份和数据持久化)。

实操步骤
1. 准备 Headless Service(为 StatefulSet 提供网络标识)

StatefulSet 需要一个 “无头服务”(Headless Service)来生成固定的 DNS 记录,先创建它:

statefulset-service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx-headless  # 服务名称
spec:
  selector:
    app: nginx-stateful  # 匹配 StatefulSet 的 Pod 标签
  ports:
  - port: 80
    targetPort: 80
  clusterIP: None  # 关键:Headless Service 无集群 IP,通过 DNS 提供 Pod 域名

创建服务:

kubectl apply -f statefulset-service.yaml
------------------------------------------------------------------------------------------------------------
#测试
[root@k8s-master Pod-controller]# kubectl get service
NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes       ClusterIP   10.96.0.1    <none>        443/TCP   3d22h
nginx-headless   ClusterIP   None         <none>        80/TCP    96s
2. 编写 StatefulSet YAML 配置(statefulset-demo.yaml)
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: sts-demo  # StatefulSet 名称
spec:
  serviceName: "nginx-headless"  # 关联上面的 Headless Service(必须)
  replicas: 2  # 2 个副本
  selector:
    matchLabels:
      app: nginx-stateful  # 匹配 Pod 标签
  # 存储卷声明模板:为每个 Pod 自动创建独立的存储(PVC)
  volumeClaimTemplates:
  - metadata:
      name: data-volume  # 存储卷名称(与容器挂载对应)
    spec:
      accessModes: [ "ReadWriteOnce" ]  # 存储访问模式(单节点读写)
      resources:
        requests:
          storage: 1Gi  # 每个 Pod 请求 1GB 存储
  template:
    metadata:
      labels:
        app: nginx-stateful  # 与 selector 匹配
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80
          name: web
        # 挂载持久化存储到容器内的 /usr/share/nginx/html 目录
        volumeMounts:
        - name: data-volume  # 与 volumeClaimTemplates.name 对应
          mountPath: /usr/share/nginx/html
3. 创建 StatefulSet
kubectl apply -f statefulset-demo.yaml
4. 验证创建结果
  • 查看 StatefulSet:

kubectl get statefulset

输出示例:NAME READY AGE

sts-demo 2/2 40s


- 查看 Pod(名称固定,带序号):

```bash
kubectl get pods
# 输出示例:NAME         READY   STATUS    RESTARTS   AGE
#          sts-demo-0   1/1     Running   0          45s
#          sts-demo-1   1/1     Running   0          40s
# 名称格式:<statefulset 名称>-<序号>(0 开始,固定不变)
  • 查看自动创建的 PVC(每个 Pod 一个):

    kubectl get pvc
    # 输出示例:NAME                     STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    #          data-volume-sts-demo-0   Bound    pv-xxx    1Gi        RWO            standard       50s
    #          data-volume-sts-demo-1   Bound    pv-yyy    1Gi        RWO            standard       45s
    
5. 测试固定网络标识(可选)

在集群内的任意 Pod 中,通过 DNS 访问 StatefulSet 的 Pod:

# 进入一个测试 Pod(如用 busybox)
kubectl run -it --rm busybox --image=busybox:1.36 -- sh
# 在 busybox 中执行 ping 命令(域名格式:<pod 名称>.<service 名称>)
ping sts-demo-0.nginx-headless
ping sts-demo-1.nginx-headless
# 应能 ping 通(证明网络标识固定)
6. 清理资源
# 先删除 StatefulSet(会自动删除 Pod 和 PVC)
kubectl delete -f statefulset-demo.yaml
# 再删除 Headless Service
kubectl delete -f statefulset-service.yaml
# 验证:kubectl get statefulset、service、pvc、pods 均无相关资源

五、Job(任务)

作用

管理一次性任务:确保 Pod 执行完任务后终止(成功则状态为 Completed,失败则按配置重试),不持续运行。

适用场景

批处理任务(如数据备份、日志分析、临时计算等)。

实操步骤
1. 编写 YAML 配置(job-demo.yaml)
apiVersion: batch/v1
kind: Job
metadata:
  name: job-demo  # Job 名称
spec:
  completions: 1   # 任务需要成功完成的总次数(默认 1)
  parallelism: 1   # 并行执行的 Pod 数量(默认 1)
  backoffLimit: 4  # 失败重试次数(超过则任务失败,默认 6)
  template:
    spec:
      containers:
      - name: task
        image: busybox:1.36
        # 任务命令:打印信息 → 休眠 20 秒(模拟任务执行)→ 打印完成
        command: ["/bin/sh", "-c", "echo '任务开始'; sleep 20; echo '任务完成'"]
      restartPolicy: Never  # 任务失败时不重启 Pod(Job 会新建 Pod 重试)
      # 注意:Job 的 restartPolicy 只能是 Never 或 OnFailure(不能是 Always)
2. 创建 Job
kubectl apply -f job-demo.yaml
3. 验证创建结果
  • 查看 Job:

    kubectl get job
    # 输出示例:NAME       COMPLETIONS   DURATION   AGE
    #          job-demo   0/1           10s        10s
    # 等待 20 秒后再次查看,COMPLETIONS 会变为 1/1
    
  • 查看 Job 创建的 Pod:

    kubectl get pods
    # 任务执行中:STATUS 为 Running
    # 任务完成后:STATUS 为 Completed
    
  • 查看任务输出日志:

    # 替换为实际 Pod 名称
    kubectl logs job-demo-abc123
    -----------------------------------------------------------------------------------------------------
    #验证
    [root@k8s-master Pod-controller]# kubectl logs job-demo-j84zr 
    任务开始
    任务完成
    
4. 测试失败重试(可选)

修改 YAML 中的 command 为错误命令(如 echo '任务开始'; exit 1,让任务失败),重新创建 Job:

kubectl apply -f job-demo.yaml
# 查看 Pod 会发现多次重试(最多 backoffLimit 次)
kubectl get pods
5. 清理资源
kubectl delete -f job-demo.yaml
# 验证:kubectl get job 和 pods 均无相关资源

六、CronJob(定时任务)

作用

基于时间调度的 Job,类似 Linux 的 crontab,按指定周期(如每分钟、每天)重复执行任务。

适用场景

周期性任务(如定时备份、日志清理、定时报表生成等)。

实操步骤
1. 编写 YAML 配置(cronjob-demo.yaml)
apiVersion: batch/v1
kind: CronJob
metadata:
  name: cronjob-demo  # CronJob 名称
spec:
  # 调度时间(cron 表达式:分 时 日 月 周)
  # 这里表示“每分钟执行一次”
  schedule: "*/1 * * * *"
  # Job 模板(定义要执行的任务,与 Job 配置一致)
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: cron-task
            image: busybox:1.36
            # 任务命令:打印当前时间和信息
            command: ["/bin/sh", "-c", "date; echo '定时任务执行了'"]
          restartPolicy: Never
  # 并发策略:控制任务是否允许并发执行
  concurrencyPolicy: Allow  # Allow(允许)、Forbid(禁止)、Replace(替换)
  # 任务启动的截止时间(超过 100 秒未启动则视为失败)
  startingDeadlineSeconds: 100
  # 是否暂停任务(false 表示正常调度)
  suspend: false
2. 创建 CronJob
kubectl apply -f cronjob-demo.yaml
3. 验证创建结果
  • 查看 CronJob:

    kubectl get cronjob
    -----------------------------------------------------------------------------------------------------
    [root@k8s-master Pod-controller]# kubectl get cronjob
    NAME           SCHEDULE      SUSPEND   ACTIVE   LAST SCHEDULE   AGE
    cronjob-demo   */1 * * * *   False     0        <none>          5s
    
  • 查看定时生成的 Job(每分钟一个):

    kubectl get jobs
    -----------------------------------------------------------------------------------------------------
    # 示例:
    [root@k8s-master Pod-controller]# kubectl get jobs -w
    NAME                    COMPLETIONS   DURATION   AGE
    cronjob-demo-29374947   1/1           1s         37s
    cronjob-demo-29374948   0/1                      0s
    cronjob-demo-29374948   0/1           0s         0s
    cronjob-demo-29374948   0/1           1s         1s
    cronjob-demo-29374948   1/1           1s         1s
    cronjob-demo-29374949   0/1                      0s
    cronjob-demo-29374949   0/1           0s         0s
    cronjob-demo-29374949   0/1           1s         1s
    cronjob-demo-29374949   1/1           1s         1s
    cronjob-demo-29374950   0/1                      0s
    cronjob-demo-29374950   0/1           0s         0s
    cronjob-demo-29374950   0/1           2s         2s
    cronjob-demo-29374950   1/1           2s         2s
    cronjob-demo-29374947   1/1           1s         3m2s
    
  • 查看 Job 对应的 Pod 及日志:

    kubectl get pods
    -----------------------------------------------------------------------------------------------------
    [root@k8s-master Pod-controller]# kubectl get pods
    NAME                          READY   STATUS      RESTARTS   AGE
    cronjob-demo-29374948-g5vr7   0/1     Completed   0          2m47s
    cronjob-demo-29374949-x8wsz   0/1     Completed   0          107s
    cronjob-demo-29374950-spzm5   0/1     Completed   0          47s
    -----------------------------------------------------------------------------------------------------
    kubectl logs <pod 名称>
    -----------------------------------------------------------------------------------------------------
    #查看
    [root@k8s-master Pod-controller]# kubectl logs cronjob-demo-29374949-x8wsz
    Fri Nov  7 06:29:01 UTC 2025
    定时任务执行了
    
4. 暂停 / 恢复任务(可选)
  • 暂停任务(停止调度新 Job):

    kubectl patch cronjob cronjob-demo -p '{"spec":{"suspend":true}}'
    
  • 恢复任务:

    kubectl patch cronjob cronjob-demo -p '{"spec":{"suspend":false}}'
    
5. 清理资源
kubectl delete -f cronjob-demo.yaml
# 注意:CronJob 创建的历史 Job 和 Pod 不会自动删除,需手动清理:
kubectl delete jobs --all  # 删除所有 Job(会同时删除关联的 Pod)
# 验证:kubectl get cronjob、job、pods 均无相关资源

总结

控制器核心特点练习关键操作
ReplicaSet维持固定副本数手动删除 Pod 测试自愈
Deployment滚动更新、版本回滚更新镜像、回滚版本
DaemonSet每个节点一个 Pod查看 Pod 分布的节点
StatefulSet固定名称、独立存储验证 Pod 名称和 PVC 对应关系
Job一次性任务查看任务日志、测试失败重试
CronJob定时任务观察周期性生成的 Job、暂停 / 恢复任务

更多推荐