kubernetes daemonset


DaemonSet

什么是 DaemonSet?

DaemonSet 確保全部(或者一些)Node 上運行一個 Pod 的副本。當有 Node 加入集群時,也會為他們新增一個 Pod 。當有 Node 從集群移除時,這些 Pod 也會被回收。刪除 DaemonSet 將會刪除它創建的所有 Pod。

使用 DaemonSet 的一些典型用法:

  • 運行集群存儲 daemon,例如在每個 Node 上運行 glusterdceph
  • 在每個 Node 上運行日志收集 daemon,例如fluentdlogstash
  • 在每個 Node 上運行監控 daemon,例如 Prometheus Node Exportercollectd、Datadog 代理、New Relic 代理,或 Ganglia gmond

一個簡單的用法是,在所有的 Node 上都存在一個 DaemonSet,將被作為每種類型的 daemon 使用。 一個稍微復雜的用法可能是,對單獨的每種類型的 daemon 使用多個 DaemonSet,但具有不同的標志,和/或對不同硬件類型具有不同的內存、CPU要求。

編寫 DaemonSet Spec

必需字段

和其它所有 Kubernetes 配置一樣,DaemonSet 需要 apiVersionkind 和 metadata字段。有關配置文件的通用信息,詳見文檔 部署應用配置容器 和資源管理。

DaemonSet 也需要一個 .spec配置段。

Pod 模板

.spec 唯一必需的字段是 .spec.template

.spec.template 是一個 Pod 模板。 它與 Pod 具有相同的 schema,除了它是嵌套的,而且不具有 apiVersion 或 kind 字段。

Pod 除了必須字段外,在 DaemonSet 中的 Pod 模板必須指定合理的標簽(查看 pod selector)。

在 DaemonSet 中的 Pod 模板必需具有一個值為 Always 的 RestartPolicy,或者未指定它的值,默認是 Always

Pod Selector

.spec.selector 字段表示 Pod Selector,它與 Job 或其它資源的 .spec.selector 的原理是相同的。

spec.selector 表示一個對象,它由如下兩個字段組成:

  • matchLabels - 與 ReplicationController 的 .spec.selector 的原理相同。
  • matchExpressions - 允許構建更加復雜的 Selector,可以通過指定 key、value 列表,以及與 key 和 value 列表的相關的操作符。

當上述兩個字段都指定時,結果表示的是 AND 關系。

如果指定了 .spec.selector,必須與 .spec.template.metadata.labels 相匹配。如果沒有指定,它們默認是等價的。如果與它們配置的不匹配,則會被 API 拒絕。

如果 Pod 的 label 與 selector 匹配,或者直接基於其它的 DaemonSet、或者 Controller(例如 ReplicationController),也不可以創建任何 Pod。 否則 DaemonSet Controller 將認為那些 Pod 是它創建的。Kubernetes 不會阻止這樣做。一個場景是,可能希望在一個具有不同值的、用來測試用的 Node 上手動創建 Pod。

僅在相同的 Node 上運行 Pod

如果指定了 .spec.template.spec.nodeSelector,DaemonSet Controller 將在能夠匹配上 Node Selector 的 Node 上創建 Pod。 類似這種情況,可以指定 .spec.template.spec.affinity,然后 DaemonSet Controller 將在能夠匹配上 Node Affinity 的 Node 上創建 Pod。 如果根本就沒有指定,則 DaemonSet Controller 將在所有 Node 上創建 Pod。

如何調度 Daemon Pod

正常情況下,Pod 運行在哪個機器上是由 Kubernetes 調度器進行選擇的。然而,由 Daemon Controller 創建的 Pod 已經確定了在哪個機器上(Pod 創建時指定了 .spec.nodeName),因此:

  • DaemonSet Controller 並不關心一個 Node 的 unschedulable 字段。
  • DaemonSet Controller 可以創建 Pod,即使調度器還沒有被啟動,這對集群啟動是非常有幫助的。

