一、控制器核心概念

1.1 控制器的作用

自主创建的 Pod 在进程退出或节点异常后不会自动重建。控制器在用户声明期望副本数后将目标状态写入 etcd,kube-apiserver 持续比对实际状态与期望状态,驱动 kubelet 完成调谐(reconcile)循环。

对比维度

自主式 Pod

控制器管理 Pod

故障自愈

自动重建

扩缩容

手动逐个操作

一条命令调整 replicas

版本更新

删除重建

滚动更新/回滚

适用场景

临时调试

生产环境

1.2 控制器类型总览

控制器

API Group

核心职责

ReplicationController

core/v1

已废弃,被 ReplicaSet 替代

ReplicaSet

apps/v1

维持指定数量 Pod 副本

Deployment

apps/v1

管理 ReplicaSet,提供声明式更新

DaemonSet

apps/v1

每个节点运行一个 Pod 副本

StatefulSet

apps/v1

有状态应用管理

Job

batch/v1

一次性批处理任务

CronJob

batch/v1

基于时间调度的 Job

HPA

autoscaling/v2

基于指标自动扩缩容


二、ReplicaSet

2.1 功能与参数

ReplicaSet 通过 spec.selector.matchLabels 关联 Pod,通过 spec.template 定义 Pod 模板。标签必须一致,否则控制器无法接管已有 Pod。

参数路径

说明

spec.replicas

期望副本数

spec.selector.matchLabels

标签选择器

spec.template.metadata.labels

Pod 模板标签,须与 selector 匹配

spec.template.spec.containers

容器定义列表

2.2 实验记录

生成 YAML:

kubectl create deployment webcluster --image myapp:v1 --dry-run=client -o yaml > repset.yml

repset.yml:

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

创建与验证:

kubectl apply -f repset.yml
kubectl get pods --show-labels

输出:

NAME               READY   STATUS    LABELS
webcluster-tbxq4   1/1     Running   app=webcluster
webcluster-jna23   1/1     Running   app=webcluster

伸缩测试:

kubectl scale replicaset webcluster --replicas 4
kubectl get pods --show-labels
# 输出4个Pod,均带 app=webcluster 标签

kubectl scale replicaset webcluster --replicas 2
kubectl get pods --show-labels
# 缩减回2个

标签篡改触发自愈:

kubectl label pod webcluster-tbxq4 app=webcluster-tmp --overwrite
kubectl get pods --show-labels

输出:

webcluster-jna23   1/1   Running   app=webcluster
webcluster-tbxq4   1/1   Running   app=webcluster-tmp
webcluster-tr5qk   1/1   Running   app=webcluster

原 Pod 标签被改后脱离控制器管理,ReplicaSet 立即新建一个 Pod 补足副本数。

删除 Pod 自愈验证:

kubectl delete pod webcluster-jna23
kubectl get pods --show-labels
# 新的 webcluster-9km2p 被创建

恢复原标签并清理:

kubectl label pod webcluster-tbxq4 app=webcluster --overwrite
kubectl delete -f repset.yml

三、Deployment

3.1 架构关系

Deployment → ReplicaSet(v1) → Pod
                ↓
     ReplicaSet(v2) → Pod(滚动更新期间)

Deployment 不直接管理 Pod,每个 ReplicaSet 对应一个镜像版本。更新时创建新 ReplicaSet,逐步扩容新 RS 同时缩容旧 RS。

3.2 滚动更新参数

参数

默认值

含义

maxSurge

25%

更新期间可超出期望副本数的最大数量

maxUnavailable

25%

更新期间允许低于期望副本数的最大数量

minReadySeconds

0

新 Pod 就绪后等待时间,防止过早判定可用

3.3 实验记录

dep.yml:

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

创建与暴露服务:

kubectl apply -f dep.yml
kubectl expose deployment webcluster --port 80 --target-port 80
curl 10.107.142.60
# Hello MyApp | Version: v1 | ...

升级到 v2:

修改 image: myapp:v2 后重新 apply,验证:

