iT邦幫忙

2025 iThome 鐵人賽

DAY 9
0
DevOps

新創視角下的 DevOps × AI 探索系列 第 9

Day9: DaemonSet:系統級服務的部署(如 log agent)

  • 分享至 

  • xImage
  •  

前言

在前一篇我們談到 Job 與 CronJob,它們適合處理一次性的批次任務或週期性的排程工作。
而今天要介紹的 DaemonSet,則是 Kubernetes 中專門用來處理「系統級服務」的一種工作負載。

關鍵特色:
DaemonSet 會確保 每個節點(Node)上都會有一個 Pod 運行,非常適合安裝日誌收集、監控代理、網路插件這類基礎元件。

什麼是 DaemonSet?

  • Deployment 的重點:你定義多少副本數,系統會幫你分配到集群中。
  • DaemonSet 的重點:你不用指定副本數,Kubernetes 會確保「每個節點至少一份 Pod」。

常見使用場景:

  1. Log Agent(如 Fluentd、Filebeat)
  2. Monitoring Agent(如 Node Exporter、Datadog Agent)

為什麼在 Node 上部屬一個 Log Agent 就能補捉到所有 Pod 的日誌?

在 Kubernetes 中,容器的標準輸出(stdout、stderr)會被 container runtime(如 Docker、containerd) 收集並寫到檔案。

預設情況下,這些日誌檔案存在 Node 上的:

/var/lib/docker/containers/<container-id>/<container-id>-json.log

或者:

/var/log/pods/<namespace>_<pod-name>_<uid>/<container-name>/0.log

雖然 Pod 之間彼此隔離,但它們的日誌最後都會落到 Node 的某個固定目錄。
如果能在用 Log 的路徑掛載到 Log Agent 的 Volume,Log Agent 就能捕捉到 Node 上所有的日誌了。

實作範例:在每個節點部署 Fluentd 收集日誌

以下我們建立一個簡單的 Fluentd DaemonSet,將每個節點的日誌收集起來。

Step 1:建立 Namespace 與 ServiceAccount

apiVersion: v1
kind: Namespace
metadata:
  name: logging
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: fluentd
  namespace: logging

配置解釋
Namespace

  • 建立一個獨立的空間 logging,避免和其他應用的資源混在一起。
  • 例如在 kubectl 操作時,可以使用 -n 來指定存取某個 namespace 的資源。

ServiceAccount

  • 在 Kubernetes 裡,Pod 並不是匿名的,它需要一個「身份」來跟 API Server 溝通。
  • ServiceAccount 就是這個身份,它決定 Pod 可以「以誰的角色」去存取 Kubernetes 的資源。
  • 如果 Fluentd 需要存取 API Server 或讀取 ConfigMap,就會用到這個身份。
  • 預設情況下,每個 Namespace 都會有一個 default 的 ServiceAccount,如果你不指定,Pod 就會使用這個。

Step 2:建立 DaemonSet

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  namespace: logging
spec:
  selector:
    matchLabels:
      app: fluentd
  template:
    metadata:
      labels:
        app: fluentd
    spec:
      serviceAccountName: fluentd
      containers:
      - name: fluentd
        image: fluent/fluentd:v1.16
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

Step 3:驗證

  1. 建立 DaemonSet
kubectl apply -f fluentd-daemonset.yaml
  1. 確認 DaemonSet 狀態
kubectl get ds -n logging
  1. 查看是否每個 Node 都有一個 Pod
kubectl get pod -n logging -o wide

好的,我幫你把這兩段補充得更完整一點,讀起來會更有深度,也能讓讀者感覺這篇文章是 實務導向 + 知識完整。

進階應用

NodeSelector / Node Affinity

預設情況下,DaemonSet 會在所有節點上都建立 Pod。但實務上,我們可能只需要在某些節點上運行(例如專門收集 GPU 節點的日誌,或只監控邊緣節點)。

  • NodeSelector:最簡單的方式,在 Pod 定義裡加入 nodeSelector,限制 Pod 只會跑在打了特定 label 的節點。
  • Node Affinity:更進階的語法,可以使用 requiredDuringSchedulingIgnoredDuringExecution(硬性規則)或 preferredDuringSchedulingIgnoredDuringExecutio(偏好規則),靈活地控制 Pod 的落點。

總結

透過 Fluentd DaemonSet 的範例,我們實際體驗了如何在每個節點部署日誌收集代理,並逐一解析了配置中的 NamespaceServiceAccountselector.matchLabelsvolumes 等細節,幫助更清楚理解為什麼要這樣寫。

下一篇預告
在 Day10,我們將探討 StatefulSet。不同於 DaemonSet 或 Deployment,StatefulSet 專門解決「有狀態應用」的問題,例如資料庫、Zookeeper、Kafka。這些服務需要固定的身份與穩定的儲存,而 StatefulSet 正是 Kubernetes 的解法。


上一篇
Day8: Job 與 CronJob:批次任務與排程任務
下一篇
Day10: StatefulSet:有狀態服務與 Headless Service
系列文
新創視角下的 DevOps × AI 探索11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言