如何設定Kubernetes資源限制
Kubernetes 作為當下最流行的的容器叢集管理平臺,需要統籌叢集整體的資源使用情況,將合適的資源分配給pod容器使用,既要保證充分利用資源,提高資源利用率,又要保證重要容器在執行週期內能夠分配到足夠的資源穩定執行。
配置容器資源限制
對於一個pod來說,資源最基礎的2個的指標就是:CPU和記憶體。
Kubernetes提供了個採用requests和limits 兩種型別引數對資源進行預分配和使用限制。
limit 會限制pod的資源利用:
- 當pod 記憶體超過limit時,會被oom。
- 當cpu超過limit時,不會被kill,但是會限制不超過limit值。
測試記憶體限制
部署一個壓測容器,壓測時會分配250M記憶體,但實際pod的記憶體limit為100Mi
apiVersion: v1
kind: Pod
metadata:
name: memory-demo
namespace: example
spec:
containers:
- name: memory-demo-2-ctr
image: polinux/stress
resources:
requests:
memory: "50Mi"
limits:
memory: "100Mi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "250M", "--vm-hang", "1"]
部署後檢視pod狀態,可以看到pod被OOM,
kubectl -n example get po
NAME READY STATUS RESTARTS AGE
memory-demo 0/1 OOMKilled 1 11s
測試CPU限制
apiVersion: v1
kind: Pod
metadata:
name: cpu-demo
namespace: example
spec:
containers:
- name: cpu-demo-ctr
image: vish/stress
resources:
limits:
cpu: "1"
requests:
cpu: "0.5"
args:
- -cpus
- "2"
檢視容器資訊,可以看到pod 雖然不會被kill掉,但是實際使用cpu被限制只有1000m。
kubectl -n example top po cpu-demo
NAME CPU(cores) MEMORY(bytes)
cpu-demo 1000m 0Mi
容器服務質量(QoS)
Kubernetes 提供服務質量管理,根據容器的資源配置,將pod 分為Guaranteed, Burstable, BestEffort 3個級別。當資源緊張時根據分級決定排程和驅逐策略,這三個分級分別代表:
- Guaranteed: pod中所有容器都設定了limit和request, 並且相等(設定limit後假如沒有設定request會自動設定為limit值)
- Burstable: pod中有容器未設定limit, 或者limit和request不相等。這種型別的pod在排程節點時, 可能出現節點超頻的情況。
- BestEffort: pod中沒有任何容器設定request和limit。
計算qos程式碼:https://github.com/kubernetes/kubernetes/blob/master/pkg/apis/core/helper/qos/qos.go
不同QoS對容器影響
oom:
Kubernetes會根據QoS設定oom的評分調整引數oom_score_adj
,oom_killer 根據 記憶體使用情況算出oom_score, 並且和oom_score_adj
綜合評價,程式的評分越高,當發生oom時越優先被kill。
QoS | oom_score_adj |
---|---|
Guaranteed | -998 |
BestEffort | 1000 |
Burstable | min(max(2, 1000 – (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999) |
當節點記憶體不足時,QoS為Guaranteed 的pod 最後被kill。 而BestEffort 級別的pod優先被kill。 其次是Burstable,根據計算公式 oom_score_adj 值範圍2到999,設定的request越大,oom_score_adj越低,oom時保護程度越高。
實踐
節點資訊:
# kubectl describe no cn-beijing.i-2zeavb11mttnqnnicwj9 | grep -A 3 Capacity
Capacity:
cpu: 4
memory: 8010196Ki
pods: 110
apiVersion: v1
kind: Pod
metadata:
name: memory-demo-qos-1
namespace: example
spec:
containers:
- name: memory-demo-qos-1
image: polinux/stress
resources:
requests:
memory: "200Mi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "50M", "--vm-hang", "1"]
---
apiVersion: v1
kind: Pod
metadata:
name: memory-demo-qos-2
namespace: example
spec:
containers:
- name: memory-demo-qos-2
image: polinux/stress
resources:
requests:
memory: "400Mi"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "50M", "--vm-hang", "1"]
---
apiVersion: v1
kind: Pod
metadata:
name: memory-demo-qos-3
namespace: example
spec:
containers:
- name: memory-demo-qos-3
image: polinux/stress
resources:
requests:
memory: "200Mi"
cpu: "2"
limits:
memory: "200Mi"
cpu: "2"
command: ["stress"]
args: ["--vm", "1", "--vm-bytes", "50M", "--vm-hang", "1"]
單個節點可分配記憶體為8010196Ki, 大約7822.45Mi。
根據Burstable 的計算方式:
request 200Mi: (1000 - 1000*200/7822.45) 約為975
request 400Mi: (1000 - 1000*400/7822.45) 約為950
我們分別檢視這3個pod的oom引數
// request 200Mi
kubectl -n example exec memory-demo-qos-1 cat /proc/1/oom_score_adj
975
// request 400Miß
kubectl -n example exec memory-demo-qos-2 cat /proc/1/oom_score_adj
949
// Guaranteed
kubectl -n example exec memory-demo-qos-3 cat /proc/1/oom_score_adj
-998
設定oom 規則程式碼: https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/qos/policy.go
pod 驅逐:
當節點的記憶體和cpu資源不足,開始驅逐節點上的pod時。QoS同樣會影響驅逐的優先順序。順序如下:
- kubelet 優先驅逐 BestEffort的pod 和 實際佔用資源大於requests的Burstable pod。
- 接下來驅逐實際佔用資源小於request的Burstable pod。
- QoS為Guaranteed的pod最後驅逐, kubelet 會保證Guaranteed的pod 不會因為其他pod的資源消耗而被驅逐。
- 當QoS相同時,kubelet 根據 Priority 計算驅逐的優先順序
ResourceQuota
Kubernetes提供ResourceQuota物件,用於配置限制namespace內的每種型別的k8s物件數量和資源(cpu,記憶體)。
- 一個namespace中可以建立一個或多個ResourceQuota
- 如果namespace中配置了ResourceQuota, 部署時必須設定request和limit, 否則會拒絕建立請求。
- 可以通過這是limitRange配置每個pod預設的requests和limits避免上述問題
- 1.10以後支援擴充套件資源 詳見:https://kubernetes.io/docs/tasks/configure-pod-container/extended-resource/
apiVersion: v1
kind: ResourceQuota
metadata:
name: mem-cpu-demo
namespace: example
spec:
hard:
requests.cpu: "3"
requests.memory: 1Gi
limits.cpu: "5"
limits.memory: 2Gi
pods: "5"
LimitRange
LimitRange 是用來設定 namespace 中 Pod 的預設的資源 request 和 limit 值,以及大小範圍。
apiVersion: v1
kind: LimitRange
metadata:
name: mem-limit-range
namespace: example
spec:
limits:
- default: # default limit
memory: 512Mi
cpu: 2
defaultRequest: # default request
memory: 256Mi
cpu: 0.5
max: # max limit
memory: 800Mi
cpu: 3
min: # min request
memory: 100Mi
cpu: 0.3
maxLimitRequestRatio: # max value for limit / request
memory: 2
cpu: 2
type: Container # limit type, support: Container / Pod / PersistentVolumeClaim
limitRange支援的引數如下:
- default 代表預設的limit
- defaultRequest 代表預設的request
- max 代表limit的最大值
- min 代表request的最小值
- maxLimitRequestRatio 代表 limit / request的最大值。由於節點是根據pod request 排程資源,可以做到節點超賣,maxLimitRequestRatio 代表pod最大超賣比例。
總結
- Kubernetes 提供request 和 limit 兩種方式設定容器資源。
- 為了提高資源利用率,k8s排程時根據pod 的request值計算排程策略,從而實現節點資源超賣。
- k8s根據limit限制pod使用資源,當記憶體超過limit時會觸發oom。 且限制pod的cpu 不允許超過limit。
- 根據pod的 request和limit,k8s會為pod 計算服務質量,並分為Guaranteed, Burstable, BestEffort 這3級。當節點資源不足時,發生驅逐或者oom時, Guaranteed 級別的pod 優先保護, Burstable 節點次之(request越大,使用資源量越少 保護級別越高), BestEffort 最先被驅逐。
- Kubernetes提供了RequestQuota和LimitRange 用於設定namespace 內pod 的資源範圍 和 規模總量。 RequestQuota 用於設定各種型別物件的數量, cpu和記憶體的總量。 LimitRange 用於設定pod或者容器 request和limit 的預設值,最大最小值, 以及超賣比例(limit / request)。
- 對於一些重要的線上應用,我們應該合理設定limit和request,limit和request 設定一致,資源不足時k8s會優先保證這些pod正常執行。
- 為了提高資源利用率。 對一些非核心,並且資源不長期佔用的應用,可以適當減少pod的request,這樣pod在排程時可以被分配到資源不是十分充裕的節點,提高使用率。但是當節點的資源不足時,也會優先被驅逐或被oom kill。
參考文件
- https://kubernetes.io/docs/concepts/policy/resource-quotas/#quota-scopes
- https://kubernetes.io/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/
相關文章
- Kubernetes資源請求與限制
- 深入理解Kubernetes資源限制:CPU
- Kubernetes:容器資源需求與限制(約束)
- 深入理解Kubernetes資源限制:記憶體記憶體
- Kubernetes筆記(四):詳解Namespace與資源限制ResourceQuota,LimitRange筆記namespaceMIT
- 在kubernetes裡使用AppArmor限制容器對資源的訪問APP
- 如何用 Kubernetes 自定義資源?
- kubernetes下的jenkins如何設定mavenJenkinsMaven
- Docker的資源限制Docker
- Kubernetes中如何使用CPU請求和限制? - daniele
- JVM 如何獲取當前容器的資源限制?JVM
- 【遊戲設計】如何搭建資源框架之遊戲資源價值錨定遊戲設計框架
- 小程式專案如何設定資源的防盜鏈?
- dhtmlxGantt如何在DHTMLX Gantt中設定資源管理選項HTML
- 如何處理帝國cms後臺設定IP限制後,將自己的IP都限制了
- 帝國CMS後臺設定IP限制後,將自己的IP都限制了,如何處理?
- Kubernetes 如何成為計算資源的標準
- Kubernetes as Database: 使用kubesql查詢kubernetes資源DatabaseSQL
- 如何在ubuntu上設定清華源Ubuntu
- 達夢資料庫專用機報錯會話讀取資料頁數超過資源限制設定值資料庫會話
- Kubernetes CRDs 自定義資源
- setrlimit函式限制程序資源MIT函式
- 容器技術之Docker資源限制Docker
- 在 Kubernetes 中應該如何設定 CPU 的 requests 和 limitsMIT
- 如何使用 Docker 來限制 CPU、記憶體和 IO等資源?Docker記憶體
- 小程式如何設定資源的防盜鏈 — 隨筆小記
- win10資源管理器多標籤如何設定_win10檔案資源管理器怎麼設定多標籤Win10
- win10限制上傳速度在哪裡設定 win10電腦限制上傳速度怎麼設定Win10
- docker筆記34-容器資源需求、資源限制及HeapSterDocker筆記
- Mysql:canal-adapter:如何設定多個 src 源資料庫連線?!MySqlAPT資料庫
- kubernetes資源均衡器Descheduler
- kubernetes排程之資源配額
- kubernetes之常用核心資源物件物件
- pip 映象源設定
- Pip源設定(使用清華源)
- Oracle的過載保護-資料庫資源限制Oracle資料庫
- kubernetes之計算機資源管理計算機
- kubernetes排程之資源配額示例