[kubernetes] 资源管理 --- 资源预留实践
一 概述
1.1 問(wèn)題
系統(tǒng)資源可分為兩類:可壓縮資源(CPU)和不可壓縮資源(memory、storage)。可壓縮資源比如CPU超配后,在系統(tǒng)滿負(fù)荷時(shí)會(huì)劃分時(shí)間片分時(shí)運(yùn)行進(jìn)程,系統(tǒng)整體會(huì)變慢(一般不會(huì)導(dǎo)致太大的問(wèn)題)。但不可壓縮資源如Memory,當(dāng)系統(tǒng)內(nèi)存不足時(shí),就有可能觸發(fā)系統(tǒng) OOM;這時(shí)候根據(jù) oom score 來(lái)確定優(yōu)先殺死哪個(gè)進(jìn)程,而 oom_score_adj 又是影響 oom score 的重要參數(shù),其值越低,表示 oom 的優(yōu)先級(jí)越低。在計(jì)算節(jié)點(diǎn)中,進(jìn)程的 oom_score_adj 如下:
?
所以,OOM 的優(yōu)先級(jí)如下:
BestEffort Pod > Burstable Pod > 其它進(jìn)程 > Guaranteed Pod > kubelet/docker 等 > sshd 等
在Kubernetes平臺(tái),默認(rèn)情況下Pod能夠使用節(jié)點(diǎn)全部可用資源。如果節(jié)點(diǎn)上的Pod負(fù)載較大,那么這些Pod可能會(huì)與節(jié)點(diǎn)上的系統(tǒng)守護(hù)進(jìn)程和k8s組件爭(zhēng)奪資源并導(dǎo)致節(jié)點(diǎn)資源短缺,甚至引發(fā)系統(tǒng)OOM,導(dǎo)致某些進(jìn)程被Linux系統(tǒng)的OOM killer機(jī)制殺掉,假如被殺掉的進(jìn)程是系統(tǒng)進(jìn)程或K8S組件,會(huì)導(dǎo)致比較嚴(yán)重的問(wèn)題。
1.2 解決方案
針對(duì)這種問(wèn)題,主要有兩種解決方案(兩種也可以結(jié)合使用):
??? 啟用kubelet的Node Allocatable特性,為系統(tǒng)守護(hù)進(jìn)程和k8s組件預(yù)留資源。 官方文檔:https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources
??? 設(shè)置pod的驅(qū)逐策略,在pod使用資源到一定程度時(shí)進(jìn)行pod驅(qū)逐。官方文檔:https://kubernetes.io/docs/tasks/administer-cluster/out-of-resource/#eviction-policy
?
二? Kubelet Node Allocatable
kubelet的啟動(dòng)配置中有一個(gè)Node Allocatable特性,來(lái)為系統(tǒng)守護(hù)進(jìn)程和k8s組件預(yù)留計(jì)算資源,使得即使節(jié)點(diǎn)滿負(fù)載運(yùn)行時(shí),也不至于出現(xiàn)pod去和系統(tǒng)守護(hù)進(jìn)程以及k8s組件爭(zhēng)搶資源,導(dǎo)致節(jié)點(diǎn)掛掉的情況。kubernetes官方建議根據(jù)各個(gè)節(jié)點(diǎn)的負(fù)載情況來(lái)具體配置相關(guān)參數(shù)。
- Kubelet Node Allocatable用來(lái)為Kube組件和System進(jìn)程預(yù)留資源,從而保證當(dāng)節(jié)點(diǎn)出現(xiàn)滿負(fù)荷時(shí)也能保證Kube和System進(jìn)程有足夠的資源。
- 目前支持cpu, memory, ephemeral-storage三種資源預(yù)留。
- Node Capacity是Node的所有硬件資源,kube-reserved是給kube組件預(yù)留的資源,system-reserved是給System進(jìn)程預(yù)留的資源, eviction-threshold是kubelet eviction的閾值設(shè)定,allocatable才是真正scheduler調(diào)度Pod時(shí)的參考值(保證Node上所有Pods的request resource不超過(guò)Allocatable)。
- Node Allocatable Resource = Node Capacity - Kube-reserved - system-reserved - eviction-threshold
如何配置
- --enforce-node-allocatable,默認(rèn)為pods,要為kube組件和System進(jìn)程預(yù)留資源,則需要設(shè)置為pods,kube-reserved,system-reserve。
- --cgroups-per-qos,Enabling QoS and Pod level cgroups,默認(rèn)開啟。開啟后,kubelet會(huì)將管理所有workload Pods的cgroups。
- --cgroup-driver,默認(rèn)為cgroupfs,另一可選項(xiàng)為systemd。取決于容器運(yùn)行時(shí)使用的cgroup driver,kubelet與其保持一致。比如你配置docker使用systemd cgroup driver,那么kubelet也需要配置--cgroup-driver=systemd。
- --kube-reserved,用于配置為kube組件(kubelet,kube-proxy,dockerd等)預(yù)留的資源量,比如—kube-reserved=cpu=1000m,memory=8Gi,ephemeral-storage=16Gi。
- --kube-reserved-cgroup,如果你設(shè)置了--kube-reserved,那么請(qǐng)一定要設(shè)置對(duì)應(yīng)的cgroup,并且該cgroup目錄要事先創(chuàng)建好,否則kubelet將不會(huì)自動(dòng)創(chuàng)建導(dǎo)致kubelet啟動(dòng)失敗。比如設(shè)置為kube-reserved-cgroup=/kubelet.service 。
- --system-reserved,用于配置為System進(jìn)程預(yù)留的資源量,比如—system-reserved=cpu=500m,memory=4Gi,ephemeral-storage=4Gi。
- --system-reserved-cgroup,如果你設(shè)置了--system-reserved,那么請(qǐng)一定要設(shè)置對(duì)應(yīng)的cgroup,并且該cgroup目錄要事先創(chuàng)建好,否則kubelet將不會(huì)自動(dòng)創(chuàng)建導(dǎo)致kubelet啟動(dòng)失敗。比如設(shè)置為system-reserved-cgroup=/system.slice。
- --eviction-hard,用來(lái)配置kubelet的hard eviction條件,只支持memory和ephemeral-storage兩種不可壓縮資源。當(dāng)出現(xiàn)MemoryPressure時(shí),Scheduler不會(huì)調(diào)度新的Best-Effort QoS Pods到此節(jié)點(diǎn)。當(dāng)出現(xiàn)DiskPressure時(shí),Scheduler不會(huì)調(diào)度任何新Pods到此節(jié)點(diǎn)。關(guān)于Kubelet Eviction的更多解讀,請(qǐng)參考我的相關(guān)博文。
- Kubelet Node Allocatable的代碼很簡(jiǎn)單,主要在pkg/kubelet/cm/node_container_manager.go,感興趣的同學(xué)自己去走讀一遍。
?
3. 實(shí)踐
根據(jù)是否對(duì)system和kube做cgroup上的硬限制進(jìn)行劃分,資源預(yù)留主要有兩種方式:
- 只對(duì)所有pod使用的資源總量做cgroup級(jí)別的限制,對(duì)system和kube不做cgroup級(jí)別限制
- 對(duì)pod、system、kube均分別做cgroup級(jí)別限制
方式1—只限制pod資源總量
1? 將以下內(nèi)容添加到kubelet的啟動(dòng)參數(shù)中:
--enforce-node-allocatable=pods \
--cgroup-driver=cgroupfs \
--kube-reserved=cpu=1,memory=1Gi,ephemeral-storage=10Gi \
--system-reserved=cpu=1,memory=2Gi,ephemeral-storage=10Gi \
--eviction-hard=memory.available<500Mi,nodefs.available<10%
按以上設(shè)置
??? 節(jié)點(diǎn)上可供Pod所request的資源總和allocatable計(jì)算如下:
??? allocatable = capacity - kube-reserved - system-reserved - eviction-hard
??? 節(jié)點(diǎn)上所有Pod實(shí)際使用的資源總和不會(huì)超過(guò):
??? capacity - kube-reserved - system-reserved
2. 重啟kubelet
service kubelet restart
3. 驗(yàn)證
1.驗(yàn)證公式計(jì)算的allocatable與實(shí)際一致
通過(guò)kubectl describe node查看節(jié)點(diǎn)實(shí)際capacity及allocatable的值
Capacity:cpu: 8memory: 32930152Ki(約31.4G)pods: 110 Allocatable:cpu: 6memory: 29272424Ki(約27.9G)pods: 110根據(jù)公式capacity - kube-reserved - system-reserved - eviction-hard,memory的allocatable的值為31.4G - 1G - 2G - 0.5G = 27.9G,與Allocatable的值一致。
2.驗(yàn)證公式計(jì)算的總使用量限制與實(shí)際值一致
查看kubepods控制組中對(duì)內(nèi)存的限制值memory.limit_in_bytes(memory.limit_in_bytes值決定了Node上所有的Pod實(shí)際能使用的內(nèi)存上限)
$ cat /sys/fs/cgroup/memory/kubepods/memory.limit_in_bytes
30499250176(約28.4G)
根據(jù)公式capacity - kube-reserved - system-reserved,Node上Pod能實(shí)際使用的資源上限值為:31.4G - 1G -2G = 28.4G,與實(shí)際一致。
?
方式2—同時(shí)限制pod、k8s系統(tǒng)組件、linux系統(tǒng)守護(hù)進(jìn)程資源
配置過(guò)程
1.將以下內(nèi)容添加到kubelet的啟動(dòng)參數(shù)中:
--enforce-node-allocatable=pods,kube-reserved,system-reserved \
--cgroup-driver=cgroupfs \
--kube-reserved=cpu=1,memory=1Gi,ephemeral-storage=10Gi \
--kube-reserved-cgroup=/system.slice/kubelet.service \
--system-reserved cpu=1,memory=2Gi,ephemeral-storage=10Gi \
--system-reserved-cgroup=/system.slice \
--eviction-hard=memory.available<500Mi,nodefs.available<10%
至于如何設(shè)置cgroup結(jié)構(gòu),請(qǐng)參考官方建議。
2.為system.slice創(chuàng)建cpuset子系統(tǒng):
mkdir -p /sys/fs/cgroup/cpuset/system.slice/kubelet.service
mkdir -p /sys/fs/cgroup/pids/system.slice/kubelet.service
mkdir -p /sys/fs/cgroup/devices/system.slice/kubelet.service
mkdir -p /sys/fs/cgroup/memory/system.slice/kubelet.service
mkdir -p /sys/fs/cgroup/hugetlb/system.slice/kubelet.service
mkdir -p /sys/fs/cgroup/cpu,cpuacct/system.slice/kubelet.service
mkdir -p /sys/fs/cgroup/blkio/system.slice/kubelet.service
mkdir -p /sys/fs/cgroup/systemd/system.slice/kubelet.service
備注:這一步手工創(chuàng)建,否則啟動(dòng)kubelet會(huì)報(bào)找不到相應(yīng)cgroup的錯(cuò)誤。
1. 可以看到未創(chuàng)建前system.slice這個(gè)cgroup是沒(méi)有cpuset子系統(tǒng)的:
find /sys/fs/cgroup -name system.slice
/sys/fs/cgroup/devices/system.slice/sys/fs/cgroup/memory/system.slice/sys/fs/cgroup/blkio/system.slice/sys/fs/cgroup/cpu,cpuacct/system.slice/sys/fs/cgroup/systemd/system.slice?
2. 可以看到未創(chuàng)建前kubelet是沒(méi)有cpuset子系統(tǒng)的:
find /sys/fs/cgroup -name kubelet.service
??
3.重啟kubelet
驗(yàn)證過(guò)程
這種情況下pod可分配的資源和實(shí)際可使用資源理論上與方法一的計(jì)算方式和結(jié)果是一樣的,實(shí)際實(shí)驗(yàn)中也是一樣的,在這里不做贅述。重點(diǎn)驗(yàn)證此情況下是否對(duì)k8s系統(tǒng)組件和linux系統(tǒng)守護(hù)進(jìn)程做了cgroup硬限制。
查看system.slice控制組中對(duì)內(nèi)存的限制值memory.limit_in_bytes:
$ cat /sys/fs/cgroup/memory/system.slice/memory.limit_in_bytes
2147483648(2G)
查看kubelet.service控制組中對(duì)內(nèi)存的限制值memory.limit_in_bytes:
$ cat /sys/fs/cgroup/memory/system.slice/kubelet.service/memory.limit_in_bytes
1073741824(1G)
可以看到,方法2這種預(yù)留方式,對(duì)k8s組件和系統(tǒng)進(jìn)程也做了cgroup硬限制,當(dāng)k8s組件和系統(tǒng)組件資源使用量超過(guò)這個(gè)限制時(shí),會(huì)出現(xiàn)這些進(jìn)程被殺掉的情況。
?
例子
以如下的kubelet資源預(yù)留為例,Node Capacity為memory=32Gi, cpu=16, ephemeral-storage=100Gi,我們對(duì)kubelet進(jìn)行如下配置:
--enforce-node-allocatable=pods,kube-reserved,system-reserved --kube-reserved-cgroup=/system.slice/kubelet.service --system-reserved-cgroup=/system.slice --kube-reserved=cpu=1,memory=2Gi,ephemeral-storage=1Gi --system-reserved=cpu=1,memory=1Gi,ephemeral-storage=1Gi --eviction-hard=memory.available<500Mi,nodefs.available<10%NodeAllocatable = NodeCapacity - Kube-reserved - system-reserved - eviction-threshold =
cpu=14, memory=28Gi ephemeral-storage=98Gi.
Scheduler會(huì)確保Node上所有的Pod Resource Request不超過(guò)NodeAllocatable。Pods所使用的memory和storage之和超過(guò)NodeAllocatable后就會(huì)觸發(fā)kubelet Evict Pods。
?
參考:
https://my.oschina.net/jxcdwangtao/blog/1629059
https://blog.csdn.net/liukuan73/article/details/81054961
https://blog.csdn.net/liukuan73/article/details/82024085
?
總結(jié)
以上是生活随笔為你收集整理的[kubernetes] 资源管理 --- 资源预留实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Win10系统键盘无法打字怎么办(教你固
- 下一篇: [机器学习] TF-IDF算法