DaemonSet 適用於需要在每個 Kubernetes 節點上執行單一 Pod 副本的場景,例如日誌收集、監控代理和網路外掛。不同於 Deployment 或 StatefulSet,DaemonSet 不需要指定副本數量,它會自動在每個新增節點上佈署 Pod,並在節點移除時移除對應的 Pod。這確保了關鍵服務在每個節點上的可用性。以 Calico 網路外掛為例,它通常以 DaemonSet 方式佈署,確保每個節點都具備網路功能。Fluentd 日誌收集器也是 DaemonSet 的典型應用,可以收集每個節點上的日誌並傳送到集中式系統。理解 DaemonSet 的運作機制對於構建和維護穩定的 Kubernetes 叢集至關重要,它能確保系統服務的可靠性和一致性,並簡化跨節點服務的佈署和管理。

DaemonSet:在節點上維護 Pod 單例

檢查 Calico DaemonSet

在 minikube 叢集中,Calico 被用作 CNI 外掛,並且是以 DaemonSet 的形式佈署的。我們可以使用以下命令檢查 Calico 相關的 Pod:

$ kubectl get po -n kube-system -o wide|grep calico
calico-kube-controllers-ddf655445-jx26x   1/1     Running   0          82m   10.244.120.65   minikube   <none>           <none>
calico-node-fkjxb                        1/1     Running   0          82m   192.168.59.126   minikube   <none>           <none>
calico-node-nrzpb                        1/1     Running   0          81m   192.168.59.128   minikube-m03   <none>           <none>
calico-node-sg66x                        1/1     Running   0          82m   192.168.59.127   minikube-m02   <none>           <none>

從輸出中可以看到,Calico Pod 分佈在不同的 minikube 節點上,每個節點都有一個 Calico Pod 在執行。

內容解密:

  • kubectl get po -n kube-system -o wide|grep calico:這個命令用於取得 kube-system 名稱空間中與 Calico 相關的 Pod 資訊。
  • -o wide:表示輸出更多的資訊,包括 Pod 的 IP 地址和節點名稱。
  • grep calico:用於過濾出包含 “calico” 的行。

建立和管理 DaemonSets

為了演示 DaemonSets 的工作原理,我們將使用 Fluentd Pod。Fluentd 是一個流行的開源日誌聚合器,可以高效地收集、過濾和轉換日誌訊息。

建立 DaemonSet

首先,我們需要建立一個名為 logging 的名稱空間:

apiVersion: v1
kind: Namespace
metadata:
  name: logging

接下來,我們建立 DaemonSet 的 YAML 清單檔案 Fluentd-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:
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v4.7
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

內容解密:

  • apiVersion: apps/v1:指定 DaemonSet 的 API 版本。
  • kind: DaemonSet:表示這是一個 DaemonSet 物件。
  • spec.selector:定義了 DaemonSet 如何識別它所擁有的 Pod。
  • spec.template:定義了用於建立 Pod 的範本。
  • spec.template.spec.containers:定義了容器相關的設定,包括映像檔、資源限制和掛載卷。
  • terminationGracePeriodSeconds: 30:表示在刪除 Pod 時,Kubernetes 將等待 30 秒以讓容器正常終止。
  • volumes:定義了 Pod 所需的卷,包括主機上的 /var/log 目錄。

DaemonSet 的 spec 部分與 Deployment 和 StatefulSet 相似,需要組態 Pod 範本並使用正確的標籤選擇器來匹配 Pod 的標籤。DaemonSet 的特殊之處在於,它不需要指定 replicas 欄位,因為它會根據叢集中的節點數量自動決定要執行的 Pod 數量。

使用 Headless Service 存取 DaemonSet 端點

為了存取 DaemonSet 端點,我們將使用 Headless Service,類別似於第 12 章中對 StatefulSet 的處理方式。大多數實際的 DaemonSet 使用案例都相當複雜,涉及將各種系統資源掛載到 Pod 中。我們的 DaemonSet 示例將盡可能簡單,以展示其原理。

建立 Headless Service

您可以參考 node-exporter.yaml 檔案,該檔案提供了另一個 DaemonSet 示例,使用 Prometheus node-exporter,並透過 Headless Service 提供服務。您需要將 Service 名稱更改為 node-exporter,並使用埠 9100,同時在請求中附加 /metrics 路徑。

DaemonSet:確保節點上的 Pod 單例持續執行

DaemonSet 是 Kubernetes 中的一種資源物件,用於確保在叢集中的每個節點(或特定節點)上執行一個 Pod 副本。這種機制非常適合需要在每個節點上執行特定服務的場景,例如日誌收集、監控代理或網路代理等。

Fluentd DaemonSet 示例

以下是一個使用 DaemonSet 佈署 Fluentd 的示例,Fluentd 是一種日誌收集和轉發工具。在這個例子中,Fluentd 被組態為收集節點上的日誌並將其傳送到 Elasticsearch。

首先,我們需要建立一個 DaemonSet YAML 清單檔案(fluentd-daemonset.yaml),其中定義了 Fluentd Pod 的規格,包括容器映像、掛載的卷以及環境變數等。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        env:
        - name: FLUENT_ELASTICSEARCH_HOST
          value: "elasticsearch-logging"
        - name: FLUENT_ELASTICSEARCH_PORT
          value: "9200"
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

內容解密:

  1. DaemonSet 定義:定義了一個名為 fluentd-elasticsearch 的 DaemonSet,位於 logging 名稱空間。
  2. 容器規格:指定了使用的容器映像為 quay.io/fluentd_elasticsearch/fluentd:v2.5.2,並掛載了主機的 /var/log 目錄到容器的 /var/log 目錄。
  3. 環境變數:設定了 FLUENT_ELASTICSEARCH_HOSTFLUENT_ELASTICSEARCH_PORT 環境變數,分別指定了 Elasticsearch 的主機名和埠。

佈署 DaemonSet

要佈署 DaemonSet,可以使用 kubectl apply 命令:

$ kubectl apply -f fluentd-daemonset.yaml
namespace/logging created
daemonset.apps/fluentd-elasticsearch created

驗證 DaemonSet

佈署完成後,可以使用 kubectl getkubectl describe 命令來驗證 DaemonSet 的狀態:

$ kubectl get pods -n logging -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
fluentd-elasticsearch-cs4hm 1/1 Running 0 3m48s 10.244.120.68 minikube <none> <none>
fluentd-elasticsearch-stfqs 1/1 Running 0 3m48s 10.244.205.194 minikube-m02 <none> <none>
fluentd-elasticsearch-zk6pt 1/1 Running 0 3m48s 10.244.151.2 minikube-m03 <none> <none>

內容解密:

  1. Pod 狀態:顯示了每個節點上執行的 Fluentd Pod 的狀態,包括名稱、就緒狀態、重啟次數、年齡、IP 地址和所屬節點等資訊。

高階組態:優先順序和更新策略

優先順序

可以透過定義 PriorityClass 物件來為 DaemonSet 中的 Pod 指定優先順序,從而確保關鍵的 Pod 不會被低優先順序的 Pod 搶佔資源。

apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: fluentd-priority
value: 100000
globalDefault: false
description: "Fluentd Daemonset priority class"

更新策略

DaemonSet 支援兩種更新策略:RollingUpdateOnDelete。預設情況下,使用 RollingUpdate 策略,可以控制更新過程中最多有多少個 Pod 不可用。

spec:
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1

內容解密:

  1. PriorityClass 定義:定義了一個名為 fluentd-priority 的優先順序類別,值為 100000,表示高優先順序。
  2. RollingUpdate 策略:指定了 DaemonSet 的更新策略為滾動更新,並且最多允許一個 Pod 不可用。

透過這些組態,可以有效地管理和更新 DaemonSet 中的 Pod,確保關鍵服務的連續性和可靠性。

DaemonSet 的佈署與管理

DaemonSet 是 Kubernetes 中的一個重要物件,用於確保每個符合特定條件的節點上執行一個 Pod 副本。本章節將探討 DaemonSet 的佈署、更新、回復和刪除等操作,並介紹其常見的使用場景。

更新 DaemonSet

