天天看點

hualinux 進階 1.21:k8s資源管理(整理)

目錄

​​一、資源管理​​

​​1.1 可壓縮資源和非可壓縮資源​​

​​1.2 記憶體和CPU含義​​

​​二、QoS(服務品質保證)的級别​​

​​2.1 Guaranteed(保證)類型​​

​​2.2 Burstable(突發) 類型​​

​​2.3 BestEffort(盡力而為)類型​​

​​三、QoS作用及模式​​

​​3.1 作用​​

​​3.2 模式​​

​​四、cpuset 的設定​​

我們前面配置pod及pod相關時,預設對資源是沒有限制的,就是盡可能地使用主控端的資源。

而在實作生産環境中,我們需要對資源做一些限制,這樣避免資源之間競争對pod産生影響。

可以先看一下官網的《​​為容器管理資源​​》

一、資源管理

作為一個容器叢集編排與管理項目,Kubernetes 為使用者提供的基礎設施能力,不僅包括了我在前面為你講述的應用定義和描述的部分,還包括了對應用的資源管理和排程的處理。

我在前面的文章中已經提到過,在 Kubernetes 裡,Pod 是最小的原子排程機關。這也就意味着,所有跟排程和資源管理相關的屬性都應該是屬于 Pod 對象的字段。

如果 Pod 運作所在的節點具有足夠的可用資源,容器可能(且可以)使用超出對應資源 ​

​request​

​​ 屬性所設定的資源量。不過,容器不可以使用超出其資源 ​

​limit​

​ 屬性所設定的資源量。

1.1 可壓縮資源和非可壓縮資源

《​​為容器管理資源​​》中的例子如下:

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: app
    image: images.my-company.example/app:v4
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "password"
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: log-aggregator
    image: images.my-company.example/log-aggregator:v6
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"      

在 Kubernetes 中,像 CPU 這樣的資源被稱作“可壓縮資源”(compressible resources)。它的典型特點是,當可壓縮資源不足時,Pod 隻會“饑餓”,但不會退出。

而像記憶體這樣的資源,則被稱作“不可壓縮資源(incompressible resources)。當不可壓縮資源不足時,Pod 就會因為 OOM(Out-Of-Memory)被核心殺掉。

1.2 記憶體和CPU含義

可以直接看官網《​​為容器管理資源​​​》中  ​​記憶體的含義 ​​

記憶體的限制和請求以位元組為機關。你可以使用以下字尾之一以一般整數或定點整數形式來表示記憶體: E、P、T、G、M、K。你也可以使用對應的 2 的幂數:Ei、Pi、Ti、Gi、Mi、Ki。

可以直接看官網《​​為容器管理資源​​​》中  ​​CPU的含義​​

CPU 資源的限制和請求以 cpu 為機關。

Kubernetes 中的一個 cpu 等于雲平台上的 1 個 vCPU/核和裸機 Intel 處理器上的 **1 個超線程 **。

你也可以表達帶小數 CPU 的請求。​

​spec.containers[].resources.requests.cpu​

​​ 為 0.5 的 Container 肯定能夠獲得請求 1 CPU 的容器的一半 CPU 資源。表達式 ​

​0.1​

​​ 等價于表達式 ​

​100m​

​​, 可以看作 “100 millicpu”。有些人說成是“一百毫 cpu”,其實說的是同樣的事情。 具有小數點(如 ​

​0.1​

​​)的請求由 API 轉換為 ​

​100m​

​​;最大精度是 ​

​1m​

​​。 是以,或許你應該優先考慮使用 ​

​100m​

​ 的形式。

CPU 總是按絕對數量來請求的,不可以使用相對數量; 0.1 的 CPU 在單核、雙核、48 核的機器上的意義是一樣的。

Kubernetes 裡 Pod 的 CPU 和記憶體資源,實際上還要分為 limits 和 requests 兩種情況

spec.containers[].resources.limits.cpu

spec.containers[].resources.limits.memory

spec.containers[].resources.requests.cpu

spec.containers[].resources.requests.memory

這兩者的差別其實非常簡單:在排程的時候,kube-scheduler 隻會按照 requests 的值進行計算。而在真正設定 Cgroups 限制的時候,kubelet 則會按照 limits 的值來進行設定。

二、QoS(服務品質保證)的級别

在 Kubernetes 中,不同的 requests 和 limits 的設定方式,其實會将這個 Pod 劃分到不同的 QoS 級别當中。

2.1 Guaranteed(保證)類型

當 Pod 裡的每一個 Container 都同時設定了 requests 和 limits,并且 requests 和 limits 值相等的時候,這個 Pod 就屬于 Guaranteed 類别,如下所示:

apiVersion: v1
kind: Pod
metadata:
  name: qos-demo
  namespace: qos-example
spec:
  containers:
  - name: qos-demo-ctr
    image: nginx
    resources:
      limits:
        memory: "200Mi"
        cpu: "700m"
      requests:
        memory: "200Mi"
        cpu: "700m"      

