iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0
Kubernetes

都什麼年代了,還在學 Kubernetes系列 第 27

學 Kubernetes 的第二十七天 - Scheduling - Taints 和 Tolerations

  • 分享至 

  • xImage
  •  

上一章節中,我們介紹了如何主動指定 Pod 要部署在哪些節點上。然而在預設情況下,調度器會將 Pod 平均部署在所有可用的節點中。如果我們希望某些節點預設情況下不被調度,TaintsTolerations 的搭配便是很好的解決方案。

Taints 和 Tolerations 是什麼

TaintsTolerations 是 Kubernetes 中的機制,用於控制 Pod 的調度靈活性,確保 Pod 調度到合適的節點。

  • Taints

    • 被應用於節點上,表示該節點不適合某些 Pod 調度過來。
    • 當節點上有 Taints 時,Pod 需要相應的 Tolerations 才能被允許調度到這些節點上。
  • Tolerations

    • 應用在 Pod 上,用來指定該 Pod 可以容忍哪些 Taints。
    • 具有相應 Tolerations 的 Pod 可以忽略這些 Taints,並調度到這些節點上。

與其他調度、驅逐方式的差異

nodeSelector 和 Node Affinity

  • nodeSelector:用於選擇 Pod 應該調度到哪些節點上,但只能基於標籤進行選擇,缺乏 Taints 的排他性。
  • Node Affinity:提供了更靈活的調度規則,可以指定更複雜的條件來選擇節點。但 Taints 和 Tolerations 提供了反向的機制,即指定哪些節點不適合調度 Pod。

Preemption

搶占(Preemption) 是在資源緊張時,為高優先級的 Pod 騰出資源,可能會驅逐低優先級的 Pod。而 Taints 則用於預防不合適的 Pod 調度到特定節點。

Eviction

驅逐(Eviction) 是指當節點資源不足或節點出現故障時,Kubernetes 會主動移除一些 Pod。Taints 則更側重於調度前的預防措施,而不是調度後的處理。

應用場景

專用節點

某些節點可能配置了特殊硬件(如 GPU)或用於特定用途。使用 Taints 可以避免其他無關的 Pod 被調度到這些節點上,確保這些節點僅運行特定工作負載。

節點隔離

當節點出現故障或處於維護模式時,可以通過應用 Taints 暫時阻止新的 Pod 被調度到這些節點上。

多租戶環境

在多租戶 Kubernetes 集群中,可以使用 Taints 來確保不同租戶的工作負載被隔離到各自專用的節點上,避免資源衝突。

組態檔案說明

設置 Taints 給節點

Taints 通過以下命令設置,可以在節點的 YAML 定義中指定:

kubectl taint nodes nodename key=value:taint-effect
  • key=value:Taint 的鍵和值,這些是任意的自定義標籤。
  • taint-effect:有三種類型:
    • NoSchedule:阻止 Pod 被調度到這個節點上,除非 Pod 有相應的 Toleration。
    • PreferNoSchedule:優先阻止 Pod 被調度到這個節點上,但並不絕對。
    • NoExecute:不僅阻止 Pod 調度到這個節點上,還會驅逐已經在這個節點上的不匹配的 Pod。

設置 Tolerations 給 Pod

Tolerations 通過 Pod 的 YAML 組態檔來設置:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mycontainer
    image: nginx
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "value"
    effect: "NoSchedule"
    tolerationSeconds: 3600
  • key:Toleration 的鍵,必須與節點上 Taint 的鍵相匹配。
  • operatorEqual 表示必須匹配指定的 keyvalue
  • value:必須與節點上 Taint 的值相匹配。
  • effect:指定 Toleration 的效果,應與 Taint 的效果相匹配(如 NoSchedule)。
  • tolerationSeconds:可選,指定 Toleration 的有效時間,適用於 NoExecute Taint。該 Pod 會在指定時間內被允許運行,超過時間後將被驅逐。

實作

添加污點

  • 查詢叢集節點的 Taints 資訊
kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, taints: .spec.taints}'

結果如下

{
  "name": "wslkind-control-plane",
  "taints": [
    {
      "effect": "NoSchedule",
      "key": "node-role.kubernetes.io/control-plane"
    }
  ]
}
{
  "name": "wslkind-worker",
  "taints": null
}
{
  "name": "wslkind-worker2",
  "taints": null
}
  • 為 worker2 節點增加污點
kubectl taint nodes wslkind-worker2 dedicated=nginx-app:NoSchedule
  • 再次查詢節點的 Taints 資訊
kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, taints: .spec.taints}'

結果如下

{
  "name": "wslkind-control-plane",
  "taints": [
    {
      "effect": "NoSchedule",
      "key": "node-role.kubernetes.io/control-plane"
    }
  ]
}
{
  "name": "wslkind-worker",
  "taints": null
}
{
  "name": "wslkind-worker2",
  "taints": [
    {
      "effect": "NoSchedule",
      "key": "dedicated",
      "value": "nginx-app"
    }
  ]
}

