Kubernetes 資源配額使用指南
當(dāng) Kubernetes 集群運(yùn)行過(guò)一段時(shí)間或者在被開(kāi)發(fā)者大量使用后,Kubernetes 資源(例如 CPU 和內(nèi)存)的控制的問(wèn)題就會(huì)顯現(xiàn)出來(lái)。而在大多情況下只有集群出問(wèn)題后,我們才會(huì)意識(shí)到資源控制的重要性。
Kubernetes 部署過(guò)程如果沒(méi)有能充分考慮到將來(lái)的擴(kuò)展性,資源類問(wèn)題將會(huì)非常常見(jiàn),此類問(wèn)題與集群的管理和部署團(tuán)隊(duì)的經(jīng)驗(yàn)有關(guān)。
如果不加以合理控制,一個(gè)暴力的應(yīng)用或者開(kāi)發(fā)者可能影響到共享該集群的所有業(yè)務(wù),大家因此會(huì)相互埋怨、指責(zé)并保護(hù)性地?fù)屨假Y源。這對(duì)于集群管理和開(kāi)發(fā)人員都是非常難以處理的場(chǎng)景。
在 Kubernetes 環(huán)境中控制應(yīng)用的計(jì)算資源使用有多種方式。大部分情況下,我們可以使用“資源控制”和“限制范圍”。注意存儲(chǔ)管理不在我們討論范圍之內(nèi),存儲(chǔ)管理可以通過(guò)持久卷Persistent Volume 件,以實(shí)現(xiàn)針對(duì)不同的存儲(chǔ)控制需求。
資源配額是一種控制 Kubernetes 計(jì)算資源的方法。本文告訴你如何使用該功能來(lái)管理開(kāi)發(fā)人員行為并控制應(yīng)用的資源使用。
什么是資源配額
簡(jiǎn)而言之,資源配額 提供了限制每個(gè)命名空間資源消耗的約束條件,它們只能在命名空間級(jí)別上應(yīng)用,這意味著它們可以應(yīng)用于計(jì)算資源,并限制命名空間內(nèi)的對(duì)象數(shù)量。
Kubernetes資源配額通過(guò) ResourceQuota 對(duì)象來(lái)為每個(gè)命名空間設(shè)置資源配額,對(duì)以下對(duì)象類型的 CPU 和內(nèi)存進(jìn)行限制:
- 吊艙P(yáng)od
- 服務(wù)Service
- 機(jī)密信息Secret
- 持久卷斷言Persistent Volume Claim(PVC)
- 配置映射ConfigMap
Kubernetes 通過(guò) request 和 limit 兩個(gè)參數(shù)對(duì) CPU 和內(nèi)存進(jìn)行限制(參考 LimitRange 文檔)。前者表示容器最小被保證資源,后者表示容器最大可用資源。實(shí)際上最大可用資源還受限于其它容器的實(shí)際使用情況。
下一張圖片解釋了配額中 request 和 limit 的區(qū)別:
Requests and limits in Kubernetes resource quotas下面我們就通過(guò)一個(gè)例子來(lái)說(shuō)明如何設(shè)置資源配額來(lái)創(chuàng)建約束,將應(yīng)用程序限制在某些資源上,它還展示了實(shí)現(xiàn)資源配額以獲得對(duì) Kubernetes 的控制的有用性。
準(zhǔn)備環(huán)境
首先你需要一個(gè) Kubernetes 環(huán)境。以下是我使用 Kubernetes 環(huán)境:
- Minikube v1.14.2
- Fedora 33 操作系統(tǒng)
- 互聯(lián)網(wǎng)接入
如果你想在 Linux 機(jī)器上通過(guò) Minikube 搭建 Kubernetes 測(cè)試環(huán)境,可以參考 Bryant Son 的《Minikube 入門》 一文。Window 或者 macOS 用戶可以參考這篇文章。
設(shè)置資源配額
這里我們僅展示 CPU 配額設(shè)置步驟,配置內(nèi)存配額或兩者的組合與之類似。
在生產(chǎn)環(huán)境中,CPU 是最需要被控制的資源,尤其是在多應(yīng)用的場(chǎng)景下特別需要注意防止某些應(yīng)用消耗太多 CPU 而影響到其它應(yīng)用。
首先我們創(chuàng)建一個(gè)命名空間,在其中設(shè)置 CPU 配額:
- $ kubectl create namespace quota-test
- namespace/quota-test created
準(zhǔn)備 cpu-quota.yaml 文件,內(nèi)容如下:
- apiVersion: v1
- kind: ResourceQuota
- metadata:
- name: test-cpu-quota
- spec:
- hard:
- requests.cpu: "100m"
- limits.cpu: "200m"
應(yīng)用 CPU 配額到 Kubernetes 集群:
- $ kubectl apply -f cpu-qouta.yaml
- resourcequota/test-cpu-quota created
使用 kubectl describe 檢查配額配置情況:
- $ kubectl describe resourcequota/test-cpu-quota --namespace quota-test
- Name: test-cpu-quota
- Namespace: quota-test
- Resource Used Hard
- -------- ---- ----
- limits.cpu 0 200m
- requests.cpu 0 100m
在 Used resources 列中顯示了當(dāng)前情況,該列值會(huì)隨著吊艙P(yáng)od的部署而變化。
下面是我們來(lái)驗(yàn)證限額管理的場(chǎng)景。我們將在同一命名空間下部署三個(gè)不同的吊艙,為它們配置以不同的資源限制如下:
- PodA:第一個(gè)被實(shí)例化,使用 50% 可用 CPU 資源
- PodB:第二個(gè)被實(shí)例化,使用其余 50% 可用 CPU 資源
- PodC:沒(méi)有可用 CPU 資源,因此不會(huì)被部署
部署吊艙
PodA:
- $ kubectl create -n quota-test -f - << EOF
- apiVersion: v1
- kind: Pod
- metadata:
- name: poda
- spec:
- containers:
- - name: quota-test
- image: busybox
- imagePullPolicy: IfNotPresent
- command: ['sh', '-c', 'echo Pod is Running ; sleep 5000']
- resources:
- requests:
- cpu: "50m"
- limits:
- cpu: "100m"
- restartPolicy: Never
- EOF
部署 PodA 后,再次查看配額描述信息中的 Used CPU 信息:
- $ kubectl describe resourcequota/test-cpu-quota --namespace quota-test
- Name: test-cpu-quota
- Namespace: quota-test
- Resource Used Hard
- -------- ---- ----
- limits.cpu 100m 200m
- requests.cpu 50m 100m
PodB:
- $ kubectl create -n quota-test -f - << EOF
- apiVersion: v1
- kind: Pod
- metadata:
- name: podb
- spec:
- containers:
- - name: quota-test
- image: busybox
- imagePullPolicy: IfNotPresent
- command: ['sh', '-c', 'echo Pod is Running ; sleep 5000']
- resources:
- requests:
- cpu: "50m"
- limits:
- cpu: "100m"
- restartPolicy: Never
- EOF
再次查看 CPU 資源使用,此時(shí) PodB 啟動(dòng)后 CPU 限制已經(jīng)達(dá)到上限:
- $ kubectl describe resourcequota/test-cpu-quota --namespace quota-test
- Name: test-cpu-quota
- Namespace: quota-test
- Resource Used Hard
- -------- ---- ----
- limits.cpu 200m 200m
- requests.cpu 100m 100m
PodC:
試著創(chuàng)建 PodC,此時(shí) CPU 配額已經(jīng)被 PodA 和 PodB 用盡:
- $ kubectl create -n quota-test -f - << EOF
- apiVersion: v1
- kind: Pod
- metadata:
- name: podc
- spec:
- containers:
- - name: quota-test
- image: busybox
- imagePullPolicy: IfNotPresent
- command: ['sh', '-c', 'echo Pod is Running ; sleep 5000']
- resources:
- requests:
- cpu: "5m"
- limits:
- cpu: "10m"
- restartPolicy: Never
- EOF
正我們期望,第三個(gè) Pod 無(wú)法被啟動(dòng),配額限制了吊艙的創(chuàng)建:
- Error from server (Forbidden): error when creating "STDIN": pods "podc" is forbidden: exceeded quota: test-cpu-quota, requested: limits.cpu=10m,requests.cpu=5m, used: limits.cpu=200m,requests.cpu=100m, limited: limits.cpu=200m,requests.cpu=100m
如我們的例子所示,定義合理的資源配額限制開(kāi)發(fā)者行為對(duì) Kubernetes 管理十分重要。
清理
刪除剛才創(chuàng)建的命名空間 quota-test:
- $ kubectl delete -n quota-test
規(guī)劃資源配額
Kubernetes 中提供多種方式來(lái)控制資源的搶占和使用,合理的規(guī)劃和配置配額、限制范圍和其它原生參數(shù)對(duì)保持集群的穩(wěn)定性十分必要。
你應(yīng)該十分謹(jǐn)慎地控制計(jì)算資源的資源配額,特別是關(guān)鍵業(yè)務(wù)的生產(chǎn)應(yīng)用環(huán)境。
在規(guī)劃資源配額時(shí),開(kāi)發(fā)人員的參與很重要,需要他們預(yù)估并給出最合理的資源使用值。