[Kubernetes]資源模型與資源管理

做爲 Kubernetes 的資源管理與調度部分的基礎,須要從它的資源模型提及.mysql

資源管理模型的設計

咱們知道,在 Kubernetes 裏面, Pod 是最小的原子調度單位,這就意味着,全部和調度和資源管理有關的屬性,應該都是屬於 Pod 對象的字段,而在這些字段中,最重要的部分就是 Pod 的 CPU 和內存配置.
在 Kubernetes 中,像 CPU 這樣的資源被稱做"可壓縮資源"( compressible resources ).它典型特色是,當可壓縮資源不足時, Pod 只會"飢餓",可是不會退出.
可是內存這樣的資源,被稱做"不可壓縮資源"( incompressible resources ).當不可壓縮資源不足時, Pod 就會由於 OOM( Out-Of-Memory )被內核殺掉.
還記得嗎, Pod 能夠由多個 Container 組成,因此 CPU 和內存資源的限額,是要配置在每一個 Container 的定義上的.這樣, Pod 總體的資源配置,就由這些 Container 的配置值累加獲得.
web

來個例子:sql

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: db
    image: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "password"
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: wp
    image: wordpress
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

在上面,咱們可以看到, cpu limits 的值是 500m ( 500m 指的就是 500 millicpu ,也就是 0.5 個 cpu 的意思),因此這個 Pod 會被分配到 1 個 CPU 一半的計算能力.
對於內存資源來講,它的單位是 bytes . Kubernetes 支持使用 Ei , Pi , Ti , Gi , Mi , Ki (或者 E , P , T , G , M , K )的方式來做爲 bytes 的值.在上面的例子中,咱們可以看到, Memory requests 的值就是 64MiB ( 2 的 26 次方 bytes ).因此, Kubernetes 中的 Pod 中 CPU 和內存資源,實際上還要分爲 limits 和 requests 兩種狀況,以下所示:
api

spec.containers[].resources.limits.cpu
spec.containers[].resources.limits.memory
spec.containers[].resources.requests.cpu
spec.containers[].resources.requests.memory

limits 和 requests 的區別其實很簡單:在調度的時候, kube-scheduler 只會按照 requests 的值進行計算,但在真正設置 Cgroups 限制的時候, kubelet 則會按照 limits 的值來進行設置.
說的再確切一點兒就是:當指定 requests.cpu=250m 以後,至關於將 Cgroups 的 cpu.shares 的值設置爲 ( 250/1000)×1024 .若是沒有設置 reques.cpu 的時候,默認是 1024 .若是指定了 limits.cpu=500m ,就至關於將 Cgroups 的 cpu.cfs_quota_us 的值設置爲 (500/1000)×100ms , cpu.cfs_period_us 的值始終是 100ms .這個時候, Kubernetes 就設置了這個容器只能用到 CPU 的 50& .
對於內存來講,當指定了 limits.memory=128Mi 以後,至關於將 Cgroups 的 memory.limit_in_bytes 設置爲 128×1024×1024 .可是在調度的時候,調度器只會使用 requests.memory=64Mi 來進行判斷.
以上就是 Kubernetes 資源管理模型的設計.
frontend

QoS模型

在上面說到, Kubernetes 會有不一樣的 requests 和 limits 的設置方式, Kubernetes 接下來會將這個 Pod 劃分到不一樣的 QoS 級別當中.因此,接下來我們來講說, Kubernetes 中的 QoS 模型.svg

若是 Pod 中的每個 Container 都同時設置了 requests 和 limits ,而且 requests 和 limits 值相等的時候,這個 Pod 就屬於 Guaranteed 類別.若是 Pod 只是設置了 limits 的值,而沒有設置 requests 的值, Kubernetes 會自動爲它設置和 limits 相同的 requests 的值,此時這也屬於 Guaranteed 狀況.
若是 Pod 不知足以上的狀況,可是至少有一個 Container 設置了 requests ,那麼這個 Pod 就會被劃分爲 Burstable 類別.
若是一個 Pod 既沒有設置 requests ,也沒有設置 limits ,那麼它的 QoS 類型就是 BestEffort .
wordpress

爲何 Kubernetes 要爲 Pod 設置這三種 QoS 類別呢?這樣設置有什麼做用呢?
那麼咱們就要知道, QoS 劃分的主要應用場景:當宿主機資源緊張的時候, kubelet 對 Pod 進行 Eviction (即資源回收)時須要用到的.
也就是說,當 Kubernetes 所管理的宿主機上不可壓縮資源短缺時,就有可能觸發 Eviction .好比,可用內存,可用的宿主機磁盤空間等資源短缺時,就會觸發 Eviction .
那麼當 Eviction 發生的時候, kubelet 就會開始挑選 Pod 進行刪除操做,來釋放不可壓縮資源,這個時候,就須要參考這些 Pod 的 QoS 類別了.
學習

  • 要進行刪除的時候
    • 首先考慮刪掉的,確定是 BestEffort 類別的 Pod
    • 若是不可壓縮資源仍是短缺,則會刪除 Burstable 類別,並且發生"飢餓"的資源使用量已經超出 requests 的 Pod
    • 若是資源仍是短缺,會考慮 Guaranteed 類別.而且, Kubernetes 會保證只有當 Guaranteed 類別的 Pod 的資源使用量超過了 limits 的限制,或者宿主機自己正處於 Memory Pressure 狀態時, Guaranteed 的 Pod 纔可能被選中進行 Eviction 操做.
  • 因此呢,在實際的使用過程當中,建議將 DaemonSet 的 Pod 都設置爲 Guaranteed 的 QoS 類型.不然,一旦 DaemonSet 的 Pod 被回收,它又會當即在原宿主機上被重建出來,這就使得資源回收變得沒有意義了.設計

    要分享的內容,到這裏就差很少了.
    以上內容來自我學習<深刻剖析Kubernetes>專欄文章以後的一些看法,有偏頗之處,還望指出.
    感謝您的閱讀~
    code

    相關文章
    相關標籤/搜索