kubernets資源預留


一、  Kubelet Node Allocatable

  • Kubelet Node Allocatable用來為Kube組件和System進程預留資源,從而保證當節點出現滿負荷時也能保證Kube和System進程有足夠的資源。
  • 目前支持cpu, memory, ephemeral-storage三種資源預留。
  • Node Capacity是Node的所有硬件資源,kube-reserved是給kube組件預留的資源,system-reserved是給System進程預留的資源, eviction-threshold是kubelet eviction的閾值設定,allocatable才是真正scheduler調度Pod時的參考值(保證Node上所有Pods的request resource不超過Allocatable)。

      Node Capacity

--------------------------------

|     kube-reserved         |

|-------------------------------|

|     system-reserved      |

|-------------------------------|

|    eviction-threshold     |

|-------------------------------|

|      allocatable              |

|   (available for pods)   |

--------------------------------

可分配資源

Node Allocatable Resource = Node Capacity - Kube-reserved - system-reserved - eviction-threshold

二、  Kubernetes配置資源預留

以下均為kubelet組件參數

  • --enforce-node-allocatable,默認為pods,要為kube組件和System進程預留資源,則需要設置為pods,kube-reserved,system-reserve。
  • --cgroups-per-qos,Enabling QoS and Pod level cgroups,默認開啟。開啟后,kubelet會將管理所有workload Pods的cgroups。
  • --cgroup-driver,默認為cgroupfs,另一可選項為systemd。取決於容器運行時使用的cgroup driver,kubelet與其保持一致。比如你配置docker使用systemd cgroup driver,那么kubelet也需要配置--cgroup-driver=systemd。
  • --kube-reserved,用於配置為kube組件(kubelet,kube-proxy,dockerd等)預留的資源量,比如—kube-reserved=cpu=1000m,memory=8Gi,ephemeral-storage=16Gi。
  • --kube-reserved-cgroup,如果你設置了--kube-reserved,那么請一定要設置對應的cgroup,並且該cgroup目錄要事先創建好,否則kubelet將不會自動創建導致kubelet啟動失敗。比如設置為kube-reserved-cgroup=/kubelet.service 。
  • --system-reserved,用於配置為System進程預留的資源量,比如—system-reserved=cpu=500m,memory=4Gi,ephemeral-storage=4Gi。
  • --system-reserved-cgroup,如果你設置了--system-reserved,那么請一定要設置對應的cgroup,並且該cgroup目錄要事先創建好,否則kubelet將不會自動創建導致kubelet啟動失敗。比如設置為system-reserved-cgroup=/system.slice。
  • --eviction-hard,用來配置kubelet的hard eviction條件,只支持memory和ephemeral-storage兩種不可壓縮資源。當出現MemoryPressure時,Scheduler不會調度新的Best-Effort QoS Pods到此節點。當出現DiskPressure時,Scheduler不會調度任何新Pods到此節點。關於Kubelet Eviction的更多解讀,請參考我的相關博文

Kubelet Node Allocatable的代碼很簡單,主要在pkg/kubelet/cm/node_container_manager.go,感興趣的同學自己去走讀一遍。

示例:

以如下的kubelet資源預留為例,Node Capacity為memory=32Gi, cpu=16, ephemeral-storage=100Gi,我們對kubelet進行如下配置:

--enforce-node-allocatable=pods,kube-reserved,system-reserved
--kube-reserved-cgroup=/kubelet.service
--system-reserved-cgroup=/system.slice
--kube-reserved=cpu=1,memory=2Gi,ephemeral-storage=1Gi
--system-reserved=cpu=500m,memory=1Gi,ephemeral-storage=1Gi
--eviction-hard=memory.available<500Mi,nodefs.available<10%

NodeAllocatable = NodeCapacity - Kube-reserved - system-reserved - eviction-threshold = cpu=14.5,memory=28.5Gi,ephemeral-storage=98Gi.

Scheduler會確保Node上所有的Pod Resource Request不超過NodeAllocatable。Pods所使用的memory和storage之和超過NodeAllocatable后就會觸發kubelet Evict Pods。

1.    Kube Reserved

Kubelet Flag: --kube-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=1Gi][,][pid=1000]
Kubelet Flag: --kube-reserved-cgroup=

kube-reserved 是為了給諸如 kubelet、container runtime、node problem detector 等 kubernetes 系統守護進程爭取資源預留。這並不代表要給以 pod 形式運行的系統守護進程保留資源。kube-reserved 通常是節點上的一個 pod 密度(pod density) 功能。 這個性能儀表盤 從 pod 密度的多個層面展示了 kubelet 和 docker engine 的 cpu 和 memory使用情況。

