k8s中計算資源策略 Limit Range


文章轉載自:https://www.kuboard.cn/learning/k8s-advanced/policy/lr.html

默認情況下,容器在 Kubernetes 集群上運行時,不受 計算資源 的限制。使用 Resource quota,集群管理員可以針對名稱空間限定資源的使用情況。在名稱空間內部,一個 Pod(或容器)的資源消耗不受限制。此時的顧慮在於,可能有一個 Pod(或容器)獨占了名稱空間的大部分資源。Limit Range 是一種用來限定名稱空間內 Pod(或容器)可以消耗資源數量的策略(Policy)。

Kubernetes LimitRange 對象可以:

  • 限制名稱空間中每個 Pod 或容器的最小最大計算資源
  • 限制名稱空間中每個 PersistentVolumeClaim 可使用的最小最大存儲空間
  • 限制名稱空間中計算資源請求request、限定limit之間的比例
  • 設置名稱空間中默認的計算資源的 request/limit,並在運行時自動注入到容器中

啟用 Limit Range

執行命令 kubectl api-resources 可查看您的集群是否支持 Limit Range,輸出結果如下所示,通常 LimitRange 是默認啟用的。

NAME                              SHORTNAMES   APIGROUP                       NAMESPACED   KIND
bindings                                                                      true         Binding
componentstatuses                 cs                                          false        ComponentStatus
configmaps                        cm                                          true         ConfigMap
endpoints                         ep                                          true         Endpoints
events                            ev                                          true         Event
limitranges                       limits                                      true         LimitRange
namespaces                        ns                                          false        Namespace
nodes                             no                                          false        Node
persistentvolumeclaims            pvc                                         true         PersistentVolumeClaim
persistentvolumes                 pv                                          false        PersistentVolume
pods                              po                                          true         Pod
podtemplates                                                                  true         PodTemplate

基本介紹

  • 集群管理員在名稱空間中創建一個 LimitRange 對象
  • 用戶在名稱空間中創建工作負載等對象,例如 Pod、Container、PersistentVolumeClaim 等
  • 針對那些沒有設置 計算資源請求request和限制limit 的 Pod 和容器,LimitRanger 根據名稱空間中的 LimitRange 對象為其設定默認的資源請求和響應,並確保 Pod 和容器對計算資源的實際消耗不會超過指定的值
  • 如果創建或更新對象(Pod、Container、PersistentVolumeClaim)的請求與 Limit Range 的限定相沖突,apiserver 將返回 HTTP status 狀態碼 403 FORBIDDEN,以及相應的錯誤提示信息
  • 如果名稱空間中激活了 limit range 來限定 cpu 和內存等計算資源的使用,則,用戶創建 Pod、Container 時,必須指定 cpu 或內存的 request 和 limit,否則系統將拒絕創建 Pod
  • Kubernetes 只在 Pod 創建階段檢查 LimitRange 的限定,而不在 Pod 運行時執行任何檢查

LimitRange 對象激活后,再創建Pod、Container、PersistentVolumeClaim,必須指定 cpu 或內存的 request 和 limit,否則系統將拒絕創建 Pod
先創建的Pod、Container、PersistentVolumeClaim,然后再創建激活LimitRange 對象。沒有設置 計算資源請求request和限制limit 的 Pod 和容器,LimitRanger 根據名稱空間中的 LimitRange 對象為其設定默認的資源請求和響應

使用 LimitRange 的例子有:

  • 在一個總容量為 8G內存 16核CPU 的 2 節點集群上,限定某個名稱空間中的 Pod 使用 100m的CPU請求(request)且不超過 500m的CPU上限(limit),200Mi的內存請求(request)且不超過 600Mi的內存上線(limit)
  • 為沒有定義cpu和內存請求的容器,指定默認的 CPU 請求(request)和限制(limit)均為 150m,默認的內存請求為 300Mi

當名稱空間總的 limit 小於名稱空間中 Pod/Container 的 limit 之和時,將發生資源爭奪的現象,容器或者 Pod 將不能創建。
在資源爭奪現象發生時,或者修改 limit range 的時候,這兩種情況都不會影響到已經創建的 Pod/Container。

限定容器的計算資源

假設有一個 Pod 包含 4個容器,每個容器都定義了 spec.resource,此時 LimitRanger 管理控制器在處理該 Pod 中的 4個容器時,處理方式是不一樣的。

演示步驟如下:
1.執行如下命令創建名稱空間 limitrange-demo

kubectl create namespace limitrange-demo

將 kubectl 默認名稱空間切換至 limitrange-demo

kubectl config set-context --current --namespace=limitrange-demo

2.LimitRange 對象的 yaml 文件如下所示:

