048.集群管理-資源限制實踐
- 2020 年 4 月 8 日
- 筆記
一 實踐規劃
1.1 實踐需求
本實驗通過資源配額和資源配置範圍的配合來控制一個命名空間的資源使用。
集群管理員根據集群用戶的數量來調整集群配置,以達到這個目的:能控制特定命名空間中的資源使用量,最終實現集群的公平使用和成本控制。
需要實現的功能如下:
- 限制運行狀態的Pod的計算資源用量。
- 限制持久存儲卷的數量以控制對存儲的訪問。
- 限制負載均衡器的數量以控制成本。
- 防止濫用網路埠這類稀缺資源。
- 提供默認的計算資源Requests以便於系統做出更優化的調度。
二 實驗步驟
2.1 創建命名空間
[root@k8smaster01 study]# vi namespace.yaml
1 apiVersion: v1 2 kind: Namespace 3 metadata: 4 name: quota-example 5
[root@k8smaster01 study]# kubectl create -f namespace.yaml
[root@k8smaster01 study]# kubectl get namespaces
NAME STATUS AGE
……
quota-example Active 14s
2.2 設置對象數目的資源配額
通過設置限定對象的數量的資源配額,可以控制以下資源的數量:
- 持久存儲卷;
- 負載均衡器;
- NodePort。
[root@k8smaster01 study]# vi object-counts.yaml
1 apiVersion: v1 2 kind: ResourceQuota 3 metadata: 4 name: object-counts 5 spec: 6 hard: 7 persistentvolumeclaims: "2" 8 services.loadbalancers: "2" 9 services.nodeports: "0" 10
[root@k8smaster01 study]# kubectl create -f object-counts.yaml –namespace=quto-example
[root@k8smaster01 study]# kubectl describe quota object-counts –namespace=quota-example
Name: object-counts
Namespace: quota-example
Resource Used Hard
——– —- —-
persistentvolumeclaims 0 2
services.loadbalancers 0 2
services.nodeports 0 0
提示:配額系統會檢測到資源項配額的創建,並且會統計和限制該命名空間中的資源消耗,創建完畢後,配額系統會自動阻止那些使資源用量超過資源配額限定值的請求。
2.3 設置計算資源的資源配額
通過設置限定計算資源的資源配額,限制該命名空間中的計算資源的使用總量。
[root@k8smaster01 study]# vi compute-resources.yaml
1 apiVersion: v1 2 kind: ResourceQuota 3 metadata: 4 name: compute-resources 5 spec: 6 hard: 7 pods: "4" 8 requests.cpu: "1" 9 requests.memory: 1Gi 10 limits.cpu: "2" 11 limits.memory: 2Gi 12
[root@k8smaster01 study]# kubectl create -f compute-resources.yaml –namespace=quota-example
[root@k8smaster01 study]# kubectl describe quota compute-resources –namespace=quota-example
Name: compute-resources
Namespace: quota-example
Resource Used Hard
——– —- —-
limits.cpu 0 2
limits.memory 0 2Gi
pods 0 4
requests.cpu 0 1
requests.memory 0 1Gi
解讀:配額系統會自動防止在該命名空間中同時擁有超過4個非「終止態」的Pod。此外,由於該項資源配額限制了CPU和記憶體的Limits和Requests的總量,因此會強制要求該命名空間下的所有容器都顯式定義CPU和記憶體的Limits和Requests(可使用默認值 Requests默認等於Limits)。
2.4 配置默認Requests和Limits
在命名空間已經配置了限定計算資源的資源配額的情況下,如果嘗試在該命名空間下創建一個不指定Requests和Limits的Pod,由於Pod中沒有指定CPU和記憶體的Requests和Limits,那麼Pod的創建會失敗。為了避免這種失敗,可以使用LimitRange來為這個命名空間下的所有Pod都提供一個資源配置的默認值。
[root@k8smaster01 study]# vi limits.yaml
1 apiVersion: v1 2 kind: LimitRange 3 metadata: 4 name: limits 5 spec: 6 limits: 7 - default: 8 cpu: 200m 9 memory: 512Mi 10 defaultRequest: 11 cpu: 100m 12 memory: 256Mi 13 type: Container 14
[root@k8smaster01 study]# kubectl create -f limits.yaml –namespace=quota-example
[root@k8smaster01 study]# kubectl describe limitranges limits –namespace=quota-example
Name: limits
Namespace: quota-example
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
—- ——– — — ————— ————- ———————–
Container cpu – – 100m 200m –
Container memory – – 256Mi 512Mi –
解讀:在LimitRange創建成功後,用戶在該命名空間下創建未指定資源限制的Pod的請求時,系統會自動為該Pod設置默認的資源限制。
2.5 觸發limits
[root@k8smaster01 study]# kubectl run nginx –image=nginx –replicas=1 –namespace=quota-example
[root@k8smaster01 study]# kubectl run nginx
–image=nginx
–replicas=1
–requests=cpu=100m,memory=256Mi
–limits=cpu=200m,memory=512Mi
–namespace=quota-example
[root@k8smaster01 study]# kubectl get pods –namespace=quota-example
NAME READY STATUS RESTARTS AGE
nginx-78df7bdbcf-mxcql 1/1 Running 0 21s
[root@k8smaster01 study]# kubectl describe quota –namespace=quota-example
解讀:每個Pod在創建時都會消耗指定的資源量,而這些使用量都會被Kubernetes準確跟蹤、監控和管理。
三 指定作用域
3.1 作用域場景
假設並不想為某個命名空間配置默認的計算資源配額,而是希望限定在命名空間內運行的QoS為BestEffort的Pod總數,例如讓集群中的部分資源運行QoS為非BestEffort的服務,而讓閑置的資源運行QoS為BestEffort的服務,即可避免集群的所有資源僅被大量的BestEffortPod耗盡。此需求可通過創建兩個資源配額來實現。
3.2 創建命名空間
[root@k8smaster01 study]# kubectl create namespace quota-scopes
3.3 創建兩個ResourceQuota
[root@k8smaster01 study]# vi best-effort.yaml
1 apiVersion: v1 2 kind: ResourceQuota 3 metadata: 4 name: best-effort 5 spec: 6 hard: 7 pods: "10" 8 scopes: 9 - BestEffort 10
[root@k8smaster01 study]# kubectl create -f best-effort.yaml –namespace=quota-scopes
[root@k8smaster01 study]# vi not-best-effort.yaml
1 apiVersion: v1 2 kind: ResourceQuota 3 metadata: 4 name: not-best-effort 5 spec: 6 hard: 7 pods: "4" 8 requests.cpu: "1" 9 requests.memory: 1Gi 10 limits.cpu: "2" 11 limits.memory: 2Gi 12 scopes: 13 - NotBestEffort 14
[root@k8smaster01 study]# kubectl create -f not-best-effort.yaml –namespace=quota-scopes
[root@k8smaster01 study]# kubectl describe quota –namespace=quota-scopes
Name: best-effort
Namespace: quota-scopes
Scopes: BestEffort
* Matches all pods that do not have resource requirements set. These pods have a best effort quality of service.
Resource Used Hard
——– —- —-
pods 0 10
Name: not-best-effort
Namespace: quota-scopes
Scopes: NotBestEffort
* Matches all pods that have at least one resource requirement set. These pods have a burstable or guaranteed quality of service.
Resource Used Hard
——– —- —-
limits.cpu 0 2
limits.memory 0 2Gi
pods 0 4
requests.cpu 0 1
requests.memory 0 1Gi
提示:創建完成後,對於沒有配置Requests的Pod將會被名為best-effort的ResourceQuota限制;而配置了Requests的Pod會被名為not-best-effort的ResourceQuota限制。
3.4 創建Pod
[root@k8smaster01 study]# kubectl run best-effort-nginx –image=nginx –replicas=8 –namespace=quota-scopes
[root@k8smaster01 study]# kubectl run not-best-effort-nginx
–image=nginx
–replicas=2
–requests=cpu=100m,memory=256Mi
–limits=cpu=200m,memory=512Mi
–namespace=quota-scopes
[root@k8smaster01 study]# kubectl get pods –namespace=quota-scopes
解讀:名為best-effort-nginx的Deployment因為沒有配置Requests和Limits,所以它的QoS級別為BestEffort,因此它的創建過程由best-effort資源配額項來限制,而not-best-effort資源配額項不會對它進行限制。best-effort資源配額項沒有限制Requests和Limits,因此best-effort-nginx Deployment可以成功創建8個Pod。
名為not-best-effort-nginx的Deployment因為配置了Requests和Limits,且二者不相等,所以它的QoS級別為Burstable,因此它的創建過程由not-best-effort資源配額項限制,而best-effort資源配額項不會對它進行限制。not-best-effort資源配額項限制了Pod的Requests和Limits的總上限,not-best-effort-nginx Deployment並沒有超過這個上限,所以可以成功創建兩個Pod。
3.5 觸發資源配額
[root@k8smaster01 study]# kubectl describe quota –namespace=quota-scopes
Name: best-effort
Namespace: quota-scopes
Scopes: BestEffort
* Matches all pods that do not have resource requirements set. These pods have a best effort quality of service.
Resource Used Hard
——– —- —-
pods 8 10
Name: not-best-effort
Namespace: quota-scopes
Scopes: NotBestEffort
* Matches all pods that have at least one resource requirement set. These pods have a burstable or guaranteed quality of service.
Resource Used Hard
——– —- —-
limits.cpu 400m 2
limits.memory 1Gi 2Gi
pods 2 4
requests.cpu 200m 1
requests.memory 512Mi 1Gi
解讀:如上所示best-effort資源配額項已經統計了在best-effort-nginx Deployment中創建的8個Pod的資源使用資訊,not-best-effort資源配額項也已經統計了在not-best-effort-nginx Deployment中創建的兩個Pod的資源使用資訊。
結論:資源配額的作用域(Scopes)提供了一種將資源集合分割的機制,可以使集群管理員更加方便地監控和限制不同類型的對象對各類資源的使用情況,同時為資源分配和限制提供更大的靈活度和便利性。
四 資源管理總結
Kubernetes中資源管理的基礎是容器和Pod的資源配置(Requests和Limits)。容器的資源配置指定了容器請求的資源和容器能使用的資源上限, Pod的資源配置則是Pod中所有容器的資源配置總和上限。
通過資源配額機制,可以對命名空間中所有Pod使用資源的總量進行限制,也可以對這個命名空間中指定類型的對象的數量進行限制。
使用作用域可以讓資源配額只對符合特定範圍的對象加以限制,因此作用域機制可以使資源配額的策略更加豐富、靈活。
如果需要對用戶的Pod或容器的資源配置做更多的限制,則可以使用資源配置範圍(LimitRange)來達到這個目的。LimitRange可以有效地限制Pod和容器的資源配置的最大、最小範圍,也可以限制Pod和容器的Limits與Requests的最大比例上限,此外LimitRange還可以為Pod中的容器提供默認的資源配置。
Kubernetes基於Pod的資源配置實現了資源服務品質(QoS)。不同QoS級別的Pod在系統中擁有不同的優先順序:高優先順序的Pod有更高的可靠性,可以用於運行可靠性要求較高的服務;低優先順序的Pod可以實現集群資源的超售,可以有效地提高集群資源利用率。