k8s中的資源管理和排程
阿新 • • 發佈:2021-01-10
k8s中的Resource,目前支援型別:
臨時儲存功能(預設不啟動)啟動後Pod掛載的emptyDir不能超過sizeLimit、Container對本地臨時儲存的使用量不能超過其Limit、Pod對本地臨時儲存的使用量不能超過所有Container的Limit之和,否則會被驅逐
巨頁的request必須等於limit,多尺寸的巨頁預設不支援。
自定義資源的request必須等於limit。
Pod服務質量(Qos)配置
根據CPU、記憶體資源的需求,對Pod的服務質量進行分類:
memory上也會按照不同的Qos劃分OOMScore。物理機出現OOM時會優先kill掉OOMScore得分高的Pod。
Guaranteed:會配置預設的-998的OOMScore;
Burstable:會根據記憶體設計的大小和節點的關係(申請資源越多得分越低)來分配 2~999的OOMScore;
BestEffort:會固定分配1000的OOMScore
排程配置
(1)Pod進行Node選擇
在Pod的sepc中指定:
- cpu,單位為Core(此處1 Core實際指一個Hyperthread),1 millicore=0.001Core
- memory,單位Byte
- storage
- ephemeral-storage:容器日誌、emptyDir、可寫入的容器映象層
- hugepages-<size>:目前屬於Pod級別的資源
- 自定義資源(如GPU):配置時,指定的數量必須為整數。
- Guaranteed:Pod中每個容器都有CPU、記憶體的request以及limit宣告,且request=limit
- Burstable:CPU、記憶體的request≠limit,或者只填寫了其中一種資源
- BestEffort:沒有任何request和limit
nodeSelector: <object>(2)workload進行Node選擇 在workload的spec中通過matchLabels來篩選出一批Pod;通過matchExpressions來決定這批Pod的排程。
selector: matchLabels: <object> matchExpressions: <object>(3)Node禁止排程 在Node的sepc中指定:
unschedulable: true(3)Pod的拓撲排程 在Pod的spec中描述這一組Pod在某個topologyKey上的分佈 如果定義了多個,則是並列關係。比如說可以在一個zone級別上,也可以在一個Node級別上。
topologySpreadConstraints: - maxSkew: <integer> topologyKey: <string> whenUnsatisfiable: <string> labelSelector: <object>topologyKey為zone時,Pod將在zone間均勻分佈。沒有key為zone的Node將被忽略(位於這些Node上的Pod不會被計算,新Pod也不會啟動到這些Node上) maxSkew是最大允許不均衡的數量。如果設定為1,那麼Pod將在所有zone間完全均勻分佈。 舉例: 假設叢集中有三個zone,某個部署的Pod在zone1和zone2中都分配了一個Pod。 計算不均衡數量公式為:Skew = count[topo] - min(count[topo]),由此可以算出三個zone的Skew分別是1、1、0。 如果新Pod分配到zone1/zone2,zone1/zone2的skew將變為2,大於設定的maxSkew=1;如果分配到zone3的話,zone1-zone3的Skew均為0。因此新Pod只能分配到zone3 假設maxSkew為2,如果新Pod分配到zone1/zone2,skew 的值為2 <=maxSkew。因此zone1-zone3都是允許的。 在不均衡的情況下可以設定whenUnsatisfiable:在過濾階段一般設定為DoNotSchedule(不允許被排程),也可以設定為ScheduleAnyway(隨便排程) 在kube-scheduler配置檔案的profile中可以設定預設的PodTopologySpread:
apiVersion: kubescheduler.config.k8s.io/v1beta1
kind: KubeSchedulerConfiguration
profiles:
pluginConfig:
- name: PodTopologySpread
args:
defaultConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
Pod沒有配置PodTopologySpread時會自動使用此配置。
配置中沒有labelSelector,會根據service、rs等自動計算。因此Pod必須屬於某個資源物件。
開啟此預設配置時,最好禁用scheduler framework中的SelectorSpread外掛。
此時scheduler framework中的PodTopologySpread會使用如下預設配置:
defaultConstraints:
- maxSkew: 3
topologyKey: "kubernetes.io/hostname"
whenUnsatisfiable: ScheduleAnyway
- maxSkew: 5
topologyKey: "topology.kubernetes.io/zone"
whenUnsatisfiable: ScheduleAnyway
(4)Pod親和排程和反親和排程
Exists範圍比In更大。當Operator填了Exists,就不需要再填寫values,會直接禁止排程到帶該key標籤的Pod的節點。即,不管 values是什麼值,只要帶了k1這個key標籤的Pod所在節點,都不能排程過去。
優先排程和優先反排程時,preferred裡面可以是一個list選擇填上多個條件,每對key: kalue有不同的權重。排程器會優先把Pod分配到權重分更高的排程條件節點上去。
(5)Node親和排程
NodeSelector其實是一個map結構,在pod的spec.nodeSelector裡面直接寫上對node標籤key:value的要求即可。
NodeAffinity的Operator上提供了比 PodAffinity的Operator更豐富的內容。增加了Gt和Lt(數值比較,values只能填數字)。
(6)Node標記/容忍
例如上圖綠色部分,給demo-node打了taint後,效果是:新建的Pod沒有專門容忍這個taint,那就沒法排程到這個節點上。
除非如上圖藍色部分,在Pod上打一個key、value、effect完全相同的Pod Tolerations。
該特性目前已變為taints:使用cordon命令將節點標記為不可排程,使用drain命令將已經在節點上執行的pod驅逐到其他節點;uncordon命令解鎖節點,使其重新變得可排程
(7)優先順序搶佔排程
比如有一個Node的CPU已經被一個Pod佔用了。另一個高優先順序Pod來的時候,低優先順序的Pod應該把CPU讓給高優先順序的Pod使用。低優先順序的Pod需要回到等待佇列,或者是業務重新提交。
Kubernetes v1.14後,優先順序(PodPriority)和搶佔(Preemption)的特點變成了stable。並且預設開啟。