Kubernetes 控制器

控制器类型作用典型场景是否推荐单独使用
Deployment管理无状态应用:滚动升级、回滚、扩缩容Web 服务、API✅ 常用
ReplicaSet仅维护 Pod 副本数被 Deployment 隐式调用❌ 不建议单独用
DaemonSet保证每个节点跑一个 Pod日志收集、监控、CNI
Job一次性任务计算、备份、迁移
CronJob定时任务周期性备份、报告
StatefulSet有状态应用:稳定网络+存储+顺序MySQL、ZK、Kafka

2. Deployment:无状态应用“万金油”

2.1 最小可运行模板

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.26-alpine
        ports:
        - containerPort: 80

2.2 常用操作速查

# 创建/更新
kubectl apply -f deployment-nginx.yml

# 扩容 & 缩容
kubectl scale deployment deploy-nginx --replicas=3

# 滚动升级(记录版本)
kubectl set image deployment/deploy-nginx nginx=nginx:1.29-alpine --record

# 查看滚动状态
kubectl rollout status deployment deploy-nginx

# 版本历史
kubectl rollout history deployment deploy-nginx

# 回滚到上一版本 / 指定版本
kubectl rollout undo deployment deploy-nginx
kubectl rollout undo deployment deploy-nginx --to-revision=1

# 删除(级联删除 Pod)
kubectl delete deployment deploy-nginx

2.3 故障排查 Tips

  • Pod 一直 ContainerCreating
    查看 kubectl describe pod <pod-name> → 关注 FailedCreatePodSandBox 网络插件错误。
    重启 Calico:
    kubectl rollout restart daemonset calico-node -n kube-system
    

3. ReplicaSet:幕后英雄

Deployment 自动创建 RS,不建议单独维护
验证 RS 存在:

kubectl get rs

手动扩容 RS 可行,但无滚动策略,升级镜像不会触发滚动 → 故弃用。


4. DaemonSet:节点级守护进程

4.1 示例(日志采集)

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: daemonset-nginx
spec:
  selector:
    matchLabels:
      name: nginx-ds
  template:
    metadata:
      labels:
        name: nginx-ds
    spec:
      # 容忍 master 污点,使其也运行
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: nginx
        image: nginx:1.26-alpine
        resources:
          requests:
            memory: 100Mi

4.2 常用命令

kubectl apply -f daemonset-nginx.yml
kubectl get ds
kubectl set image daemonset/daemonset-nginx nginx=nginx:latest

注意:DaemonSet 不能手动扩缩容(副本数=节点数),但支持滚动升级。


5. Job:一次性任务

5.1 计算 π 2000 位

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      nodeName: node2        # 指定节点,避免镜像大拉取慢
      containers:
      - name: c-pi
        image: perl
        command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

5.2 固定次数任务

spec:
  completions: 10   # 总执行次数
  parallelism: 2    # 并发数

5.3 常用命令

kubectl apply -f job.yml
kubectl get job
kubectl logs pi-xxxxx          # 查看结果
kubectl delete job pi

6. CronJob:Linux 级 crontab 云原生版

6.1 每分钟打印问候

apiVersion: batch/v1
kind: CronJob
metadata:
  name: cronjob1
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo hello kubernetes
          restartPolicy: OnFailure

6.2 周期备份 MySQL

spec:
  schedule: "0 2 * * *"  # 每天 02:00
  jobTemplate:
    spec:
      template:
        spec:
          nodeName: node1
          containers:
          - name: mysqldump
            image: mysql:5.7
            command:
            - /bin/sh
            - -c
            - |
              mysqldump --host=mysql-test -uroot -pabc123 \
                --databases mysql > /root/mysql$(date +\%Y\%m\%d\%H\%M).sql
            volumeMounts:
            - name: data
              mountPath: /root
          volumes:
          - name: data
            hostPath:
              path: /opt/mysqldump
          restartPolicy: Never