當這個 Pod 建立之後,它的 qosClass 字段就會被 Kubernetes 自動設定為 Guaranteed。需要注意的是,當 Pod 僅設定了 limits 沒有設定 requests 的時候,Kubernetes 會自動為它設定與 limits 相同的 requests 值,是以,這也屬于 Guaranteed 情況。

2.2 Burstable(突發) 類型

而當 Pod 不滿足 Guaranteed 的條件,但至少有一個 Container 設定了 requests。那麼這個 Pod 就會被劃分到 Burstable 類别。比如下面這個例子:

apiVersion: v1
kind: Pod
metadata:
  name: qos-demo-2
  namespace: qos-example
spec:
  containers:
  - name: qos-demo-2-ctr
    image: nginx
    resources:
      limits
        memory: "200Mi"
      requests:
        memory: "100Mi"      

2.3 BestEffort(盡力而為)類型

而如果一個 Pod 既沒有設定 requests,也沒有設定 limits,那麼它的 QoS 類别就是 BestEffort。比如下面這個例子

apiVersion: v1
kind: Pod
metadata:
  name: qos-demo-3
  namespace: qos-example
spec:
  containers:
  - name: qos-demo-3-ctr
    image: nginx      

三、QoS作用及模式

3.1 作用

實際上,QoS 劃分的主要應用場景,是當主控端資源緊張的時候,kubelet 對 Pod 進行 Eviction(即資源回收)時需要用到的。

具體地說,當 Kubernetes 所管理的主控端上不可壓縮資源短缺時,就有可能觸發 Eviction。比如,可用記憶體(memory.available)、可用的主控端磁盤空間(nodefs.available),以及容器運作時鏡像存儲空間(imagefs.available)等等。

目前,Kubernetes 為你設定的 Eviction 的預設門檻值如下所示:

memory.available<100Mi

nodefs.available<10%

nodefs.inodesFree<5%

imagefs.available<15%

3.2 模式

當然,上述各個觸發條件在 kubelet 裡都是可配置的。比如下面這個例子:

kubelet --eviction-hard=imagefs.available<10%,memory.available<500Mi,nodefs.available<5%,nodefs.inodesFree<5% --eviction-soft=imagefs.available<30%,nodefs.available<10% --eviction-soft-grace-period=imagefs.available=2m,nodefs.available=2m --eviction-max-pod-grace-period=600      

你可以看到 Eviction 在 Kubernetes 裡其實分為 Soft 和 Hard 兩種模式。

其中,Soft Eviction 允許你為 Eviction 過程設定一段“優雅時間”,比如上面例子裡的 imagefs.available=2m,就意味着當 imagefs 不足的門檻值達到 2 分鐘之後,kubelet 才會開始 Eviction 的過程。

而 Hard Eviction 模式下,Eviction 過程就會在門檻值達到之後立刻開始。

Kubernetes 計算 Eviction 門檻值的資料來源,主要依賴于從 Cgroups 讀取到的值,以及使用 cAdvisor 監控到的資料。

當主控端的 Eviction 門檻值達到後,就會進入 MemoryPressure 或者 DiskPressure 狀态,進而避免新的 Pod 被排程到這台主控端上。

而當 Eviction 發生的時候,kubelet 具體會挑選哪些 Pod 進行删除操作,就需要參考這些 Pod 的 QoS 類别了。

首當其沖的,自然是 BestEffort 類别的 Pod。

其次,是屬于 Burstable 類别、并且發生“饑餓”的資源使用量已經超出了 requests 的 Pod。

最後,才是 Guaranteed 類别。并且,Kubernetes 會保證隻有當 Guaranteed 類别的 Pod 的資源使用量超過了其 limits 的限制,或者主控端本身正處于 Memory Pressure 狀态時,Guaranteed 的 Pod 才可能被選中進行 Eviction 操作。

當然,對于同 QoS 類别的 Pod 來說,Kubernetes 還會根據 Pod 的優先級來進行進一步地排序和選擇。

四、cpuset 的設定

在了解了 Kubernetes 裡的 QoS 類别的設計之後,我再來為你講解一下Kubernetes 裡一個非常有用的特性:cpuset 的設定。

我們知道,在使用容器的時候,你可以通過設定 cpuset 把容器綁定到某個 CPU 的核上,而不是像 cpushare 那樣共享 CPU 的計算能力。

這種情況下,由于作業系統在 CPU 之間進行上下文切換的次數大大減少,容器裡應用的性能會得到大幅提升。事實上,cpuset 方式,是生産環境裡部署線上應用類型的 Pod 時,非常常用的一種方式。

在 Kubernetes 裡又該如何實作如下:

首先,你的 Pod 必須是 Guaranteed 的 QoS 類型;

然後,你隻需要将 Pod 的 CPU 資源的 requests 和 limits 設定為同一個相等的整數值即可。

spec:
  containers:
  - name: nginx
    image: nginx
    resources:
      limits:
        memory: "200Mi"
        cpu: "2"
      requests:
        memory: "200Mi"
        cpu: "2"      

繼續閱讀