網站首頁 編程語言 正文
DaemonSet 簡介
DaemonSet 的主要作用,是在 Kubernetes 集群里,運行一個 Daemon Pod。 DaemonSet 只管理 Pod 對象,然后通過 nodeAffinity 和 Toleration 這兩個調度器參數的功能,保證了每個節點上有且只有一個 Pod。
DaemonSet 是一種面向特定應用場景的 Pod 控制器,盡管它也可以管理 Pod 的多個副本,但它主要用于保證一個 Node 上只運行一個 Pod 的場景:
DaemonSet 使用場景
每個節點上只有一個這樣的 Daemon Pod 實例,然后當有新的節點加入 Kubernetes 集群后,該 Pod 會自動地在新節點上被創建出來。當舊節點被刪除后,它上面的 Pod 也會相應地被回收掉。
Daemon Pod 的意義確實是非常重要的。比如的作用:
- 網絡插件的 Agent 組件,都必須運行在每一個節點上,用來處理這個節點上的容器網絡。
- 存儲插件的 Agent 組件,也必須運行在每一個節點上,用來在這個節點上掛載遠程存儲目錄,操作容器的 Volume 目錄,比如:glusterd、ceph。
- 監控組件和日志組件,也必須運行在每一個節點上,負責這個節點上的監控信息和日志搜集,比如:fluentd、logstash、Prometheus 等。
DaemonSet 創建
k8s 環境搭建參考網上教程,這里就不再贅述了。
先來個簡單的例子快速體驗 DaemonSet 控制器是如何應用的。
一個簡單的 DaemonSet 配置如下:
apiVersion: apps/v1 kind: DaemonSet metadata: name: nginx-daemonset labels: app: nginx spec: selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.17.0
初步看,這份配置跟 Deployment 基本類似,唯一一個顯著的差異是 DaemonSet 不需要指定副本數,因為它的副本數取決于工作節點數。
DaemonSet 配置中 spec.selector 和 spec.template 作用我們已在介紹 Deployment 時介紹過,在此不再贅述。
該份配置將創建一個 DaemonSet 對象,然后 DaemonSet 控制器會根據該對象信息分別在每個節點上創建一個 Pod 副本。
接下來使用kubectl create
命令將該配置提次給 kube-apiserver,如下所示:
[root@k8s-master]# kubectl create -f daemonset.yaml daemonset.apps/nginx-daemonset created
查看 DaemonSet
首先查看剛剛創建的 DaemonSet 對象:
[root@k8s-master]# kubectl get daemonset NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE nginx-daemonset 3 3 3 3 3 <none> 1m3s
命令行輸出中各字段含義如下:
- NAME: DaemonSet 對象名稱,同配置中的 metadata.name;
- DESIRED:需求副本個數,由于沒有刻意篩選節點,所以副本個數等同于節點個數(默認);
- CURRENT:當前已創建的副本個數;
- READY:處于 Ready 狀態的副本個數;
- UP-TO-DATE:已按最新 Pod 模版創建的 Pod 個數;
- AVAILABLE:可用的副本個數;
- NODE SELECTOR:節點選擇器,本例中我們沒有選擇,值為空;
- AGE:創建至今經歷的時間。
上面的字段中,除了 NODE SELECTOR 以外,我們已在前面的章節中介紹過。其實 Node Selector 并不是 DaemonSet 對象特有的配置,它是 Pod 模版中用于為 Pod 匹配節點的配置,DaemonSet 控制器使用該 Node Selector 來篩選需要創建副本的節點,如果沒有指定,則默認選擇全部節點。
接著,查看 DaemonSet 控制器所創建的 Pod 副本信息:
[root@k8s-master]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-daemonset-66dbc 1/1 Running 0 5m13s 10.135.3.2 k8s-master <none> <none> nginx-daemonset-akpdg 1/1 Running 0 5m13s 10.135.1.2 k8s-node1 <none> <none> nginx-daemonset-l3wnd 1/1 Running 0 5m13s 10.135.2.2 k8s-node2 <none> <none>
可以看到,在每個節點上均創建了一個副本,是符合預期的。
更新 DaemonSet
下面我們適當的調整下 Pod 部署策略,只希望 Pod 運行在名為 k8s-node 的節點上,這樣我們只需要配置 DaemonSet 對象的 spec.template.spec.nodeSelector 來選擇節點即可。
在 k8s-node 的節點中存在一個標識節點的 label:
kubernetes.io/hostname: k8s-node1
使用 kubectl edit 命令修改配置的 spec.template.spec.nodeSelector 參數如下:
apiVersion: apps/v1 kind: DaemonSet metadata: ... spec: ... template: ... spec: ... nodeSelector: kubernetes.io/hostname: k8s-node1
然后再次觀察 DaemonSet 對象和 Pod 副本:
[root@k8s-master]# kubectl get daemonsets NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE nginx-daemonset 1 1 1 1 1 kubernetes.io/hostname=k8s-node1 37m [root@k8s-master]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-daemonset-66gk2 1/1 Running 0 10s 10.135.2.3 k8s-node1 <none> <none>
可以發現 DaemonSet 狀態中,NODE SELECTOR 正確地展示了上面的修改,而且需求的 Pod 副本數也變成了 1 個,符合預期。
原來運行的 3 個 Pod 副本減少到 1 個,而且只在我們配置選定的節點(k8s-node1)上運行。
刪除 DaemonSet
像其他 Pod 控制器一樣,當刪除 DaemonSet 對象時,其所管理的 Pod 默認也會被刪除,操作如下所示:
[root@k8s-master ~]# kubectl delete daemonsets nginx-daemonset daemonset.apps "nginx-daemonset" deleted [root@k8s-master ~]# kubectl get pods No resources found in default namespace.
其它使用場景
容忍性 Toleration 使用
DaemonSet 還會給這個 Pod 自動加上另外一個與調度相關的字段,叫作 tolerations。這個字段意味著這個 Pod,會“容忍”(Toleration)某些 Node 的“污點”(Taint)。
Toleration 使用 yaml 配置如下:
apiVersion: v1 kind: Pod metadata: name: with-toleration spec: tolerations: - key: node.kubernetes.io/unschedulable operator: Exists effect: NoSchedule
在正常情況下,被標記了 unschedulable“污點”的 Node,是不會有任何 Pod 被調度上去的(effect: NoSchedule)。
可是,DaemonSet 自動地給被管理的 Pod 加上了這個特殊的 Toleration,就使得這些 Pod 可以忽略這個限制,繼而保證每個節點上都會被調度一個 Pod。
當然,如果這個節點有故障的話,這個 Pod 可能會啟動失敗,而 DaemonSet 則會始終嘗試下去,直到 Pod 啟動成功。
主要作用:
通過這樣一個 Toleration,調度器在調度這個 Pod 的時候,就會忽略當前節點上的“污點”,從而成功地將一些組件調度到這臺機器上啟動起來。
這種機制,正是我們在部署 Kubernetes 集群的時候,能夠先部署 Kubernetes 本身、再部署網絡插件的根本原因:因為當時我們所創建的 Weave 的 YAML,實際上就是一個 DaemonSet。
節點親和性 nodeAffinity 使用
正常情況下 DaemonSet Controller 會在創建 Pod 的時候,自動在這個 Pod 的 API 對象里,加上這樣一個 nodeAffinity 定義。
在這個 Pod 里,聲明了一個 spec.affinity 字段,然后定義了一個 nodeAffinity。其中,spec.affinity 字段,是 Pod 里跟調度相關的一個字段。
nodeAffinity 使用 yaml 配置如下:
apiVersion: v1 kind: Pod metadata: name: demo-node-affinity spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: metadata.name operator: In values: - demo-node
以上關鍵參數含義:
- requiredDuringSchedulingIgnoredDuringExecution 這個代表 nodeAffinity 必須在每次調度的時候予以考慮,同時,這也意味著可以設置在某些情況下不考慮這個 nodeAffinity;
- 這個 Pod,將來只允許運行在“metadata.name”是“demo-node”的節點上。
總結
DaemonSet 其實就是依靠 nodeAffinity 和 Toleration 實現的。這是一種不需要增加設計結構,而直接使用標簽等方式完成的 Daemon 進程。這樣的結構非常符合 Kubernetes 的控制器模式,正所謂一切皆對象。
原文鏈接:https://juejin.cn/post/7139909452815138853
相關推薦
- 2023-07-09 Go 數組與切片的區別
- 2023-03-16 PostgreSQL?復制表的?5?種方式詳解_PostgreSQL
- 2022-05-11 如何使 React 中的 useEffect、useLayoutEffect 只調用一次
- 2022-03-16 .Net?6簡介并和之前版本寫法做對比_基礎應用
- 2022-03-24 Android繪制旋轉動畫方法詳解_Android
- 2022-05-08 Windows?Bat腳本實現定時重啟應用程序的項目實踐_DOS/BAT
- 2022-03-15 could not open extension control file “/usr/pgsql-
- 2022-04-19 運行 npm run xxx 的時候都執行了些什么
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支