apiVersion: v1
kind: LimitRange
metadata:
  name: limit-mem-cpu-per-container
spec:
  limits:
  - max:
      cpu: "800m"
      memory: "1Gi"
    min:
      cpu: "100m"
      memory: "99Mi"
    default:
      cpu: "700m"
      memory: "900Mi"
    defaultRequest:
      cpu: "110m"
      memory: "111Mi"
    type: Container

該對象為名稱空間中的容器定義了:

  • 最大和最小的CPU/內存
  • 默認的 CPU/內存限定
  • 默認的 CPU/內存請求

執行命令以創建該對象:

kubectl create -f https://kuboard.cn/statics/learning/policy/lr-container-limit-range.yaml -n limitrange-demo

執行命令查看結果

kubectl describe limitrange/limit-mem-cpu-per-container -n limitrange-demo

Type        Resource  Min   Max   Default Request  Default Limit  Max Limit/Request Ratio
----        --------  ---   ---   ---------------  -------------  -----------------------
Container   cpu       100m  800m  110m             700m           -
Container   memory    99Mi  1Gi   111Mi            900Mi          -

3.前面提到的包含 4 個容器的 Pod,其 yaml 文件如下所示:

apiVersion: v1
kind: Pod
metadata:
  name: busybox1
spec:
  containers:
  - name: busybox-cnt01
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo hello from cnt01; sleep 10;done"]
    resources:
      requests:
        memory: "100Mi"
        cpu: "100m"
      limits:
        memory: "200Mi"
        cpu: "500m"
  - name: busybox-cnt02
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo hello from cnt02; sleep 10;done"]
    resources:
      requests:
        memory: "100Mi"
        cpu: "100m"
  - name: busybox-cnt03
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo hello from cnt03; sleep 10;done"]
    resources:
      limits:
        memory: "200Mi"
        cpu: "500m"
  - name: busybox-cnt04
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo hello from cnt04; sleep 10;done"]

執行命令以創建該 Pod

kubectl apply -f https://kuboard.cn/statics/learning/policy/lr-container-pod.yaml

容器包含有效的 CPU/內存的requests/limits

執行以下命令,查看 busybox-cnt01 的配置信息

kubectl get  po/busybox1 -n limitrange-demo -o json | jq ".spec.containers[0].resources"

{
  "limits": {
    "cpu": "500m",
    "memory": "200Mi"
  },
  "requests": {
    "cpu": "100m",
    "memory": "100Mi"
  }
}
  • busybox Pod 中的容器 busybox-cnt01 定義了 requests.cpu=100m 和 requests.memory=100Mi
  • 100m <= 500m <= 800m 容器的 cpu limit(500m)在名稱空間 LimitRange 指定的范圍內
  • 99Mi <= 200Mi <= 1Gi 容器的內存 limit(200Mi)在名稱空間 LimitRange 指定的范圍內
  • 沒有為CPU/內存指定 request/limit 比例
  • 此時容器的定義是有效的,將被創建

容器包含有效的 CPU/內存requests且沒有指定limits

執行以下命令,查看 busybox-cnt02 的配置信息

kubectl get  po/busybox1 -n limitrange-demo -o json | jq ".spec.containers[1].resources"

{
  "limits": {
    "cpu": "700m",
    "memory": "900Mi"
  },
  "requests": {
    "cpu": "100m",
    "memory": "100Mi"
  }
}
  • busybox Pod 中的容器 busybox-cnt02 定義了 requests.cpu=100m 和 requests.memory=100Mi,且為指定 CPU/內存的最大限定
  • 由於容器沒有定義 limits,則名稱空間的 LimitRange 定義的 limits.cpu=700mi 和 limits.memory=900Mi 被注入到該容器
  • 100m <= 700m <= 800m 容器的CPU最大限定(700m)在名稱空間 LimitRange 指定的范圍內
  • 99Mi <= 900Mi <= 1Gi 容器的內存 limit(900Mi)在名稱空間 LimitRange 指定的范圍內
  • 沒有為CPU/內存指定 request/limit 比例
  • 此時容器的定義是有效的,將被創建

容器包含有效的CPU/內存limits且沒有指定requests

執行以下命令,查看 busybox-cnt03 的配置信息

kubectl get  po/busybox1 -n limitrange-demo -o json | jq ".spec.containers[2].resources"