curl 10.107.142.60
# Hello MyApp | Version: v2 | ...
kubectl get replicasets.apps
# webcluster-77c87d9946  0 0 0(旧)
# webcluster-7f4786db9c  2 2 2(新)

回滚到 v1:

修改 image: myapp:v1 后重新 apply,验证版本恢复为 v1。

自定义滚动策略:

spec:
  replicas: 6
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
kubectl apply -f dep.yml
kubectl describe deployment webcluster | grep RollingUpdate
# RollingUpdateStrategy:  0 max unavailable, 1 max surge

暂停与恢复:

kubectl rollout pause deployment webcluster
# 修改 dep.yml 中 image 和 resources 后 apply,不会触发更新
kubectl rollout history deployment webcluster  # 无新 revision
kubectl rollout resume deployment webcluster
kubectl rollout history deployment webcluster  # 新增 revision 3

清理:

kubectl delete -f dep.yml
kubectl delete service webcluster

四、DaemonSet

4.1 调度行为

场景

行为

新节点加入集群

自动在新节点创建 Pod

节点被删除

回收该节点上的 Pod

设置 nodeSelector

仅在匹配标签的节点上运行

4.2 实验记录

daemonset.yml:

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

创建验证:

kubectl apply -f daemonset.yml
kubectl get pods -o wide

输出(3节点集群):

daemonset-87h6s   10.244.0.8    k8s-master
daemonset-n4vs4   10.244.2.38   k8s-node2
daemonset-vhxmq   10.244.1.40   k8s-node1

加入 node3 后自动调度:

kubectl get pods -o wide
# 新增 daemonset-pq9km  10.244.3.2  node3

清理:

kubectl delete -f daemonset.yml

五、Job

5.1 重启策略对照

restartPolicy

Pod 失败行为

适用场景

OnFailure

容器重启,Pod 不重建

任务可重试

Never

创建新 Pod,原 Pod 保留 Completed 状态

需查看失败日志

Always

持续重启

不适用于 Job

5.2 实验记录

job.yml:

apiVersion: batch/v1
kind: Job
metadata:
  name: testjob
spec:
  completions: 6
  parallelism: 2
  backoffLimit: 4
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: testjob
        image: busybox
        command: ["/bin/sh", "-c"]
        args:
        - |
          echo this is testjob message
          sleep 10

创建与验证:

kubectl apply -f job.yml
kubectl get pods
# 看到多个 testjob-xxxxx Pod,状态依次为 Completed
kubectl logs testjob-4cdlr
# this is testjob message

字段

含义

completions

6

总共需要成功完成 6 次

parallelism

2

同时最多运行 2 个 Pod

backoffLimit

4

失败重试上限


六、CronJob

6.1 调度格式

与 Linux cron 一致:

分钟 小时 日 月 星期

6.2 实验记录

cronjob.yml:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: cronjob
spec:
  schedule: "* * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - name: cronjob
            image: busybox
            command: ["/bin/sh", "-c"]
            args:
            - echo "hello timinglee"

创建与验证:

kubectl apply -f cronjob.yml
kubectl get cronjobs.batch
# NAME      SCHEDULE    ACTIVE   LAST SCHEDULE   AGE
# cronjob   * * * * *   0        17s             70s

kubectl get pods
# cronjob-29598241-pxggh   0/1   Completed   0   2m

kubectl logs cronjob-29598241-pxggh
# hello timinglee

清理:

kubectl delete -f cronjob.yml

七、问题排查速查表

现象

排查命令

Pod 一直 Pending

kubectl describe pod <name> 查看 Events

Pod 反复重启

kubectl logs <pod> --previous

滚动更新卡住

kubectl rollout status deployment <name>

标签不匹配导致 Pod 不被接管

kubectl get pods --show-labels 对比 selector

DaemonSet Pod 未调度到新节点

检查节点污点 kubectl describe node <node>

Job 不执行

检查 restartPolicy 是否为 Never 或 OnFailure

CronJob 未触发

检查 schedule 格式及控制器时间同步

更多推荐