03.01 k8s實踐(六):Pod資源管理

一、計算資源管理(Compute Resources)

1. 概念

  在配置Pod時,我們可以為其中的每個容器指定需要使用的計算資源(CPU和內存)。計算資源的配置項分為兩種:Requests和Limits。Requests表示容器希望被分配到的、可完全保證的資源量(資源請求量);Limits是容器最多能使用的資源量的上限(資源限制量)。

  資源請求量能夠保證Pod有足夠的資源來運行,資源限制量則是防止某個Pod無限制地使用資源,導致其他Pod崩潰。

  我們創建一個pod時,可以指定容器對CPU和內存的資源請求量及資源限制量,它們並不在pod裡定義,而是針對每個容器單獨指定。pod對資源的請求量和限制量是它所包含的所有容器的請求量和限制量之和。

CPU和內存的Requests和Limits有如下特點:


  • Requests和Limits都是可選的。在Pod創建和更新時,如果未設置Requests和Limits,則使用系統提供的默認值,該默認值取決於集群配置。
  • 如果Requests沒有配置,默認被設置等於Limits。
  • 任何情況下Limits都應該設置為大於或等於Requests。

2. 查看節點資源總量

2.1 命令方式

<code>[root@master ~]# kubectl describe nodes /<code>
k8s實踐(六):Pod資源管理

2.2 Dashboard方式

k8s實踐(六):Pod資源管理

k8s實踐(六):Pod資源管理

3. requests

3.1 創建包含資源requests的pod

<code>[root@master ~]# more requests-pod.yaml             apiVersion: v1kind: Podmetadata:  name: requests-podspec:  containers:  - image: busybox    name: busybox     args:    - /bin/sh    - -c    - sleep 60000    resources:      requests:          #資源申請        cpu: 500m        #容器申請500毫核(一個CPU核心時間的1/2)        memory: 500Mi    #容器申請500M內存  nodeName: node01[root@master ~]# kubectl apply -f requests-pod.yaml pod/requests-pod created/<code>

在Kubernetes系統上,l個單位的CPU相當於虛擬機上的l顆虛擬CPU(vCPU)或物理機上的一個超線程(Hyperthread,或稱為一個邏輯CPU),它支持分數計量方式,一個核心(1core)相當於1000個微核心(millicores),因此500m相當於是0.5個核心,即二分之一個核心。內存的計量方式與日常使用方式相同,默認單位是字節,也可以使用E,P、T、G、M和K作為單位後綴,或Ei、Pi、Ti、Gi、Mi和Ki形式的單位後綴。

3.2 查看pod

<code>[root@master ~]# kubectl get po -o wide[root@master ~]# kubectl describe po requests-pod/<code>
k8s實踐(六):Pod資源管理

3.3 基於requests的pod調度機制

3.3.1 不指定requests

<code>[root@master ~]# kubectl delete all --all[root@master ~]# more deploy-busybox.yaml apiVersion: apps/v1kind: Deploymentmetadata:  name: busyboxspec:  selector:    matchLabels:      env: prod  replicas: 10   template:    metadata:      labels:        env: prod    spec:      containers:      - name: busybox        image: busybox        args:        - /bin/sh        - -c        - sleep 60000      nodeSelector:        node: node01[root@master ~]# kubectl apply -f deploy-busybox.yaml deployment.apps/busybox created/<code>
k8s實踐(六):Pod資源管理

若不指定資源請求量,節點node01上可成功運行10個pod

3.3.2 OutOfmemory

