Kubernetes DaemonSet 控制器详解
它确保集群中所有(或部分)节点上都运行一个 Pod 的副本。当有新节点加入集群时,DaemonSet 会自动在新节点上创建 Pod;当节点从集群中移除时,这些 Pod 也会被垃圾回收。
DaemonSet 的核心特性
- 每个节点一个 Pod:确保满足条件的每个节点上都运行一个 Pod 实例
- 自动扩展:随着集群节点的增减自动调整 Pod 数量
- 特定节点运行:可以通过节点选择器(nodeSelector)或节点亲和性(nodeAffinity)在特定节点上运行
DaemonSet 的典型使用场景
- 集群存储守护进程:如 glusterd、ceph
- 日志收集:如 fluentd、logstash
- 监控采集:如 Prometheus Node Exporter、collectd
- 网络插件:如 Calico、Weave 网络组件
- 安全控制:如安全审计、入侵检测代理
DaemonSet 的工作机制
- 控制器模式:DaemonSet 控制器通过监听 API 服务器获取节点和 Pod 的变化
- 节点匹配:根据
.spec.template
和节点选择条件确定应该在哪些节点上运行 Pod - Pod 管理:
- 创建缺失的 Pod
- 删除多余的 Pod
- 更新需要变更的 Pod
DaemonSet 的 YAML 示例
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: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
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
DaemonSet 的关键配置
1. 节点选择
nodeSelector:简单选择器,匹配节点标签
spec: template: spec: nodeSelector: disktype: ssd
nodeAffinity:更复杂的节点亲和性规则
spec: template: spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/os operator: In values: - linux
2. 容忍度(Tolerations)
允许 Pod 调度到带有污点的节点上:
spec:
template:
spec:
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
3. 更新策略
- RollingUpdate(默认):滚动更新 DaemonSet Pod
- OnDelete:手动删除旧 Pod 时才创建新 Pod
配置示例:
spec:
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
DaemonSet 与 Deployment 的区别
特性 | DaemonSet | Deployment |
---|---|---|
调度目标 | 每个匹配节点一个 Pod | 指定数量的 Pod,不考虑节点 |
扩展性 | 随节点数量自动扩展 | 手动指定副本数 |
使用场景 | 节点级服务(监控、日志等) | 应用服务 |
更新策略 | RollingUpdate 或 OnDelete | RollingUpdate 或 Recreate |
节点亲和性 | 通常需要 | 通常不需要 |
DaemonSet 的管理操作
创建 DaemonSet
kubectl apply -f daemonset.yaml
查看 DaemonSet 状态
kubectl get daemonset -n kube-system
kubectl describe daemonset fluentd-elasticsearch -n kube-system
更新 DaemonSet
修改 YAML 文件后重新应用
kubectl apply -f daemonset-updated.yaml
直接编辑
kubectl edit daemonset fluentd-elasticsearch -n kube-system
删除 DaemonSet
kubectl delete daemonset fluentd-elasticsearch -n kube-system
高级主题
1. 仅在某些节点上运行
通过节点标签和选择器控制:
# 给节点打标签
kubectl label nodes <node-name> <label-key>=<label-value>
# 然后在 DaemonSet 中配置 nodeSelector
2. 使用 initContainers
可以在主容器前运行初始化容器:
spec:
template:
spec:
initContainers:
- name: init-sysctl
image: busybox
command: ["sysctl", "-w", "vm.max_map_count=262144"]
securityContext:
privileged: true
3. 资源限制
为 DaemonSet Pod 设置资源请求和限制:
resources:
limits:
cpu: "1"
memory: 500Mi
requests:
cpu: "0.5"
memory: 250Mi
常见问题解决
Pod 无法调度:
- 检查节点选择器和污点/容忍度配置
- 检查节点资源是否充足
更新失败:
- 检查更新策略配置
- 检查新镜像是否可用
权限问题:
- 可能需要配置 SecurityContext 或 PodSecurityPolicy
案列:部署守护进程DaenonSet
ds,yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: ds-test
labels:
app: filebeat
spec:
selector:
matchLabels:
app: filebeat
template:
metadata:
labels:
app: filebeat
spec:
containers:
- name: logs
image: nginx:1.27.5
ports:
- containerPort: 80
volumeMounts:
- name: varlog
mountPath: /tmp/log
volumes:
- name: varlog
hostPath:
path: /var/log
- 在每个node上运行一个pod,新加入的node也同
样运行在一个pod里面 - 在每个node节点安装数据采集工具