要選擇性的在系統守護進程上執行 kube-reserved,需要把 kubelet 的 --kube-reserved-cgroup 標志的值設置為 kube 守護進程的父控制組。

 推薦將 kubernetes 系統守護進程放置於頂級控制組之下(例如 systemd 機器上的 runtime.slice)。理想情況下每個系統守護進程都應該在其自己的子控制組中運行。請參考這篇文檔,獲取更過關於推薦控制組層次結構的細節。

 請注意,如果 --kube-reserved-cgroup 不存在,Kubelet 將不會創建它。如果指定了一個無效的 cgroup,Kubelet 將會失敗。

2.    系統預留值(System Reserved)

Kubelet Flag: --system-reserved=[cpu=100m][,][memory=100Mi][,][ephemeral-storage=1Gi][,][pid=1000]
Kubelet Flag: --system-reserved-cgroup=

system-reserved 用於為諸如 sshd、udev 等系統守護進程爭取資源預留。system-reserved 也應該為 kernel 預留 內存,因為目前 kernel 使用的內存並不記在 Kubernetes 的 pod 上。同時還推薦為用戶登錄會話預留資源(systemd 體系中的 user.slice)。

要想在系統守護進程上可選地執行 system-reserved,請指定 --system-reserved-cgroup kubelet 標志的值為 OS 系統守護進程的父級控制組。

推薦將 OS 系統守護進程放在一個頂級控制組之下(例如 systemd 機器上的system.slice)。

請注意,如果 --system-reserved-cgroup 不存在,Kubelet 不會創建它。如果指定了無效的 cgroup,Kubelet 將會失敗。

3.    驅逐閾值(Eviction Thresholds)

Kubelet Flag: --eviction-hard=[memory.available<10%][,][ephemeral-storage<1Gi]

節點級別的內存壓力將導致系統內存不足(System OOMs),這將影響到整個節點及其上運行的所有 pod。節點可以暫時離線直到內存已經回收為止。為了防止(或減少可能性)系統內存不足,kubelet 提供了 資源不足(Out of Resource) 管理。驅逐(Eviction)操作只支持 memory 和ephemeral-storage。通過 --eviction-hard 標志預留一些內存后,當節點上的可用內存降至保留值以下時,kubelet 將嘗試 驅逐 pod。假設,如果節點上不存在系統守護進程,pod 將不能使用超過 capacity-eviction-hard 的資源。因此,為驅逐而預留的資源對 pod 是不可用的。

eviction-hard的值支持1Gi或者10%格式。

kubelet的默認eviction-hard值如下:

  • memory.available<100Mi
  • nodefs.available<10%
  • nodefs.inodesFree<5%
  • imagefs.available<15%

1.    執行節點 Allocatable

Kubelet Flag: --enforce-node-allocatable=pods[,][system-reserved][,][kube-reserved]

調度器將 Allocatable 按 pod 的可用 capacity 對待。

kubelet 默認在 pod 中執行 Allocatable。無論何時,如果所有 pod 的總用量超過了 Allocatable,驅逐 pod 的措施將被執行。有關驅逐策略的更多細節可以在 這里 找到。請通過設置 kubelet --enforce-node-allocatable 標志值為 pods 控制這個措施。

可選的,通過在相同標志中同時指定 kube-reserved 和 system-reserved 值能夠使 kubelet 執行 kube-reserved 和 system-reserved。請注意,要想執行 kube-reserved 或者 system-reserved時,需要分別指定 --kube-reserved-cgroup 或者 --system-reserved-cgroup。

三、  一般原則

系統守護進程期望被按照類似 Guaranteed pod 一樣對待。系統守護進程可以在其范圍控制組中爆發式增長,您需要將這個行為作為 kubernetes 部署的一部分進行管理。例如,kubelet 應該有它自己的控制組並和容器運行時(container runtime)共享 Kube-reserved 資源。然而,如果執行了 kube-reserved,則 kubelet 不能突然爆發並耗盡節點的所有可用資源。

在執行 system-reserved 預留操作時請加倍小心,因為它可能導致節點上的關鍵系統服務 CPU 資源短缺或因為內存不足(OOM)而被終止。

在 pods 上執行 Allocatable 作為開始。

一旦足夠用於追蹤系統守護進程的監控和告警的機制到位,請嘗試基於用量探索(usage heuristics)方式執行 kube-reserved。

隨着時間推進,如果絕對必要,可以執行 system-reserved。

隨着時間的增長以及越來越多特性的加入,kube 系統守護進程對資源的需求可能也會增加。以后 kubernetes 項目將嘗試減少對節點系統守護進程的利用,但目前那並不是優先事項。所以,請期待在將來的發布中將 Allocatable 容量降低。

