K8s控制器详解:从原理到实战

在 Kubernetes(K8s)中,控制器(Controller) 是核心组件,用于实现对 Pod 及其他资源的自动化管理,确保集群状态始终符合用户定义的 "期望状态"。控制器通过监控集群状态,自动调整资源(如创建 / 删除 Pod、扩展副本数),实现自愈、扩缩容、滚动更新等核心功能。

一、控制器核心概念

  • 期望状态(Desired State):用户通过 YAML 配置定义的目标状态(如 "3 个 nginx 副本")。
  • 实际状态(Current State):集群中资源的当前运行状态。
  • 控制循环(Control Loop):控制器持续监控实际状态,对比期望状态,通过 "调谐(Reconciliation)" 操作消除差异(如实际副本数不足时创建新 Pod)。

二、常用控制器类型及应用场景

K8s 提供多种控制器,适用于不同业务场景,以下是最常用的几种:

1. Deployment(部署控制器)

功能 :管理无状态应用的 Pod 和 ReplicaSet,支持滚动更新、版本回滚、扩缩容。适用场景:Web 服务、API 接口等无状态应用(实例可替换,无顺序依赖)。

核心特性

  • 自动创建 ReplicaSet(副本集),通过 ReplicaSet 管理 Pod。
  • 支持滚动更新(逐步替换旧 Pod,避免服务中断)。
  • 保留历史版本,可一键回滚到之前的状态。

