Kubernetes集群多租戶資源管理
1.概述
先講解Pod的兩個(gè)重要參數(shù):CPU Request與Memory Request。在大多數(shù)情況下我們?cè)诙xPod時(shí)并沒(méi)有定義這兩個(gè)參數(shù),此時(shí)Kubernetes會(huì)認(rèn)為該P(yáng)od所需的資源很少,并可以將其調(diào)度到任何可用的Node上。這樣一來(lái),當(dāng)集群中的計(jì)算資源不很充足時(shí),如果集群中的Pod負(fù)載突然加大,就會(huì)使某個(gè)Node的資源嚴(yán)重不足。
為了避免系統(tǒng)掛掉,該Node會(huì)選擇“清理”某些Pod來(lái)釋放資源,此時(shí)每個(gè)Pod都可能成為犧牲品。但有些Pod擔(dān)負(fù)著更重要的職責(zé),比其他Pod更重要,比如與數(shù)據(jù)存儲(chǔ)相關(guān)的、與登錄相關(guān)的、與查詢余額相關(guān)的,即使系統(tǒng)資源嚴(yán)重不足,也需要保障這些Pod的存活,Kubernetes中該保障機(jī)制的核心如下。
- 通過(guò)資源限額來(lái)確保不同的Pod只能占用指定的資源
- 允許集群的資源被超額分配,以提高集群的資源利用率
- 為Pod劃分等級(jí),確保不同等級(jí)的Pod有不同的服務(wù)質(zhì)量(QoS),資源不足時(shí),低等級(jí)的Pod會(huì)被清理,以確保高等級(jí)的Pod穩(wěn)定運(yùn)行
Kubernetes集群里的節(jié)點(diǎn)提供的資源主要是計(jì)算資源,計(jì)算資源是可計(jì)量的能被申請(qǐng)、分配和使用的基礎(chǔ)資源,這使之區(qū)別于API資源(API Resources,例如Pod和Services等)。當(dāng)前Kubernetes集群中的計(jì)算資源主要包括CPU、GPU及Memory,絕大多數(shù)常規(guī)應(yīng)用是用不到GPU的,因此這里重點(diǎn)介紹CPU與Memory的資源管理問(wèn)題
CPU與Memory是被Pod使用的,因此在配置Pod時(shí)可以通過(guò)參數(shù)CPU Request及Memory Request為其中的每個(gè)容器指定所需使用的CPU與Memory量,Kubernetes會(huì)根據(jù)Request的值去查找有足夠資源的Node來(lái)調(diào)度此Pod,如果沒(méi)有,則調(diào)度失敗。
2.Pod資源使用規(guī)范
我們知道,一個(gè)pod所使用的CPU與Memory是一個(gè)動(dòng)態(tài)的量,確切地說(shuō),是一個(gè)范圍,跟它的負(fù)載密切相關(guān):負(fù)載增加時(shí),CPU和Memory的使用量也會(huì)增加。因此最準(zhǔn)確的說(shuō)法是,某個(gè)進(jìn)程的CPU使用量為0.1個(gè)CPU~1個(gè)CPU,內(nèi)存占用則為500MB~1GB。對(duì)應(yīng)到Kubernetes的Pod容器上,cpu和Memory 分別有兩個(gè)限制:
- Requests 表示業(yè)務(wù)正常運(yùn)行所需要資源 屬于預(yù)留資源
- Limit 表示業(yè)務(wù)最大使用資源 該值為不保障資源 資源足夠情況下最大使用資源值
其中CPU 為可壓縮資源 按照時(shí)間片進(jìn)行調(diào)度,Memory 為不可壓縮資源 屬于硬限制資源類型,limits對(duì)應(yīng)資源量的上限,即最多允許使用這個(gè)上限的資源量。由于CPU資源是可壓縮的,進(jìn)程無(wú)論如何也不可能突破上限,因此設(shè)置起來(lái)比較容易。對(duì)于Memory這種不可壓縮資源來(lái)說(shuō),它的Limit設(shè)置就是一個(gè)問(wèn)題了,如果設(shè)置得小了,當(dāng)進(jìn)程在業(yè)務(wù)繁忙期試圖請(qǐng)求超過(guò)Limit限制的Memory時(shí),此進(jìn)程就會(huì)被Kubernetes殺掉。因此,Memory的Request與Limit的值需要結(jié)合進(jìn)程的實(shí)際需求謹(jǐn)慎設(shè)置。如果不設(shè)置CPU或Memory的Limit值,會(huì)怎樣呢?在這種情況下,該P(yáng)od的資源使用量有一個(gè)彈性范圍,我們不用絞盡腦汁去思考這兩個(gè)Limit的合理值,但問(wèn)題也來(lái)了,考慮下面的例子:
Pod A的Memory Request被設(shè)置為1GB,Node A當(dāng)時(shí)空閑的Memory為1.2GB,符合Pod A的需求,因此Pod A被調(diào)度到Node A上。運(yùn)行3天后,Pod A的訪問(wèn)請(qǐng)求大增,內(nèi)存需要增加到1.5GB,此時(shí)Node A的剩余內(nèi)存只有200MB,由于PodA新增的內(nèi)存已經(jīng)超出系統(tǒng)資源,所以在這種情況下,Pod A就會(huì)被Kubernetes殺掉。
沒(méi)有設(shè)置Limit的Pod,或者只設(shè)置了CPU Limit或者M(jìn)emory Limit兩者之一的Pod,表面看都是很有彈性的,但實(shí)際上,相對(duì)于4個(gè)參數(shù)都被設(shè)置的Pod,是處于一種相對(duì)不穩(wěn)定的狀態(tài)的,它們與4個(gè)參數(shù)都沒(méi)設(shè)置的Pod相比,只是穩(wěn)定一點(diǎn)而已。理解了這一點(diǎn),就很容易理解Resource QoS問(wèn)題了。
如果我們有成百上千個(gè)不同的Pod,那么先手動(dòng)設(shè)置每個(gè)Pod的這4個(gè)參數(shù),再檢查并確保這些參數(shù)的設(shè)置,都是合理的。比如不能出現(xiàn)內(nèi)存超過(guò)2GB或者CPU占據(jù)2個(gè)核心的Pod。最后還得手工檢查不同租戶(Namespace)下的Pod的資源使用量是否超過(guò)限額。為此,Kubernetes提供了另外兩個(gè)相關(guān)對(duì)象:LimitRange及ResourceQuota,前者解決request與limit參數(shù)的默認(rèn)值和合法取值范圍等問(wèn)題,后者則解決約束租戶的資源配額問(wèn)題。
- CPU 相關(guān)規(guī)則如下:
單位m,10m=0.01核,1核=1000m
Requests 根據(jù)業(yè)務(wù)實(shí)際使用量進(jìn)行預(yù)估填寫
Limits = Requests * 20% + Requests
- Memory 相關(guān)規(guī)則如下:
單位Mi 1024Mi=1G內(nèi)存
Requests 根據(jù)業(yè)務(wù)實(shí)際使用量進(jìn)行預(yù)估填寫
Limits = Requests * 20% + Requests
3.Namespace資源管理規(guī)范
業(yè)務(wù)實(shí)際Requests Limit 不超過(guò)整體80% 防止業(yè)務(wù)滾動(dòng)更新無(wú)足夠資源創(chuàng)建Pod
3.1 多租戶資源使用策略
通過(guò)ResourceQuota限制對(duì)應(yīng)項(xiàng)目組資源用量
3.2 資源用量變更流程
4.資源監(jiān)控及檢查
4.1 資源使用監(jiān)控
- Namespace Reuqests資源使用率
- sum (kube_resourcequota{type="used",resource="requests.cpu"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="requests.cpu"}) by (resource,namespace) * 100
- sum (kube_resourcequota{type="used",resource="requests.memory"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="requests.memory"}) by (resource,namespace) * 100
- Namespace Limit資源使用率
- sum (kube_resourcequota{type="used",resource="limits.cpu"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="limits.cpu"}) by (resource,namespace) * 100
- sum (kube_resourcequota{type="used",resource="limits.memory"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="limits.memory"}) by (resource,namespace) * 100
4.2 通過(guò)Grafana 進(jìn)行查看
- CPU請(qǐng)求率
- sum (kube_resourcequota{type="used",resource="requests.cpu",namespace=~"$NameSpace"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="requests.cpu",namespace=~"$NameSpace"}) by (resource,namespace)
- 內(nèi)存請(qǐng)求率
- sum (kube_resourcequota{type="used",resource="requests.memory",namespace=~"$NameSpace"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="requests.memory",namespace=~"$NameSpace"}) by (resource,namespace)
- CPU限制率
- sum (kube_resourcequota{type="used",resource="limits.cpu"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="limits.cpu"}) by (resource,namespace)
- 內(nèi)存限制率
- sum (kube_resourcequota{type="used",resource="limits.memory"}) by (resource,namespace) / sum (kube_resourcequota{type="hard",resource="limits.memory"}) by (resource,namespace)
4.3 集群內(nèi)查看資源使用
- 查看資源使用量
- [root@k8s-dev-slave04 yaml]# kubectl describe resourcequotas -n cloudchain--staging
- Name: mem-cpu-demo
- Namespace: cloudchain--staging
- Resource Used Hard
- -------- ---- ----
- limits.cpu 200m 500m
- limits.memory 200Mi 500Mi
- requests.cpu 150m 250m
- requests.memory 150Mi 250Mi
- 查看event事件 判斷是否正常創(chuàng)建
- [root@kevin ~]# kubectl get event -n default
- LAST SEEN TYPE REASON OBJECT MESSAGE
- 46m Warning FailedCreate replicaset/hpatest-57965d8c84 Error creating: pods "hpatest-57965d8c84-s78x6" is forbidden: exceeded quota: mem-cpu-demo, requested: limits.cpu=400m,limits.memory=400Mi, used: limits.cpu=200m,limits.memory=200Mi, limited: limits.cpu=500m,limits.memory=500Mi
- 29m Warning FailedCreate replicaset/hpatest-57965d8c84 Error creating: pods "hpatest-57965d8c84-5w6lk" is forbidden: exceeded quota: mem-cpu-demo, requested: limits.cpu=400m,limits.memory=400Mi, used: limits.cpu=200m,limits.memory=200Mi, limited: limits.cpu=500m,limits.memory=500Mi
- 13m Warning FailedCreate replicaset/hpatest-57965d8c84 Error creating: pods "hpatest-57965d8c84-w2qvz" is forbidden: exceeded quota: mem-cpu-demo, requested: limits.cpu=400m,limits.memory=400Mi, used: limits.cpu=200m,limits.memory=200Mi, limited: limits.cpu=500m,limits.memory=500Mi
本文轉(zhuǎn)載自微信公眾號(hào)「運(yùn)維開(kāi)發(fā)故事」
































