在前面一篇《CI&CD落地實踐2-Jenkins環(huán)境搭建&常見使用技巧》中,我們介紹了Jenkins的架構原理:
Jenkins是一種典型的Master-Slave主從架構。該架構包括一個Master(主)節(jié)點和多個Slave(從)節(jié)點。Jenkins的Master-Slave架構提供了可擴展性和靈活性,允許用戶添加更多節(jié)點來提高Jenkins的處理能力,同時保持構建和管理過程的可靠性。
在Jenkins的分布式環(huán)境中,有以下幾個好處:
總之,Jenkins分布式環(huán)境可以提供更好的性能、伸縮性、可靠性和安全性,使得整個系統更加高效、穩(wěn)定和安全。
其實驅使我搭建分布式環(huán)境倒不是因為伸縮性不足、性能低下等方面的原因,而是我在一次Jenkins配置Maven項目、編譯后端springboot項目時,老是報Maven依賴庫錯誤的問題,最終導致編譯不過,嘗試了很多方法都沒有解決。但該項目在我本地的IDEA中是可以正常編譯通過的,于是我想了一個曲線救國的方案,就是在另一臺Windows機器上,搭建一套和我本機一模一樣的環(huán)境,將我本機的Maven倉庫整體打包復制過去,然后再安裝一個Jenkins,作為從節(jié)點使用。
當前我只在一個單節(jié)點服務器上安裝了Jenkins,計劃在一臺Linux系統機器上安裝Jenkins作為從節(jié)點1,在另一臺Windows系統機器上安裝Jenkins作為從節(jié)點2。
節(jié)點 | 主機 | 系統 | 用途 |
Master 主節(jié)點 | 192.168.1.20 | CentOS 7 | 分配、調度任務 |
Slave 從節(jié)點1 | 192.168.1.122 | CentOS 7 | 編譯前端項目 |
Slave 從節(jié)點2 | 192.168.1.188 | Win 10 | 編譯后端項目 |
所在服務器需要安裝Jenkins,版本最好與主節(jié)點Jenkins版本保持一致,安裝步驟參考前面的《Jenkins環(huán)境搭建&常見使用技巧》
需要安裝Git以及相關插件,如果是編譯前端項目,需要配置nodejs,如果是編譯后端項目,還需要安裝maven等。前端環(huán)境配置可以參考前面的一篇《Jenkins實現前端項目自動化構建》
入口:系統管理-節(jié)點管理-添加節(jié)點,填寫從節(jié)點名稱,選擇固定節(jié)點
注意最后“節(jié)點屬性”,可以勾選“工具位置”提前指定該機器中的如JDK等工具的路徑。
剛添加好后的從節(jié)點處于不可用狀態(tài),還需要進行一堆的配置:
主節(jié)點:系統管理-全局安全配置-代理,指定一個代理端口(注意:從節(jié)點服務器防火墻一定要開放此端口)
在管理節(jié)點點擊查看新增的從節(jié)點詳情,會給出從節(jié)點如何連接主節(jié)點的提示:
在從節(jié)點上執(zhí)行:
# 下載agent.jar
curl -sO http://192.168.1.20:8080/jenkins/jnlpJars/agent.jar
# 連接主節(jié)點
java -jar agent.jar -jnlpUrl http://192.168.1.20:8080/jenkins/manage/computer/h122/jenkins-agent.jnlp -secret 5d40fefd1148aa3e1461eb53a7764f655c030a7859cfa648b2340ba019146a3d -workDir "/home/jenkins/workspace"
此時我的報錯了,提示42730端口不可用,也就是前面提到的從節(jié)點服務器防火墻一定要開放主節(jié)點中配置的代理端口
防火墻開通端口號
firewall-cmd --permanent --add-port 42730/tcp
firewall-cmd --reload
再次執(zhí)行連接命令后,連接成功
但是這種啟動方式會一直處于前臺運行,此時終端窗口無法再進行其他操作。因此,可以給它創(chuàng)建一個啟動腳本,使其后臺運行。
腳本內容如下:
nohup java -jar agent.jar -jnlpUrl http://192.168.1.20:8080/jenkins/manage/computer/h122/jenkins-agent.jnlp -secret 5d40fefd1148aa3e1461eb53a7764f655c030a7859cfa648b2340ba019146a3d -workDir "/home/jenkins/workspace" 2>&1 >nohup.out &
運行腳本
chmod +x start_agent.sh
./start_agent.sh
在前面一篇《Jenkins實現前端項目自動化構建》中,已經在主節(jié)點成功構建運行了前端項目,此時我們再次構建該項目,看看它會不會在從節(jié)點運行。
當我點擊構建時,該項目確實是通過我新建的從節(jié)點"h122"執(zhí)行構建的
但出現了報錯"No such file or directory",提示項目路徑不存在:
經過一番排查,終于找到了原因:
解決方式有兩種:
全局變量
我用的是第二種,將構建步驟中原本的"cd /home/jenkins/workspace/開普勒-前端"改為"cd $WORKSPACE"
再次構建,構建成功!
企微群也收到了構建成功的消息通知:
同樣是需要先在Windows電腦上提前安裝好Jenkins。
同樣需要安裝JDK、Git以及相關插件,如果是編譯前端項目,需要配置nodejs,如果是編譯后端項目,還需要安裝maven等。
入口:系統管理-節(jié)點管理-添加節(jié)點,填寫從節(jié)點名稱,選擇固定節(jié)點
同樣選擇“通過Java Web啟動代理”
在管理節(jié)點點擊查看新增的從節(jié)點詳情,會給出從節(jié)點如何連接主節(jié)點的提示:
在從節(jié)點上執(zhí)行:
curl -sO http://192.168.1.20:8080/jenkins/jnlpJars/agent.jar
java -jar agent.jar -jnlpUrl http://192.168.1.20:8080/jenkins/manage/computer/win188/jenkins-agent.jnlp -secret ed74e189c3cf7012fac65f0c9af7e091a1159d36ebbef8c581491fccff40a1b5 -workDir "C:\Users\chenjigang\.jenkins"
連接成功:
此時會在我們配置的自定義工作目錄下自動創(chuàng)建生成remoting內部數據目錄
創(chuàng)建完成,從節(jié)點win188處于在線狀態(tài):
比如我想為某個項目指定用這個從節(jié)點win188來運行,那么則可以在該項目配置-General中勾選“限制項目的運行節(jié)點”,并填寫標簽表達式,也就是前面我們填寫從節(jié)點時設置的標簽名稱“win188”
構建該項目,可以看到,已經通過win188這個從節(jié)點來運行:
但是在運行的時候報錯了,提示maven路徑不存在,原因是此項目原本是在主節(jié)點(Linux)上運行的,該臺機器上的maven目錄是/home/apache-maven-3.6.3,而換到了從節(jié)點(Windows)系統運行以后,maven路徑不一致。
需要在win188從節(jié)點配置中指定相關工具位置:
再次運行,構建成功:
以上就是Jenkins分別添加Linux從節(jié)點、Windows從節(jié)點以及構建過程中出現報錯問題排查解決的全部過程。總體來說,不管Linux從節(jié)點還是Windows從節(jié)點,步驟基本一致。關鍵的是如何合理利用好這些節(jié)點,從而物盡其用,使其發(fā)揮出更大價值!
前面一篇文章理解 Kubernetes 的親和性調度,現在仔細回頭去看看,發(fā)現有很多地方沒有理解透徹,不夠深入,今天我們重新來理解下親和性調度這一塊知識。
一般情況下我們部署的 Pod 是通過集群的自動調度策略來選擇節(jié)點的,默認情況下調度器考慮的是資源足夠,并且負載盡量平均,但是有的時候我們需要能夠更加細粒度的去控制 Pod 的調度,比如我們內部的一些服務 gitlab 之類的也是跑在Kubernetes集群上的,我們就不希望對外的一些服務和內部的服務跑在同一個節(jié)點上了,害怕內部服務對外部的服務產生影響;但是有的時候我們的服務之間交流比較頻繁,又希望能夠將這兩個服務的 Pod 調度到同一個的節(jié)點上。這就需要用到 Kubernetes 里面的一個概念:親和性和反親和性。
親和性有分成節(jié)點親和性(nodeAffinity)和 Pod 親和性(podAffinity)。
nodeSelector
在了解親和性之前,我們先來了解一個非常常用的調度方式:nodeSelector。我們知道label是kubernetes中一個非常重要的概念,用戶可以非常靈活的利用 label 來管理集群中的資源,比如最常見的一個就是 service 通過匹配 label 去匹配 Pod 資源,而 Pod 的調度也可以根據節(jié)點的 label 來進行調度。
我們可以通過下面的命令查看我們的 node 的 label:
$ kubectl get nodes --show-labels NAME STATUS ROLES AGE VERSION LABELS master Ready master 147d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=master,node-role.kubernetes.io/master=node02 Ready <none> 67d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,course=k8s,kubernetes.io/hostname=node02 node03 Ready <none> 127d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,jnlp=haimaxy,kubernetes.io/hostname=node03
現在我們先給節(jié)點node02增加一個com=youdianzhishi的標簽,命令如下:
$ kubectl label nodes node02 com=youdianzhishi node "node02" labeled
我們可以通過上面的--show-labels參數可以查看上述標簽是否生效。當 node 被打上了相關標簽后,在調度的時候就可以使用這些標簽了,只需要在 Pod 的spec字段中添加nodeSelector字段,里面是我們需要被調度的節(jié)點的 label 即可。比如,下面的 Pod 我們要強制調度到 node02 這個節(jié)點上去,我們就可以使用 nodeSelector 來表示了:(node-selector-demo.yaml)
apiVersion: v1 kind: Pod metadata: labels: app: busybox-pod name: test-busybox spec: containers: - command: - sleep - "3600" image: busybox imagePullPolicy: Always name: test-busybox nodeSelector: com: youdianzhishi
然后我們可以通過 describe 命令查看調度結果:
$ kubectl create -f node-selector-demo.yaml pod "test-busybox" created $ kubectl describe pod test-busybox Name: test-busybox Namespace: default Node: node02/10.151.30.63 ...... QoS Class: BestEffort Node-Selectors: com=youdianzhishi Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s node.kubernetes.io/unreachable:NoExecute for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal SuccessfulMountVolume 55s kubelet, node02 MountVolume.SetUp succeeded for volume "default-token-n9w2d" Normal Scheduled 54s default-scheduler Successfully assigned test-busybox to node02 Normal Pulling 54s kubelet, node02 pulling image "busybox" Normal Pulled 40s kubelet, node02 Successfully pulled image "busybox" Normal Created 40s kubelet, node02 Created container Normal Started 40s kubelet, node02 Started container
我們可以看到 Events 下面的信息,我們的 Pod 通過默認的 default-scheduler 調度器被綁定到了node02節(jié)點。不過需要注意的是nodeSelector屬于強制性的,如果我們的目標節(jié)點沒有可用的資源,我們的 Pod 就會一直處于 Pending 狀態(tài),這就是nodeSelector的用法。
通過上面的例子我們可以感受到nodeSelector的方式比較直觀,但是還夠靈活,控制粒度偏大,接下來我們再和大家了解下更加靈活的方式:節(jié)點親和性(nodeAffinity)。
親和性和反親和性調度
上節(jié)課我們了解了 kubernetes 調度器的一個調度流程,我們知道默認的調度器在使用的時候,經過了 predicates 和 priorities 兩個階段,但是在實際的生產環(huán)境中,往往我們需要根據自己的一些實際需求來控制 pod 的調度,這就需要用到 nodeAffinity(節(jié)點親和性)、podAffinity(pod 親和性) 以及 podAntiAffinity(pod 反親和性)。
親和性調度可以分成軟策略和硬策略兩種方式:
對于親和性和反親和性都有這兩種規(guī)則可以設置: preferredDuringSchedulingIgnoredDuringExecution和requiredDuringSchedulingIgnoredDuringExecution,前面的就是軟策略,后面的就是硬策略。
這命名不覺得有點反人類嗎?有點無語……
nodeAffinity
節(jié)點親和性主要是用來控制 pod 要部署在哪些主機上,以及不能部署在哪些主機上的。它可以進行一些簡單的邏輯組合了,不只是簡單的相等匹配。
比如現在我們用一個 Deployment 來管理3個 pod 副本,現在我們來控制下這些 pod 的調度,如下例子:(node-affinity-demo.yaml)
apiVersion: apps/v1beta1 kind: Deployment metadata: name: affinity labels: app: affinity spec: replicas: 3 revisionHistoryLimit: 15 template: metadata: labels: app: affinity role: test spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 name: nginxweb affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: # 硬策略 nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: NotIn values: - node03 preferredDuringSchedulingIgnoredDuringExecution: # 軟策略 - weight: 1 preference: matchExpressions: - key: com operator: In values: - youdianzhishi
上面這個 pod 首先是要求不能運行在 node03 這個節(jié)點上,如果有個節(jié)點滿足com=youdianzhishi的話就優(yōu)先調度到這個節(jié)點上。
下面是我們測試的節(jié)點列表信息:
$ kubectl get nodes --show-labels NAME STATUS ROLES AGE VERSION LABELS master Ready master 154d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=master,node-role.kubernetes.io/master=node02 Ready <none> 74d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,com=youdianzhishi,course=k8s,kubernetes.io/hostname=node02 node03 Ready <none> 134d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,jnlp=haimaxy,kubernetes.io/hostname=node03
可以看到 node02 節(jié)點有com=youdianzhishi這樣的 label,按要求會優(yōu)先調度到這個節(jié)點來的,現在我們來創(chuàng)建這個 pod,然后使用descirbe命令查看具體的調度情況是否滿足我們的要求。
$ kubectl create -f node-affinity-demo.yaml deployment.apps "affinity" created $ kubectl get pods -l app=affinity -o wide NAME READY STATUS RESTARTS AGE IP NODE affinity-7b4c946854-5gfln 1/1 Running 0 47s 10.244.4.214 node02 affinity-7b4c946854-l8b47 1/1 Running 0 47s 10.244.4.215 node02 affinity-7b4c946854-r86p5 1/1 Running 0 47s 10.244.4.213 node02
從結果可以看出 pod 都被部署到了 node02,其他節(jié)點上沒有部署 pod,這里的匹配邏輯是 label 的值在某個列表中,現在Kubernetes提供的操作符有下面的幾種:
如果nodeSelectorTerms下面有多個選項的話,滿足任何一個條件就可以了;如果matchExpressions有多個選項的話,則必須同時滿足這些條件才能正常調度 POD。
podAffinity
pod 親和性主要解決 pod 可以和哪些 pod 部署在同一個拓撲域中的問題(其中拓撲域用主機標簽實現,可以是單個主機,也可以是多個主機組成的 cluster、zone 等等),而 pod 反親和性主要是解決 pod 不能和哪些 pod 部署在同一個拓撲域中的問題,它們都是處理的 pod 與 pod 之間的關系,比如一個 pod 在一個節(jié)點上了,那么我這個也得在這個節(jié)點,或者你這個 pod 在節(jié)點上了,那么我就不想和你待在同一個節(jié)點上。
由于我們這里只有一個集群,并沒有區(qū)域或者機房的概念,所以我們這里直接使用主機名來作為拓撲域,把 pod 創(chuàng)建在同一個主機上面。
$ kubectl get nodes --show-labels NAME STATUS ROLES AGE VERSION LABELS master Ready master 154d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=master,node-role.kubernetes.io/master=node02 Ready <none> 74d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,com=youdianzhishi,course=k8s,kubernetes.io/hostname=node02 node03 Ready <none> 134d v1.10.0 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,jnlp=haimaxy,kubernetes.io/hostname=node03
同樣,還是針對上面的資源對象,我們來測試下 pod 的親和性:(pod-affinity-demo.yaml)
apiVersion: apps/v1beta1 kind: Deployment metadata: name: affinity labels: app: affinity spec: replicas: 3 revisionHistoryLimit: 15 template: metadata: labels: app: affinity role: test spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 name: nginxweb affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: # 硬策略 - labelSelector: matchExpressions: - key: app operator: In values: - busybox-pod topologyKey: kubernetes.io/hostname
上面這個例子中的 pod 需要調度到某個指定的主機上,至少有一個節(jié)點上運行了這樣的 pod:這個 pod 有一個app=busybox-pod的 label。
我們查看有標簽app=busybox-pod的 pod 列表:
$ kubectl get pods -o wide -l app=busybox-pod NAME READY STATUS RESTARTS AGE IP NODE test-busybox 1/1 Running 164 7d 10.244.4.205 node02
我們看到這個 pod 運行在了 node02 的節(jié)點上面,所以按照上面的親和性來說,上面我們部署的3個 pod 副本也應該運行在 node02 節(jié)點上:
$ kubectl get pods -o wide -l app=affinity NAME READY STATUS RESTARTS AGE IP NODE affinity-564f9d7db9-lzzvq 1/1 Running 0 3m 10.244.4.216 node02 affinity-564f9d7db9-p79cq 1/1 Running 0 3m 10.244.4.217 node02 affinity-564f9d7db9-spfzs 1/1 Running 0 3m 10.244.4.218 node02
如果我們把上面的 test-busybox 和 affinity 這個 Deployment 都刪除,然后重新創(chuàng)建 affinity 這個資源,看看能不能正常調度呢:
$ kubectl delete -f node-selector-demo.yaml pod "test-busybox" deleted $ kubectl delete -f pod-affinity-demo.yaml deployment.apps "affinity" deleted $ kubectl create -f pod-affinity-demo.yaml deployment.apps "affinity" created $ kubectl get pods -o wide -l app=affinity NAME READY STATUS RESTARTS AGE IP NODE affinity-564f9d7db9-fbc8w 0/1 Pending 0 2m <none> <none> affinity-564f9d7db9-n8gcf 0/1 Pending 0 2m <none> <none> affinity-564f9d7db9-qc7x6 0/1 Pending 0 2m <none> <none>
我們可以看到處于Pending狀態(tài)了,這是因為現在沒有一個節(jié)點上面擁有busybox-pod這個 label 的 pod,而上面我們的調度使用的是硬策略,所以就沒辦法進行調度了,大家可以去嘗試下重新將 test-busybox 這個 pod 調度到 node03 這個節(jié)點上,看看上面的 affinity 的3個副本會不會也被調度到 node03 這個節(jié)點上去?
我們這個地方使用的是kubernetes.io/hostname這個拓撲域,意思就是我們當前調度的 pod 要和目標的 pod 處于同一個主機上面,因為要處于同一個拓撲域下面,為了說明這個問題,我們把拓撲域改成beta.kubernetes.io/os,同樣的我們當前調度的 pod 要和目標的 pod 處于同一個拓撲域中,目標的 pod 是不是擁有beta.kubernetes.io/os=linux的標簽,而我們這里3個節(jié)點都有這樣的標簽,這也就意味著我們3個節(jié)點都在同一個拓撲域中,所以我們這里的 pod 可能會被調度到任何一個節(jié)點:
$ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE affinity-7d86749984-glkhz 1/1 Running 0 3m 10.244.2.16 node03 affinity-7d86749984-h4fb9 1/1 Running 0 3m 10.244.4.219 node02 affinity-7d86749984-tj7k2 1/1 Running 0 3m 10.244.2.14 node03
podAntiAffinity
這就是 pod 親和性的用法,而 pod 反親和性則是反著來的,比如一個節(jié)點上運行了某個 pod,那么我們的 pod 則希望被調度到其他節(jié)點上去,同樣我們把上面的 podAffinity 直接改成 podAntiAffinity,(pod-antiaffinity-demo.yaml)
apiVersion: apps/v1beta1 kind: Deployment metadata: name: affinity labels: app: affinity spec: replicas: 3 revisionHistoryLimit: 15 template: metadata: labels: app: affinity role: test spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80 name: nginxweb affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: # 硬策略 - labelSelector: matchExpressions: - key: app operator: In values: - busybox-pod topologyKey: kubernetes.io/hostname
這里的意思就是如果一個節(jié)點上面有一個app=busybox-pod這樣的 pod 的話,那么我們的 pod 就別調度到這個節(jié)點上面來,上面我們把app=busybox-pod這個 pod 固定到了 node03 這個節(jié)點上面來,所以正常來說我們這里的 pod 不會出現在 node03 節(jié)點上:
$ kubectl create -f pod-antiaffinity-demo.yaml deployment.apps "affinity" created $ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE affinity-bcbd8854f-br8z8 1/1 Running 0 5s 10.244.4.222 node02 affinity-bcbd8854f-cdffh 1/1 Running 0 5s 10.244.4.223 node02 affinity-bcbd8854f-htb52 1/1 Running 0 5s 10.244.4.224 node02 test-busybox 1/1 Running 0 23m 10.244.2.10 node03
這就是 pod 反親和性的用法。
污點(taints)與容忍(tolerations)
對于nodeAffinity無論是硬策略還是軟策略方式,都是調度 pod 到預期節(jié)點上,而Taints恰好與之相反,如果一個節(jié)點標記為 Taints ,除非 pod 也被標識為可以容忍污點節(jié)點,否則該 Taints 節(jié)點不會被調度 pod。
比如用戶希望把 Master 節(jié)點保留給 Kubernetes 系統組件使用,或者把一組具有特殊資源預留給某些 pod,則污點就很有用了,pod 不會再被調度到 taint 標記過的節(jié)點。我們使用kubeadm搭建的集群默認就給 master 節(jié)點添加了一個污點標記,所以我們看到我們平時的 pod 都沒有被調度到 master 上去:
$ kubectl describe node master Name: master Roles: master Labels: beta.kubernetes.io/arch=amd64 beta.kubernetes.io/os=linux kubernetes.io/hostname=master node-role.kubernetes.io/master=...... Taints: node-role.kubernetes.io/master:NoSchedule Unschedulable: false ......
我們可以使用上面的命令查看 master 節(jié)點的信息,其中有一條關于 Taints 的信息:node-role.kubernetes.io/master:NoSchedule,就表示給 master 節(jié)點打了一個污點的標記,其中影響的參數是NoSchedule,表示 pod 不會被調度到標記為 taints 的節(jié)點,除了 NoSchedule 外,還有另外兩個選項:
污點 taint 標記節(jié)點的命令如下:
$ kubectl taint nodes node02 test=node02:NoSchedule node "node02" tainted
上面的命名將 node02 節(jié)點標記為了污點,影響策略是 NoSchedule,只會影響新的 pod 調度,如果仍然希望某個 pod 調度到 taint 節(jié)點上,則必須在 Spec 中做出Toleration定義,才能調度到該節(jié)點,比如現在我們想要將一個 pod 調度到 master 節(jié)點:(taint-demo.yaml)
apiVersion: apps/v1beta1 kind: Deployment metadata: name: taint labels: app: taint spec: replicas: 3 revisionHistoryLimit: 10 template: metadata: labels: app: taint spec: containers: - name: nginx image: nginx:1.7.9 ports: - name: http containerPort: 80 tolerations: - key: "node-role.kubernetes.io/master" operator: "Exists" effect: "NoSchedule"
由于 master 節(jié)點被標記為了污點節(jié)點,所以我們這里要想 pod 能夠調度到 master 節(jié)點去,就需要增加容忍的聲明:
tolerations: - key: "node-role.kubernetes.io/master" operator: "Exists" effect: "NoSchedule"
然后創(chuàng)建上面的資源,查看結果:
$ kubectl create -f taint-demo.yaml deployment.apps "taint" created $ kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE ...... taint-845d8bb4fb-57mhm 1/1 Running 0 1m 10.244.4.247 node02 taint-845d8bb4fb-bbvmp 1/1 Running 0 1m 10.244.0.33 master taint-845d8bb4fb-zb78x 1/1 Running 0 1m 10.244.4.246 node02 ......
我們可以看到有一個 pod 副本被調度到了 master 節(jié)點,這就是容忍的使用方法。
對于 tolerations 屬性的寫法,其中的 key、value、effect 與 Node 的 Taint 設置需保持一致, 還有以下幾點說明:
另外,還有兩個特殊值:
最后,如果我們要取消節(jié)點的污點標記,可以使用下面的命令:
$ kubectl taint nodes node02 test- node "node02" untainted
這就是污點和容忍的使用方法。