四、  示例場景

這是一個用於說明節點 Allocatable 計算方式的示例:

 

節點擁有 32Gi 內存,16 核 CPU 和 100Gi 存儲

--kube-reserved 設置為 cpu=1,memory=2Gi,storage=1Gi

--system-reserved 設置為 cpu=500m,memory=1Gi,storage=1Gi

--eviction-hard 設置為 memory.available<500Mi,nodefs.available<10%

在這個場景下,Allocatable 將會是 14.5 CPUs、28.5Gi 內存以及 98Gi 存儲。調度器保證這個節點上的所有 pod 請求的內存總量不超過 28.5Gi,存儲不超過 88Gi。當 pod 的內存使用總量超過 28.5Gi 或者磁盤使用總量超過 88Gi 時,Kubelet 將會驅逐它們。如果節點上的所有進程都盡可能多的使用 CPU,則 pod 加起來不能使用超過 14.5 CPUs 的資源。

 

當沒有執行 kube-reserved 和/或 system-reserved 且系統守護進程使用量超過其預留時,如果節點內存用量高於 31.5Gi 或存儲大於 90Gi,kubelet 將會驅逐 pod。

 

可用特性

截至 Kubernetes 1.2 版本,已經可以可選的指定 kube-reserved 和 system-reserved 預留。當在相同的發布中都可用時,調度器將轉為使用 Allocatable 替代 Capacity。

 

截至 Kubernetes 1.6 版本,eviction-thresholds 是通過計算 Allocatable 進行考慮。要使用舊版本的行為,請設置 --experimental-allocatable-ignore-eviction kubelet 標志為 true。

 

截至 Kubernetes 1.6 版本,kubelet 使用控制組在 pod 上執行 Allocatable。要使用舊版本行為,請取消設置 --enforce-node-allocatable kubelet 標志。請注意,除非 --kube-reserved 或者 --system-reserved 或者 --eviction-hard 標志沒有默認參數,否則 Allocatable 的實施不會影響已經存在的 deployment。

 

截至 Kubernetes 1.6 版本,kubelet 在 pod 自己的 cgroup 沙箱中啟動它們,這個 cgroup 沙箱在 kubelet 管理的 cgroup 層次結構中的一個獨占部分中。在從前一個版本升級 kubelet之前,要求操作員 drain 節點,以保證 pod 及其關聯的容器在 cgroup 層次結構中合適的部分中啟動。

 

截至 Kubernetes 1.7 版本,kubelet 支持指定 storage 為 kube-reserved 和 system-reserved 的資源。

五、  Openshift配置

在kubelet中新增參數system-reserved和kube-reserved,

 

可以在每個node節點的/etc/origin/node/node-config.yaml修改,但是這是臨時生效,

 

想要永久生效,需要修改openshift-node命名空間里的configmap,想改哪個group的參數就修改哪個configmap。

 

在openshift中新增或者修改kubelet的參數都可以通過這種方式。

 

例如:給compute-normal group新增system-reserved和kube-reserved參數:

 

kubectl edit -n openshift-node cm node-config-compute-normal

    kubeletArguments:
      bootstrap-kubeconfig:
      - /etc/origin/node/bootstrap.kubeconfig
      cert-dir:
      - /etc/origin/node/certificates
      enable-controller-attach-detach:
      - 'true'
      feature-gates:
      - RotateKubeletClientCertificate=true,RotateKubeletServerCertificate=true
      node-labels:
      - node-role.kubernetes.io/compute-normal=true
      pod-manifest-path:
      - /etc/origin/node/pods
      rotate-certificates:
      - 'true'
      evction-hard:
      - 'memory.available<500Mi,nodefs.available<10%'
      system-reserved:
      - 'cpu=200m,memory=1Gi'
      kube-reserved:
      - "cpu=200m,memory=1Gi"

如果修改的是master組件的參數,而不是kubelet的,則按照下面的方法。

修改master的配置在每個master的/etc/origin/master/master-config.yaml

kubernetesMasterConfig:
  controllerArguments: 
    node-monitor-period:
    - "10m"

重啟相關組件

# master-restart api

# master-restart controllers

 

修改pod-evction-timeout參數:

1.修改每個master上/etc/origin/master/master-config.yaml

  podEvictionTimeout: "2m0s"

2.重啟controller:

master-restart controllers

 

六、  參數資料

http://docs.kubernetes.org.cn/723.html

https://my.oschina.net/jxcdwangtao/blog/1629059

https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/

https://kubernetes.io/docs/tasks/administer-cluster/out-of-resource/


免責聲明!

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



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