Daemon Pod 關心 Taint 和 Toleration,它們會為沒有指定 tolerationSeconds 的 node.alpha.kubernetes.io/notReady 和 node.alpha.kubernetes.io/unreachable 的 Taint,而創建具有 NoExecute 的 Toleration。這確保了當 alpha 特性的 TaintBasedEvictions 被啟用,當 Node 出現故障,比如網絡分區,這時它們將不會被清除掉(當 TaintBasedEvictions 特性沒有啟用,在這些場景下也不會被清除,但會因為 NodeController 的硬編碼行為而被清除,Toleration 是不會的)。

與 Daemon Pod 通信

與 DaemonSet 中的 Pod 進行通信,幾種可能的模式如下:

  • Push:配置 DaemonSet 中的 Pod 向其它 Service 發送更新,例如統計數據庫。它們沒有客戶端。
  • NodeIP 和已知端口:DaemonSet 中的 Pod 可以使用 hostPort,從而可以通過 Node IP 訪問到 Pod。客戶端能通過某種方法知道 Node IP 列表,並且基於此也可以知道端口。
  • DNS:創建具有相同 Pod Selector 的 Headless Service,然后通過使用 endpoints 資源或從 DNS 檢索到多個 A 記錄來發現 DaemonSet。
  • Service:創建具有相同 Pod Selector 的 Service,並使用該 Service 訪問到某個隨機 Node 上的 daemon。(沒有辦法訪問到特定 Node)

更新 DaemonSet

如果修改了 Node Label,DaemonSet 將立刻向新匹配上的 Node 添加 Pod,同時刪除新近無法匹配上的 Node 上的 Pod。

可以修改 DaemonSet 創建的 Pod。然而,不允許對 Pod 的所有字段進行更新。當下次 Node(即使具有相同的名稱)被創建時,DaemonSet Controller 還會使用最初的模板。

可以刪除一個 DaemonSet。如果使用 kubectl 並指定 --cascade=false 選項,則 Pod 將被保留在 Node 上。然后可以創建具有不同模板的新 DaemonSet。具有不同模板的新 DaemonSet 將鞥能夠通過 Label 匹配識別所有已經存在的 Pod。它不會修改或刪除它們,即使是錯誤匹配了 Pod 模板。通過刪除 Pod 或者 刪除 Node,可以強制創建新的 Pod。

在 Kubernetes 1.6 或以后版本,可以在 DaemonSet 上 執行滾動升級

init 腳本

很可能通過直接在一個 Node 上啟動 daemon 進程(例如,使用 initupstartd、或 systemd)。這非常好,然而基於 DaemonSet 來運行這些進程有如下一些好處:

  • 像對待應用程序一樣,具備為 daemon 提供監控和管理日志的能力。
  • 為 daemon 和應用程序使用相同的配置語言和工具(如 Pod 模板、kubectl)。
  • Kubernetes 未來版本可能會支持對 DaemonSet 創建 Pod 與 Node升級工作流進行集成。
  • 在資源受限的容器中運行 daemon,能夠增加 daemon 和應用容器的隔離性。然而這也實現了在容器中運行 daemon,但卻不能在 Pod 中運行(例如,直接基於 Docker 啟動)。

裸 Pod

可能要直接創建 Pod,同時指定其運行在特定的 Node 上。 然而,DaemonSet 替換了由於任何原因被刪除或終止的 Pod,例如 Node 失敗、例行節點維護,比如內核升級。由於這個原因,我們應該使用 DaemonSet 而不是單獨創建 Pod。

靜態 Pod

很可能,通過在一個指定目錄下編寫文件來創建 Pod,該目錄受 Kubelet 所監視。這些 Pod 被稱為 靜態 Pod。 不像 DaemonSet,靜態 Pod 不受 kubectl 和 其它 Kubernetes API 客戶端管理。靜態 Pod 不依賴於 apiserver,這使得它們在集群啟動的情況下非常有用。 而且,未來靜態 Pod 可能會被廢棄掉。

Replication Controller

DaemonSet 與 Replication Controller 非常類似,它們都能創建 Pod,這些 Pod 都具有不期望被終止的進程(例如,Web 服務器、存儲服務器)。 為無狀態的 Service 使用 Replication Controller,像 frontend,實現對副本的數量進行擴縮容、平滑升級,比之於精確控制 Pod 運行在某個主機上要重要得多。需要 Pod 副本總是運行在全部或特定主機上,並需要先於其他 Pod 啟動,當這被認為非常重要時,應該使用 Daemon Controller。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM