文章目錄
- K8s 高級調度
- CronJob
- initContainer
- Taint 和 Toleration
- 污點(Taint)
- 容忍(Toleration)
- Affinity
- NodeAffinity
- PodAnffinity 和 PodAntiAffinity
- 總結
K8s 高級調度
CronJob
在 k8s 中周期性運行計劃任務,與 linux 中的 crontab 相同
注意點:CronJob 執行的時間是 controller-manager 的時間,所以一定要確保 controller-manager 時間是準確的,另外 cronjob
apiVersion: batch/v1
kind: CronJob
metadata:name: cron-job-test
spec:concurrencyPolicy: Allow # 并發調度策略:Allow 允許并發調度,Forbid:不允許并發執行,Replace:如果之前的任務還沒執行完,就直接執行新的,放棄上一個任務failedJobsHistoryLimit: 1 # 保留多少個失敗的任務successfulJobsHistoryLimit: 3 # 保留多少個成功的任務suspend: falsestartingDeadlineSeconds: 30 # 間隔多長時間檢測失敗的任務并重新執行,時間不能小于 10schedule: "* * * * *" # 調度策略jobTemplate:spec:template:spec:containers:- name: cron-jobimage: busybox:1.28imagePullPolicy: IfNotPresentcommand:- /bin/sh- -c- date; echo Hello from the Kubernetes clusterrestartPolicy: OnFailure
initContainer
在真正的容器啟動之前,先啟動 InitContainer,在初始化容器中完成真實容器所需的初始化操作,完成后再啟動真實的容器。
相對于 postStart 來說,首先 InitController 能夠保證一定在 EntryPoint 之前執行,而 postStart 不能,其次 postStart 更適合去執行一些命令操作,而 InitController 實際就是一個容器,可以在其他基礎容器環境下執行更復雜的初始化功能。
# 在 pod 創建的模板中配置 initContainers 參數:
spec:initContainers:- image: nginximagePullPolicy: IfNotPresentcommand: ["sh", "-c", "echo 'inited;' >> ~/.init"]name: init-test
Taint 和 Toleration
k8s 集群中可能管理著非常龐大的服務器,這些服務器可能是各種各樣不同類型的,比如機房、地理位置、配置等,有些是計算型節點,有些是存儲型節點,此時我們希望能更好的將 pod 調度到與之需求更匹配的節點上。
此時就需要用到污點(Taint)和容忍(Toleration),這些配置都是 key: value 類型的。
官網地址
污點(Taint)
污點:是標注在節點上的,當我們在一個節點上打上污點以后,k8s 會認為盡量不要將 pod 調度到該節點上,除非該 pod 上面表示可以容忍該污點,且一個節點可以打多個污點,此時則需要 pod 容忍所有污點才會被調度該節點。
# 為節點打上污點
kubectl taint node k8s-master key=value:NoSchedule# 移除污點
kubectl taint node k8s-master key=value:NoSchedule-節點名稱 污點的k,v 污點描述 - 刪除# 查看污點
kubectl describe no k8s-master污點的描述:
NoSchedule:不能容忍的 pod 不能被調度到該節點,但是已經存在的節點不會被驅逐
NoExecute:不能容忍的節點會被立即清除,能容忍且沒有配置 tolerationSeconds 屬性,則可以一直運行,設置了 tolerationSeconds: 3600 屬性,則該 pod 還能繼續在該節點運行 3600 秒
PreferNoSchedule:盡量避免把Pod調度到具有該污點的Node上,除非沒有其他節點可調度
容忍(Toleration)
容忍:是標注在 pod 上的,當 pod 被調度時,如果沒有配置容忍,則該 pod 不會被調度到有污點的節點上,只有該 pod 上標注了滿足某個節點的所有污點,則會被調度到這些節點
污點就是拒絕,容忍就是忽略,Node通過污點拒絕pod調度上去,Pod通過容忍忽略拒絕
# pod 的 spec 下面配置容忍
tolerations:
- key: "污點的 key"value: "污點的 value"offect: "NoSchedule" # 污點產生的影響operator: "Equal" # 表是 value 與污點的 value 要相等,也可以設置為 Exists 表示存在 key 即可,此時可以不用配置 value
Affinity
NodeAffinity
節點親和力:進行 pod 調度時,優先調度到符合條件的親和力節點上
requiredDuringSchedulingIgnoredDuringExecution
: 調度器只有在規則被滿足的時候才能執行調度。此功能類似于nodeSelector
, 但其語法表達能力更強。preferredDuringSchedulingIgnoredDuringExecution
: 調度器會嘗試尋找滿足對應規則的節點。如果找不到匹配的節點,調度器仍然會調度該 Pod。
apiVersion: v1
kind: Pod
metadata:name: with-node-affinity
spec:affinity: # 親和力配置nodeAffinity: # 節點親和力requiredDuringSchedulingIgnoredDuringExecution: # 節點必須匹配下方配置nodeSelectorTerms: # 選擇器- matchExpressions: # 匹配表達式- key: topology.kubernetes.io/zone # 匹配 label 的 keyoperator: In # 匹配方式,只要匹配成功下方的一個 value 即可values:- antarctica-east1 # 匹配的 value- antarctica-west1 # 匹配的 valuepreferredDuringSchedulingIgnoredDuringExecution: # 節點盡量匹配下方配置- weight: 1 # 權重[1,100],按照匹配規則對所有節點累加權重,最終之和會加入優先級評分,優先級越高被調度的可能性越高preference:matchExpressions: # 匹配表達式- key: another-node-label-key # label 的 keyoperator: In # 匹配方式,滿足一個即可values:- another-node-label-value # 匹配的 value
# - weight: 20......containers:- name: with-node-affinityimage: pause:2.0
在這一示例中,所應用的規則如下:
- 節點必須包含一個鍵名為
topology.kubernetes.io/zone
的標簽, 并且該標簽的取值必須為antarctica-east1
或antarctica-west1
。 - 節點最好具有一個鍵名為
another-node-label-key
且取值為another-node-label-value
的標簽。
你可以使用 operator
字段來為 Kubernetes 設置在解釋規則時要使用的邏輯操作符。 你可以使用 In
、NotIn
、Exists
、DoesNotExist
、Gt
和 Lt
之一作為操作符。 詳情可以參考官網
補充:如果你同時指定了
nodeSelector
和nodeAffinity
,兩者必須都要滿足, 才能將 Pod 調度到候選節點上。如果你在與 nodeAffinity 類型關聯的 nodeSelectorTerms 中指定多個條件, 只要其中一個
nodeSelectorTerms
滿足(各個條件按邏輯或操作組合)的話,Pod 就可以被調度到節點上。如果你在與
nodeSelectorTerms
中的條件相關聯的單個matchExpressions
字段中指定多個表達式, 則只有當所有表達式都滿足(各表達式按邏輯與操作組合)時,Pod 才能被調度到節點上。
PodAnffinity 和 PodAntiAffinity
PodAnffinity :Pod 親和力將與指定 pod 親和力相匹配的 pod 部署在同一節點。
PodAntiAffinity: Pod 反親和力 根據策略盡量部署或不部署到一塊
Pod 的親和性與反親和性也有兩種類型:
requiredDuringSchedulingIgnoredDuringExecution
preferredDuringSchedulingIgnoredDuringExecution
apiVersion: v1
kind: Pod
metadata:name: with-pod-affinity
spec:affinity: # 親和力配置podAffinity: # pod 親和力配置requiredDuringSchedulingIgnoredDuringExecution: # 當前 pod 必須匹配到對應條件 pod 所在的 node 上- labelSelector: # 標簽選擇器matchExpressions: # 匹配表達式- key: security # 匹配的 keyoperator: In # 匹配方式values: # 匹配其中的一個 value- S1topologyKey: topology.kubernetes.io/zonepodAntiAffinity: # pod 反親和力配置preferredDuringSchedulingIgnoredDuringExecution: # 盡量不要將當前節點部署到匹配下列參數的 pod 所在的 node 上- weight: 100 # 權重podAffinityTerm: # pod 親和力配置條件labelSelector: # 標簽選擇器matchExpressions: # 匹配表達式- key: security # 匹配的 keyoperator: In # 匹配的方式values:- S2 # 匹配的 valuetopologyKey: topology.kubernetes.io/zonecontainers:- name: with-pod-affinityimage: pause:2.0
總結
默認情況下,一個Pod在哪個Node節點上運行,是由Scheduler組件采用相應的算法計算出來的,這個過程是不受人工控制的。但是在實際使用中,這并不滿足的需求,我們想控制某些Pod到達某些節點上,就要求了解kubernetes對Pod的調度規則,kubernetes提供了四大類調度方式:
**自動調度:**運行在哪個節點上完全由Scheduler經過一系列的算法計算得出
**定向調度:**NodeName、NodeSelector
**親和性調度:**NodeAffinity、PodAffinity、PodAntiAffinity
**污點(容忍)調度:**Taints、Toleration