Kubernetes 控制器深度指南:从 ReplicaSet 到 DaemonSet

控制器(Controller)是 Kubernetes 控制面的灵魂。整个集群之所以能在节点宕机、Pod 漂移、版本劣化的情况下依然稳定对外服务,靠的不是人工干预,而是控制器永不停歇的调谐循环(Reconcile Loop)。本文以实操为主线,逐一拆解 ReplicaSet、Deployment、DaemonSet 的设计哲学、边界与工程实践。

文章目录

    • 一、Controllers:期望状态的守护者
      • [1. 核心职责](#1. 核心职责)
      • [2. 两类容器,两条治理路径](#2. 两类容器,两条治理路径)
      • [3. 环境准备](#3. 环境准备)
    • 二、ReplicaSet:副本数量的守门人
      • [1. 定义与定位](#1. 定义与定位)
      • [2. 工作原理](#2. 工作原理)
      • [3. 创建与验证](#3. 创建与验证)
      • [4. 健壮性实测](#4. 健壮性实测)
      • [5. 删除行为与孤儿保留](#5. 删除行为与孤儿保留)
    • 三、ReplicationController:已被取代的前辈
    • 四、Deployment:声明式更新的编排者
      • [1. 定位与层级关系](#1. 定位与层级关系)
      • [2. 典型用例](#2. 典型用例)
      • [3. 创建:两种范式](#3. 创建:两种范式)
      • [4. 编辑](#4. 编辑)
      • [5. 删除](#5. 删除)
      • [6. 水平伸缩](#6. 水平伸缩)
      • [7. 健壮性实测:节点宕机后的自愈](#7. 健壮性实测:节点宕机后的自愈)
      • [8. 更新镜像](#8. 更新镜像)
      • [9. 版本控制与回滚](#9. 版本控制与回滚)
      • [10. 滚动更新:两个参数决定一切](#10. 滚动更新:两个参数决定一切)
    • 五、DaemonSet:节点级守护进程
      • [1. 定义](#1. 定义)
      • [2. 典型用例](#2. 典型用例)
      • [3. 用法层次](#3. 用法层次)
      • [4. 创建与查看](#4. 创建与查看)
      • [5. 调度:污点决定 Pod 落点](#5. 调度:污点决定 Pod 落点)
      • [6. 健壮性与删除](#6. 健壮性与删除)
      • [7. K8s 集群中的 DaemonSet](#7. K8s 集群中的 DaemonSet)
    • 总结

一、Controllers:期望状态的守护者

1. 核心职责

Controller 的唯一使命,是让被管理资源的实际状态 不断逼近用户声明的期望状态 。它持续监控集群对象,一旦发现实际与期望存在偏差,就立即执行补偿动作------这正是 Kubernetes 自愈能力 与自动弹性伸缩的能力来源。

2. 两类容器,两条治理路径

从运行形态看,容器可分为两类,Kubernetes 也据此给出了两套控制器体系:

容器类型 行为特征 典型场景 对应控制器
服务类容器 常驻运行,持续对外提供服务 Nginx、API 服务、数据库 ReplicaSet、Deployment、DaemonSet
工作类容器 一次性任务,执行完毕后容器退出 批处理、数据清洗、定时报表 Job、CronJob

3. 环境准备

为隔离实验资源,先建立独立命名空间并切换上下文:

bash 复制代码
root@master30:~# kubectl create ns controllers
root@master30:~# kubectl config set-context --current --namespace controllers

二、ReplicaSet:副本数量的守门人

1. 定义与定位

ReplicaSet(简称 RS)负责维护一组在任意时刻都处于运行状态的 Pod 副本集合,其价值在于保证指定数量的、完全相同的 Pod 始终可用。

需要清醒认识到它的定位:RS 主要被 Deployment 用作 Pod 创建、删除与更新的底层编排机制。日常生产中,几乎没有人直接操作 ReplicaSet。

2. 工作原理

ReplicaSet 由三个核心字段驱动:

  1. selector ------ 用于识别归属 Pod 集合的选择算符;
  2. replicas ------ 应当维持的副本数量;
  3. template ------ 创建新 Pod 时使用 Pod 模板。

RS 依据模板创建出指定数量的 Pod,并通过持续的差值比对实现自身价值:

  • 实际数量 多于 期望数量 → RS 主动终止多余的 Pod;
  • 实际数量 少于 期望数量 → RS 立即补齐 Pod(例如宿主机内核升级后,在其他节点上重建新 Pod)。

3. 创建与验证

bash 复制代码
root@master30:~# vim rs.yaml
bash 复制代码
# rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: hub.laoma.cloud/library/nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
bash 复制代码
root@master30:~# kubectl apply -f rs.yaml

root@master30:~# kubectl get rs
NAME    DESIRED   CURRENT   READY   AGE
nginx   3         3         3       8m45s

root@master30:~# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
nginx-95pth   1/1     Running   0          8m48s
nginx-9jg4f   1/1     Running   0          8m48s
nginx-tjtp2   1/1     Running   0          8m48s

# 确认 Pod 的属主关系
root@master30:~# kubectl describe pod nginx-9jg4f | grep Controlled
Controlled By:  ReplicaSet/nginx

4. 健壮性实测

测试一:删除单个副本,观察自愈
bash 复制代码
root@master30:~# kubectl get rs
NAME    DESIRED   CURRENT   READY   AGE
nginx   3         3         3       8m45s

root@master30:~# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
nginx-95pth   1/1     Running   0          8m48s
nginx-9jg4f   1/1     Running   0          8m48s
nginx-tjtp2   1/1     Running   0          8m48s

# 删除一个 Pod
root@master30:~# kubectl delete pod nginx-95pth --force

root@master30:~# kubectl get pods
NAME          READY   STATUS    RESTARTS   AGE
nginx-4qw2z   1/1     Running   0          2s
nginx-9jg4f   1/1     Running   0          9m20s
nginx-tjtp2   1/1     Running   0          9m20s

nginx-95pth 消失 2 秒后,nginx-4qw2z 被立即补建,副本数重回 3。

机制要点 :Pod 的 metadata.ownerReferences 字段记录了所属的主资源。正是通过这条引用链,ReplicaSet 才能掌握自己维护的 Pod 集合状态,并据此规划操作行为。

更值得注意的是认领规则 :RS 通过 selector 获取 Pod 集合。若某个 Pod 没有 OwnerReference,或其 OwnerReference 并非控制器,同时又能匹配到某个 ReplicaSet 的选择算符,那么该 Pod 会立即被这个 ReplicaSet 认领。

测试二:手动创建相同标签的 Pod
bash 复制代码
# 创建一个带 app=nginx 标签的裸 Pod
root@master30:~# kubectl run nginx --image=hub.laoma.cloud/library/nginx:latest -l app=nginx; kubectl get pods
NAME          READY   STATUS        RESTARTS   AGE
nginx         0/1     Terminating   0          0s
nginx-4qw2z   1/1     Running       0          3m40s
nginx-9jg4f   1/1     Running       0          12m
nginx-tjtp2   1/1     Running       0          12m

# 结果:刚创建出来就立刻被 Terminating

裸 Pod 被 RS 认领后,因超出 replicas: 3 的期望值,随即被回收------认领即治理。

5. 删除行为与孤儿保留

默认删除 RS 控制器时,其管理的全部 Pod 会被级联删除:

bash 复制代码
root@master30:~# kubectl delete rs nginx
root@master30:~# kubectl get pods

使用 --cascade=orphan 可只删除 RS、保留 Pod( Pod 变为无主孤儿):

bash 复制代码
root@master30:~# kubectl apply -f rs.yaml
root@master30:~# kubectl delete rs nginx --cascade=orphan

root@master30:~# kubectl get pods
NAME              READY   STATUS    RESTARTS   AGE
pod/nginx-27vzb   1/1     Running   0          73s
pod/nginx-7lc95   1/1     Running   0          73s
pod/nginx-mmrhk   1/1     Running   0          73s

# 清理残留 Pod
root@master30:~# kubectl delete all -l app=nginx

三、ReplicationController:已被取代的前辈

ReplicationController(简称 RC)与 ReplicaSet 功能相近,是早期版本中的副本管理机制。ReplicaSet 是 RC 的升级版 ,关键差异在于 RS 支持新的基于集合的标签选择算符 (matchExpressions)。

由于 RC 已退出主流实践,本文不再展开。新项目一律使用 ReplicaSet 或 Deployment。


四、Deployment:声明式更新的编排者

1. 定位与层级关系

Deployment(简称 deploy)为 Pod 与 ReplicaSet 提供声明式的更新能力。

三者的层级清晰可见:

bash 复制代码
# 资源层级:上层控制器逐层托管下层资源
Deployment → ReplicaSet → Pod
  • ReplicaSet 只解决"跑够 N 个副本";
  • Deployment 管理 ReplicaSet,并在此之上提供滚动更新、版本回滚、暂停恢复、伸缩等编排能力。

因此官方建议:用 Deployment 管理 ReplicaSet,除非你需要自定义更新编排。这意味着你可能永远不需要直接操作 ReplicaSet 对象。

2. 典型用例

场景 具体动作
上线发布 创建 Deployment 将 ReplicaSet 上线,并检查其是否成功
渐进更新 更新 PodTemplateSpec 声明 Pod 新状态,新 ReplicaSet 被创建,Pod 以受控速率从旧 RS 迁移至新 RS,每轮都推进修订版本
故障回滚 当前状态不稳定时回滚至较早版本,每次回滚同样更新修订版本
容量扩展 扩大 Deployment 规模以承载更高负载
批量变更 暂停上线以应用多项 PodTemplateSpec 修改,再恢复执行启动新版本
停滞判定 使用 Deployment Status 判断上线过程是否卡住
资源清理 清理较旧的、不再需要的 ReplicaSet

3. 创建:两种范式

方式一:命令行(快捷起手)
bash 复制代码
root@master30:~# kubectl create deployment web --image=hub.laoma.cloud/library/nginx:1.27 --replicas=2

# 查看 Deployment 连带创建的所有资源
root@master30:~# kubectl get all
NAME                      READY   STATUS    RESTARTS   AGE
pod/web-b78cbd74b-6fjxs   1/1     Running   0          3s
pod/web-b78cbd74b-mh6fh   1/1     Running   0          3s

NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/web   2/2     2            2           3s

NAME                            DESIRED   CURRENT   READY   AGE
replicaset.apps/web-b78cbd74b   2         2         2       3s

逐层验证属主关系:

bash 复制代码
# Deployment 详细信息
root@master30:~# kubectl describe deployments.apps web
Name:                   web
Namespace:              laoma
CreationTimestamp:      Sat, 21 Oct 2023 13:17:06 +0000
Labels:                 app=web
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=web
Replicas:               2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=web
  Containers:
   nginx:
    Image:        nginx:1.27
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   web-b78cbd74b (2/2 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  21s   deployment-controller  Scaled up replica set web-b78cbd74b to 2

# ReplicaSet 与 Deployment 的关系
root@master30:~# kubectl describe replicaset.apps web-b78cbd74b | grep Controlled
Controlled By:  Deployment/web
# 指明 ReplicaSet 由 Deployment/web 创建

# Pod 与 ReplicaSet 的关系
root@master30:~# kubectl describe pod web-b78cbd74b-6fjxs | grep Controlled
Controlled By:  ReplicaSet/web-b78cbd74b
# 指明 Pod 由 ReplicaSet/web-b78cbd74b 创建
方式二:YAML 清单(生产首选)

先用 dry-run 导出清单,再纳入版本管理:

bash 复制代码
# 导出 Deployment 的 yaml 文件
root@master30:~# kubectl create deployment web --image=hub.laoma.cloud/library/nginx:1.27 --replicas=2 --dry-run=client -o yaml > deployment-web.yaml

root@master30:~# cat deployment-web.yaml
# deployment-web.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: web
  name: web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - image: hub.laoma.cloud/library/nginx:1.27
        name: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80

root@master30:~# kubectl apply -f deployment-web.yaml

关键字段语义

字段 含义
apiVersion 当前配置格式的版本
kind 要创建的资源类型,此处为 Deployment
metadata 资源元数据,name 为必需项
spec 该 Deployment 的规格说明
spec.replicas 副本数量,默认为 1
spec.template Pod 模板,配置文件的核心部分
spec.template.metadata Pod 元数据,至少定义一个 label,key/value 可任意指定
spec.template.spec Pod 规格,定义容器属性,name 与 image 为必需
两种方式如何选
维度 命令行方式 配置文件方式
上手成本 简单、直观、快捷 需熟悉清单语法,有一定门槛
表达内容 描述 How(怎么做) 描述 What(最终要达到的状态)
可复用性 一次性 提供资源模板,可重复部署
适用场景 临时测试、实验验证 正式、跨环境、规模化部署

附带一句实用价值:kubectl apply 不仅能创建资源,同样能更新资源,一个命令贯穿建与改。

4. 编辑

bash 复制代码
# 方法一:命令行直接修改
root@master30:~# kubectl edit deployments.apps web

# 方法二:编辑资源文件后 apply 应用

# 方法三:命令行定向修改,例如调整副本数
root@master30:~# kubectl scale deployment web --replicas=4

5. 删除

删除 Deployment 时,默认连带删除其管理的子资源:

bash 复制代码
root@master30:~# kubectl delete deployments.apps web
deployment.apps "web" deleted

使用 --cascade=orphan 可保留子资源:

bash 复制代码
root@master30:~# kubectl apply -f deployment-web.yaml
root@master30:~# kubectl delete deployments.apps web --cascade=orphan

# 先确认待删除对象
root@master30:~# kubectl get all -l app=web

# 确认无误后再删除
root@master30:~# kubectl delete all -l app=web
root@master30:~# kubectl get all -l app=web

6. 水平伸缩

bash 复制代码
# 创建 Deployment
root@master30:~# kubectl create deployment web --image=hub.laoma.cloud/library/nginx:1.27 --replicas=2

# 一键扩容
root@master30:~# kubectl scale deployment web --replicas=3

# 或者交互式编辑
root@master30:~# kubectl edit deployments.apps web

# 或者导出清单、修改后 apply
root@master30:~# kubectl get deployments.apps web -o yaml > web.yaml
root@master30:~# vim web.yaml

root@master30:~# kubectl get pod
NAME                  READY   STATUS    RESTARTS   AGE
web-5899d78c9-cckln   1/1     Running   0          9m28s
web-5899d78c9-p8pk4   1/1     Running   0          43s
web-5899d78c9-phntq   1/1     Running   0          9m28s

7. 健壮性实测:节点宕机后的自愈

关闭 worker 节点,观察 Pod 重建行为:

bash 复制代码
root@master30:~# kubectl get pod -o wide
NAME                  READY   STATUS    RESTARTS   AGE     IP              NODE                 NOMINATED NODE   READINESS GATES
web-5899d78c9-cckln   1/1     Running   0          14m     10.224.51.134   worker31.laoma.cloud   <none>           <none>
web-5899d78c9-p8pk4   1/1     Running   0          6m12s   10.224.51.135   worker31.laoma.cloud   <none>           <none>
web-5899d78c9-phntq   1/1     Running   0          14m     10.224.225.69   worker32.laoma.cloud   <none>           <none>

# 关闭 worker32
root@worker32:~# init 0

# 等待约 5 分钟:Kubernetes 判定 worker32 不可用,将其上的 Pod 标记为 Unknown,
# 并在 worker31 上重建 Pod,维持总副本数为 3

# 当 worker32 恢复后,Unknown 的 Pod 会被删除;
# 已在其他节点运行的 Pod 不会重新调度回 worker32

Kubernetes 判定节点宕机,需经历三个阶段:

阶段 机制 关键参数 归属组件
① 心跳上报 Node 上 kubelet 默认每 10s 向 apiserver 上报自身状态(kubelet → kube-apiserver) --- kubelet
② 健康判定 Master 上 controller-manager 每 5s 检查一次心跳,连续 40s 未收到即判定 Node 不健康并标记为 NotReady node-monitor-period=5s node-monitor-grace-period=40s kube-controller-manager
③ 驱逐 Pod 节点 NotReady 持续满 5 分钟,开始将 Pod 驱逐到其他节点 pod-eviction-timeout=300s kube-controller-manager

参数修改方式(该组件以静态 Pod 形式运行在 master 节点):

bash 复制代码
# 配置路径
/etc/kubernetes/manifests/kube-controller-manager.yaml

# 编辑静态 Pod 配置文件,找到 command 段,
# 在其下面添加或修改上述参数行,保存文件即可触发静态 Pod 重启

8. 更新镜像

将 Deployment 的镜像从 nginx:1.27 升级至 nginx:1.28:

bash 复制代码
# 获取容器名称
root@master30:~# kubectl get deployments.apps -o wide
NAME   READY   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS   IMAGES                             SELECTOR
web    3/3     3            3           139m   nginx        hub.laoma.cloud/library/nginx:1.27 app=web

# 或者
root@master30:~# kubectl describe deployments.apps web | grep Container -i -A2
  Containers:
   nginx:
    Image:        hub.laoma.cloud/library/nginx:1.27

# 更新镜像
root@master30:~# kubectl set image deployment/web nginx=hub.laoma.cloud/library/nginx:1.28 --record

# 或者直接编辑 Deployment 设置镜像
root@master30:~# kubectl edit deployments.apps web

# 可以看到新增了一个 ReplicaSet,用于创建新的 Pod
root@master30:~# kubectl get rs
NAME                             DESIRED   CURRENT   READY   AGE
replicaset.apps/web-5899d78c9    0         0         0       26m
replicaset.apps/web-6c57bdf5f4   3         3         3       9s

# 校验镜像版本
root@master30:~# kubectl get deployments.apps web -o wide
NAME   READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                             SELECTOR
web    3/3     3            3           26m   nginx        hub.laoma.cloud/library/nginx:1.28 app=web

旧 ReplicaSet 被缩容至 0 但并未删除------这正是回滚能力的物质基础。

9. 版本控制与回滚

kubectl rollout 是 Deployment 版本控制的统一入口:

bash 复制代码
root@master30:~# kubectl rollout -h
Manage the rollout of one or many resources.

 Valid resource types include:

  *  deployments
  *  daemonsets
  *  statefulsets

Examples:
  # Rollback to the previous deployment
  kubectl rollout undo deployment/abc

  # Check the rollout status of a daemonset
  kubectl rollout status daemonset/foo

  # Restart a deployment
  kubectl rollout restart deployment/abc

  # Restart deployments with the 'app=nginx' label
  kubectl rollout restart deployment --selector=app=nginx

Available Commands:
  history       View rollout history
  pause         Mark the provided resource as paused
  restart       Restart a resource
  resume        Resume a paused resource
  status        Show the status of the rollout
  undo          Undo a previous rollout

Usage:
  kubectl rollout SUBCOMMAND [options]

Use "kubectl rollout <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).

实操示例:

bash 复制代码
# 再次更新镜像至 nginx:1.29
root@master30:~# kubectl set image deployment/web nginx=hub.laoma.cloud/library/nginx:1.29 --record

# 查看更新记录(--record 会把变更原因写入 CHANGE-CAUSE)
root@master30:~# kubectl rollout history deployment web
deployment.apps/web
REVISION  CHANGE-CAUSE
1         <none>
2         kubectl set image deployment/web nginx=nginx:1.28 --record=true
3         kubectl set image deployment/web nginx=nginx:1.29 --record=true

# 回滚到版本 1
root@master30:~# kubectl rollout undo deployment web --to-revision=1
deployment.apps/web rolled back

root@master30:~# kubectl rollout history deployment web
deployment.apps/web
REVISION  CHANGE-CAUSE
2         kubectl set image deployment/web *=nginx:1.28 --record=true
3         kubectl set image deployment/web *=nginx:1.29 --record=true
4         <none>

注意回滚后修订版本号的走向:回滚本身会生成 REVISION 4 ,而不是把编号倒退回 1。Kubernetes 的版本序列是单调递增的,回滚只是复用旧模板的一次新上线。

10. 滚动更新:两个参数决定一切

Kubernetes 用 maxSurge 与 maxUnavailable 精细控制 Pod 替换节奏:

参数 作用 取值形式 默认 示例(DESIRED=10)
maxSurge 滚动更新过程中,副本总数允许超过期望值的上限 整数(如 3)或百分比,向上取整 25% 副本总数最大为 roundUp(10 + 10 × 25%) = 13,因此 CURRENT 可见 13
maxUnavailable 滚动更新过程中,不可用副本占期望值的最大比例 整数(如 3)或百分比,向下取整 25% 可用副本至少为 roundDown(10 - 10 × 25%) = 8,因此 AVAILABLE 可见 8

两条直觉结论:

  • maxSurge 越大 → 初始创建的新副本越多;
  • maxUnavailable 越大 → 初始销毁的旧副本越多,更新初期造成的不可用副本也越多。

理想情况下,本案例的滚动更新过程应当如此演进:

  1. 创建 3 个新副本,此时 Running 副本数为 10,叠加 maxSurge 后副本总数达到 13;
  2. 销毁 2 个旧副本,同时再创建 2 个新副本,此时 Running 副本数为 8。若先前创建的 3 个副本尚未转为 Running,则 ContainerCreating 副本数为 5,maxSurge 总数仍为 13;
  3. 新副本状态转为 Running------例如先前创建的 5 个新副本在同一时刻变为 Running(这是一种理想化情形);
  4. 此时 Running 状态副本为 13 个,那么可以一次性销毁 5 个旧副本,同时一次性创建 5 个新副本,使 Running 副本数回到 8;
  5. 该过程持续循环,直到所有旧副本被新副本替换,滚动更新完成。

实践验证:更新 Deployment 镜像,并用以下脚本持续监控 Pod 状态分布:

bash 复制代码
root@master30:~# vim monitor_pod_numbers
bash 复制代码
#!/bin/bash
while true
do
  echo '===================' >> output.log
  kubectl get pods --no-headers |awk '{print $3}' |sort | uniq -c |sed -r 's/^ +//' >> output.log
  sleep 0.5
done

采集到的日志形态如下(可清晰看到状态从 Running 向 ContainerCreating / Terminating 扩散、再收敛回全量 Running 的完整曲线):

bash 复制代码
# output.log
===================
10 Running
===================
5 ContainerCreating
8 Running
2 Terminating
===================
5 ContainerCreating
8 Running
2 Terminating
===================
5 ContainerCreating
8 Running
===================
5 ContainerCreating
8 Running
===================
3 ContainerCreating
1 Pending
9 Running
4 Terminating
===================
5 ContainerCreating
8 Running
5 Terminating
===================
5 ContainerCreating
8 Running
5 Terminating
===================
5 ContainerCreating
8 Running
3 Terminating
===================
10 Running
4 Terminating
===================
10 Running
2 Terminating
===================
10 Running
===================
10 Running
===================
10 Running

五、DaemonSet:节点级守护进程

1. 定义

DaemonSet(简称 DS)确保全部或指定节点上各运行一个 Pod 副本。集群规模变化时,DS 自动跟随:

  • 新节点加入集群 → 在该节点上新建一个 Pod;
  • 节点从集群移除 → 该节点上的 Pod 同步回收。

一句话概括其语义:"每台机器都要有一个"。

2. 典型用例

DS 天然适合承载节点级守护进程:

类别 代表组件
集群守护进程 存储守护进程 glusterd、ceph
日志收集 fluentd、logstash
监控采集 Prometheus Node Exporter、collectd

3. 用法层次

  • 简单用法:为每种守护进程,在所有节点上各启动一个 DaemonSet;
  • 复杂用法:为同一种守护进程部署多个 DaemonSet,各自携带不同标志,并对不同硬件类型施加不同的内存与 CPU 要求(配合节点亲和性实现差异化部署)。

4. 创建与查看

bash 复制代码
root@master30:~# vim daemonset.yaml
bash 复制代码
# daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: busybox
spec:
  selector:
    matchLabels:
      app: busybox
  template:
    metadata:
      labels:
        app: busybox
    spec:
      containers:
      - name: busybox
        image: hub.laoma.cloud/library/busybox
        imagePullPolicy: IfNotPresent
        command:
        - sleep
        - "36000"

root@master30:~# kubectl apply -f daemonset.yaml

root@master30:~# kubectl get pod -o wide
NAME            READY   STATUS    RESTARTS   AGE    IP              NODE                 NOMINATED NODE   READINESS GATES
busybox-5hfv6   1/1     Running   0          102s   10.224.41.132   worker31.laoma.cloud   <none>           <none>
busybox-jdnsv   1/1     Running   0          102s   10.224.193.66   worker32.laoma.cloud   <none>           <none>

root@master30:~# kubectl get ds
NAME      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
busybox   2         2         2       2            2           <none>          118s

5. 调度:污点决定 Pod 落点

master 节点默认携带 NoSchedule 污点,因此不可调度:

bash 复制代码
# master 节点默认是不可调度节点
root@master30:~# kubectl describe node master.laoma.cloud | grep Taints
Taints:             node-role.kubernetes.io/control-plane:NoSchedule

# 移除污点,设置 master 节点可调度
root@master30:~# kubectl taint node master.laoma.cloud node-role.kubernetes.io/control-plane-

root@master30:~# kubectl get ds
NAME      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
busybox   3         3         3       3            3           <none>          7m43s

# 重新加回污点,设置 master 节点不可调度
root@master30:~# kubectl taint node master.laoma.cloud node-role.kubernetes.io/control-plane:NoSchedule

root@master30:~# kubectl get ds
NAME      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
busybox   2         2         2       2            2           <none>          8m37s

# Pod 数量为 2,但 master 节点上已有的 busybox Pod 不会自动删除,
# 也不再计入这里的统计

值得记住的细节:污点回收的是调度资格 ,不是既有负载。已容忍污点运行的 Pod 不会被驱逐,DS 的计数也只会把它排除在外。

6. 健壮性与删除

bash 复制代码
# 删除其中一个 Pod
root@master30:~# kubectl delete pod busybox-5hfv6

# 自动在原节点重建新 Pod
root@master30:~# kubectl get pod -o wide
NAME            READY   STATUS    RESTARTS   AGE    IP              NODE                 NOMINATED NODE   READINESS GATES
busybox-jdnsv   1/1     Running   0          7m6s   10.224.193.66   worker32.laoma.cloud   <none>           <none>
busybox-wlqqv   1/1     Running   0          8s     10.224.41.133   worker31.laoma.cloud   <none>           <none>

删除行为与 Deployment 一致:默认级联删除其创建的所有 Pod;使用 --cascade=orphan 可保留 Pod。

bash 复制代码
[root@master master]# kubectl delete daemonsets.apps busybox
daemonset.apps "busybox" deleted

7. K8s 集群中的 DaemonSet

Kubernetes 自身的系统组件正是由 DS 承载的------kube-proxy、calico-node 都是 DaemonSet:

bash 复制代码
root@master30:~# kubectl get daemonsets.apps --namespace kube-system
NAME          DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR         AGE
calico-node   3         3         3       3            3           kubernetes.io/os=linux   4h12m
kube-proxy    3         3         3       3            3           kubernetes.io/os=linux   4h56m

分析 calico-node 的清单(可见其通过 nodeSelector 排除 Windows 节点,并用 RollingUpdate + maxUnavailable: 1 保证网络插件逐节点安全升级):

bash 复制代码
# kubectl get ds calico-node -n kube-system -o yaml(节选)
kind: DaemonSet
apiVersion: apps/v1
metadata:
  name: calico-node
  namespace: kube-system
  labels:
    k8s-app: calico-node
spec:
  selector:
    matchLabels:
      k8s-app: calico-node
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
  template:
    metadata:
      labels:
        k8s-app: calico-node

总结

控制器的本质,是把运维经验固化为一套持续运转的自动调谐机制。ReplicaSet 用最朴素的差值比对守住副本数量,让"死一个补一个"成为集群本能;Deployment 在其之上编排多套 ReplicaSet,用 maxSurge 与 maxUnavailable 精确权衡发布速度与业务可用性,把升级风险压进可控区间;DaemonSet 则换以节点为单位,让日志、监控、网络插件天然覆盖每台机器。实践需牢记三条边界:标签与 selector 一旦重叠,裸 Pod 会被立即认领;污点回收的是调度资格,不是既有负载;--cascade=orphan 是保留现场的安全阀。

相关推荐
你看我名字1 小时前
Kubernetes HPA 自动扩缩容详解:指标、策略、资源与常见故障
云原生·容器·kubernetes
一级新生1 小时前
Dify 日常使用手册(小白版)
人工智能·docker·云原生·eureka·dify·ai工具
Z21-X2 小时前
云原生运维学习笔记:KVM实战——从环境搭建到热迁移的硬核体验
运维·笔记·学习·云原生
阿里云云原生17 小时前
Personal Agent 观察:拆解全天候运行的技术挑战
云原生·agent
SelectDB技术团队18 小时前
Snowflake 的开源替代怎么选:能力对照、三条部署路径与迁移执行
大数据·数据库·云原生·开源·snowflake·apache doris
时间售卖铺18 小时前
Nginx 反向代理
运维·nginx·云原生
Regentsoft丽晶软件18 小时前
服装B2B分销返利规则引擎:多返利池与历史订单区分的技术设计
云原生·产品运营·需求分析
阿里云云原生19 小时前
非算法工程师也能看懂,推理框架的来龙去脉
云原生
Lysander.Jovian21 小时前
Node 和 Cluster部署
kubernetes