Kubernetes No CPU Limit:不限制 CPU 可能會更好
介紹
Kubernetes 是一個開源容器編排平臺,可幫助編排您的容器化應(yīng)用程序。使用Kubernetes之后 ,無需擔(dān)心應(yīng)用程序的擴(kuò)展和可用性。在將應(yīng)用程序遷移到Kubernetes 集群之前,集群需要擁有災(zāi)難恢復(fù)的高可用性,以及安全、可擴(kuò)展和優(yōu)化的特性。
Kubernetes 利用來自底層虛擬機(jī)或物理機(jī)的資源,然后由各個容器使用。最常見的資源是 CPU 和 RAM,還有其他資源。如果需要,Kubernetes 可以限制這些資源及其容器對它們的消耗。對容器的 CPU/Memory 使用設(shè)置限制是一種普遍的做法。
CPU/Memory 限制是容器可以使用的最大 CPU/Memory。它限制容器使用節(jié)點上所有可用的 CPU/Memory。因此,從理論上講,這聽起來不錯,可以保護(hù)節(jié)點不會耗盡資源并變得無響應(yīng)。
CPU 和內(nèi)存限制的實現(xiàn)方式和工作方式彼此不同。內(nèi)存限制更容易檢測到,我們只需要檢查 pod 的上次重啟狀態(tài),如果它由于內(nèi)存不足(OOMKilled)而被殺死。另一方面,為了實現(xiàn) CPU 限制,Kubernetes 使用內(nèi)核限制并暴露指標(biāo)而不是使用 cgroup 相關(guān)的指標(biāo),這使得很難檢測 CPU 限制。這意味著,如果應(yīng)用程序超出 CPU 限制,它就會受到限制。
這就是問題所在。
在我們了解 CPU throttling之前,讓我們了解 CPU 限制的需求以及它是如何工作的。
如果我們沒有在 Kubernetes 中指定 CPU limit 與 request怎么辦?
如果您不指定 CPU 限制,則容器將沒有任何 CPU 上限,然后它可以使用節(jié)點上所有可用的 CPU。這會使 CPU 密集型容器降低同一節(jié)點上的其他容器的速度,并可能耗盡節(jié)點上所有可用的 CPU。這反過來又會觸發(fā)諸如 kubelet 等 Kubernetes 組件變得無響應(yīng)的事件。這可以使節(jié)點變?yōu)?NotReady 狀態(tài),并且來自該節(jié)點的容器將被重新調(diào)度到某個其他節(jié)點上。
什么是 CPU 限制以及 CPU 限制如何工作?
CPU throttling確保如果應(yīng)用程序超過指定的限制,它就會受到限制。有時,即使 CPU 使用率接近限制,也可以觀察到容器throttling。發(fā)生這種情況是因為 Linux 內(nèi)核中的一個錯誤會不必要地限制擁有 CPU 限制的容器。
現(xiàn)在,在我們繼續(xù)之前,讓我們首先了解 CPU 限制在 Kubernetes 中是如何工作的。Kubernetes使用CFS (https://kubernetes.io/docs/tasks/administer-cluster/cpu-management-policies/) 配額來對運(yùn)行應(yīng)用程序的 pod 實施 CPU 限制。Completely Fair Scheduler (CFS) 是一個進(jìn)程調(diào)度程序,它根據(jù)時間段而不是基于可用的 CPU 功率來處理執(zhí)行進(jìn)程的 CPU 資源分配,并使用兩個files:cfs_period_us 和 cfs_quota_us。(https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt)
- cpu.cfs_quota_us:一段時間內(nèi)的總可用運(yùn)行時間[以微秒為單位]
- cpu.cfs_period_us:一個周期的長度[以微秒為單位]
cat /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_period_us
o/p → 100000
這里,100000 us = 100 ms
cat /sys/fs/cgroup/cpu,cpuacct/cpu.cfs_quota_us
o/p → -1
這里,cpu.cfs_quota_us 的值為 -1 表示沒有任何帶寬限制。
例如,有一個單線程應(yīng)用程序在 CPU 上運(yùn)行,但有 CPU 限制,應(yīng)用程序需要 200 毫秒的處理時間。應(yīng)用程序完成其請求的圖表如下所示。
在第二種情況下,如果我們?yōu)閼?yīng)用程序設(shè)置 0.4 個 CPU 的 CPU 限制,則應(yīng)用程序在每 100 毫秒周期后獲得 40
毫秒的運(yùn)行時間。在這里,之前需要 200 毫秒的請求現(xiàn)在需要 440 毫秒才能完成。
從上面的例子可以看出,CPU 限制是問題的真正原因。
案例
讓我們以以下示例為例,其中工作節(jié)點有1 個 CPU。您可以在 linux 服務(wù)器上使用“cat /proc/cpuinfo”命令檢查它。
現(xiàn)在,在我們創(chuàng)建有 CPU 限制的 Pod 之前,讓我們在集群上部署一個“Metrics
Server”,它可以用來獲取資源使用率的相關(guān)指標(biāo)。尤其是Pod/Node的指標(biāo)。
可以使用以下命令部署 Metrics 服務(wù)器,這些命令首先克隆“kubernetes-metrics-server”git
存儲庫并在集群上創(chuàng)建所需的對象。
git clone https://github.com/kodekloudhub/kubernetes-metrics-server.git
cd kubernetes-metrics-server/
kubectl apply -f .
要創(chuàng)建有 CPU 請求和限制的 pod,請使用以下 pod 定義創(chuàng)建一個文件“pod-with-cpu-limit.yaml”。這為 Pod 設(shè)置了Limit “1”和Request “0.5”。Request是容器預(yù)留的資源,Limit確保容器永遠(yuǎn)不會超過某個值。 (https://cloud.google.com/blog/products/gcp/kubernetes-best-practices-resource-requests-and-limits)
requests:
cpu: 100m
limits:
cpu: 500m
這將創(chuàng)建一個沒有任何問題的 pod,因為 Limit 不超過我們在工作節(jié)點上擁有的實際 CPU 數(shù)量,并且請求在我們指定的限制范圍內(nèi)。
使用以下命令創(chuàng)建一個 pod:
kubectl apply -f pod-with-cpu-limit.yaml
kubectl get pods
kubectl describe pod cpu-demo-pod
現(xiàn)在,如果您使用以下命令檢查 pod 的實際 CPU 使用率,它是 1003m(1 個 CPU)。由于我們傳遞給 pod 的參數(shù)超過了我們在限制中指定的參數(shù),這里 CPU 正在throttling。
使用以下命令檢查使用情況。
kubectl top pods cpu-demo-pod
但是,如果您指定的 CPU 限制超過了工作節(jié)點上可用的數(shù)量,您將面臨問題并且 Pod 將進(jìn)入 Pending 狀態(tài)。
首先刪除現(xiàn)有的 pod,更改 CPU 限制和請求,然后嘗試使用以下命令創(chuàng)建一個 Pod。
kubectl get pods
kubectl delete pod cpu-demo-pod
kubectl apply -f pod-with-cpu-limit.yaml
通過描述 Pod 來檢查失敗的原因。
kubectl get pods
kubectl describe pod cpu-demo-pod
您可以清楚地看到,由于 CPU 請求超過了工作節(jié)點上實際可用的 CPU,因此 Pod 無法創(chuàng)建并處于 Pending 狀態(tài)。
刪除 CPU 限制時要小心
就集群穩(wěn)定性而言,移除 CPU 限制并不是一個容易的決定。如果默認(rèn)情況下未設(shè)置 CPU 限制,則它的默認(rèn)限制則是節(jié)點的最高可用值。
在取消 CPU 限制之前,了解應(yīng)用如何工作以及它們對 CPU 的需求非常重要。
我們可以嘗試移除對延遲敏感的應(yīng)用的 CPU 限制,而不是隨意的從所有應(yīng)用中移除 CPU 限制。
隔離沒有 CPU 限制的應(yīng)用是個好的方式。如果資源分配出現(xiàn)任何問題,這將有助于輕松控制和識別此類應(yīng)用pod。
結(jié)論
如果 Docker container/Kubernetes Pod 在 Linux 系統(tǒng)上運(yùn)行,那么它們可能會由于throttling而表現(xiàn)異常。雖然這可能很危險,但刪除 CPU Limited 是解決此限制問題的解決方案。這也可以通過將內(nèi)核升級到修復(fù) CPU throttling問題的版本來解決。沒有 CPU 限制的應(yīng)用程序也可以隔離到不同的節(jié)點,以便更容易找出影響pod容器性能的罪魁禍?zhǔn)住?/p>