<code>[root@master ~]# more requests-pod.yaml               apiVersion: v1kind: Podmetadata:  name: requests-podspec:  containers:  - image: busybox    name: busybox     args:    - /bin/sh    - -c    - sleep 60000    resources:      requests:          #資源申請        cpu: 500m        #容器申請500毫核(一個CPU核心時間的1/2)        memory: 800Mi    #容器申請800M內存  nodeName: node01[root@master ~]# more requests-pod-2.yaml                             apiVersion: v1kind: Podmetadata:  name: requests-pod-2spec:  containers:  - image: busybox    name: busybox     args:    - /bin/sh    - -c    - sleep 60000    resources:      requests:        cpu: 500m         memory: 800Mi  nodeName: node01[root@master ~]# kubectl apply -f requests-pod.yaml pod/requests-pod created[root@master ~]# kubectl get po -o wide             NAME           READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATESrequests-pod   1/1     Running   0          4s    10.244.1.67   node01   <none>           <none>[root@master ~]# kubectl apply -f requests-pod-2.yaml pod/requests-pod-2 created[root@master ~]# kubectl get po -o wide               NAME             READY   STATUS        RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATESrequests-pod     1/1     Running       0          14s   10.244.1.67   node01   <none>           <none>requests-pod-2   0/1     OutOfmemory   0          2s    <none>        node01   <none>           <none>/<none>/<none>/<none>/<none>/<none>/<none>/<code>
k8s實踐(六):Pod資源管理

報節點node01 內存資源不足,pod requests-pod-2調度失敗

3.3.3 OutOfcpu

<code>[root@master ~]# kubectl delete all --all [root@master ~]# more requests-pod.yaml apiVersion: v1kind: Podmetadata:  name: requests-podspec:  containers:  - image: busybox    name: busybox     args:    - /bin/sh    - -c    - sleep 60000    resources:      requests:          #資源申請        cpu: 1           #容器申請一個CPU核心時間        memory: 80Mi    #容器申請80M內存  nodeName: node01[root@master ~]# more requests-pod-2.yaml   apiVersion: v1kind: Podmetadata:  name: requests-pod-2spec:  containers:  - image: busybox    name: busybox     args:    - /bin/sh    - -c    - sleep 60000    resources:      requests:        cpu: 1         memory: 80Mi  nodeName: node01[root@master ~]# kubectl apply -f requests-pod.yaml pod/requests-pod created[root@master ~]# kubectl get po -o wide             NAME           READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATESrequests-pod   1/1     Running   0          4s    10.244.1.68   node01   <none>           <none>[root@master ~]# kubectl apply -f requests-pod-2.yaml pod/requests-pod-2 created[root@master ~]# kubectl get po -o wide               NAME             READY   STATUS     RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATESrequests-pod     1/1     Running    0          13s   10.244.1.68   node01   <none>           <none>requests-pod-2   0/1     OutOfcpu   0          2s    <none>        node01   <none>           <none>/<none>/<none>/<none>/<none>/<none>/<none>/<code> 
k8s實踐(六):Pod資源管理

報節點node01 cpu資源不足,pod requests-pod-2調度失敗

3.3.4 結論

  • 調度器在調度時並不關注各類資源在當前時刻的實際使用量(node01可以同時運行10個busybox pod)
  • 調度器只關心節點上部署的所有pod的資源申請量之和(超出時就會報OutOfmemory或OutOfcpu)
  • 儘管現有pods的資源實際使用量可能小於它的申請量,但如果使用基於實際資源消耗量的調度算法將打破系統為這些已部署成功的pods提供足夠資源的保證
k8s實踐(六):Pod資源管理

4. limits

4.1 創建包含資源limits的pod

<code>[root@master ~]# more limited-pod.yaml apiVersion: v1kind: Podmetadata:  name: limited-podspec:  containers:  - image: busybox    command: ["sleep","600000"]    name: busybox     resources:      requests:         #資源申請        cpu: 200m       #容器申請200毫核(一個CPU核心時間的1/5)        memory: 80Mi    #容器申請80M內存      limits:           #資源限制        cpu: 2          #容器最大允許使用2核CPU        memory: 2Gi     #容器最大允許使用2GB內存  nodeName: node01[root@master ~]# kubectl apply -f limited-pod.yaml pod/limited-pod created[root@master ~]# kubectl get po -o wideNAME          READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATESlimited-pod   1/1     Running   0          12s   10.244.1.75   node01   <none>           <none>/<none>/<code>

創建pod limited-pod,資源限制為cpu 2核,內存2G

4.2 limits overcommitted

4.2.1 創建pod

