Kubernetes DaemonSet - 確保每個節點都運行副本
DaemonSet 確保叢集中的 全部 (或部分) 節點上,都運行一個 Pod 的副本。 當有新節點加入叢集時,DaemonSet 會自動在上面新增一個 Pod;當節點被移除時,該 Pod 也會被回收。
使用場景
DaemonSet 通常用於執行 系統級別 的背景任務:
- 日誌收集 (Logging): 在每個節點上運行 log agent,如
fluentd或filebeat,收集該節點上所有容器的 log。 - 監控 (Monitoring): 在每個節點上運行監控 agent,如
Prometheus Node Exporter,監控節點的資源使用量 (CPU/RAM/Disk)。 - 儲存 (Storage): 運行叢集儲存 daemon,如
glusterd或ceph。
定義 DaemonSet
建立 fluentd-ds.yaml:
# fluentd-ds.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system # 通常 Log Agent 會部署在系統命名空間
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch # 用來選擇要管理的 Pod,必須與 template.metadata.labels 匹配
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1 # 更新過程中,最多允許幾個 Pod 無法服務 (即一次更新幾個節點)
template:
metadata:
labels:
name: fluentd-elasticsearch # Pod 的標籤
spec:
tolerations: # 容忍度設定,讓 Pod 可以排程到 Master/Control Plane 節點
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
resources: # 設定資源限制,避免佔用過多節點資源
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
注意:DaemonSet 不需要指定 replicas,因為它的副本數取決於符合條件的節點數量。
指定節點運行
並非所有 DaemonSet 都要跑在所有節點上。你可以透過 nodeSelector 或 affinity 來限制。
使用 NodeSelector
假設你只想在標有 type=gpu 的節點上運行監控 GPU 的程式:
spec:
template:
spec:
nodeSelector:
type: gpu
Tolerations (汙點與容忍)
K8s 的 Master 節點通常會有 Taints (汙點) 防止一般 Pod 調度上去。但 DaemonSet (如網路插件 CNI、Log Agent) 通常需要跑在 Master 上以收集 Master 的監控數據。
這時可以在 DaemonSet 中設定 tolerations 來容忍 Master 的汙點。
spec:
template:
spec:
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
操作 DaemonSet
查看狀態
kubectl get ds -n kube-system
輸出範例:
- DESIRED: 應運行的 Pod 數量(通常等於節點數)。
- CURRENT: 目前運行的 Pod 數量。
- READY: 就緒的 Pod 數量。
- UP-TO-DATE: 已更新到最新版本的 Pod 數量。
滾動更新與回滾
當修改了 Image Tag 或 ConfigMap,DaemonSet 預設會自動進行 滾動更新 (RollingUpdate)。
你可以監控更新進度:
kubectl rollout status ds/fluentd-elasticsearch -n kube-system
若更新失敗,可以回滾:
kubectl rollout undo ds/fluentd-elasticsearch -n kube-system
OnDelete 策略
對於某些核心服務(如 CNI 網路插件),你可能不希望自動重啟所有節點的網路。這時可使用 OnDelete 策略:
spec:
updateStrategy:
type: OnDelete
這種模式下,更新 YAML 不會 觸發 Pod 重建。你必須 手動刪除 某個節點上的 Pod,Set Controller 才會在該節點建立新版本的 Pod。這讓管理者能完全控制更新時機。
總結
- Deployment: 部署無狀態應用,關心的是副本總數。
- StatefulSet: 部署有狀態應用,關心的是唯一標識與順序。
- DaemonSet: 部署系統級 Agent,關心的是每個節點都要有一份。