Kubernetes Pod 控制器管理与实验记录

一、控制器核心概念

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 格式及控制器时间同步
相关推荐
时间售卖铺2 小时前
MySQL 备份
运维·数据库·mysql·云原生
对象存储与RustFS2 小时前
GPU 在空转等数据?PyTorch 训练集进 RustFS 的三种接法
后端·docker·云原生
fb_123454 小时前
K8s 网络通关手册:Ingress-Nginx 生产级路由 + Calico 三种隧道模式 + NetworkPolicy 白名单实战
网络·nginx·kubernetes
KIDULT°5 小时前
K8s 网络进阶实战:Ingress-Nginx、Calico 与 NetworkPolicy 实验 + 排坑记录
网络·nginx·云原生·kubernetes
fengkai45456 小时前
7、Kubernetes的Ingress&Network&Scheduler
运维·kubernetes·k8s·ingress·network·scheduler
孔令飞21 小时前
知己知彼,百战不殆:AI SKILL 实现原理剖析
云原生·go·ai编程
姜鱼问生1 天前
网页一片白?Docker 跑 Nginx 读不到文件,403 Forbidden 排查实录
nginx·docker·容器
\光辉岁月/1 天前
2.spring5-IOC
java·容器·ioc·注解
分布式存储与RustFS1 天前
把 LSM 引擎直接架在对象存储上:slatedb 能不能跑在 RustFS 上?
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
java_logo1 天前
Docker 部署 Excalidraw:轻松搭建手绘风格白板
运维·docker·容器·excalidraw·白板·轩辕镜像