k8s實踐(六):Pod資源管理

k8s實踐(六):Pod資源管理

創建limited-pod和limited-pod-2,cpu為2核,內存2G,pod運行正常。

4.2.2 查看node01資源使用

k8s實踐(六):Pod資源管理

4.2.3 結論

  • 節點上所有pod的資源limits之和可以超過節點資源總量的100%
  • requests不同的是,limits並不會影響pod的調度結果
k8s實踐(六):Pod資源管理

二、服務質量管理(QoS)

1. 概念

  前面曾提到過,Kubernetes允許節點資源對Limits的過載使用,這意味著節點無法同時滿足其上的所有Pod對象以資源滿載的方式運行。於是,在內存資源緊缺時,應該以何種次序先後終止哪些Pod對象?Kubernetes無法自行對此做出決策,它需要藉助於Pod對象的優先級完成判定。根據Pod對象的requests和limits屬性,Kubernetes將Pod象歸類到BestEffort、Burstable和Guaranteed三個服務質量(Quality of Service,QoS)類別下,具體說明如下。


  • Guaranteed:每個容器都為CPU資源設置了具有相同值的requests和limits屬性,以及每個容器都為內存資源設置了具有相同值的requests和limits屬性的Pod資源會自動歸屬於此類別,這類Pod資源具有最高優先級。
  • Burstable:至少有一個容器設置了CPU或內存資源requests屬性,但不滿足Guaranteed類別要求的Pod資源將自動歸屬於此類別,它們具有中等優先級。
  • BestEffort:未為任何一個容器設置requests或limits屬性的Pod資源將自動歸屬於此類別,它們的優先級為最低級別。

在一個overcommitted的系統,QoS等級決定著哪個容器第一個被殺掉,這樣釋放出的資源可以提供給高優先級的pod使用。BestEffort等級的pod首先被殺掉,其次是Burstable pod, 最後是Guaranteed pod。Guaranteed pod只有在系統進程需要內存時才會被殺掉。

2. 定義QoS

資源的requests、limits和QoS等級

k8s實踐(六):Pod資源管理

3. 相同等級QoS容器處理

k8s實踐(六):Pod資源管理

每個行狀態容器都有其OOM得分,得分越高越會被優先殺死。OOM得分主要根據兩個緯度進行計算:由QoS類別繼承而來的默認分值和容器的可用內存資源比例。同等類別的Pod資源的默認分值相同,同等級別優先級的Pod資源在OOM時,與自身的requests屬性相比,其內存佔用比例最大的Pod對象將被首先殺死。

三、資源配置範圍管理(LimitRange)

1. 概念

  默認情況下,Kubernetes中所有容器都沒有任何CPU和內存限制。LimitRange用來給Namespace增加一個資源限制,包括最小、最大和默認資源。

2. 為什麼需要LimitRange

  為單個容器設置資源requests和limits很有必要性:1.提升QoS等級,防止在OOM時被首先kill;2.默認情況下Pod會以無限制的CPU和內存運行,很有可能因故吞掉所在工作節點上的所有可用計算資源。

  通過配置Pod的計算資源Requests和Limits,我們可以限制Pod的資源使用,但對於Kubemetes集群管理員而言,配置每一個Pod的Requests和Limits是煩瑣且限制性過強的。更多時,我們需要的是對集群內Requests和Limits的配置做一個全局的統一的限制。

3 創建LimitRange

<code>[root@master ~]# more limits.yaml apiVersion: v1kind: LimitRangemetadata:  name: limitrange spec:  limits:  - type: Pod                      #指定整個pod的資源limits    min:                           #pod中所有容器的Requests值的總和的下限      cpu: 50m      memory: 5Mi    max:                           #pod中所有容器的Limits值的總和的上限      cpu: 1      memory: 1Gi  - type: Container                #指定容器的資源限制    defaultRequest:                #容器Requests默認值      cpu: 100m      memory: 10Mi    default:                       #容器Limits默認值      cpu: 200m      memory: 100Mi    min:                           #pod中所有容器的Requests值的下限      cpu: 50m      memory: 5Mi    max:                           #pod中所有容器的Limits值的上限      cpu: 1      memory: 1Gi    maxLimitRequestRatio:          #每種資源Requests與Limits的最大比值      cpu: 4      memory: 10  - type: PersistentVolumeClaim    #指定請求PVC存儲容量的最小值和最大值    min:      storage: 1Gi    max:      storage: 10Gi[root@master ~]# kubectl apply -f limits.yaml limitrange/limitrange created/<code>

LimitRange資源支持限制Container、Pod和PersistentVolumeClaim三種資源對象的系統資源用量

4. 查看LimitRange

<code>[root@master ~]# kubectl describe limitranges limitrange /<code>
k8s實踐(六):Pod資源管理

5. LimitRange測試

5.1 requests和limits默認值

新建pod

<code>[root@master ~]# more default.yaml apiVersion: v1kind: Podmetadata:  name: default-podspec:  containers:  - image: busybox    name: busybox     args:    - /bin/sh    - -c    - sleep 60000[root@master ~]# kubectl apply -f default.yaml pod/default-pod created[root@master ~]# kubectl get po -o wide           NAME            READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATESdefault-pod     1/1     Running   0          8s    10.244.2.43   node02   <none>           <none>limited-pod     1/1     Running   1          22h   10.244.1.81   node01   <none>           <none>limited-pod-2   1/1     Running   1          22h   10.244.1.82   node01   <none>           <none>/<none>/<none>/<none>/<none>/<none>/<code>

新建pod default-pod,yaml中未指定requests和limits

查看pod

k8s實踐(六):Pod資源管理

容器的requests和limits與我們在LimitRange對象中設置的一致。

5.2 強制限制

5.2.1 cpu超限制

<code>[root@master ~]# kubectl run  cpu-over --image=busybox --restart=Never --requests='cpu=1200m,memory=30Mi' sleep 6000 The Pod "cpu-over" is invalid: spec.containers[0].resources.requests: Invalid value: "1200m": must be less than or equal to cpu limit/<code>

5.2.2 內存超限制

<code>[root@master ~]# kubectl run  cpu-over --image=busybox --restart=Never --requests='cpu=200m,memory=300Mi' sleep 6000 The Pod "cpu-over" is invalid: spec.containers[0].resources.requests: Invalid value: "300Mi": must be less than or equal to memory limit/<code>
k8s實踐(六):Pod資源管理

四、資源配額管理(ResourceQuota)

1. 概念

  Kubemetes可以通過存活探針(liveness probe)檢查容器是否還在運行。可以為pod中的每個容器單獨指定存活探針。如果探測失敗,Kubemetes將定期執行探針並重新啟動容器。

  資源配額(Resource Quotas)是用來限制用戶資源用量的一種機制,限制Pod的請求不會超過配額,需要在namespace中創建一個ResourceQuota對象

資源配額類型:

  • 計算資源。包括 cpu 和 memory
  • 存儲資源。包括存儲資源的總量以及指定 storage class 的總量
  • 對象數。即可創建的對象的個數

2. ResourceQuota作用

  儘管LimitRange資源能限制單個容器、Pod及PVC等相關計算資源或存儲資源的用量,但用戶依然可以創建數量眾多的此類資源對象進而侵佔所有的系統資源。於是,Kubernetes提供了ResourceQuota資源用於定義名稱空間的對象數量或系統資源配額。

3. 為CPU和內存創建ResourceQuota

<code>[root@master ~]# more quota-cpu-memory.yaml                apiVersion: v1kind: ResourceQuotametadata:  name: cpu-and-memspec:  hard:    requests.cpu: 1    requests.memory: 1Gi    limits.cpu: 1500m    limits.memory: 1500Mi[root@master ~]# kubectl apply -f quota-cpu-memory.yaml resourcequota/cpu-and-mem created/<code>
k8s實踐(六):Pod資源管理

LimitRange應用於單獨的pod,ResourceQuota應用於命名空間中所有的pod

3.1 查看ResourceQuota

<code>[root@master ~]# kubectl describe resourcequotas cpu-and-mem/<code>
k8s實踐(六):Pod資源管理

3.2 resourcequota測試

<code>[root@master ~]# kubectl run  quota-test --image=busybox  --limits='cpu=200m,memory=90Mi' --replicas=10 sleep 6000kubectl run --generator=deployment/apps.v1 is DEPRECATED and will be removed in a future version. Use kubectl run --generator=run-pod/v1 or kubectl create instead.deployment.apps/quota-test created[root@master ~]# kubectl get po -o wideNAME                          READY   STATUS    RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATESdefault-pod                   1/1     Running   0          31m     10.244.2.52   node02   <none>           <none>quota-test-5d4f79c664-2tq66   1/1     Running   0          5m44s   10.244.1.90   node01   <none>           <none>quota-test-5d4f79c664-cvptj   1/1     Running   0          5m44s   10.244.0.68   master   <none>           <none>quota-test-5d4f79c664-ph79j   1/1     Running   0          5m44s   10.244.2.64   node02   <none>           <none>quota-test-5d4f79c664-tvwpz   1/1     Running   0          5m44s   10.244.2.65   node02   <none>           <none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<none>/<code>

發現只運行了4個pod,原因是requests的cpu為200(requests值未設置時與limits相同),resourcequotas中requests.cpu的限制值為1000m,系統之前使用了100m(default-pod),故只有900m可用,所以最多隻能新建4個pod

k8s實踐(六):Pod資源管理

4. 限制可創建對象的個數

<code>[root@master ~]# more quota-count.yaml apiVersion: v1kind: ResourceQuotametadata:  name: count-quota spec:  hard:    pods: 10    replicationcontrollers: 5    secrets: 10    configmaps: 10    persistentvolumeclaims: 5    services: 5    services.loadbalancers: 1    services.nodeports: 2    ssd.storageclass.storage.k8s.io/persistentvolumeclaims: 2[root@master ~]# kubectl apply -f quota-count.yaml resourcequota/count-quota created/<code>

該命名空間最多創建10個pod、5個Replication Controller、10個Secret、10個ConfigMap、4個PVC、5個Service、1個LoadBalancer、2個NodePort和2個StorageClass為ssd的PVC。

pod

Replication Controller

Secret

ConfigMap

PVC

Service

LoadBalancer

NodePort

ssd PVC

10

5

10

10

4

5

1

2

2

4.1 查看ResourceQuota

<code>[root@master ~]# kubectl describe resourcequotas count-quota /<code>
k8s實踐(六):Pod資源管理

4.2 resourcequota測試

<code>[root@master ~]# kubectl create service nodeport nodeport01 --tcp=5678:8080service/nodeport01 created[root@master ~]# kubectl create service nodeport nodeport02 --tcp=5678:8081service/nodeport02 created[root@master ~]# kubectl create service nodeport nodeport03 --tcp=5678:8082Error from server (Forbidden): services "nodeport03" is forbidden: exceeded quota: count-quota, requested: services.nodeports=1, used: services.nodeports=2, limited: services.nodeports=2/<code>

services.nodeports只能創建2個,當創建第三個時報錯。

k8s實踐(六):Pod資源管理

5. 特定的pod狀態或者QoS等級指定配額

<code>[root@master ~]# more quota-scoped.yaml apiVersion: v1kind: ResourceQuotametadata:  name: scoped-quota spec:  scopes:  - BestEffort  - NotTerminating  hard:    pods: 4[root@master ~]# kubectl apply -f quota-scoped.yaml resourcequota/scoped-quota created/<code>

這個quota只會應用於擁有BestEffort QoS以及沒有設置有效期的pod上,這樣的pod只允許存在4個。

5.1 查看ResourceQuota

<code>[root@master ~]# kubectl describe resourcequotas scoped-quota /<code>
k8s實踐(六):Pod資源管理

resourcequota測試思路同cpu-and-mem和count-quota,這裡不再贅述。

本文所有腳本和配置文件已上傳github:https://github.com/loong576/k8s-Managing-pods-computational-resources.git


分享到:


相關文章: