K8S 之概念DaemonSet 對象

什麼是 DaemonSet?
    編寫 DaemonSet 規約
        必需字段
        Pod 模板
        Pod Selector
        僅在某些節點上運行 Pod
    如何調度 Daemon Pod
    與 Daemon Pod 通訊
    更新 DaemonSet
    DaemonSet 的可替代選擇
        init 腳本
        裸 Pod
        靜態 Pod
        Replication Controller

什麼是 DaemonSet?前端

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

使用 DaemonSet 的一些典型用法:數據庫

運行集羣存儲 daemon,例如在每一個節點上運行 glusterd、ceph。
在每一個節點上運行日誌收集 daemon,例如fluentd、logstash。
在每一個節點上運行監控 daemon,例如 Prometheus Node Exporter、collectd、Datadog 代理、New Relic 代理,或 Ganglia gmond。

一個簡單的用法是在全部的節點上都啓動一個 DaemonSet,將被做爲每種類型的 daemon 使用。 一個稍微複雜的用法是單獨對每種 daemon 類型使用多個 DaemonSet,但具備不一樣的標誌,和/或對不一樣硬件類型具備不一樣的內存、CPU要求。
編寫 DaemonSet 規約
必需字段api

和其它全部 Kubernetes 配置同樣,DaemonSet 須要 apiVersion、kind 和 metadata 字段。 有關配置文件的基本信息,詳見文檔 deploying applications、配置容器 和 資源管理 。服務器

DaemonSet 也須要一個 .spec 配置段。
Pod 模板網絡

.spec 惟一必需的字段是 .spec.template。app

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

除了 Pod 必需字段外,在 DaemonSet 中的 Pod 模板必須指定合理的標籤(查看 Pod Selector)。ide

在 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 不會阻止這樣作。一個場景是,可能但願在一個具備不一樣值的、用來測試用的節點上手動建立 Pod。
僅在某些節點上運行 Pod

若是指定了 .spec.template.spec.nodeSelector,DaemonSet Controller 將在可以與 Node Selector 匹配的節點上建立 Pod。 相似這種狀況,能夠指定 .spec.template.spec.affinity,而後 DaemonSet Controller 將在可以與 Node Affinity 匹配的節點上建立 Pod。 若是根本就沒有指定,則 DaemonSet Controller 將在全部節點上建立 Pod。
如何調度 Daemon Pod

正常狀況下,Pod 運行在哪一個機器上是由 Kubernetes 調度器來選擇的。然而,由 Daemon Controller 建立的 Pod 已經肯定了在哪一個機器上(Pod 建立時指定了 .spec.nodeName),所以:

DaemonSet Controller 並不關心一個節點的 unschedulable 字段。
DaemonSet Controller 能夠建立 Pod,即便調度器尚未啓動,這對集羣啓動是很是有幫助的。

Daemon Pod 關心 Taint 和 Toleration,它們會爲沒有指定 tolerationSeconds 的 node.kubernetes.io/not-ready 和 node.alpha.kubernetes.io/unreachable 的 Taint,建立具備 NoExecute 的 Toleration。這確保了當 alpha 特性的 TaintBasedEvictions 被啓用時,發生節點故障,好比網絡分區,這時它們將不會被清除掉(當 TaintBasedEvictions 特性沒有啓用,在這些場景下也不會被清除,但會由於 NodeController 的硬編碼行爲而被清除,而不會由於 Toleration 致使被清除)。
與 Daemon Pod 通訊

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

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

更新 DaemonSet

若是修改了節點標籤(Label),DaemonSet 將馬上向新匹配上的節點添加 Pod,同時刪除新近不可以匹配的節點上的 Pod。

咱們能夠修改 DaemonSet 建立的 Pod。然而,不容許對 Pod 的全部字段進行更新。當下次節點(即便具備相同的名稱)被建立時,DaemonSet Controller 還會使用最初的模板。

能夠刪除一個 DaemonSet。若是使用 kubectl 並指定 --cascade=false 選項,則 Pod 將被保留在節點上。而後能夠建立具備不一樣模板的新 DaemonSet。具備不一樣模板的新 DaemonSet 將可以經過標籤匹配並識別全部已經存在的 Pod。它不會修改或刪除它們,即便是錯誤匹配了 Pod 模板。經過刪除 Pod 或者刪除節點,能夠強制建立新的 Pod。

在 Kubernetes 1.6 或之後版本,能夠在 DaemonSet 上 執行滾動升級。

將來的 Kubernetes 版本將支持節點的可控更新。
DaemonSet 的可替代選擇
init 腳本

咱們極可能但願直接在一個節點上啓動 daemon 進程(例如,使用 init、upstartd、或 systemd)。這很是好,但基於 DaemonSet 來運行這些進程有以下一些好處:

像對待應用程序同樣,具有爲 daemon 提供監控和管理日誌的能力。
爲 daemon 和應用程序使用相同的配置語言和工具(如 Pod 模板、kubectl)。
Kubernetes 將來版本可能會支持對 DaemonSet 建立 Pod 與節點升級工做流進行集成。
在資源受限的容器中運行 daemon,可以增長 daemon 和應用容器的隔離性。然而,這也實現了在容器中運行 daemon,但卻不能在 Pod 中運行(例如,直接基於 Docker 啓動)。

裸 Pod

可能要直接建立 Pod,同時指定其運行在特定的節點上。 然而,DaemonSet 替換了因爲任何緣由被刪除或終止的 Pod,例如節點失敗、例行節點維護、內核升級。因爲這個緣由,咱們應該使用 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

相關文章
相關標籤/搜索