寫在前面
- 分享一些 K8s 中資源配額管理 Resource Quotas 的筆記
- 博文内容涉及: Resource Quotas(資源配額) 簡單介紹如何開啟 資源配額計算,存儲,對象資源配額 Demo配額作用域的簡單介紹
- 了解不足小夥伴幫忙指正
投我以桃,報之以李。——《大雅·抑》
Resource Quotas 簡單介紹
在 k8s 中,容器、Pod 級别的的計算資源限制設定,可以通過定義 yaml 檔案時的 limits 和 requests 字段來做限制, 通過配置不同的 Limits 和 requests不但可以限制資源 , 還可以實作不同等級的 Qos,同時可以通過 LimitRange 來對命名空間内的所有 pod 計算資源配置做統一的限制管理。 那麼對于叢集級别命名空間的計算資源限制, k8s 提供了什麼解決方案? 對于對象數量又有什麼方式來進行限制,難道可以無限制的建立 pod、cm、svc 麼?
當然不是,對于叢集級别, k8s 可以通過 Resource Quotas 來實作叢集級别的資源配額,實作對每個命名空間的資源消耗總量提供限制。這裡的限制包括:
- 限制命名空間中某種類型的 對象的總數目上限
- 限制命名空間中的 Pod 可以使用的 計算資源的總上限
叢集管理者可以為每個命名空間建立一個或多個 Resource Quota 對象。
當使用者在命名空間下建立資源(如 Pod、Service 等)時,Kubernetes 的 配額系統 會跟蹤叢集的資源使用情況, 以確定使用的資源用量不超過 Resource Quota 中定義的 硬性資源限額。
如果資源建立或者更新請求 違反了配額限制,那麼該請求會報錯(HTTP 403 FORBIDDEN), 并在消息中給出有可能違反的限制。
不管是資源競争還是配額的修改,都不會影響已經建立的資源使用對象。
如果叢集中總的可用資源小于各命名空間中資源配額的總和,那麼可能會導緻資源競争。資源競争時,Kubernetes 系統會遵循先到先得的原則。
對于計算資源,這裡的 Resource Quota 和 LimitRange 職責并不重合,Resource Quota 限制命名空間 pod 總的用量(不考慮配額域),而 LimitRange 限制目前命名空間 中 每個 Pod 或者容器的計算資源。
啟用資源配額
當 API 伺服器 的指令行标志 --enable-admission-plugins= 中包含 ResourceQuota 時, 資源配額會被啟用。當命名空間中存在一個 ResourceQuota 對象時,對于該命名空間而言,資源配額就是開啟的。
如果需要開啟資源配額,需要在 修改 apiservice 元件靜态 pod 的 yaml 檔案 kube-apiserver.yaml
┌──[[email protected]]-[/etc/kubernetes/manifests]
└─$cat kube-apiserver.yaml | grep -i quota
- --enable-admission-plugins=NodeRestriction,ResourceQuota
檢視目前命名空間的 資源配額
┌──[[email protected]]-[/etc/kubernetes/manifests]
└─$kubectl get resourcequotas -A
No resources found
預設情況下,不指定 配額域 的情況,配額配置對目前命名空間有效,指定了配額域的情況,隻對配額域比對的資源有效。
計算資源配額
使用者可以對給定命名空間下的可被請求的 計算資源 總量進行限制。
如果命名空間下的計算資源 (如 cpu 和 memory)的配額被啟用, 則使用者必須為這些資源設定請求值(request)和限制值(limit),否則配額系統将拒絕 Pod 的建立。 可使用 LimitRanger 準入控制器來為沒有設定計算資源需求的 Pod 設定預設值。
┌──[[email protected]]-[~/ansible/quota]
└─$kubectl apply -f my-quota.yaml
resourcequota/object-quota-demo created
┌──[[email protected]]-[~/ansible/quota]
└─$kubectl describe resourcequota object-quota-demo
Name: object-quota-demo
Namespace: liruilong-topo-namespace
Resource Used Hard
-------- ---- ----
limits.cpu 50m 6
limits.memory 100Mi 20Gi
requests.cpu 20m 4
requests.memory 50Mi 15Gi
上面的清單中 ,Used 為目前的計算資源情況,Hard 為配額情況。 配額機制所支援的資源類型
┌──[[email protected]]-[~/ansible/quota]
└─$cat my-quota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-quota-demo
spec:
hard:
limits.cpu: '6' #所有非終止狀态的 Pod,其 CPU 限額總量不能超過該值。
limits.memory: '20Gi' #所有非終止狀态的 Pod,其記憶體限額總量不能超過該值。
requests.cpu: '4' #所有非終止狀态的 Pod,其 CPU 需求總量不能超過該值。
requests.memory: '15Gi' #所有非終止狀态的 Pod,其記憶體需求總量不能超過該值。
#hugepages-<size> 對于所有非終止狀态的 Pod,針對指定尺寸的巨頁請求總數不能超過此值。
#cpu 與 requests.cpu 相同。
#memory 與 requests.memory 相同。
存儲資源配額
使用者可以對給定命名空間下的存儲資源 總量進行限制。此外,還可以根據相關的存儲類(Storage Class)來限制存儲資源的消耗。
┌──[[email protected]]-[~/ansible/quota]
└─$kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
local-path (default) rancher.io/local-path Delete WaitForFirstConsumer false 84d
┌──[[email protected]]-[~/ansible/quota]
└─$
目前隻有一個預設的以本地存儲做的一個 SC,我們用來 Demo。
┌──[[email protected]]-[~/ansible/quota]
└─$kubectl apply -f my-quota-sc.yaml
resourcequota/object-quota-sc-demo created
┌──[[email protected]]-[~/ansible/quota]
└─$kubectl describe resourcequotas object-quota-sc-demo
Name: object-quota-sc-demo
Namespace: liruilong-topo-namespace
Resource Used Hard
-------- ---- ----
local-path.storageclass.storage.k8s.io/persistentvolumeclaims 0 3
local-path.storageclass.storage.k8s.io/requests.storage 0 10Gi
persistentvolumeclaims 0 50Gi
requests.storage 0 20Gi
┌──[[email protected]]-[~/ansible/quota]
└─$
具體可以限制的 存儲資源配額
┌──[[email protected]]-[~/ansible/quota]
└─$cat my-quota-sc.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-quota-sc-demo
spec:
hard:
requests.storage: "20Gi" #所有 PVC,存儲資源的需求總量不能超過該值。
persistentvolumeclaims: "50Gi" #在該命名空間中所允許的 PVC 總量。
local-path.storageclass.storage.k8s.io/requests.storage: "10Gi" #在所有與 <storage-class-name> 相關的持久卷申領中,存儲請求的總和不能超過該值 。
local-path.storageclass.storage.k8s.io/persistentvolumeclaims: 3 #在與 storage-class-name 相關的所有持久卷申領中,命名空間中可以存在的持久卷申領總數
┌──[[email protected]]-[~/ansible/quota]
└─$
對象數量配額
可以使用以下文法對所有标準的、命名空間域的資源類型進行配額設定:
- count/.:用于非核心(core)組的資源
- count/:用于核心組的資源
kubectl create quota test --hard=count/deployments.apps=2,count/replicasets.apps=4,count/pods=3,count/secrets=4 --namespace=myspace
也可以直接通過 yaml 資源檔案的方式配置
┌──[[email protected]]-[~/ansible/quota]
└─$kubectl apply -f my-quota-objects.yaml
resourcequota/object-quota-count-demo created
┌──[[email protected]]-[~/ansible/quota]
└─$kubectl describe resourcequotas object-quota-count-demo
Name: object-quota-count-demo
Namespace: liruilong-topo-namespace
Resource Used Hard
-------- ---- ----
configmaps 1 10
persistentvolumeclaims 0 5
pods 4 15
replicationcontrollers 0 10
resourcequotas 3 5
secrets 4 7
services 0 5
services.loadbalancers 0 5
services.nodeports 0 5
對象數量配額對應的 yaml 檔案
┌──[[email protected]]-[~/ansible/quota]
└─$cat my-quota-objects.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-quota-count-demo
spec:
hard:
configmaps: 10 #在該命名空間中允許存在的 ConfigMap 總數上限。
persistentvolumeclaims: 5 #在該命名空間中允許存在的 PVC 的總數上限。
pods: 15 #在該命名空間中允許存在的非終止狀态的 Pod 總數上限。Pod 終止狀态等價于 Pod 的 .status.phase in (Failed, Succeeded) 為真。
replicationcontrollers: 10 #在該命名空間中允許存在的 ReplicationController 總數上限。
resourcequotas: 5 #在該命名空間中允許存在的 ResourceQuota 總數上限。
services: 5 #在該命名空間中允許存在的 Service 總數上限。
services.loadbalancers: 5 #在該命名空間中允許存在的 LoadBalancer 類型的 Service 總數上限。
services.nodeports: 5 #在該命名空間中允許存在的 NodePort 類型的 Service 總數上限。
secrets: 7 #在該命名空間中允許存在的 Secret 總數上限。
資源配額将整個叢集中的資源總量做了一個靜态劃分,但它并沒有對叢集中的節點做任何限制:不同命名空間中的 Pod 仍然可以運作在同一個節點上,如果期望 pod 均勻的分布到不同的 工作節點,需要考慮使用 pod 的拓撲分布限制來實作。
配額作用域
上面的配額配置中,預設情況下對整個命名空間有效,實際上每個配額都有一組相關的 scope(作用域),配額隻會對作用域内的資源生效。 配額機制僅統計所列舉的作用域的交集中的資源用量。
當一個作用域被添加到配額中後,它會對作用域相關的資源數量作限制。 如配額中指定了允許(作用域)集合之外的資源,會導緻驗證錯誤。
- Terminating :比對所有 spec.activeDeadlineSeconds 不小于 0 的 Pod。
- NotTerminating :比對所有 spec.activeDeadlineSeconds 是 nil 的 Pod。
- BestEffort : 比對所有 Qos 是 BestEffort 的 Pod。
- NotBestEffort : 比對所有 Qos 不是 BestEffort 的 Pod。
- PriorityClass :比對所有引用了所指定的優先級類的 Pods。
activeDeadlineSeconds 表示 Pod 可以運作的最長時間,達到設定的該值後,Pod 會自動停止,BestEffort 表示 Qos 的三個等級中等級最低的一個,盡力而為的,不太可靠的,
┌──[[email protected]]-[~/ansible/quota]
└─$kubectl apply -f my-quota-objects-scop.yaml
resourcequota/object-quota-count-scop-demo created
┌──[[email protected]]-[~/ansible/quota]
└─$kubectl describe resourcequotas object-quota-count-scop-demo
Name: object-quota-count-scop-demo
Namespace: liruilong-topo-namespace
Resource Used Hard
-------- ---- ----
pods 2 15
┌──[[email protected]]-[~/ansible/quota]
└─$cat my-quota-objects-scop.yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: object-quota-count-scop-demo
spec:
hard:
pods: 15 #在該命名空間中允許存在的非終止狀态的 Pod 總數上限。Pod 終止狀态等價于 Pod 的 .status.phase in (Failed, Succeeded) 為真。
scopeSelector:
matchExpressions:
- operator: Exists
scopeName: BestEffort
┌──[[email protected]]-[~/ansible/quota]
└─$
博文參考
https://kubernetes.io/zh-cn/docs/concepts/policy/resource-quotas/