1 前言
最近k8s在使用過程中遇到這樣一個問題
由于Pod沒有對內(nèi)存及CPU進(jìn)行限制,導(dǎo)致Pod在運行過程中所需的內(nèi)存超過了節(jié)點本身的內(nèi)存(OOM),從而導(dǎo)致節(jié)點崩潰,使得運行在該節(jié)點上的所有Pod都失敗了
為了解決這個問題以及提高節(jié)點的穩(wěn)定性,綜合k8s的一些特性,方案如下
- 每個節(jié)點為系統(tǒng)守護(hù)進(jìn)程預(yù)留計算資源(CPU、內(nèi)存、磁盤空間)
- Pod驅(qū)逐:節(jié)點資源到達(dá)一定使用量,開始驅(qū)逐 pod
- 每個Pod需指定所需資源
2 預(yù)留資源
Kubernetes 的節(jié)點可以按照 Capacity
調(diào)度。默認(rèn)情況下 pod 能夠使用節(jié)點全部可用容量。 這是個問題,因為節(jié)點自己通常運行了不少驅(qū)動 OS 和 Kubernetes 的系統(tǒng)守護(hù)進(jìn)程。 除非為這些系統(tǒng)守護(hù)進(jìn)程留出資源,否則它們將與 Pod 爭奪資源并導(dǎo)致節(jié)點資源短缺問題。
kubelet
公開了一個名為 ‘Node Allocatable’ 的特性,有助于為系統(tǒng)守護(hù)進(jìn)程預(yù)留計算資源。 Kubernetes 推薦集群管理員按照每個節(jié)點上的工作負(fù)載密度配置 ‘Node Allocatable’。
Kubernetes 節(jié)點上的 ‘Allocatable’ 被定義為 Pod 可用計算資源量。 調(diào)度器不會超額申請 ‘Allocatable’。 目前支持 ‘CPU’、‘memory’ 和 ‘ephemeral-storage’ 這幾個參數(shù)。
可分配的節(jié)點暴露為 API 中 v1.Node
對象的一部分,也是 CLI 中 kubectl describe node
的一部分。
在 kubelet
中,可以為兩類系統(tǒng)守護(hù)進(jìn)程預(yù)留資源。
Node Capacity:Node的所有硬件資源
Node Capacity | 說明 |
---|---|
kube-reserved | 給kube組件預(yù)留的資源:kubelet,kube-proxy以及docker等 |
system-reserved | 給system進(jìn)程預(yù)留的資源 |
eviction-threshold | kubelet eviction的閾值設(shè)定 |
allocatable(available for pods) | Allocatable 被定義為 pod 可用計算資源量。調(diào)度器不會超額申請 Allocatable。 目前支持 CPU, memory 和 storage 這幾個參數(shù) (保證Node上所有Pods的request resource不超過Allocatable) |
allocatable的值即對應(yīng) describe node 時看到的allocatable容量,pod 調(diào)度的上限
計算公式:節(jié)點上可配置值 = 總量 - 預(yù)留值 - 驅(qū)逐閾值
Allocatable = Capacity - Reserved(kube+system) - Eviction Threshold
Kube-reserved
-
Kubelet 標(biāo)志 :
--kube-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=1Gi][,][pid=1000]
-
Kubelet 標(biāo)志 :
--kube-reserved-cgroup=
kube-reserved
用來給諸如 kubelet
、容器運行時、節(jié)點問題監(jiān)測器等 Kubernetes 系統(tǒng)守護(hù)進(jìn)程記述其資源預(yù)留值。 該配置并非用來給以 Pod 形式運行的系統(tǒng)守護(hù)進(jìn)程預(yù)留資源。kube-reserved
通常是節(jié)點上 Pod 密度
的函數(shù)。
除了 cpu
、內(nèi)存
和 ephemeral-storage
之外,pid
可用來指定為 Kubernetes 系統(tǒng)守護(hù)進(jìn)程預(yù)留指定數(shù)量的進(jìn)程 ID。
設(shè)置方式
-
systemctl status kubelet 查看 kubelet啟動的配置文件路徑:–kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/lib/kubelet/config.yaml
-
編輯/var/lib/kubelet/config.yaml,添加如下內(nèi)容
apiVersion: kubelet.config.k8s.io/v1beta1 ... kubeReserved: # 配置 kube 資源預(yù)留, 根據(jù)實際情況進(jìn)行設(shè)置 cpu: 1000m memory: 5Gi ephemeral-storage: 5Gi
System-reserved
-
Kubelet 標(biāo)志 :
--system-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=1Gi][,][pid=1000]
-
Kubelet 標(biāo)志 :
--system-reserved-cgroup=
system-reserved
用于為諸如 sshd
、udev
等系統(tǒng)守護(hù)進(jìn)程記述其資源預(yù)留值。 system-reserved
也應(yīng)該為 kernel
預(yù)留 內(nèi)存
,因為目前 kernel
使用的內(nèi)存并不記在 Kubernetes 的 Pod 上。 同時還推薦為用戶登錄會話預(yù)留資源(systemd 體系中的 user.slice
)。
除了 cpu
、內(nèi)存
和 ephemeral-storage
之外,pid
可用來指定為 Kubernetes 系統(tǒng)守護(hù)進(jìn)程預(yù)留指定數(shù)量的進(jìn)程 ID。
設(shè)置方式
編輯/var/lib/kubelet/config.yaml,添加如下內(nèi)容
apiVersion: kubelet.config.k8s.io/v1beta1
...
systemReserved: # 配置系統(tǒng)資源預(yù)留
cpu: 1000m
memory: 10Gi
ephemeral-storage: 10Gi
Eviction Thresholds
Kubelet 標(biāo)志 :--eviction-hard=[memory.available<500Mi]
節(jié)點級別的內(nèi)存壓力將導(dǎo)致系統(tǒng)內(nèi)存不足,這將影響到整個節(jié)點及其上運行的所有 Pod。 節(jié)點可以暫時離線直到內(nèi)存已經(jīng)回收為止。為了防止系統(tǒng)內(nèi)存不足(或減少系統(tǒng)內(nèi)存不足的可能性), kubelet 提供了資源不足管理。 驅(qū)逐操作只支持 memory
和 ephemeral-storage
。 通過 --eviction-hard
標(biāo)志預(yù)留一些內(nèi)存后,當(dāng)節(jié)點上的可用內(nèi)存降至預(yù)留值以下時, kubelet
將嘗試驅(qū)逐 Pod。 如果節(jié)點上不存在系統(tǒng)守護(hù)進(jìn)程,Pod 將不能使用超過 capacity-eviction-hard
所指定的資源量。 因此,為驅(qū)逐而預(yù)留的資源對 Pod 是不可用的。
設(shè)置方式
apiVersion: kubelet.config.k8s.io/v1beta1
...
evictionHard:
memory.available: 1Gi
nodefs.available: "10%""
實施節(jié)點可分配約束
Kubelet 標(biāo)志 :--enforce-node-allocatable=pods[,][system-reserved][,][kube-reserved]
調(diào)度器將 ‘Allocatable’ 視為 Pod 可用的 capacity
(資源容量)。
kubelet
默認(rèn)對 Pod 執(zhí)行 ‘Allocatable’ 約束。 無論何時,如果所有 Pod 的總用量超過了 ‘Allocatable’,驅(qū)逐 Pod 的措施將被執(zhí)行。 可通過設(shè)置 kubelet --enforce-node-allocatable
標(biāo)志值為 pods
控制這個措施。
可選地,通過在同一標(biāo)志中同時指定 kube-reserved
和 system-reserved
值, 可以使 kubelet
強制實施 kube-reserved
和 system-reserved
約束。 請注意,要想執(zhí)行 kube-reserved
或者 system-reserved
約束, 需要對應(yīng)設(shè)置 --kube-reserved-cgroup
或者 --system-reserved-cgroup
默認(rèn)情況下只對Pod進(jìn)行約束,在對系統(tǒng)進(jìn)程約束時需要注意一些系統(tǒng)核心進(jìn)程被殺掉導(dǎo)致節(jié)點失效的問題。
設(shè)置方式
apiVersion: kubelet.config.k8s.io/v1beta1
...
systemReservedCgroup: /system.slice
enforceNodeAllocatable:
- pods
- system-reserved
3 Pod優(yōu)先級
系統(tǒng)守護(hù)進(jìn)程一般會被按照類似 Guaranteed 的 Pod 一樣對待。 系統(tǒng)守護(hù)進(jìn)程可以在與其對應(yīng)的控制組中出現(xiàn)突發(fā)資源用量,這一行為要作為 Kubernetes 部署的一部分進(jìn)行管理。 例如,kubelet
應(yīng)該有它自己的控制組并和容器運行時共享 kube-reserved
資源。 不過,如果執(zhí)行了 kube-reserved
約束,則 kubelet 不可出現(xiàn)突發(fā)負(fù)載并用光節(jié)點的所有可用資源。
在執(zhí)行 system-reserved
預(yù)留策略時請加倍小心,因為它可能導(dǎo)致節(jié)點上的關(guān)鍵系統(tǒng)服務(wù)出現(xiàn) CPU 資源短缺、 因為內(nèi)存不足而被終止或者無法在節(jié)點上創(chuàng)建進(jìn)程。 建議只有當(dāng)用戶詳盡地描述了他們的節(jié)點以得出精確的估計值, 并且對該組中進(jìn)程因內(nèi)存不足而被殺死時,有足夠的信心將其恢復(fù)時, 才可以強制執(zhí)行 system-reserved
策略。
- 作為起步,可以先針對
pods
上執(zhí)行 ‘Allocatable’ 約束。 - 一旦用于追蹤系統(tǒng)守護(hù)進(jìn)程的監(jiān)控和告警的機制到位,可嘗試基于用量估計的方式執(zhí)行
kube-reserved
策略。 - 隨著時間推進(jìn),在絕對必要的時候可以執(zhí)行
system-reserved
策略。
當(dāng)資源不足時,配置了如上驅(qū)逐參數(shù),pod之間的驅(qū)逐順序是怎樣的呢?以下描述設(shè)置不同優(yōu)先級來確保集群中核心的組件不被驅(qū)逐還正常運行,OOM 的優(yōu)先級如下,pod oom 值越低,也就越不容易被系統(tǒng)殺死。
BestEffort Pod > Burstable Pod > 其它進(jìn)程(內(nèi)核init進(jìn)程等) > Guaranteed Pod > kubelet/docker 等 > sshd 等進(jìn)程
kubernetes 把 pod 分成了三個 QoS 等級,而其中和limits和requests參數(shù)有關(guān):
- Guaranteed:oom優(yōu)先級最低,可以考慮數(shù)據(jù)庫應(yīng)用或者一些重要的業(yè)務(wù)應(yīng)用。除非 pods 使用超過了它們的 limits,或者節(jié)點的內(nèi)存壓力很大而且沒有 QoS 更低的 pod,否則不會被殺死。
- Burstable:這種類型的 pod 可以多于自己請求的資源(上限有 limit 指定,如果 limit 沒有配置,則可以使用主機的任意可用資源),但是重要性認(rèn)為比較低,可以是一般性的應(yīng)用或者批處理任務(wù)。
- Best Effort:oom優(yōu)先級最高,集群不知道 pod 的資源請求情況,調(diào)度不考慮資源,可以運行到任意節(jié)點上(從資源角度來說),可以是一些臨時性的不重要應(yīng)用。pod 可以使用節(jié)點上任何可用資源,但在資源不足時也會被優(yōu)先殺死。
Pod 的 requests 和 limits 是如何對應(yīng)到這三個 QoS 等級上的,可以用下面一張表格概括:
request是否配置 | limits是否配置 | 兩者的關(guān)系 | Qos | 說明 |
---|---|---|---|---|
是 | 是 | requests=limits | Guaranteed | 所有容器的cpu和memory都必須配置相同的requests和limits |
是 | 是 | request<limit | Burstable | 只要有容器配置了cpu或者memory的request和limits就行 |
是 | 否 | Burstable | 只要有容器配置了cpu或者memory的request就行 | |
否 | 是 | Guaranteed/ Burstable |
如果配置了limits,k8s會自動把對應(yīng)資源的request設(shè)置和limits一樣。 如果所有容器所有資源都配置limits,那就是Guaranteed;如果只有部分配置了limits, 就是Burstable |
|
否 | 否 | Best Effort | 所有的容器都沒有配置資源requests或limits |
說明:
- request和limits相同,可以參考資源動態(tài)調(diào)整中的VPA設(shè)置合理值。
- 如果只配置了limits,沒有配置request,k8s會把request值和limits值一樣。
- 如果只配置了request,沒有配置limits,該pod共享node上可用的資源,實際上很反對這樣設(shè)置。
4 生產(chǎn)應(yīng)用
配置文件
編輯/var/lib/kubelet/config.yaml
apiVersion: kubelet.config.k8s.io/v1beta1
...
# 添加如下內(nèi)容
systemReserved:
memory: 5Gi
cpu: 1000m
ephemeral-storage: 10Gi
kubeReserved:
memory: 5Gi
cpu: 1000m
ephemeral-storage: 10Gi
evictionHard:
memory.available: "3%"
nodefs.available: "10%"
# systemReservedCgroup: /system.slice
enforceNodeAllocatable:
- pods
# - system-reserved
重啟kubelet服務(wù)
systemctl restart kubelet
查看節(jié)點資源
資源類型 | SystemReserved | KubeReserved | EvictionHard | Allocatable | All |
---|---|---|---|---|---|
CPU | 1000m | 1000m | 0 | 8000m | 1000m |
Memory | 5Gi | 5Gi | 1.88Gi (3%) | 50.93Gi | 62.81Gi |
Ephemeral-storage | 10Gi | 10Gi | 50Gi | 429.7Gi | 499.7Gi |
Allocatable = All - SystemReserved - KubeReserved - EvictionHard文章來源:http://www.zghlxwxcb.cn/news/detail-613589.html
說明配置成功。文章來源地址http://www.zghlxwxcb.cn/news/detail-613589.html
到了這里,關(guān)于第四篇:k8s之節(jié)點kubelet預(yù)留資源配置的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!