最近在kubernetes部署一個springcloud微服務項目,到了最后一步部署邊緣路由:使用nginx-ingress和traefik都可以,必須使用DaemonSet部署,但是發現三個節點,卻總共只有兩個pod。
換句話說,?DaemonSet沒法調度到master節點上。
?要理解這種情況,就必須理解kubernets中pod的污點和容忍度的問題
什么是污點(taint)和容忍度(toleration)
“污點”是Kubernetes節點的一個屬性,字段名為taint,它的含義說的直白點,就是表明這個節點“不干凈”
和“污點”相對應的,就是Pod的“容忍度”,顧名思義,就是Pod能否“容忍”污點。
? ? ? 打個形象的比喻:集群里的節點各式各樣,有的節點“純潔無瑕”,沒有“污點”;而有的節點因為某種原因粘上了“泥巴”,也就有了“污點”。Pod也脾氣各異,有的“潔癖”很嚴重,不能容忍“污點”,只能挑選“干凈”的節點;而有的Pod則比較“大大咧咧”,要求不那么高,可以適當地容忍一些小“污點”。
這么看來,“污點”和“容忍度”倒是有點像是一個“相親”的過程。Pod就是一個挑剔的“甲方”,而“乙方”就是集群里的各個節點,Pod會根據自己對“污點”的“容忍程度”來選擇合適的目標,比如要求“不抽煙不喝酒”,但可以“無車無房”,最終決定在哪個節點上“落戶”。
Kubernetes在創建集群的時候會自動給節點Node加上一些“污點”,方便Pod的調度和部署。
如下面Master和Node節點的狀態:
[root@k8s-node2 vhost]# kubectl get nodes
NAME ? ? ? ? STATUS ? ROLES ? ?AGE ? ? ?VERSION
k8s-master ? Ready ? ?master ? 3y292d ? v1.17.2
k8s-node1 ? ?Ready ? ?<none> ? 4d5h ? ? v1.17.2
k8s-node2 ? ?Ready ? ?<none> ? 3y292d ? v1.17.2
[root@k8s-node2 vhost]# kubectl describe node k8s-master|grep Taints
Taints: ? ? ? ? ? ? node-role.kubernetes.io/master:NoSchedule
[root@k8s-node2 vhost]# kubectl describe node k8s-node1|grep Taints
Taints: ? ? ? ? ? ? <none>
[root@k8s-node2 vhost]# kubectl describe node k8s-node2|grep Taints
Taints: ? ? ? ? ? ? <none>
?
?可以看到,Master節點默認有一個?taint污點
,名字是?node-role.kubernetes.io/master
,它的效果是?NoSchedule
,也就是說這個污點會拒絕Pod調度到本節點上運行,而node節點的?taint
?字段則是空的。
這正是Master和node在Pod調度策略上的區別所在,通常來說Pod都不能容忍任何“污點”,所以加上了?taint
?屬性的Master節點被認為是有污點,pod默認不會調度到該節點。
這個也很好理解:?由于master節點具有一定的特殊性,出于安全及角色的原因,一般不建議在Master節點部署應用的Pod實例, 因為Master 節點主要運行集群管理組件和控制面等關鍵組件。
那么怎么解決這個問題,讓pod能調度到master節點: 引入toleration,允許容忍這個污點
具體來說,就是在pod定義yml文件中跟container容器的同級字段加入下面的配置:
tolerations:
- key: node-role.kubernetes.io/master
? effect: NoSchedule
? operator: Exists
它的定義位置或者可以說在這里:daemonSet定義的spec.template.spec下
解釋一下它們的含義:
key: node-role.kubernetes.io/master
:?key表示tolerations能容忍的節點標記,這里就是指能容忍的節點類型是master節點
effect: NoSchedule
:?effect表示taint污點標記產生的效果,NoSchedule是指
告訴調度器,不允許調度到帶有這個 taint 污點標識的節點上,除非 Pod 顯式容忍(tolerate)這個 taint,
operator: Exists
:?表示只容忍key指定類型的節點。在這個例子中,Pod 只要運行在帶有node-role.kubernetes.io/master
taint 的節點上,就能夠被容忍。
?配置在yml文件中的具體情形:
?定義了容忍污點以后,pod果然可以調度到master節點了:
?