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-elasticsearchnamespace: kube-systemlabels:k8s-app: fluentd-logging
spec:selector:matchLabels:name: fluentd-elasticsearchtemplate:metadata:labels:name: fluentd-elasticsearchspec:tolerations:- key: node-role.kubernetes.io/mastereffect: NoSchedulecontainers:- name: fluentd-elasticsearchimage: quay.io/fluentd_elasticsearch/fluentd:v2.5.2resources:limits:memory: 200Mirequests:cpu: 100mmemory: 200MivolumeMounts:- name: varlogmountPath: /var/log- name: varlibdockercontainersmountPath: /var/lib/docker/containersreadOnly: trueterminationGracePeriodSeconds: 30volumes:- name: varloghostPath:path: /var/log- name: varlibdockercontainershostPath: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/osoperator: Invalues:- linux
2. 容忍度(Tolerations)
允許 Pod 調度到帶有污點的節點上:
spec:template:spec:tolerations:- key: node-role.kubernetes.io/mastereffect: NoSchedule
3. 更新策略
- RollingUpdate(默認):滾動更新 DaemonSet Pod
- OnDelete:手動刪除舊 Pod 時才創建新 Pod
配置示例:
spec:updateStrategy:type: RollingUpdaterollingUpdate: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-sysctlimage: busyboxcommand: ["sysctl", "-w", "vm.max_map_count=262144"]securityContext:privileged: true
3. 資源限制
為 DaemonSet Pod 設置資源請求和限制:
resources:limits:cpu: "1"memory: 500Mirequests: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: filebeattemplate:metadata:labels:app: filebeatspec:containers:- name: logsimage: nginx:1.27.5ports:- containerPort: 80volumeMounts:- name: varlogmountPath: /tmp/logvolumes:- name: varloghostPath:path: /var/log
- 在每個node上運行一個pod,新加入的node也同
樣運行在一個pod里面 - 在每個node節點安裝數據采集工具