{
  "limits": {
    "cpu": "500m",
    "memory": "200Mi"
  },
  "requests": {
    "cpu": "500m",
    "memory": "200Mi"
  }
}
  • busybox Pod 中的容器 busybox-cnt03 定義了 limits.cpu=500m 和 limits.memory=200Mi,且沒有指定 CPU/內存的 requests
  • 由於容器沒有定義 requests,名稱空間中 LimitRange 定義的 defaultRequest 並沒有注入到容器的 request 字段,反而,容器定義的 limits 被設置到了其 requests 字段: limits.cpu=500m 和 limits.memory=200Mi
  • 100m <= 500m <= 800m 容器的 cpu 最大限定(500m)在名稱空間 LimitRange 指定的范圍內
  • 99Mi <= 200Mi <= 1Gi 容器的內存最大限定(200Mi)在名稱空間 LimitRange 指定的范圍內
  • 沒有為CPU/內存指定 request/limit 比例
  • 此時容器的定義是有效的,將被創建

容器不包含CPU/內存的requests/limits

執行以下命令,查看 busybox-cnt04 的配置信息

kubectl get  po/busybox1 -n limitrange-demo -o json | jq ".spec.containers[3].resources"

{
  "limits": {
    "cpu": "700m",
    "memory": "900Mi"
  },
  "requests": {
    "cpu": "110m",
    "memory": "111Mi"
  }
}
  • busybox Pod 中的容器 busybox-cnt04 既沒有定義 request,也沒有定義 limits
  • 由於容器沒有定義 limits,則名稱空間的 LimitRange 定義的 limits.cpu=700mi 和 limits.memory=900Mi 被注入到該容器
  • 由於容器沒有定義 requests,則名稱空間的 LimitRange 定義的 requests.cpu=110m 和 requests.memory=110Mi 被注入到該容器
  • 100m <= 700m <= 800m 容器的 cpu 最大限定(700m)在名稱空間 LimitRange 指定的范圍內
  • 99Mi <= 900Mi <= 1Gi 容器的內存 limit(900Mi)在名稱空間 LimitRange 指定的范圍內
  • 沒有為CPU/內存指定 request/limit 比例
  • 此時容器的定義是有效的,將被創建

Pod busybox 中所有的容器都通過了名稱空間的 LimitRange 檢查,此 Pod 將被創建

限定Pod的計算資源

下面是一個用於限定 Pod 資源使用的 LimitRange 對象。

apiVersion: v1
kind: LimitRange
metadata:
  name: limit-mem-cpu-per-pod
spec:
  limits:
  - max:
      cpu: "2"
      memory: "2Gi"
    type: Pod

在開始之前先完成 限定容器 的計算資源,並確保該教程中的 LimitRange limit-mem-cpu-per-container 和 Pod busybox1 都已經創建。

1.執行如下命令,創建 limit-mem-cpu-pod 上面 yaml 中的 LimitRange,該 LimitRange 限定了每一個 Pod 的CPU使用不超過 2 核,內存不超過 2Gi。

kubectl apply -f https://kuboard.cn/statics/learning/policy/lr-pod-limit-range.yaml -n limitrange-demo

執行命令查看 limit-mem-cpu-per-pod 的創建結果:

kubectl describe limitrange/limit-mem-cpu-per-pod -n limitrange-demo

Name:       limit-mem-cpu-per-pod
Namespace:  limitrange-demo
Type        Resource  Min  Max  Default Request  Default Limit  Max Limit/Request Ratio
----        --------  ---  ---  ---------------  -------------  -----------------------
Pod         cpu       -    2    -                -              -
Pod         memory    -    2Gi  -                -              -

2.創建第二個 Pod,yaml 文件如下:

apiVersion: v1
kind: Pod
metadata:
  name: busybox2
spec:
  containers:
  - name: busybox-cnt01
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo hello from cnt01; sleep 10;done"]
    resources:
      requests:
        memory: "100Mi"
        cpu: "100m"
      limits:
        memory: "200Mi"
        cpu: "500m"
  - name: busybox-cnt02
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo hello from cnt02; sleep 10;done"]
    resources:
      requests:
        memory: "100Mi"
        cpu: "100m"
  - name: busybox-cnt03
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo hello from cnt03; sleep 10;done"]
    resources:
      limits:
        memory: "200Mi"
        cpu: "500m"
  - name: busybox-cnt04
    image: busybox
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo hello from cnt04; sleep 10;done"]

執行如下命令可創建該 Pod

kubectl apply -f https://kuboard.cn/statics/learning/policy/lr-pod-pod.yaml -n limitrange-demo

Pod busybox2 的定義與 busybox1 的定義完全相同,但是執行該創建命令時將碰到如下錯誤,因為Pod可使用的資源現在受到了限制:

Error from server (Forbidden): error when creating "limit-range-pod-2.yaml": pods "busybox2" is forbidden: [maximum cpu usage per Pod is 2, but limit is 2400m., maximum memory usage per Pod is 2Gi, but limit is 2306867200.]

執行命令查看 busybox1 的資源使用

kubectl get  po/busybox1  -n limitrange-demo -o json | jq ".spec.containers[].resources.limits.memory" 