示例:创建 Deployment(nginx-deploy.yaml

复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deploy
spec:
  replicas: 3  # 期望 3 个副本
  selector:    # 匹配 Pod 的标签(必须与 template 中 labels 一致)
    matchLabels:
      app: nginx
  template:    # Pod 模板(定义 Pod 规格)
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80

常用操作

复制代码
# 创建 Deployment
kubectl apply -f nginx-deploy.yaml

# 查看 Deployment 和 ReplicaSet
kubectl get deployments
kubectl get replicasets

# 扩缩容(调整副本数)
kubectl scale deployment nginx-deploy --replicas=5

# 滚动更新镜像
kubectl set image deployment nginx-deploy nginx=nginx:1.25

# 查看更新状态
kubectl rollout status deployment nginx-deploy

# 回滚到上一版本
kubectl rollout undo deployment nginx-deploy
2. StatefulSet(有状态集控制器)

功能 :管理有状态应用的 Pod,确保每个 Pod 有固定的名称、网络标识和存储。适用场景:数据库(如 MySQL、MongoDB)、分布式系统(如 ZooKeeper、Kafka)等有状态应用(实例不可替换,有顺序 / 依赖关系)。

核心特性

  • 每个 Pod 有固定名称(<statefulset-name>-<ordinal-index>,如 mysql-0mysql-1)。
  • 稳定的网络标识(通过 Headless Service 提供固定 DNS 记录)。
  • 持久化存储(每个 Pod 关联独立的 PVC,数据不随 Pod 重建丢失)。
  • 有序部署 / 删除(部署时从 0 到 N-1,删除时从 N-1 到 0)。

示例:StatefulSet 核心配置

复制代码
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: mysql
spec:
  serviceName: "mysql-headless"  # 关联的 Headless Service(提供 DNS)
  replicas: 2
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:8.0
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "rootpass"
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
  volumeClaimTemplates:  # 存储模板(自动创建 PVC)
  - metadata:
      name: data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 10Gi
3. DaemonSet(守护进程集控制器)

功能 :确保集群中所有(或指定)节点运行相同的 Pod,新节点加入时自动部署 Pod。适用场景:节点级服务,如日志收集(Fluentd)、监控代理(Prometheus Node Exporter)、网络插件(Calico 节点组件)。

核心特性

  • 每个节点默认运行一个 Pod(可通过节点选择器限制)。
  • 节点删除时,对应的 Pod 自动删除。

示例:DaemonSet(部署监控代理)

复制代码
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
spec:
  selector:
    matchLabels:
      app: node-exporter
  template:
    metadata:
      labels:
        app: node-exporter
    spec:
      containers:
      - name: node-exporter
        image: prom/node-exporter:v1.5.0
        ports:
        - containerPort: 9100
4. Job(任务控制器)

功能 :管理一次性任务(执行完成后终止的 Pod),确保任务成功完成。适用场景:数据备份、批量计算、初始化操作等短期任务。

核心特性

  • 任务完成(Pod 状态为 Succeeded)后停止。
  • 支持并行执行(parallelism)和重试(backoffLimit)。

示例:Job(执行一次性命令)

复制代码
apiVersion: batch/v1
kind: Job
metadata:
  name: backup-job
spec:
  template:
    spec:
      containers:
      - name: backup
        image: busybox:1.35
        command: ["sh", "-c", "echo 'Backup done' && sleep 10"]  # 模拟备份任务
      restartPolicy: Never  # 任务型 Pod 通常设为 Never 或 OnFailure
  backoffLimit: 4  # 最大重试次数(默认 6)
5. CronJob(定时任务控制器)

功能 :基于时间调度的 Job,类似 Linux 的 cron 服务,按周期重复执行任务。适用场景:定时备份、日志清理、周期性数据同步等。

核心特性

  • schedule 字段定义的 cron 表达式触发(如 0 3 * * * 表示每天凌晨 3 点)。
  • 可配置任务历史保留策略(successfulJobsHistoryLimitfailedJobsHistoryLimit)。

示例:CronJob(每天清理日志)

复制代码
apiVersion: batch/v1
kind: CronJob
metadata:
  name: log-cleanup
spec:
  schedule: "0 3 * * *"  # 每天凌晨 3 点执行
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: cleanup
            image: busybox:1.35
            command: ["sh", "-c", "rm -rf /var/log/*"]  # 模拟清理日志
          restartPolicy: OnFailure
  successfulJobsHistoryLimit: 3  # 保留 3 个成功任务记录
  failedJobsHistoryLimit: 1      # 保留 1 个失败任务记录
6. ReplicaSet(副本集控制器)

功能 :确保指定数量的 Pod 副本始终运行(维持期望副本数)。注意:Deployment 已封装 ReplicaSet 功能,直接使用 Deployment 更推荐(支持更新和回滚),ReplicaSet 通常不单独使用。

示例:ReplicaSet 核心配置

复制代码
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx-rs
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine

三、控制器核心原理:以 Deployment 为例

  1. 用户创建 Deployment,定义期望副本数(如 3)和 Pod 模板。
  2. Deployment 自动创建 ReplicaSet,并将期望副本数传递给 ReplicaSet。
  3. ReplicaSet 监控 Pod 状态:
    • 若实际副本数 < 期望数(如 Pod 故障被删除),则创建新 Pod。
    • 若实际副本数 > 期望数,则删除多余 Pod。
  4. 当更新 Deployment(如修改镜像),会创建新的 ReplicaSet,逐步替换旧 ReplicaSet 的 Pod(滚动更新),旧 ReplicaSet 保留为历史版本(可回滚)。

四、控制器使用最佳实践

  1. 无状态选 Deployment:Web 服务、API 等用 Deployment,利用其滚动更新和回滚能力。
  2. 有状态选 StatefulSet:数据库、分布式系统等用 StatefulSet,确保稳定的标识和存储。
  3. 节点级服务选 DaemonSet:监控、日志收集等需在每个节点运行的服务用 DaemonSet。
  4. 一次性任务用 Job:批量处理、备份等短期任务用 Job;定时任务用 CronJob。
  5. 避免直接创建 Pod:Pod 无自愈能力,通过控制器管理可自动恢复故障实例。

总结

控制器是 K8s 自动化管理的核心,通过声明式配置实现 "期望状态" 与 "实际状态" 的自动对齐。选择合适的控制器类型(如 Deployment 管理无状态应用,StatefulSet 管理有状态应用)是构建稳定、可扩展 K8s 集群的关键。

相关推荐
做运维的阿瑞5 小时前
DevOps 生命周期完全指南
运维·容器·devops
大大大大物~6 小时前
数据结构之HashMap(容器)
java·数据结构·容器
梁正雄7 小时前
扩展、Docker-compose-1
docker·容器·composer
知花实央l7 小时前
【数字逻辑】数字逻辑实验实战:74HC151实现逻辑函数+74HC138搭全加器(附接线步骤+避坑指南)
算法·容器·测试用例·逻辑回归
派阿喵搞电子7 小时前
在阿里云通过docker部署srs流媒体服务器(支持webrtc、http-flv)
阿里云·docker·webrtc
zwjapple7 小时前
阿里云安装docker-compose
阿里云·docker·云计算
zwjapple7 小时前
阿里云配置了加速器还是访问不了docker.io的解决方案。
阿里云·docker·云计算
LCG元7 小时前
Docker容器化实战:将你的SpringBoot应用一键打包部署,告别环境不一致的烦恼!#第一部分
后端·docker
王忘杰7 小时前
K8S Kubernetes集群部署
kubernetes