Kubernetes DaemonSet 與節點管理

Kubernetes DaemonSet and Node Management

DaemonSet 概述

DaemonSet 是 Kubernetes 中的一種控制器,它確保在叢集中的每個節點(或符合條件的節點)上都運行一個 Pod 副本。當有新節點加入叢集時,DaemonSet 會自動在該節點上建立 Pod;當節點被移除時,對應的 Pod 也會被回收。

DaemonSet 的核心特性:

  • 每節點一個 Pod:保證每個節點上只運行一個 Pod 實例
  • 自動調度:新節點加入時自動部署,節點移除時自動清理
  • 節點親和性:可透過選擇器限制在特定節點上運行

使用場景

DaemonSet 適用於需要在每個節點上運行的工作負載:

  1. 日誌收集:如 Fluentd、Filebeat,收集每個節點上的容器日誌
  2. 監控代理:如 Node Exporter、Datadog Agent,收集節點級別的指標
  3. 網路插件:如 Calico、Cilium,提供叢集網路功能
  4. 儲存守護程式:如 GlusterFS、Ceph,提供分散式儲存
  5. 安全掃描:如 Falco,進行運行時安全監控

基本 DaemonSet YAML

以下是一個基本的 DaemonSet 配置範例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: my-daemonset
  namespace: default
  labels:
    app: my-daemon
spec:
  selector:
    matchLabels:
      app: my-daemon
  template:
    metadata:
      labels:
        app: my-daemon
    spec:
      containers:
      - name: daemon-container
        image: nginx:1.21
        resources:
          limits:
            memory: "128Mi"
            cpu: "100m"
          requests:
            memory: "64Mi"
            cpu: "50m"
        ports:
        - containerPort: 80
          name: http

Node Selector 限制節點

使用 nodeSelector 可以限制 DaemonSet 只在特定標籤的節點上運行:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: ssd-monitor
spec:
  selector:
    matchLabels:
      app: ssd-monitor
  template:
    metadata:
      labels:
        app: ssd-monitor
    spec:
      nodeSelector:
        disk-type: ssd
      containers:
      - name: ssd-monitor
        image: monitoring/ssd-monitor:v1

若需要更靈活的節點選擇,可使用 nodeAffinity

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
spec:
  template:
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: node-role.kubernetes.io/worker
                operator: Exists

Tolerations 容忍污點

預設情況下,DaemonSet 不會在帶有污點(Taint)的節點上運行。透過設定 Tolerations,可以讓 Pod 容忍特定污點:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-agent
spec:
  selector:
    matchLabels:
      app: node-agent
  template:
    metadata:
      labels:
        app: node-agent
    spec:
      tolerations:
      # 容忍 master 節點的污點
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      # 容忍 control-plane 節點的污點
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      # 容忍所有污點(謹慎使用)
      - operator: Exists
      containers:
      - name: node-agent
        image: agent/node-agent:v2

更新策略

DaemonSet 支援兩種更新策略:

RollingUpdate(預設)

逐一更新節點上的 Pod,可控制更新速度:

1
2
3
4
5
spec:
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1

OnDelete

只有在手動刪除 Pod 後才會建立新版本的 Pod:

1
2
3
spec:
  updateStrategy:
    type: OnDelete

常見 DaemonSet 範例

Fluentd 日誌收集器

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  namespace: kube-system
  labels:
    app: fluentd
spec:
  selector:
    matchLabels:
      app: fluentd
  template:
    metadata:
      labels:
        app: fluentd
    spec:
      tolerations:
      - key: node-role.kubernetes.io/control-plane
        effect: NoSchedule
      containers:
      - name: fluentd
        image: fluent/fluentd-kubernetes-daemonset:v1.16
        env:
        - name: FLUENT_ELASTICSEARCH_HOST
          value: "elasticsearch.logging.svc"
        - name: FLUENT_ELASTICSEARCH_PORT
          value: "9200"
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: containers
          mountPath: /var/lib/docker/containers
          readOnly: true
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: containers
        hostPath:
          path: /var/lib/docker/containers

Node Exporter 監控

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: monitoring
  labels:
    app: node-exporter
spec:
  selector:
    matchLabels:
      app: node-exporter
  template:
    metadata:
      labels:
        app: node-exporter
    spec:
      hostNetwork: true
      hostPID: true
      tolerations:
      - operator: Exists
      containers:
      - name: node-exporter
        image: prom/node-exporter:v1.6.1
        args:
        - --path.procfs=/host/proc
        - --path.sysfs=/host/sys
        - --path.rootfs=/host/root
        ports:
        - containerPort: 9100
          hostPort: 9100
        resources:
          limits:
            cpu: 100m
            memory: 100Mi
          requests:
            cpu: 50m
            memory: 50Mi
        volumeMounts:
        - name: proc
          mountPath: /host/proc
          readOnly: true
        - name: sys
          mountPath: /host/sys
          readOnly: true
        - name: root
          mountPath: /host/root
          readOnly: true
      volumes:
      - name: proc
        hostPath:
          path: /proc
      - name: sys
        hostPath:
          path: /sys
      - name: root
        hostPath:
          path: /

與 Deployment 比較

特性DaemonSetDeployment
Pod 數量每節點一個指定副本數
調度方式節點導向資源導向
擴展方式隨節點增減手動或自動擴展
主要用途節點級服務應用程式部署
高可用性節點級別副本級別

監控 DaemonSet

使用 kubectl 監控 DaemonSet 狀態:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 查看 DaemonSet 狀態
kubectl get daemonset -n kube-system

# 查看詳細資訊
kubectl describe daemonset <daemonset-name>

# 查看 DaemonSet 的 Pod 分佈
kubectl get pods -l app=<label> -o wide

# 查看滾動更新狀態
kubectl rollout status daemonset/<daemonset-name>

# 查看更新歷史
kubectl rollout history daemonset/<daemonset-name>

重要的監控指標包括:

  • desiredNumberScheduled:期望運行的 Pod 數量
  • currentNumberScheduled:目前已調度的 Pod 數量
  • numberReady:就緒狀態的 Pod 數量
  • numberAvailable:可用的 Pod 數量

參考資料

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy