iT邦幫忙

2026 iThome 鐵人賽

DAY 9
0
Kubernetes

Kubernetes學習心得分享系列 第 9

Day 09:【系統】 常駐服務與靜態 Pod 部署 (DaemonSet & Static Pods)

  • 分享至 

  • xImage
  •  

前言

寫這篇想要分享的重點:
在 Kubernetes 叢集中,除了由 Control Plane 統一調度的無狀態與有狀態應用外,還有一類特殊需求:例如日誌收集器、節點監控 Agent 或 CNI 網路插件,需要在「每一個 Node」上都常駐運行。本篇將說明 DaemonSet 與 Static Pods 的設計理念、原理與應用場景。

這篇想要講什麼:

  1. DaemonSet 概念:確保全叢集(或指定節點)皆運行一份 Pod copy、遵從一套YAML 定義與版本。
  2. Static Pods 運作原理:無須通過 API Server 與 Scheduler,由 Kubelet 直接監控本機目錄管理的靜態 Pod,以及 Mirror Pod 的機制。
  3. 對比與總結:DaemonSet 與 Static Pods 在架構上的差異。

為何要寫這篇:
瞭解這兩種特殊部署方式,有助我們清楚「K8s 控制面組件(如 kube-apiserver, etcd)是如何自我啟動(Bootstrapping)的」,以及叢集該如何維護除錯。

名詞對應

  • Static Pod: 靜態 Pod
  • Control Plane: 控制面
  • Scheduler: 調度器
  • Bootstrapping: 自我啟動
  • Mirror Pod: 映象 Pod

DaemonSet 全節點常駐服務

由 K8s 的 DaemonSet Controller 管理,確保 Cluster 中每一個(或符合特定條件的)Node 上,都剛好運行一個 Pod copy。每當有新 Node 加入 Cluster 時,Pod 會自動在該 Node 上被建立;當 Node 被移除時,該 Pod 也會自動被垃圾回收(Garbage Collected)。

  • 常見應用場景
    • 網路外掛(CNI):如 CalicoWeave NetFlannel(需在每台 Node 上處理網路封包轉發與跨節點 Tunnel)。
    • 網路代理(Network Proxy):如 kube-proxy,在每個 Node 上維護網路規則。
    • 日誌收集 Agent:如 FluentdLogstash
    • 節點監控 Agent:如 Prometheus Node Exporter、自訂的 Monitoring Agent。

DaemonSet 運作機制與演進

在 Kubernetes 早期的版本(v1.12 以前),DaemonSet 是由 DaemonSet Controller 直接將 Pod 的 spec.nodeName 欄位填上特定 Node 名稱來指定節點;從 v1.12 版本開始,DaemonSet 正式全面改由預設調度器(Default Scheduler)配合 NodeAffinity 來實現

即便 Node 被加上 NoSchedule 污點(例如 Control Plane 節點),只要 DaemonSet Pod 帶有對應的 Toleration(容忍度),就能順利部署到控制面節點上。

DaemonSet 定義與常用檢視指令

DaemonSet 的 YAML 寫法與 ReplicaSet 極為相似,主要差異在於 kind 指定為 DaemonSet,且不需要聲明 replicas(因為數量由 Node 的數量決定)。

💡 後面會說明ReplicaSet

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: node-exporter
  template:
    metadata:
      labels:
        app: node-exporter
    spec:
      tolerations:
      - operator: Exists # 容忍所有污點,確保控制面與工作節點都能部署
      containers:
      - name: node-exporter
        image: prom/node-exporter:v1.3.1
        ports:
        - containerPort: 9100
          hostPort: 9100 # 綁定 Node 主機連接埠

  • 常用管理指令

查詢 DaemonSet:

kubectl get daemonsets -n kube-system

查看詳細狀態(包含 desired、current、ready 數量與 Pod Template):

kubectl describe daemonsets node-exporter -n kube-system


Static Pods 由 Kubelet 直接管理的 Pods

通常 Pod 的建立流程都需要經過 API Server -> etcd -> Scheduler -> Kubelet 的完整控制流程。但有一個典型的「雞生蛋、蛋生雞」難題:當控制面(Control Plane)本身還沒建立起來、API Server 與 etcd 都尚未存在時,我們要如何把控制面的組件當作容器跑起來?

答案就是 Static Pods(靜態 Pod)

Static Pod 的特點與配置方法

  1. 完全由 Kubelet 獨立管理 (記得我們的廠長!):Kubelet 啟動時會讀取本機配置。只要將定義檔(YAML)放入特定目錄,Kubelet 就會透過 Container Runtime(如 containerdCRI-O)直接啟動並維護該 Pod。
  2. 自動同步與自我修復:Kubelet 會定期掃描該目錄。若目錄下新增或更新了 YAML 檔,Kubelet 會自動建立或更新 Pod;若將 YAML 檔案刪除,Kubelet 會自動停止並移除該 Pod。
  3. 完全無視 Scheduler:繞過Control Plane與調度器,即使 API Server 停擺,只要 Kubelet 正常運作,靜態 Pod 就會持續運行。
  4. 刪除與修改限制:無法透過 kubectl delete pod 刪除(即使強行刪除,Kubelet 發現本機 YAML 依然存在,就會立即重建 Pod)。唯一修改或刪除的方式是直接登入該 Node,修改或移除目錄中的 YAML 檔案

如何指定 Static Pods 目錄?

Kubelet 提供了兩種方式來設定Static Pod 的 Manifest 檔案目錄路徑:

  1. 透過 Kubelet 啟動參數
    kubelet.service 的啟動命令中加入 --pod-manifest-path=/etc/kubernetes/manifests
  2. 透過 Kubelet 設定檔
    kubeconfig.yamlconfig.yaml 中設定 staticPodPath: /etc/kubernetes/manifests

當 Control Plane 出現故障時,無法使用 kubectl 查詢 Pod 狀態,此時可以透過 Container Runtime 工具(如 crictl psnerdctl psdocker ps)在 Node 主機上記錄與除錯。

映象 Pod (Mirror Pod) 機制

雖然 Static Pods 繞過了 API Server,但為了讓管理者依然能透過 kubectl get pods 看到這些控制面 Pod,Kubelet 會在與 API Server 連線建立後,主動在 API Server 上建立一個唯讀的 Mirror Pod

  • Mirror Pod 的名稱通常會在最後加上 Node 的主機名稱(例如 kube-apiserver-node01)。
  • 在 API Server 端看見的 Mirror Pod 僅供唯讀狀態展示,無法透過 kubectl 進行編輯或刪除

kubeadm 叢集自我啟動(Bootstrapping)範例

使用 kubeadm 初始化 K8s 叢集時,kube-apiserverkube-controller-managerkube-scheduleretcd 就是以 Static Pods 的形式部署在 Control Plane 節點上:

# 登入 Control Plane 節點查看靜態 Pod 配置目錄
ls -la /etc/kubernetes/manifests/

# 輸出結果:
# etcd.yaml
# kube-apiserver.yaml
# kube-controller-manager.yaml
# kube-scheduler.yaml

只要執行 kubectl get pods -n kube-system,就能看到這些由 Kubelet 建立 Mirror Pod 並註冊到控制面的組件。


比較:Static Pods vs. DaemonSet

項目 Static Pods DaemonSet
由誰控管 該節點上的 kubelet Control Plane 的 DaemonSet Controller
建立機制 掃描 Node 本機 /etc/kubernetes/manifests/ 目錄直接建立 透過 API Server 配合 Default Scheduler 與 NodeAffinity/Tolerations
主要用途 部署 Control Plane 核心組件(etcd, apiserver 等) 部署全叢集基礎設施 Agent(CNI, kube-proxy, 日誌, 監控)
刪除/修改方式 直接修改/移除 Node 本機的 YAML 檔案 透過 API Server 指令(kubectl delete/edit ds
檢視工具 Node 端使用 crictl ps,Cluster 端看 Mirror Pod 直接使用 kubectl 進行叢集級別管理

總結

  • 本篇總結:
    DaemonSet 適合部署基礎設施 Agent(由 API Server 與 Controller 統一管理);而 Static Pods 則繞過控制面,由本機 Kubelet 直接監視目錄運行,常用於部署 K8s 控制面自身的基礎組件。
  • 下一篇預告:
    掌握了各式 Pod 的部署型態後,明天 Day 10 我們將學習 應用程式升級策略與無縫回滾——實作 Deployment 的 RollingUpdateRecreate 機制,並示範如何用 kubectl rollout undo 在幾秒內快速復原失敗的版次!敬請期待!

Takeaway

  • DaemonSet 全節點部署:確保叢集中每個(或指定條件的)Worker Node 上都剛好運行一個 Pod copy,常用於 kube-proxy、CNI 網路元件、日誌收集與節點監控。
  • DaemonSet 派發機制演進:自 v1.12 起,DaemonSet 正式採用 Default Scheduler 結合 NodeAffinity 進行 Pod 的統一調度。
  • Static Pods 去中心化管理:不透過 API Server 或 Scheduler,由當地的 Kubelet 掃描 /etc/kubernetes/manifests/ 目錄下的 YAML 檔直接啟動與維護。
  • Static Pods 的修改與刪除:無法透過 kubectl delete pod 刪除,只能直接移除或修改 Node 當地目錄內的 YAML 檔案;在 API Server 看到的僅為唯讀的 Mirror Pod。
  • K8s 自我啟動(Bootstrapping)原理kubeadm 建立叢集時,kube-apiserveretcd 等控制面關鍵組件就是以 Static Pods 的形式運行。

上一篇
Day 08:【資源】 容器資源限制與配額管理 (Limits & Quotas)
下一篇
Day 10:【系統】 應用程式升級策略與無縫回滾 (Deployment Rolling Update & Rollback)
系列文
Kubernetes學習心得分享12
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言