驗證污點的作用

但凡節點存在污點,Pod 在調度時預設就會避開它們,我們來驗證一下。

組態檔案: deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: test-deploy
  name: test-deploy
spec:
  replicas: 6
  selector:
    matchLabels:
      app: test-pod
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: test-pod
    spec: 
      containers:
      - image: nginx
        name: nginx

該配置文件相當單純,配置 1 個具有 6 個副本的 nginx container 。

  • 建立 deployment
kubectl apply -f deploy.yaml
  • 驗證 Pod 的部署狀況
kubectl get pod -l app=test-pod -o wide

結果如下

NAME                           READY   STATUS    RESTARTS   AGE   IP            NODE             NOMINATED NODE   READINESS GATES
test-deploy-7f7cd9b788-75gjl   1/1     Running   0          12s   10.244.1.10   wslkind-worker   <none>           <none>
test-deploy-7f7cd9b788-bkgn6   1/1     Running   0          9s    10.244.1.13   wslkind-worker   <none>           <none>
test-deploy-7f7cd9b788-bpqh7   1/1     Running   0          12s   10.244.1.11   wslkind-worker   <none>           <none>
test-deploy-7f7cd9b788-th8c6   1/1     Running   0          7s    10.244.1.15   wslkind-worker   <none>           <none>
test-deploy-7f7cd9b788-wqxm2   1/1     Running   0          12s   10.244.1.12   wslkind-worker   <none>           <none>
test-deploy-7f7cd9b788-zwhj7   1/1     Running   0          8s    10.244.1.14   wslkind-worker   <none>           <none>

可以看到,由於剛剛對 wslkind-worker2 節點添加了污點,在調度的時候會避免在有污點的節點部署 Pod。
Pod 在預設中不會被調度到 control-plane 節點也是這個原因。

驗證容忍

在 Pod 添加 spec.tolerations 配置,可以使該 Pod 容忍指定的污點,允許 Pod 部署在那些節點上,下面我們來驗證一下。

修改上面的 deploy.yaml 配置文件,添加兩個容忍條件,我們預期包含控制平面節點在內,所有的節點應該都可以調度 pod。

組態檔案: deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: test-deploy
  name: test-deploy
spec:
  replicas: 6
  selector:
    matchLabels:
      app: test-pod
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: test-pod
    spec: 
      tolerations:
      - key: "dedicated"
        operator: "Equal"
        value: "nginx-app"
        effect: "NoSchedule"
      - key: "node-role.kubernetes.io/control-plane"
        operator: "Exists"
        effect: "NoSchedule"
      containers:
      - image: nginx
        name: nginx

  • 使用 deploy.yaml 建立 deployment
kubectl apply -f deploy.yaml
  • 驗證 Pod 的部署狀況
kubectl get pod -l app=test-pod -o wide

結果如下

NAME                          READY   STATUS    RESTARTS   AGE   IP            NODE                    NOMINATED NODE   READINESS GATES
test-deploy-86b969b6b-28s6b   1/1     Running   0          47s   10.244.0.22   wslkind-control-plane   <none>           <none>
test-deploy-86b969b6b-2sxj2   1/1     Running   0          52s   10.244.0.21   wslkind-control-plane   <none>           <none>
test-deploy-86b969b6b-575zn   1/1     Running   0          50s   10.244.2.7    wslkind-worker2         <none>           <none>
test-deploy-86b969b6b-cldls   1/1     Running   0          52s   10.244.0.20   wslkind-control-plane   <none>           <none>
test-deploy-86b969b6b-dp8bq   1/1     Running   0          52s   10.244.0.19   wslkind-control-plane   <none>           <none>
test-deploy-86b969b6b-kdx8l   1/1     Running   0          49s   10.244.1.16   wslkind-worker          <none>           <none>

現在 3 個節點都部署了 Pod,包括控制平面節點。

清理

kubectl taint nodes wslkind-worker2 dedicated=nginx-app:NoSchedule-

小結

Taints and Tolerations 是 Kubernetes 中強大且靈活的調度控制機制,能夠有效地控制 Pod 調度到節點的行為。它們提供了防止不合適的 Pod 被調度到特定節點上的能力,並可以在特定應用場景中進行靈活運用,如專用節點的隔離、多租戶環境的資源隔離等。這使得 Kubernetes 能夠在調度過程中保證更高的可控性和精確性。


參考


上一篇
學 Kubernetes 的第二十六天 - Scheduling - 指派 Pod 到節點
下一篇
學 Kubernetes 的第二十八天 - Resource - Pod 層級的資源管理
系列文
都什麼年代了,還在學 Kubernetes32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言