與 Deployment 物件類別似,DaemonSet 的更新可以透過 kubectl rollout 命令進行控制。以下是一個示例,展示如何透過宣告式更新將 DaemonSet 中的容器映像更新到新版本:

  1. 修改 fluentd-daemonset.yaml YAML 清單檔案,使其在範本中使用 quay.io/fluentd_elasticsearch/fluentd:v4.7.5 容器映像。

    containers:
    - name: fluentd-elasticsearch
      image: quay.io/fluentd_elasticsearch/fluentd:v4.7.5
    
  2. 將修改後的清單檔案應用到叢集:

    $ kubectl apply -f fluentd-daemonset.yaml
    namespace/logging unchanged
    daemonset.apps/fluentd-elasticsearch configured
    
  3. 使用 kubectl rollout status 命令即時檢視更新進度:

    $ kubectl rollout status ds -n logging
    Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 2 out of 3 new pods have been updated...
    Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 2 out of 3 new pods have been updated...
    Waiting for daemon set "fluentd-elasticsearch" rollout to finish: 2 of 3 updated pods are available...
    daemon set "fluentd-elasticsearch" successfully rolled out
    
  4. 使用 kubectl describe 命令檢視 DaemonSet 的事件,瞭解 Pod 重建的順序:

    $ kubectl describe ds -n logging
    Name: fluentd-elasticsearch
    Selector: name=fluentd-elasticsearch
    ...<removed for brevity>...
    Events:
    Type Reason Age From Message
    







… Normal SuccessfulDelete 5m52s daemonset-controller Deleted pod: fluentd-elasticsearch-24v2z Normal SuccessfulCreate 5m51s daemonset-controller Created pod: fluentd-elasticsearch-fxffp


#### 內容解密:
此段落展示瞭如何更新 DaemonSet 的容器映像,並使用 `kubectl rollout status` 和 `kubectl describe` 命令監控更新進度和檢視相關事件。透過這些步驟,可以確保 DaemonSet 的更新過程順利完成。

### 回復 DaemonSet

DaemonSet 的回復操作可以使用 `kubectl rollout undo` 命令完成:
```bash
$ kubectl rollout undo daemonset fluentd-elasticsearch -n logging

建議在生產環境中使用宣告式組態更新 YAML 檔案並應用變更。

內容解密:

此命令用於回復 DaemonSet 到之前的版本。宣告式組態是生產環境中的推薦做法,可以確保叢集狀態的一致性和可管理性。

刪除 DaemonSet

刪除 DaemonSet 有兩種方式:

  1. 刪除 DaemonSet 及其擁有的 Pod

    $ kubectl delete ds fluentd-elasticsearch -n logging
    

    此命令會先終止相關的 Pod,然後刪除 DaemonSet。

  2. 刪除 DaemonSet 但保留其擁有的 Pod

    $ kubectl delete ds fluentd-elasticsearch -n logging --cascade=orphan
    

    使用 --cascade=orphan 選項可以刪除 DaemonSet 但保留其建立的 Pod。

內容解密:

此段落介紹了兩種刪除 DaemonSet 的方法。第一種方法會連同 Pod 一起刪除,而第二種方法則保留 Pod。根據實際需求選擇適合的方法。

DaemonSet 的常見使用場景

DaemonSet 在 Kubernetes 中有多種常見的使用場景,包括:

  • 基礎服務:例如 kube-proxy 可能會以 DaemonSet 的形式佈署,以確保每個節點上執行一個例項。
  • CNI 外掛和網路代理:例如 Calico 和 Flannel 等 CNI 外掛通常以 DaemonSet 的形式執行,以維護叢集網路。
  • 儲存守護程式:例如 Ceph 的 Object Storage Daemon (OSD) 通常以 DaemonSet 的形式佈署,以提供分散式儲存功能。
  • Ingress 控制器:在某些情況下,Ingress 控制器(如 nginx)可能會以 DaemonSet 的形式佈署,特別是在裸機伺服器上佈署 Kubernetes 叢集時。

內容解密:

此段落列舉了 DaemonSet 在 Kubernetes 中的多種常見應用場景。這些場景展示了 DaemonSet 在維護叢集基礎設施和提供關鍵服務方面的重要性。