一文搞懂Kubernetes的Limits和Requests
當(dāng)在Kubernetes中使用容器時(shí),重要的是要知道所涉及的資源是什么以及如何需要它們。有些進(jìn)程比其他進(jìn)程需要更多的CPU或內(nèi)存。有些是關(guān)鍵的,不應(yīng)該被餓死。
知道了這一點(diǎn),我們應(yīng)該正確配置我們的容器和Pod,以獲得兩者的最佳效果。
在這篇文章中,我們將看到。
- Kubernetes 的Limits和Requests介紹
- 實(shí)踐案例
- Kubernetes Requests
- Kubernetes Limits
- CPU的特殊性
- 內(nèi)存的特殊性
- Namespace ResourceQuta
- Namespace LimitRange
- 總結(jié)
Kubernetes的Limits和Requests介紹
在使用Kubernetes時(shí),Limits和Requests是重要的配置,主要包含CPU和內(nèi)存的配置。
Kubernetes將Limits定義為一個(gè)容器使用的最大資源量,這意味著容器的消耗量永遠(yuǎn)不能超過所顯示的內(nèi)存量或CPU量。
另一方面,Requests是指為容器保留的資源的最小保證量。
image.png
實(shí)踐案例
讓我們來看看下面這個(gè)deployment,我們需要為兩個(gè)不同的容器在CPU和內(nèi)存上設(shè)置Limits和Requests。
假如,我們要把該deployment部署到4C16G配置的節(jié)點(diǎn)上,可以得到如下信息。
- Pod的有效請(qǐng)求是400 MiB的內(nèi)存和600 millicores的CPU,你需要一個(gè)有足夠自由可分配空間的節(jié)點(diǎn)來安排pod。
- Redis容器的CPU份額將是512,而busybox容器是102,Kubernetes總是為每個(gè)核心分配1024個(gè)份額,因此redis:1024 * 0.5 cores ? 512和busybox:1024 * 0.1核 ? 102
- 如果Redis容器試圖分配超過600MB的RAM,它將被OOM殺死,很可能使pod失敗。
- 如果Redis試圖在每100ms內(nèi)使用超過100ms的CPU,(因?yàn)槲覀冇?個(gè)核心,可用時(shí)間為每100ms 400ms),它將遭受CPU節(jié)流,導(dǎo)致性能下降。
- 如果Busybox容器試圖分配超過200MB的RAM,它將被OOM殺死,導(dǎo)致一個(gè)失敗的Pod。
- 如果Busybox試圖每100ms使用超過30ms的CPU,它將遭受CPU節(jié)流,導(dǎo)致性能下降。
Kubernetes Requests
Kubernetes將請(qǐng)求定義為容器使用的資源的最低保證量。
基本上,它將設(shè)定容器所要消耗的資源的最小數(shù)量。
當(dāng)一個(gè)Pod被調(diào)度時(shí),kube-scheduler將檢查Kubernetes請(qǐng)求,以便將其分配給一個(gè)特定的節(jié)點(diǎn):該節(jié)點(diǎn)至少可以滿足Pod中所有容器的這個(gè)數(shù)量。如果請(qǐng)求的數(shù)量高于可用的資源,Pod將不會(huì)被安排,并保持在Pending狀態(tài)。
關(guān)于Pending狀態(tài)的更多信息,請(qǐng)查看Understanding Kubernetes Pod pending problems【1】。
在這個(gè)例子中,在容器定義中,我們?cè)O(shè)置了一個(gè)請(qǐng)求,要求100m核心的CPU和4Mi的內(nèi)存。
Requests通常被使用在以下場(chǎng)景:
- 當(dāng)把Pod分配給一個(gè)節(jié)點(diǎn)時(shí),所以Pod中的容器的指定請(qǐng)求被滿足。
- 在運(yùn)行時(shí),指定的請(qǐng)求量將被保證為該P(yáng)od中的容器的最小值。
Kubernetes Limits
Kubernetes將Limits定義為一個(gè)容器使用的最大資源量。
這意味著容器的消耗量永遠(yuǎn)不能超過指定的內(nèi)存量或CPU量。
Limits通常用于以下場(chǎng)景:
- 當(dāng)把Pod分配給一個(gè)節(jié)點(diǎn)時(shí),如果沒有設(shè)置請(qǐng)求,默認(rèn)情況下,Kubernetes將分配請(qǐng)求=限制。
- 在運(yùn)行時(shí),Kubernetes將檢查Pod中的容器所消耗的資源量是否高于限制所顯示的數(shù)量。
CPU的特性
CPU是一種可壓縮的資源,這意味著它可以被拉伸,以滿足所有的需求。如果進(jìn)程要求太多的CPU,其中一些將被節(jié)制。
CPU代表計(jì)算處理時(shí)間,以核為單位。
- 你可以用毫微米(m)來表示比一個(gè)核心更小的數(shù)量(例如,500米是半個(gè)核心)。
- 最小的數(shù)量是1m
- 一個(gè)節(jié)點(diǎn)可能有一個(gè)以上的核心可用,所以請(qǐng)求CPU>1是可能的
內(nèi)存的特性
內(nèi)存是一種不可壓縮的資源,意味著它不能像CPU那樣被拉伸。如果一個(gè)進(jìn)程沒有得到足夠的內(nèi)存來工作,這個(gè)進(jìn)程就會(huì)被殺死。
在Kubernetes中,內(nèi)存的單位是字節(jié)。
- 你可以用,E,P,T,G,M,k來代表Exabyte,Petabyte,Terabyte,Gigabyte,Megabyte和kilobyte,盡管只有最后四個(gè)是常用的。(例如,500M, 4G)
- 警告:不要用小寫的m表示內(nèi)存(這代表Millibytes,低得離譜)
- 你可以用Mi來定義Mebibytes,其余的也可以用Ei、Pi、Ti來定義(例如,500Mi)
!! 一個(gè)Mebibyte(以及它們的類似物Kibibyte、Gibibyte...)是20字節(jié)的2次方。它的出現(xiàn)是為了避免與公制中的Kilo、Mega定義相混淆。你應(yīng)該使用這個(gè)符號(hào),因?yàn)樗亲止?jié)的典型定義,而Kilo和Mega是1000的倍數(shù)。
最佳實(shí)踐
在Kubernetes中,你應(yīng)該很少使用限制來控制你的資源使用。這是因?yàn)槿绻阆氡苊怵囸I(確保每個(gè)重要的進(jìn)程都能得到它的份額),你應(yīng)該首先使用請(qǐng)求。
通過設(shè)置限制,你只是防止進(jìn)程在特殊情況下檢索額外的資源,在內(nèi)存方面造成OOM殺戮,在CPU方面造成Throttling(進(jìn)程將需要等待CPU可以再次使用)。
欲了解更多信息,請(qǐng)查看article about OOM and Throttling【2】。
如果你在一個(gè)Pod的所有容器中設(shè)置一個(gè)等于限制的請(qǐng)求值,該P(yáng)od將獲得保證的服務(wù)質(zhì)量。
還需要注意的是,資源使用量高于請(qǐng)求的Pod更有可能被驅(qū)逐,所以設(shè)置非常低的請(qǐng)求會(huì)造成弊大于利??梢栽赑od eviction and Quality of Service【3】查看。
Namespace ResourceQuata
由于命名空間的存在,我們可以將Kubernetes資源隔離到不同的組,也稱為租戶。
通過ResourceQuota,你可以為整個(gè)命名空間設(shè)置一個(gè)內(nèi)存或CPU限制,確保其中的實(shí)體不能消耗超過這個(gè)數(shù)量。
- requests.cpu:這個(gè)命名空間中所有請(qǐng)求的最大CPU數(shù)量。
- requests.memory:這個(gè)命名空間中所有請(qǐng)求的最大內(nèi)存量。
- limits.cpu:這個(gè)命名空間中所有限制的最大CPU數(shù)量。
- limits.memory:這個(gè)命名空間中所有限制的總和的最大內(nèi)存量。
然后,將其應(yīng)用于你的命名空間。
你可以用以下方法列出一個(gè)命名空間的當(dāng)前ResourceQuota。
注意,如果你為命名空間中的特定資源設(shè)置了ResourceQuota,那么你就需要為該命名空間中的每個(gè)Pod指定相應(yīng)的限制或請(qǐng)求。否則,Kubernetes將返回一個(gè) "failed quota"的錯(cuò)誤。
如果你試圖添加一個(gè)新的Pod,其容器限制或請(qǐng)求超過了當(dāng)前的ResourceQuota,Kubernetes將返回一個(gè) "exceeded quota "的錯(cuò)誤。
Namespace LimitRange
如果我們想限制一個(gè)命名空間可分配的資源總量,ResourceQuotas很有用。但如果我們想給里面的元素提供默認(rèn)值,會(huì)發(fā)生什么?
LimitRanges是一種Kubernetes策略,它限制了命名空間中每個(gè)實(shí)體的資源設(shè)置。
- default。如果沒有指定,創(chuàng)建的容器將有這個(gè)值。
- min: 創(chuàng)建的容器不能有比這更小的限制或請(qǐng)求。
- max: 創(chuàng)建的容器不能有大于此值的限制或請(qǐng)求。
以后,如果你創(chuàng)建一個(gè)沒有設(shè)置請(qǐng)求或限制的新Pod,LimitRange會(huì)自動(dòng)為其所有的容器設(shè)置這些值。
現(xiàn)在,想象一下,你添加一個(gè)新的Pod,以1200M為限。你會(huì)收到以下錯(cuò)誤。
請(qǐng)注意,默認(rèn)情況下,Pod中的所有容器將有效地?fù)碛?00m CPU的請(qǐng)求,即使沒有設(shè)置LimitRanges。
總結(jié)
為我們的Kubernetes集群選擇最佳限制是關(guān)鍵,以便獲得最佳的能源消耗和成本。
為我們的Pod分配過多的資源可能會(huì)導(dǎo)致成本激增。
規(guī)模過小或?qū)S糜跇O少的CPU或內(nèi)存將導(dǎo)致應(yīng)用程序不能正常運(yùn)行,甚至Pod被驅(qū)逐。
如前所述,除非在非常特殊的情況下,否則不應(yīng)該使用Kubernetes限制,因?yàn)樗鼈兛赡軙?huì)造成更大的傷害。在內(nèi)存不足的情況下,容器有可能被殺死,在CPU不足的情況下,容器有可能被節(jié)流。
對(duì)于請(qǐng)求,當(dāng)你需要確保一個(gè)進(jìn)程獲得一個(gè)有保障的資源份額時(shí),可以使用它們。
文檔
【1】https://sysdig.com/blog/kubernetes-pod-pending-problems/
【2】https://sysdig.com/blog/troubleshoot-kubernetes-oom/
【3】?https://sysdig.com/blog/kubernetes-pod-evicted/
原文:https://sysdig.com/blog/kubernetes-limits-requests/作者:JAVIER MARTíNEZ