Kubernetes中資源配額管理


設置資源請求數量

創建Pod的時候,可以為每個容器指定資源消耗的限制。Pod的資源請求限制則是Pod中所有容器請求資源的總和。

apiVersion: v1
kind: Pod
metadata:
  name: requests-pod
spec:
  containers:
  - image: busybox
    command: ["dd", "if=/dev/zero", "of=/dev/null"]
    name: main
    resources:
      requests:
        cpu: 200m
        memory: 10Mi

如果不指定CPU請求資源,表示不關心容器會分到多少CPU資源,有可能會一直分不到而處於等待狀態。指定資源請求表示Pod對資源的最小需求,因此在調度的時候會如果Node剩余的資源不能滿足Pod的需求,則不會調度到對應的Node上。Scheduler調度的時候並不關注在調度時具體的資源使用情況,而是根據現存Pod的資源請求情況來進行調度。這就會有問題,特別是當允許Pod使用超過請求的資源時。下面的圖一看就能理解。

調度判斷首先將不符合請求的Node排除在外,然后將符合要求的Node進行排序。節點排序根據資源請求數量的不同分為兩個策略,LeastRequestPolicyMostRequestPolicy。從字面上我們可以看到,一個是優先分派到資源請求少的節點,一個是優先分派到資源請求多的節點。一般在生產環境,建議使用LeastRequestPolicy,便於將負載平均的分配到各個機器上。在公有雲的環境中建議使用MostRequestPolicy,提高資源的利用率,減少成本。

在沒有設置資源使用限制的情況下,Pod可能使用超過請求的資源數量。對於CPU資源來說,如果同時有兩個Pod請求剩余的資源,在分配剩余資源時,調度器會根據請求數量的比例在不同的Pod間分配資源。例如Pod A請求100m的CPU,Pod B請求20m的CPU,在兩個Pod中CPU使用超過請求時,會根據5:1的比例分配。

使用kubectl describe nodes命令可以查看Node資源使用的情況。

如果Kubernetes找不到滿足資源請求的Node,則Pod創建會停留在Pending狀態。

設置資源使用上限

Pod創建的時候,可以設置每個容器使用資源的上限,可以限制的資源包括CPU、內存等。如果不設置上限,則理論上可以使用Node的全部資源。如果要防止Node上的各個容器互相影響,最好為Pod指定上限。

CPU是一種可以壓榨的資源,可以用滿並且Pod之間不會互相影響。內存則不一樣,Pod之間分配的內存不能互相使用。requests的資源數量必須與Node容量一樣或者更小,limits資源數量的總和可以超過Node的容量。當節點的資源被全部使用完后,一些容器可能會被殺掉。特別是使用內存超限后,會被Kubernetes進行OOMKilled。如果這個Pod的重啟策略是Always,很可能你都沒注意到Pod被重啟了,但是隨着發生次數的增多,每次重啟delay的時間就會增加。

apiVersion: v1
kind: Pod
metadata:
  name: limit-pod
spec:
  containers:
  - image: busybox
    command: ["dd", "if=/dev/zero", "of=/dev/null"]
    name: main
    resources:
      requests:
        cpu: 200m
        memory: 10Mi
      limits:
        cpu: 1
        memory: 20Mi

容器中運行top命令你會發現,容器中能看到的CPU、內存總量是Node的總量。這樣就會造成一些應用能夠探測到的容量和Limits的限制不一樣,從而造成使用超出請求的情況。

對於CPU、內存來說,可以利用Metadata獲取的三種方式中提到的辦法通過API來獲取限制的大小,也可以在 /sys/fs/cgroup/cpu/cpu.cfs_quota_us/sys/fs/cgroup/cpu/cpu.cfs_period_us來查看。

QoS:Pod Kill的策略

在Pod使用的資源超過Node容量時,Kubernetes為了保障Node的運行,會選擇其中的一些Pod並殺掉,那么如何確定殺掉哪個Pod呢,這里就需要引入一個QoS的概念。

QoS是 Quality of Service,有三種Quality of Service 策略,Kubernetes依次選擇三種策略的Pod進行Kill。如果兩個的QoS一樣,則選擇資源利用率高的Kill。

  • BestEffort 應用到沒有資源限制的Pod上,可以使用盡可能多的資源,也可能第一個被殺死
  • Burstable limits超過requests的Pod類型
  • Guaranteed 適用於請求和上限一致的Pod(limits默認與requests相同),這種Pod不能使用超額的資源,但是會保證存活

對於單容器的Pod,遵循以下原則

對於多個容器的Pod,如果兩個容器的策略不一致,就使用Burstable策略,一致則使用容器的策略。

設置Pod/Container的默認請求和限制 LimitRange

通過創建LimitRange對象,在一個命名空間內,可以為所有創建的Pod設置一個磨人的requests和limits的限制。

apiVersion: v1
kind: LimitRange
metadata:
  name: limitrange-demo
spec:
  limits:
  - type: Pod
    min:
      cpu: 50m
      meomery: 5Mi
    max:
      cpu: 1
      meomery: 1Gi
  - type: Container
    defaultRequest:
      cpu: 100m
      memory: 10Mi
    default:
      cpu: 200m
      memory: 100Mi
    min:
      cpu: 50m
      memory: 5Mi
    max:
      cpu: 1
      memory: 1Gi
    maxLimitRequestRatio:
      cpu: 4
      memory: 10
  - type: PersistentVolumeClaim
    min:
      storage: 1Gi
    max:
      storage: 10Gi
   

創建一個不符合LimitRange要求的Pod,則會出現以下報錯。

設置集群的資源Quota

除了設置每個Pod的默認上限外,還可以通過ResourceQuota設置集群的可用資源上限。ResourceQuota可以設置一個集群可用的最大計算資源的數量,也可以設置用戶可以創建的各種對象的數量。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: cpu-and-mem
spec:
  hard:
    requests.cpu: 400m
    requests.memory: 200Mi
    limits.cpu: 600m
    limits.memory: 500Mi

查看當前的資源限制

還可以限制存儲及各種對象的數量,具體參考下面的yaml。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: storage-object
spec:
  hard:
    pods: 10
    replicationcontrollers: 5
    secrets: 10
    configmaps: 10
    persistentvolumeclaims: 4
    services: 5
    services.loadbalancers: 1
    services.nodeports: 2
    ssd.storageclass.storage.k8s.io/persistentvolumeclaims: 2

設置的Quota默認在命名空間內生效,也可以根據QoS來設定不同的生效范圍。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: quota-qos
spec:
  scopes:
  - BestEffort
  - NotTerminating
  hard:
    pods: 4

一共有四種策略:BestEffort、NotBestEffort、Terminating、NotTerminating。前兩個根據QoS來選擇Pod,后兩個根據Pod是否設置了activeDeadlineSeconds屬性來選擇。看下圖就能夠明白了。

監控

Kubernetes本身包含了cAdvisor來監控容器和節點的運行情況,如果想要從整體上看資源的使用情況需要安裝Heapster組件。但是這兩個

kubectl top node
kubectl top pod
kubectl top pod --container

使用這兩個命令可以查看短時間內的Pod、Node資源使用的情況,也可以查看每個容器資源使用的情況。如果想要將性能數據保存下來,需要安裝heapster\influxdb\grafana。具體不在這篇文章中講解了。

參考資料:

  1. cAdvisor
  2. InfluxDB
  3. Grafana
  4. influxdb yaml


免責聲明!

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



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