"200Mi"
"900Mi"
"200Mi"
"900Mi"

Pod busybox2 將不能在集群中創建,因為其中所有容器的內存限制的總和超過了 LimitRange limit-mem-cpu-per-pod 中的限定。 busybox1 將不會被驅逐,因為該 Pod 在創建 LimitRange limit-mem-cpu-per-pod 就已經創建好了。

限定存儲資源

通過 LimitRange 對象,集群管理員可以限定名稱空間中每個 PersistentVolumeClaim(存儲卷聲明)可以使用的最小、最大存儲空間。

請參考下面的例子:

apiVersion: v1
kind: LimitRange
metadata:
  name: storagelimits
spec:
  limits:
  - type: PersistentVolumeClaim
    max:
      storage: 2Gi
    min:
      storage: 1Gi

執行命令可創建該 LimitRange:

kubectl create -f https://kuboard.cn/statics/learning/policy/lr-storage-limit.yaml -n limitrange-demo

kubectl describe limits/storagelimits -n limitrange-demo
Name:                  storagelimits
Namespace:             limitrange-demo
Type                   Resource  Min  Max  Default Request  Default Limit  Max Limit/Request Ratio
----                   --------  ---  ---  ---------------  -------------  -----------------------
PersistentVolumeClaim  storage   1Gi  2Gi  -                -              -

現在假設有一個 PVC(存儲卷聲明),定義文件如下所示:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-limit-lower
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 500Mi

執行命令創建該 PVC(存儲卷聲明)

kubectl create -f https://kuboard.cn/statics/learning/policy/lr-storage-pvc-lower.yaml -n limitrange-demo

由於 PVC 中定義的字段 requests.storage 比 LimitRange storagelimits 中 limits[0].min.storage 的定義要小,所以創建該 PVC 時將失敗:

Error from server (Forbidden): error when creating "lr-storage-pvc-lower.yaml": persistentvolumeclaims "pvc-limit-lower" is forbidden: minimum storage usage per PersistentVolumeClaim is 1Gi, but request is 500Mi.

如果 PVC 的 requests.storage 大於 LimitRange 中的 limits[0].max.storage,同樣不能創建成功,參考下面的例子:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-limit-greater
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi

執行命令創建該 PVC(存儲卷聲明)

kubectl create -f https://kuboard.cn/statics/learning/policy/lr-storage-pvc-greater.yaml

Error from server (Forbidden): error when creating "lr-storage-pvc-greater.yaml": persistentvolumeclaims "pvc-limit-greater" is forbidden: maximum storage usage per PersistentVolumeClaim is 2Gi, but request is 5Gi.

限定 Limit/Request 比例

如果指定了 LimitRange 對象的 spec.limits.maxLimitRequestRatio 字段,名稱空間中的 Pod/容器的 request 和 limit 都不能為 0,且 limit 除以 request 的結果必須小於或等於 LimitRange 的 spec.limits.maxLimitRequestRatio

下面的例子中 LimitRange 限定了名稱空間中任何 Pod 的最大內存限定(limit)不能超過最小內存請求(request)的兩倍:

apiVersion: v1
kind: LimitRange
metadata:
  name: limit-memory-ratio-pod
spec:
  limits:
  - maxLimitRequestRatio:
      memory: 2
    type: Pod

執行命令以創建該 LimitRange:

kubectl create -f https://kuboard.cn/statics/learning/policy/lr-ratio-limit-range.yaml -n limitrange-demo

執行命令以查看創建結果:

kubectl describe limitrange/limit-memory-ratio-pod -n limitrange-demo

Name:       limit-memory-ratio-pod
Namespace:  limitrange-demo
Type        Resource  Min  Max  Default Request  Default Limit  Max Limit/Request Ratio
----        --------  ---  ---  ---------------  -------------  -----------------------
Pod         memory    -    -    -                -              2

此時,如果我們創建一個 Pod 包含如下屬性 requests.memory=100Mi 和 limits.memory=300Mi:

apiVersion: v1
kind: Pod
metadata:
  name: busybox3
spec:
  containers:
  - name: busybox-cnt01
    image: busybox
    resources:
      limits:
        memory: "300Mi"
      requests:
        memory: "100Mi"

執行命令以創建該 Pod:

kubectl apply -f https://kuboard.cn/statics/learning/policy/lr-ratio-pod.yaml -n limitrange-demo

由於該 Pod 的內存限制請求比例為 3,超過了 LimitRange 中定義的 2,該 Pod 將不能創建成功:

Error from server (Forbidden): error when creating "lr-ratio-pod.yaml": pods "busybox3" is forbidden: memory max limit to request ratio per Pod is 2, but provided ratio is 3.000000.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM