Kubernetes DaemonSet 详细总结
1. DaemonSet 概述
DaemonSet 是 Kubernetes 中确保所有(或部分)节点运行一个 Pod 副本的工作负载 API 对象。当节点加入集群时,DaemonSet 会自动在该节点上创建 Pod;当节点从集群中移除时,这些 Pod 会被垃圾回收。
主要特点:
- 每个节点运行一个 Pod 实例:确保满足条件的每个节点都有指定的 Pod 运行
- 自动扩展:随着集群节点的增减自动调整 Pod 数量
- 典型使用场景:集群存储守护进程、日志收集守护进程、节点监控守护进程
2. DaemonSet 核心概念
2.1 节点选择
- 默认在所有节点上运行(除非指定节点选择器或污点容忍)
- 可以通过
nodeSelector
选择特定节点 - 可以通过
tolerations
容忍节点的污点
2.2 Pod 模板
- 与 Deployment 和 StatefulSet 类似,使用 Pod 模板定义要运行的容器
- 不支持副本数(replicas)配置,因为由集群节点数决定
2.3 更新机制
- 支持滚动更新策略
- 可以控制更新的节奏和方式
3. DaemonSet 典型使用场景
- 集群存储守护进程:如 glusterd、ceph
- 日志收集:如 fluentd、filebeat
- 节点监控:如 Prometheus Node Exporter
- 网络插件:如 Calico、Flannel 的网络代理组件
- 安全代理:如安全扫描、入侵检测代理
4. DaemonSet 配置详解
4.1 基本配置示例
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: fluent/fluentd:v1.14-1
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
4.2 关键字段解释
- selector: 必须与 Pod 模板中的标签匹配
- template: 定义要在每个节点上运行的 Pod
- tolerations: 允许 Pod 调度到带有污点的节点上
- hostPath volumes: 通常用于访问节点上的文件系统
5. DaemonSet 操作
5.1 创建 DaemonSet
kubectl apply -f daemonset.yaml
5.2 查看 DaemonSet
kubectl get daemonset -n kube-system
kubectl describe daemonset <name> -n <namespace>
5.3 更新 DaemonSet
kubectl edit daemonset <name> -n <namespace>
# 或
kubectl apply -f updated-daemonset.yaml
5.4 删除 DaemonSet
kubectl delete daemonset <name> -n <namespace>
6. DaemonSet 调度控制
6.1 节点选择器
限制 DaemonSet 只在特定节点上运行:
spec:
template:
spec:
nodeSelector:
disktype: ssd
6.2 污点与容忍
允许在控制平面节点上运行(默认 Master 节点有 NoSchedule 污点):
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
6.3 节点亲和性
更复杂的节点选择规则:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- amd64
7. DaemonSet 更新策略
7.1 更新类型
updateStrategy:
type: RollingUpdate # 或 OnDelete
rollingUpdate:
maxUnavailable: 1 # 滚动更新期间不可用的最大 Pod 数
- RollingUpdate (默认): 自动滚动更新 Pod
- OnDelete: 只在手动删除旧 Pod 时创建新 Pod
7.2 更新过程
-
创建新版本的 DaemonSet
-
根据策略逐步替换旧 Pod
-
可以查看更新进度:
kubectl rollout status daemonset <name>
8. DaemonSet 与 Deployment 对比
特性 | DaemonSet | Deployment |
---|---|---|
Pod 分布 | 每个节点一个 Pod | 按副本数随机分布 |
扩展方式 | 随节点数自动变化 | 手动指定副本数 |
使用场景 | 节点级服务 | 应用服务 |
更新策略 | RollingUpdate 或 OnDelete | 多种策略 |
调度控制 | 节点选择器/污点容忍 | 更丰富的调度策略 |
9. 最佳实践
- 资源限制:为 DaemonSet Pod 设置合理的资源请求和限制
- 优先级:为关键守护进程设置适当的 Pod 优先级
- 只读根文件系统:增强安全性
- 使用专用服务账户:限制权限
- 监控守护进程:确保它们正常运行
- 考虑 Pod 中断预算:保证最小可用实例数
10. 常见问题与解决方案
Q1: DaemonSet Pod 卡在 Pending 状态
- 原因: 通常是由于节点选择器不匹配或资源不足
- 解决: 检查节点标签、资源配额和污点容忍配置
Q2: 如何只在特定节点上运行 DaemonSet
-
方法1: 使用 nodeSelector
nodeSelector: node-type: worker
-
方法2: 使用节点亲和性
affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: node-type operator: In values: - worker
Q3: 如何更新 DaemonSet 而不影响所有节点
-
解决方案: 使用 OnDelete 策略并逐步删除节点上的 Pod
updateStrategy: type: OnDelete
11. 高级特性解析
11.1 Init Containers (初始化容器)
作用: 在主应用容器启动前运行的专用容器,用于准备应用运行环境。
示例解析:
initContainers:
- name: init
image: busybox
command: ['sh', '-c', '...']
典型使用场景:
- 等待依赖服务就绪(如数据库启动完成)
- 下载配置文件或密钥
- 初始化数据库或执行数据迁移
- 设置文件系统权限
特点:
- 按顺序执行(可定义多个init容器)
- 必须成功完成后才会启动主容器
- 若失败会按策略重试
11.2 Pod 生命周期钩子 (Lifecycle Hooks)
作用: 在容器生命周期的关键节点注入自定义操作。
示例解析:
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello > /tmp/startup"]
preStop:
exec:
command: ["/bin/sh", "-c", "cleanup.sh"]
两种钩子类型:
postStart
- 容器启动后立即执行- 常用于:写入启动标记、注册服务、初始化配置
preStop
- 容器终止前执行- 常用于:优雅关闭应用、保存状态、注销服务
重要注意事项:
- 钩子执行不保证立即完成(特别是postStart)
- 应设计为幂等操作(可重复执行不产生副作用)
- preStop有默认30秒超时(可调整)
11.3 拓扑分布约束 (Topology Spread Constraints)
作用: 控制Pod在集群拓扑域中的分布策略,提高可用性。
示例解析:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
name: fluentd-elasticsearch
关键参数:
maxSkew
: 允许的最大分布不平衡度(示例中=1表示各zone间Pod数差≤1)topologyKey
: 节点标签键(如zone/region/hostname)whenUnsatisfiable
: 约束无法满足时的行为(禁止调度或允许调度)labelSelector
: 选择要应用此约束的Pod
典型应用场景:
- 确保应用均匀分布在多个可用区
- 避免同一应用的Pod集中在少数节点
- 实现跨机架/区域的高可用部署
评论需开启科学上网!