6 張配圖通俗易懂說(shuō)透 K8S 請(qǐng)求和限制
在 Kubernetes 中使用容器時(shí),了解涉及的資源是什么以及為何需要它們很重要。有些進(jìn)程比其他進(jìn)程需要更多的 CPU 或內(nèi)存。這很關(guān)鍵,永遠(yuǎn)不應(yīng)該讓進(jìn)程挨餓。知道了這一點(diǎn),我們應(yīng)該正確配置容器和 Pod,以便充分利用兩者。
Kubernetes 限制和請(qǐng)求簡(jiǎn)介
使用 Kubernetes 時(shí),限制和請(qǐng)求是重要的設(shè)置。本文將重點(diǎn)關(guān)注兩個(gè)最重要的:CPU 和內(nèi)存。
Kubernetes 將限制定義為 容器可以使用的**最大資源量。**這意味著容器永遠(yuǎn)不會(huì)消耗超過(guò)指示的內(nèi)存量或 CPU 量。
另一方面,請(qǐng)求是為容器保留的最低保證資源量。
示例
讓我們來(lái)看看這個(gè)部署,我們?cè)?CPU 和內(nèi)存上為兩個(gè)不同的容器設(shè)置限制和請(qǐng)求。
kind: Deployment
apiVersion: extensions/v1beta1
# …
template:
spec:
containers:
- name: redis
image: redis:5.0.3-alpine
resources:
limits:
memory: 600Mi
cpu: 1
requests:
memory: 300Mi
cpu: 500m
- name: busybox
image: busybox:1.28
resources:
limits:
memory: 200Mi
cpu: 300m
requests:
memory: 100Mi
cpu: 100m
假設(shè)我們正在運(yùn)行一個(gè)集群,例如,具有 4 核和 16GB RAM 節(jié)點(diǎn)。我們可以提取出很多信息:
- Pod 有效請(qǐng)求 是 400 MiB 內(nèi)存和 600 毫核 CPU。您需要一個(gè)具有足夠可用可分配空間的節(jié)點(diǎn)來(lái)調(diào)度 Pod。
- redis 容器的 CPU 份額 為 512,busybox 容器的 CPU 份額為 102。Kubernetes 總是為每個(gè)核心分配 1024 個(gè)份額,因此 redis:1024 * 0.5 個(gè)核心 ? 512 和 busybox:1024 * 0.1 個(gè)核心 ? 102
- 如果 Redis 容器嘗試分配超過(guò) 600MB 的 RAM,則它會(huì)被OOM 終止,很可能導(dǎo)致 pod 失敗。
- 如果 Redis 每 100 毫秒嘗試使用超過(guò) 100 毫秒的 CPU,(因?yàn)槲覀冇?4 個(gè)核,可用時(shí)間為每 100 毫秒 400 毫秒),Redis 將受到CPU 限制,從而導(dǎo)致性能下降。
- 如果 Busybox 容器試圖分配超過(guò) 200MB 的 RAM,它將被OOM 終止,從而導(dǎo)致 pod 失敗。
- 如果 Busybox 嘗試每 100 毫秒使用超過(guò) 30 毫秒的 CPU,它將遭受CPU 限制,從而導(dǎo)致性能下降。
Kubernetes 請(qǐng)求
Kubernetes 將請(qǐng)求定義為容器使用的保證最小資源量。
基本上,它將設(shè)置容器消耗的最小資源量。
當(dāng)一個(gè) Pod 被調(diào)度時(shí),kube-scheduler 將檢查 Kubernetes 請(qǐng)求,以便將它分配給一個(gè)特定的節(jié)點(diǎn),該節(jié)點(diǎn)至少可以滿足 Pod 中所有容器的數(shù)量。如果請(qǐng)求的數(shù)量高于可用資源,則 Pod 將不會(huì)被調(diào)度并保持在 Pending 狀態(tài)。
有關(guān)掛起(pending)
狀態(tài)的更多信息,請(qǐng)查看了解 Kubernetes Pod 掛起問(wèn)題:
https://sysdig.com/blog/kubernetes-pod-pending-problems/
在此示例中,在容器定義中我們?cè)O(shè)置了 100m CPU 核和 4Mi 內(nèi)存的請(qǐng)求:
resources:
requests:
cpu: 0.1
memory: 4Mi
使用請(qǐng)求:
- 將 Pod 分配給 Node 時(shí),滿足 Pod 中容器指示的請(qǐng)求。
- 在運(yùn)行時(shí),指示的請(qǐng)求量將保證為該 Pod 中的容器的最小請(qǐng)求量。
Kubernetes 限制
Kubernetes 將限制定義為容器可以使用的最大資源量。
這意味著容器永遠(yuǎn)不會(huì)消耗超過(guò)指示的內(nèi)存量或 CPU 量。
resources:
limits:
cpu: 0.5
memory: 100Mi
使用限制:
- 將 Pod 分配給節(jié)點(diǎn)時(shí)。如果沒(méi)有設(shè)置請(qǐng)求,默認(rèn)情況下,Kubernetes 將分配 requests = limits。
- 在運(yùn)行時(shí),Kubernetes 將檢查 Pod 中的容器是否消耗了比限制中指示的更多的資源。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-NymVkZha-1670471516534)(https://files.mdnice.com/user/23818/c5a5802c-73ed-42ee-a15c-509e6d4a1901.png)]
CPU 特性
CPU 是一種可壓縮資源,這意味著它可以被拉伸以滿足所有需求。如果進(jìn)程請(qǐng)求太多 CPU,其中一些將被限制。
CPU代表計(jì)算處理時(shí)間,以核為單位。
- 您可以使用 millicores (m) 來(lái)表示比核更小的數(shù)量(例如,500m 將是核的一半)
- 最小量為 1m
- 一個(gè)節(jié)點(diǎn)可能有多個(gè)可用核,因此請(qǐng)求 CPU > 1 是可能的
內(nèi)存特性
內(nèi)存是一種不可壓縮的資源,這意味著它不能像 CPU 那樣被拉伸。如果一個(gè)進(jìn)程沒(méi)有足夠的內(nèi)存來(lái)工作,這個(gè)進(jìn)程就會(huì)被殺死。
內(nèi)存在 Kubernetes 中以字節(jié)為單位。
- 您可以使用 E、P、T、G、M、k 來(lái)表示 Exabyte、Petabyte、Terabyte、Gigabyte、Megabyte 和 kilobyte,盡管通常只使用后四種。(例如,500M、4G)
- 警告:不要使用小寫(xiě)的 m 表示內(nèi)存(這代表 Millibytes,低得離譜)
- 您可以使用 Mi 定義 Mebibytes,其余定義為 Ei、Pi、Ti(例如 500Mi)
1 Mebibyte(及其類似物 Kibibyte、Gibibyte 等)是 2 的 20 次方字節(jié)。它的創(chuàng)建是為了避免與公制的 Kilo、Mega 定義混淆。您應(yīng)該使用這種表示法,因?yàn)樗亲止?jié)的規(guī)范定義,而 Kilo 和 Mega 是 1000 的倍數(shù)
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-5cve5zyG-1670471516538)(https://files.mdnice.com/user/23818/2f7f4a06-9863-449e-b9d2-c4e7d2cfec4c.png)]
最佳實(shí)踐
在極少數(shù)情況下,您應(yīng)該使用限制來(lái)控制 Kubernetes 中的資源使用。這是因?yàn)槿绻阆氡苊怵囸I(確保每個(gè)重要進(jìn)程都得到它的份額),你應(yīng)該首先使用請(qǐng)求。
通過(guò)設(shè)置限制,你只是防止進(jìn)程在異常情況下獲取額外的資源,在內(nèi)存的情況下導(dǎo)致 OOM kill,在 CPU 的情況下 Throttling(進(jìn)程將需要等待直到 CPU 可以再次使用)。
有關(guān)詳細(xì)信息,請(qǐng)查看有關(guān) OOM 和節(jié)流的文章:
https://sysdig.com/blog/troubleshoot-kubernetes-oom/
如果您將 Pod 的所有容器中的請(qǐng)求值設(shè)置為等于限制,則該 Pod 將獲得有保證的服務(wù)質(zhì)量。
另請(qǐng)注意,資源使用率高于請(qǐng)求的 Pod 更有可能被驅(qū)逐,因此設(shè)置非常低的請(qǐng)求弊大于利。有關(guān)更多信息,請(qǐng)查看有關(guān) Pod 驅(qū)逐和服務(wù)質(zhì)量的文章:
https://sysdig.com/blog/kubernetes-pod-evicted/
命名空間資源配額
多虧了命名空間,我們可以將 Kubernetes 資源隔離到不同的組中,也稱為租戶。
使用ResourceQuotas,您可以為整個(gè)命名空間設(shè)置內(nèi)存或 CPU 限制,確保其中的實(shí)體不能從該數(shù)量中消耗更多。
apiVersion: v1
kind: ResourceQuota
metadata:
name: mem-cpu-demo
spec:
hard:
requests.cpu: 2
requests.memory: 1Gi
limits.cpu: 3
limits.memory: 2Gi
- requests.cpu:此命名空間中所有請(qǐng)求總和的最大 CPU 量
- requests.memory:此命名空間中所有請(qǐng)求總和的最大內(nèi)存量
- limits.cpu:此命名空間中所有限制總和的最大 CPU 數(shù)量
- limits.memory:此命名空間中所有限制總和的最大內(nèi)存量
然后,將其應(yīng)用于您的命名空間:
kubectl apply -f resourcequota.yaml --namespace=mynamespace
您可以列出命名空間的當(dāng)前 ResourceQuota:
kubectl get resourcequota -n mynamespace
請(qǐng)注意,如果您為命名空間中的給定資源設(shè)置 ResourceQuota,則需要相應(yīng)地為該命名空間中的每個(gè) Pod 指定限制或請(qǐng)求。否則,Kubernetes 將返回“failed quota”錯(cuò)誤:
Error from server (Forbidden): error when creating "mypod.yaml": pods "mypod" is forbidden: failed quota: mem-cpu-demo: must specify limits.cpu,limits.memory,requests.cpu,requests.memory
如果您嘗試添加容器限制或請(qǐng)求超過(guò)當(dāng)前 ResourceQuota 的新 Pod,Kubernetes 將返回“超出配額”錯(cuò)誤:
Error from server (Forbidden): error when creating "mypod.yaml": pods "mypod" is forbidden: exceeded quota: mem-cpu-demo, requested: limits.memory=2Gi,requests.memory=2Gi, used: limits.memory=1Gi,requests.memory=1Gi, limited: limits.memory=2Gi,requests.memory=1Gi
命名空間限制范圍
如果我們想限制可分配給命名空間的資源總量,ResourceQuotas 很有用。但是如果我們想給里面的元素賦默認(rèn)值會(huì)怎樣呢?
LimitRanges是一種 Kubernetes 策略,用于限制命名空間中每個(gè)實(shí)體的資源設(shè)置。
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-resource-constraint
spec:
limits:
- default:
cpu: 500m
defaultRequest:
cpu: 500m
min:
cpu: 100m
max:
cpu: "1"
type: Container
-
default
: 如果未指定,創(chuàng)建的容器將具有此值。 -
min
:創(chuàng)建的容器不能有小于此的限制或請(qǐng)求。 -
max
: 創(chuàng)建的容器不能有比這更大的限制或請(qǐng)求。
稍后,如果您創(chuàng)建一個(gè)沒(méi)有設(shè)置請(qǐng)求或限制的新 Pod,LimitRange 會(huì)自動(dòng)將這些值設(shè)置到它的所有容器:
Limits:
cpu: 500m
Requests:
cpu: 100m
現(xiàn)在,假設(shè)您添加了一個(gè)限制為 1200M 的新 Pod。您將收到以下錯(cuò)誤:
Error from server (Forbidden): error when creating "pods/mypod.yaml": pods "mypod" is forbidden: maximum cpu usage per Container is 1, but limit is 1200m
請(qǐng)注意,默認(rèn)情況下,即使未設(shè)置 LimitRanges,Pod 中的所有容器也實(shí)際上請(qǐng)求 100m CPU。
結(jié)論
為 Kubernetes 集群選擇最佳限制是獲得最佳能耗和成本的關(guān)鍵。
為 Pod 規(guī)模過(guò)大或投入過(guò)多資源可能會(huì)導(dǎo)致成本飆升。
過(guò)小的規(guī)?;蛘咧徽加煤苌俚?CPU 或內(nèi)存將導(dǎo)致應(yīng)用程序不能正確執(zhí)行,甚至?xí)?qū)逐 Pods。
如前所述,可以不使用 Kubernetes 限制,除非在非常特殊的情況下,因?yàn)樗鼈兛赡鼙状笥诶?。在?nèi)存不足的情況下,容器有可能被殺死,或者在 CPU 不足的情況下,容器可能會(huì)被限制。
對(duì)于請(qǐng)求,當(dāng)您需要確保進(jìn)程獲得有保證的資源共享時(shí)請(qǐng)使用它。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-488387.html
譯自
作者:JAVIER MARTíNEZ
原文:https://sysdig.com/blog/kubernetes-limits-requests/文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-488387.html
到了這里,關(guān)于6 張配圖通俗易懂說(shuō)透 K8S 請(qǐng)求和限制的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!