高效配置 Kubernetes 資源限制的實戰技巧
在實際生產環境中,Pod的調度規則設置和Pod資源管理算是優化應用配置的的兩大重要手段。前面文章已經講解過Pod的多種調度規則。
今天講解一下K8S的資源限制相關知識,篇幅有點長,請耐心看完。
一、資源限制
1. 概述
Kubernetes 允許你為每個容器(Pod 中的每個容器)設置資源的 請求(Requests) 和 限制(Limits),用于指定單個容器的資源使用范圍,防止容器過度消耗節點資源。
- Requests:容器啟動時 調度器 將根據請求的資源量來決定將容器調度到哪個節點。請求的資源量是容器運行時所需的最小資源,所調度到的節點上確保容器至少可以獲得這些資源。
- Limits:限制是容器可以使用的最大資源量。如果容器超出了這個限制,Kubernetes 會采取一定措施,如限制 CPU 或殺死容器(內存溢出時會殺死容器)。
2. 作用
- 限制(limits)容器使用的最大資源量。
- 提供資源請求值(requests),確保容器啟動時至少有一定的資源。
- 防止單個容器過度使用資源而影響其他容器。
3. 配置
vim nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx-container
image: docker.m.daocloud.io/nginx:1.25
resources: # 定義資源限制
requests: # 資源請求
memory: "256Mi" # 容器至少需要 256 MiB 的內存
cpu: "500m" # 容器至少需要 500 毫核(0.5 核 CPU)
limits: # 資源限制
memory: "512Mi" # 容器最多可以使用 512 MiB 的內存
cpu: "1" # 容器最多可以使用 1 核 CPU
查看Pod的資源限制:
kubectl describe pod nginx-pod
二、資源配額
1. 概念
資源配額(Resource Quotas)是針對 命名空間 設置的資源總量限制。它控制一個命名空間內所有資源(如 Pod、服務、持久卷)的最大總量,確保資源在多個命名空間之間公平分配。
2. 作用
- 限制命名空間內所有資源的總量。
- 防止單個命名空間耗盡集群資源。
- 適合多租戶環境,幫助實現公平分配。
3. 配額類型
資源配額可以包含以下幾種資源類型的限制:
- CPU 和內存:限制命名空間內所有容器的 CPU 和內存資源總量。
- Pod 數量:限制命名空間內允許創建的 Pod 數量。
- 服務(Services):限制命名空間內允許創建的服務數量。
- 副本控制器(Replicasets):限制命名空間內允許創建的副本控制器的數量。
- 持久卷聲明(PersistentVolumeClaims):限制命名空間內允許創建的持久卷聲明的數量。
- 鏡像:限制命名空間內鏡像的總數。
4. 配置
vim quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: quota
namespace: test-quota
spec:
hard: # 硬限制,超出配額限制,將阻止創建對象資源
requests.cpu: "4" # 最多允許使用 4 核 CPU。
requests.memory: "8Gi" # 最多允許使用 8 GiB 內存
limits.cpu: "8" # 最多允許使用 8 核 CPU
limits.memory: "16Gi" # 最多允許使用 16 GiB 內存
pods: "10" # 最多允許創建 10 個 Pod。
查看配額配置:
[root@k8s-master data]# kubectl get quota -n test-quota
NAME AGE REQUEST LIMIT
quota 17s pods: 0/10, requests.cpu: 0/4, requests.memory: 0/8Gi limits.cpu: 0/8, limits.memory: 0/16Gi
[root@k8s-master data]# kubectl describe quota -n test-quota
Name: quota
Namespace: test-quota
Resource Used Hard
-------- ---- ----
limits.cpu 0 8
limits.memory 0 16Gi
pods 0 10
requests.cpu 0 4
requests.memory 0 8Gi
你可以自行創建pod測試一下配額消耗情況。
注意事項:
- 配額是針對整個命名空間的,不直接影響單個 Pod 或容器。
- 如果命名空間內的資源總量達到配額上限,則無法創建新的資源對象(如 Pod)。
三、限制范圍
1. 概念
限制范圍(LimitRange)是針對 命名空間 內的 容器或 Pod 設置默認的資源請求和限制。當用戶未在 Pod 或容器中顯式定義資源請求和限制時,LimitRange 會為這些資源設置默認值。此外,它還能設置最小和最大資源范圍,防止用戶配置不合理的資源請求或限制。
2. 作用
- 為未設置資源請求和限制的容器設置默認值。
- 限制資源請求和限制的最小值和最大值,防止配置不合理的資源規格。
- 與 ResourceQuota 配合使用,確保命名空間內的資源分配合理。
3. 配置
vim limit-pod.yaml
apiVersion: v1
kind: LimitRange
metadata:
name: container-limits
namespace: test-limits
spec:
limits:
- type: Container
max: # 定義最大可使用資源
memory: "1Gi"
cpu: "1"
min: # 定義最小資源需求
memory: "128Mi"
cpu: "200m"
default: # 定義默認資源需求
memory: "512Mi"
cpu: "500m"
defaultRequest: # 默認請求值
memory: "256Mi" # 默認內存請求為256Mi
cpu: "300m" # 默認CPU請求為300m
查看資源限制:
[root@k8s-master data]# kubectl describe limitrange -n test-limits
Name: container-limits
Namespace: test-limits
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
---- -------- --- --- --------------- ------------- -----------------------
Container cpu 200m 1 300m 500m -
Container memory 128Mi 1Gi 256Mi 512Mi
4. 注意事項
- 默認值:當容器沒有設置 requests 或 limits 時,LimitRange 會應用默認值。
- 最小值和 最大值 :約束資源請求和限制的范圍。
- 默認請求值 (defaultRequest):為未設置 requests 的容器設置默認的資源請求值。
四、三者的對比
特性 | 資源限制 | 資源配額 | 限制范圍 |
應用范圍 | 單個容器(Pod 的每個容器) | 整個命名空間 | 命名空間內的每個容器或 Pod |
作用層級 | 容器級別 | 命名空間級別 | 容器級別,但規則在命名空間級別生效 |
主要作用 | 限制單個容器的資源使用 | 限制命名空間的總資源使用量 | 提供默認值,并限制資源配置范圍 |
使用場景 | 精細控制容器資源消耗 | 控制命名空間的資源總量,適合多租戶場景 | 提供資源默認值,防止用戶配置不合理 |
限制方式 | 超出限制時限制 CPU 或殺死內存溢出的容器 | 超出限制時拒絕創建新的資源 | 不符合范圍或默認值的資源配置被拒絕 |
正面影響 | 精確控制單個容器資源使用量,保障容器性能 | 保障資源公平分配,避免資源耗盡 | 提供合理默認值,防止不合理配置 |
負面影響 | 配置不合理可能影響容器調度或性能,資源浪費 | 配額不足可能導致資源瓶頸,配置復雜 | 默認值不合理可能導致浪費或性能問題 |
典型配置場景 | 單個 Pod 運行敏感應用 | 防止命名空間獨占集群資源 | 給初學者提供合理的默認值或防止配置錯誤 |
五、三者的聯合使用
在實際生產環境中,通常會同時使用 Resource Limits、Resource Quotas 和 LimitRange 來實現資源管理的細粒度控制和全局約束。
1. 配置流程
(1) 定義 LimitRange:
- 為命名空間設置合理的默認資源請求和限制值。
- 確保用戶未指定資源時,自動應用默認配置。
(2) 設置 Resource Limits:
- 在每個 Pod 的容器級別設置具體的 requests 和 limits。
- 保證關鍵服務擁有明確的資源保障和上限,防止意外使用超出范圍。
(3) 配置 Resource Quotas:
- 為命名空間設置資源總量的硬限制。
- 防止某個命名空間消耗過多的集群資源,影響其他租戶。
2. 工作流程
(1) Pod 調度時:
- 如果未定義 requests 和 limits,LimitRange 提供默認值。
- 調度器根據 requests 選擇合適的節點。
(2) 運行時資源限制:
- 容器運行時會受到 Resource Limits 的約束。
- 超過 CPU 限制時被限制計算能力;超過內存限制時可能被殺死。
(3) 命名空間資源控制:
ResourceQuota 檢查命名空間內的資源總量,超過總量- 限制時,拒絕創建新資源。