7. StatefulSet:有状态应用“真命天子”

7.1 三大要素

  1. Headless Service(无 ClusterIP)→ 稳定 DNS
  2. StatefulSet 本体 → 顺序部署/删除/滚动
  3. volumeClaimTemplates → 自动 PVC → 绑定 PV

7.2 最小可用模板(动态供给版)

# 1. Headless Service
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  clusterIP: None
  selector:
    app: nginx
  ports:
  - port: 80
    name: web
---
# 2. StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  serviceName: "nginx-svc"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx-c
        image: nginx:1.26-alpine
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: "nfs-client"   # 动态供给类
      resources:
        requests:
          storage: 1Gi

7.3 金丝雀(灰度)发布

# 只升级序号 ≥1 的 Pod
kubectl patch sts web -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":1}}}}'

# 升级镜像
kubectl set image sts/web nginx-c=nginx:1.29-alpine

# 观察:web-0 保持旧版,web-1/web-2... 已新版
kubectl get pods -o custom-columns=Name:metadata.name,Image:spec.containers[0].image

# 全量升级:把 partition 改回 0
kubectl patch sts web -p '{"spec":{"updateStrategy":{"rollingUpdate":{"partition":0}}}}'
kubectl set image sts/web nginx-c=nginx:1.29-alpine

7.4 扩缩容顺序

  • 扩容:0→1→2→…
  • 缩容:…→2→1→0
    保证 有序 + 不变网络 ID (web-0.nginx-svc.default.svc.cluster.local)

8. 存储体系:PV、PVC、StorageClass

8.1 静态供给(提前建 PV)

# PV
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-nfs
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.100.138
    path: /data/nfs
---
# PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-nfs
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi

8.2 动态供给(StorageClass)

  1. 部署 NFS-Subdir-External-Provisioner
    官方仓库:
    https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner

  2. 一键下载(国内镜像已替换)

mkdir nfs-cli && cd nfs-cli
wget https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/class.yaml
wget https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/rbac.yaml
wget https://raw.githubusercontent.com/kubernetes-sigs/nfs-subdir-external-provisioner/master/deploy/deployment.yaml
  1. 修改 deployment.yaml

    • 镜像改为国内:registry.cn-beijing.aliyuncs.com/pylixm/nfs-subdir-external-provisioner:v4.0.0
    • 填入 NFS 服务器地址与共享目录
  2. 应用并验证

kubectl apply -f rbac.yaml
kubectl apply -f class.yaml
kubectl apply -f deployment.yaml

# 查看 StorageClass
kubectl get sc
  1. 使用:在 PVC 里写 storageClassName: nfs-client 即可自动创 PV。

9. 思维导图

Controller
├── 无状态
│   └── Deployment(RS 隐形)
├── 有状态
│   └── StatefulSet(Headless + PVC)
├── 守护进程
│   └── DaemonSet(节点级)
├── 一次性
│   └── Job(completions/parallelism)
├── 定时
│   └── CronJob(schedule)
└── 存储
    ├── 静态 PV/PVC
    └── 动态 StorageClass → 自动 PV

10. 最佳实践小结

  1. 无状态 → 直接 Deployment;有状态 → StatefulSet + Headless + PVC。
  2. 升级策略:
    • Deployment:默认滚动;可 maxUnavailable/maxSurge 调参。
    • StatefulSet:利用 partition 做金丝雀,灰度到“序号”级别。
  3. 镜像提前拉取:大镜像建议 nodeName 指定或集群提前 docker pull
  4. 存储:
    • 测试/开发:NFS + 动态供给最省事。
    • 生产:根据性能选 Ceph、Longhorn、云盘等。
  5. 备份:CronJob + mysqldump + hostPath/NFS,记得加日期变量避免覆盖。
  6. 清理:删除控制器即级联删除下属 Pod;PV 回收策略注意 Retain/Delete

更多推荐