十、K8s集群資源合理化分配
文章目錄
- 十、K8s集群資源合理化分配
- 1、K8s 資源限制 ResourceQuota
- 1.1 什么是ResourceQuota?
- 1.2 ResourceQuota通常用于如下場景:
- 1.3 基于租戶和團隊的資源限制
- 1.4 基于命名空間的資源限制
- 2、K8s 資源限制 LimitRange
- 2.1 設置容器默認的資源配置
- 2.2 限制容器可以使用的最大和最小資源
- 2.3 限制存儲使用的大小范圍
- 3、K8s資源限制Qos
- 3.1 什么是QoS?
- 3.2 Qos級別
- 3.3 實現 QoS 為 Guaranteed 的 Pod
- 3.4 實現 QoS 為 Burstable 的 Pod
- 3.5 實現 QoS 為 BestEffort 的 Pod
- 4、常見問題
- 4.1 說一下ResourceQuota、LimitRange、QoS是什么?使用場景等
- 4.2 在生產環境中如何合理的資源限制?
- 4.3 如何配置每個服務的內存和CPU?
1、K8s 資源限制 ResourceQuota
1.1 什么是ResourceQuota?
ResourceQuota是一個K8s用于資源管理的對象,主要用于限制命名空間中的資源使用量。K8s管理員可以使用ResourceQuota控制命名空間中的資源使用量,確保資源的合理分配和使用,防止某個命名空間或用戶過度消耗集群資源。
1.2 ResourceQuota通常用于如下場景:
- 限制資源使用:控制命名空間中可以使用的CPU、內存、存儲等資源的總量。
- 限制對象數量:控制命名空間中可以創建的對象數量,如Pod、ConfigMap、Secret、Service等。
- 資源公平分配:確保資源在不同命名空間之間公平分配,避免資源爭搶。
- 防止資源耗盡:防止某個命名空間或者用戶過度消耗資源,導致其他應用無法獲得所需的資源。
1.3 基于租戶和團隊的資源限制
在一個 Kubernetes 集群中,可能會有不同的團隊或者不同的租戶共同使用,此時可以針對不同的租戶和不同的團隊進行資源限制。
# 首先創建一個 Namespace 模擬租戶:
[root@k8s-master01 ~]# kubectl create namespace customer# 配置租戶的資源限制
[root@k8s-master01 ~]# vim customer-resourcequota.yaml
[root@k8s-master01 ~]# cat customer-resourcequota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:name: customer-quotanamespace: customer
spec:hard:requests.cpu: "1" # 限制最高CPU請求數requests.memory: 2Gi # 限制最高內存的請求數limits.cpu: "2" # 限制最高CPU的limits上限limits.memory: 4Gi # 限制最高內存的limits上限pods: "50" # 限制最多啟動Pod的個數persistentvolumeclaims: "10"requests.storage: 40Gi # PVC存儲請求的總和services: "40"count/replicasets.apps: 1k# `count/<resource>.<group>`:用于非核心組的資源
# `count/<resource>`:用于核心組的資源[root@k8s-master01 ~]# kubectl create -f customer-resourcequota.yaml
# 查看限制詳情
[root@k8s-master01 ~]# kubectl get resourcequota -n customer
NAME AGE REQUEST LIMIT
customer-quota 2m44s count/replicasets.apps: 0/1k, persistentvolumeclaims: 0/10, pods: 0/50, requests.cpu: 0/1, requests.memory: 0/2Gi, requests.storage: 0/40Gi, services: 0/40 limits.cpu: 0/2, limits.memory: 0/4Gi
# 創建一個 Deployment 測試
[root@k8s-master01 ~]# kubectl create deploy nginx --image=crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/nginx:stable -n customer# 此時并沒有 Pod 產生
[root@k8s-master01 ~]# kubectl get pod -n customer
No resources found in customer namespace.[root@k8s-master01 ~]# kubectl get rs -n customer
NAME DESIRED CURRENT READY AGE
nginx-67bfb68c7d 1 0 0 10m[root@k8s-master01 ~]# kubectl describe rs nginx -n customer
....Warning FailedCreate 4m34s (x8 over 9m59s) replicaset-controller (combined from similar events): Error creating: pods "nginx-67bfb68c7d-8m2gh" is forbidden: failed quota: customer-quota: must specify limits.cpu for: nginx; limits.memory for: nginx; requests.cpu for: nginx; requests.memory for: nginx
[root@k8s-master01 ~]# kubectl edit deploy nginx -n customer
....resources: requests:cpu: "1"memory: "512Mi"limits:cpu: "2"memory: "1024Mi"
....# pod已經成功創建
[root@k8s-master01 ~]# kubectl get pod -n customer
NAME READY STATUS RESTARTS AGE
nginx-7b95565d67-2kjlf 1/1 Running 0 85s# 查看目前空間資源使用情況
[root@k8s-master01 ~]# kubectl get resourcequota -n customer
NAME AGE REQUEST LIMIT
customer-quota 19m count/replicasets.apps: 2/1k, persistentvolumeclaims: 0/10, pods: 1/50, requests.cpu: 1/1, requests.memory: 512Mi/2Gi, requests.storage: 0/40Gi, services: 0/40 limits.cpu: 2/2, limits.memory: 1Gi/4Gi
和租戶與團隊一致,一個集群也可能同時存在多個環境和項目,此時也可以基于環境和項目進行資源限制。
1.4 基于命名空間的資源限制
通常情況下,出于穩定性和安全性考慮,應該對每個 Namespace 不受控制的資源進行限制,比如 Pod 和 ReplicaSet,防止異常創建導致集群故障。
[root@k8s-master01 ~]# cat default-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:name: default-quota
spec:hard:count/pods: "1000" # 限制pod數量count/replicasets.apps: 2k # 限制rs的數量
2、K8s 資源限制 LimitRange
2.1 設置容器默認的資源配置
在 Kubernetes 集群中部署任何的服務,都建議添加 resources 參數,也就是配置內存和 CPU資源的請求和限制。
如果不想給每個容器都手動添加資源配置,此時可以使用 limitRange 實現給每個容器自動添加資源配置。
比如默認給每個容器默認添加 cpu 請求 0.5 核,內存請求 256Mi,cpu 最大使用量 1 核,內存最大使用量 512Mi:
[root@k8s-master01 ~]# vim cpu-mem-limit-range.yaml
[root@k8s-master01 ~]# cat cpu-mem-limit-range.yaml
apiVersion: v1
kind: LimitRange
metadata:name: cpu-mem-limit-range
spec:limits:- default:cpu: 1memory: 512MidefaultRequest:cpu: 0.5memory: 256Mitype: Container[root@k8s-master01 ~]# kubectl create -f cpu-mem-limit-range.yaml
[root@k8s-master01 ~]# kubectl get limitRange
NAME CREATED AT
cpu-mem-limit-range 2025-06-25T12:07:26Z
# 創建一個沒有資源配置的服務
[root@k8s-master01 ~]# kubectl create deploy redis --image=crpi-q1nb2n896zwtcdts.cn-beijing.personal.cr.aliyuncs.com/ywb01/redis:7.2.5[root@k8s-master01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
redis-564b7bcf74-knw2l 1/1 Running 0 61s# 此時 Pod 里面的容器會被添加默認的 resources 配置(多個容器也會同時添加,已配置的參
數不會覆蓋)
[root@k8s-master01 ~]# kubectl get po -oyaml | grep resources -A 6resources:limits:cpu: "1"memory: 512Mirequests:cpu: 500mmemory: 256Mi
2.2 限制容器可以使用的最大和最小資源
除了給容器配置默認的資源請求和限制,limitRange 還可以限制容器能使用的最大資源及可以配置的最小資源。
比如限制容器能配置最大內存是 1G,最大 CPU 是 800m,最小內存是 128M,最小 CPU 是10m:
[root@k8s-master01 ~]# vim min-max.yaml
[root@k8s-master01 ~]# cat min-max.yaml
apiVersion: v1
kind: LimitRange
metadata:name: min-max
spec:limits:- max:cpu: "800m"memory: "1Gi"min:cpu: "10m"memory: "128Mi"type: Container[root@k8s-master01 ~]# kubectl create -f min-max.yaml
[root@k8s-master01 ~]# kubectl get limitRange
NAME CREATED AT
cpu-mem-limit-range 2025-06-25T12:07:26Z
min-max 2025-06-25T12:16:06Z
[root@k8s-master01 ~]# kubectl edit deploy redis
....resources: limits:cpu: "2"memory: 2Girequests:cpu: 1mmemory: 1Mi
....# 但實際并沒有更新
[root@k8s-master01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
redis-564b7bcf74-knw2l 1/1 Running 0 4m18s# 查看rs更新了
[root@k8s-master01 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
....
redis-74c66496 1 0 0 14s# 查看報錯日志
[root@k8s-master01 ~]# kubectl describe rs redis-74c66496
....Warning FailedCreate 13s (x4 over 31s) replicaset-controller (combined from similar events): Error creating: pods "redis-74c66496-tvc77" is forbidden: [minimum cpu usage per Container is 10m, but request is 1m, minimum memory usage per Container is 128Mi, but request is 1Mi, maximum cpu usage per Container is 800m, but limit is 2, maximum memory usage per Container is 1Gi, but limit is 2Gi]
# 改回正常配置
[root@k8s-master01 ~]# kubectl edit deploy redis
....resources:limits:cpu: 600mmemory: 512Mirequests:cpu: 100mmemory: 128Mi
....# pod已經更新
[root@k8s-master01 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
redis-675c6487c6-d9xxx 1/1 Running 0 61s
2.3 限制存儲使用的大小范圍
除了限制 CPU 和內存,也會限制 PVC 的大小范圍,此時把 type 改為 PersistentVolumeClaim 即可。
# 比如限制每個 PVC 只能使用大于等于 1G,小于等于 3G 的空間:
[root@k8s-master01 ~]# vim storage-limit.yaml
[root@k8s-master01 ~]# cat storage-limit.yaml
apiVersion: v1
kind: LimitRange
metadata:name: storagelimits
spec:limits:- max:storage: 3Gimin:storage: 1Gitype: PersistentVolumeClaim[root@k8s-master01 ~]# kubectl create -f storage-limit.yaml
[root@k8s-master01 ~]# kubectl get limitRange
NAME CREATED AT
cpu-mem-limit-range 2025-06-25T12:07:26Z
min-max 2025-06-25T12:26:28Z
storagelimits 2025-06-25T12:52:33Z
# 創建一個申請 5G 的 PVC:
[root@k8s-master01 ~]# vim pvc-test.yaml
[root@k8s-master01 ~]# cat pvc-test.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: pvc-test
spec:resources:requests:storage: 5GivolumeMode: FilesystemstorageClassName: local-storageaccessModes:- ReadWriteMany# 此時會有如下報錯:
[root@k8s-master01 ~]# kubectl create -f pvc-test.yaml
Error from server (Forbidden): error when creating "pvc-test.yaml": persistentvolumeclaims "pvc-test" is forbidden: maximum storage usage per PersistentVolumeClaim is 3Gi, but request is 5Gi# 此時把 storage 改為限制范圍內即可正常創建。
3、K8s資源限制Qos
3.1 什么是QoS?
Qos:Quality of Service,表示程序的服務質量。K8s集群中的每個Pod,都會有對應的Qos級別(在K8s中通過Resources參數即可配置QoS的級別),可用于決定Pod在資源緊張時的處理順序,同時可以確保關鍵服務的穩定性和可靠性。
3.2 Qos級別
- Guaranteed:最高服務質量,當宿主機內存不夠時,會先kill掉QoS為 BestEffort 和 Bursttable 的Pod,如果內存還是不夠,才會kill掉 Guaranteed ,該級別Pod的資源占用量一般比較明確,即 requests 的 cpu 和 memory 和 limits 的 cpu 和 memory 配置一致。
- Bursttable:服務質量低于 Guaranteed ,當宿主機內存不夠時,會先kill掉QoS為 BestEffort 的Pod,如果內存還是不夠之后就會kill掉QoS級別為 Bursttable 的Pod,用來保證QoS質量為 Guaranteed 的Pod。該級別Pod一般知道最小資源使用量,但是當機器資源充足時,還是想盡可能的使用更多的資源,即 limits 字段的 cpu 和 memory 大于 requests 的 cpu 和 memory 的配置。
- BestEffort:盡量而為,當宿主機內存不夠時,首先kill的就是Qos的Pod,用以保證 Bursttable 和 Guaranteed 級別的Pod正常運行。
3.3 實現 QoS 為 Guaranteed 的 Pod
Guaranteed 級別的 Pod 具有最高的優先級,Kubernetes 會確保這些 Pod 獲得足夠的資源,也就是 Kubernetes 調度器會確保這些 Pod 調度到能夠提供所需資源的節點上。
配置 Guaranteed 級別的 Pod,需要滿足如下條件:
- Pod 中的每個容器必須指定 limits.memory 和 requests.memory,并且兩者需要相等
- Pod 中的每個容器必須指定 limits.cpu 和 requests.cpu,并且兩者需要相等
# 修改配置
[root@k8s-master01 ~]# kubectl describe deploy redis
....resources:limits:cpu: 200mmemory: 512Mirequests:cpu: 200mmemory: 512Mi
....# 查看級別
[root@k8s-master01 ~]# kubectl describe po redis-765db65df4-rkbkg | grep "QoS Class"
QoS Class: Guaranteed
3.4 實現 QoS 為 Burstable 的 Pod
Burstable 級別的 Pod 具有中等優先級,Kubernetes 會盡量滿足其資源請求,但在資源緊張時可能會被驅逐,Kubernetes 調度器會確保這些 Pod 調度到能夠提供所需資源的節點上,如果節點上有額外的資源,這些 Pod 可以使用超過其請求的資源。
配置 Burstable 級別的 Pod,需要滿足如下條件:
- Pod 不符合 Guaranteed 的配置要求
- Pod 中至少有一個容器配置了 requests.cpu 或 requests.memory
# 修改配置
[root@k8s-master01 ~]# kubectl describe deploy redis
....resources:limits:cpu: 200mmemory: 512Mirequests:cpu: 100mmemory: 512Mi
....# 查看級別
[root@k8s-master01 ~]# kubectl describe po redis-7c578fff48-7hnnx | grep "QoS Class"
QoS Class: Burstable
3.5 實現 QoS 為 BestEffort 的 Pod
BestEffort 級別的 Pod 是最低優先級,Kubernetes 不保證這些 Pod 獲得任何資源,在資源緊張時,這些 Pod 最先被驅逐。同時 Kubernetes 調度器會嘗試將這些 Pod 調度到任何節點上,但不保證節點上有足夠的資源。
配置 BestEffort 級別的 Pod,不配置 resources 字段即可。
4、常見問題
4.1 說一下ResourceQuota、LimitRange、QoS是什么?使用場景等
ResourceQuota資源限制、LimitRange資源使用范圍及默認值、QoS服務質量。ResourceQuota用于在多租戶環境下為命名空間設置資源總量限制,避免某個租戶過度使用資源。LimitRange可以確保命名空間內的Pod有合理的資源請求和限制范圍,避免不合理的配置。QoS用于根據Pod的資源配置確定其在資源緊張的優先級,確保關鍵任務的Pod能夠獲得資源。
4.2 在生產環境中如何合理的資源限制?
每個空間都需要限制Pod和RS的資源,之后根據需要限制內存和CPU。
4.3 如何配置每個服務的內存和CPU?
根據實際情況配置、適當超分、重要服務采用 Guaranteed 級別的服務
此博客來源于:https://edu.51cto.com/lecturer/11062970.html