1. 程式人生 > >Kubernetes Pod 驅逐詳解

Kubernetes Pod 驅逐詳解

原文連結:Kubernetes Pod 驅逐詳解

在 Kubernetes 中,Pod 使用的資源最重要的是 CPU、記憶體和磁碟 IO,這些資源可以被分為可壓縮資源(CPU)和不可壓縮資源(記憶體,磁碟 IO)。可壓縮資源不可能導致 Pod 被驅逐,因為當 Pod 的 CPU 使用量很多時,系統可以通過重新分配權重來限制 Pod 的 CPU 使用。而對於不可壓縮資源來說,如果資源不足,也就無法繼續申請資源(記憶體用完就是用完了),此時 Kubernetes 會從該節點上驅逐一定數量的 Pod,以保證該節點上有充足的資源。

當不可壓縮資源不足時,Kubernetes 是通過 kubelet

來驅逐 Pod 的。kubelet 也不是隨機驅逐的,它有自己的一套驅逐機制,每個計算節點的 kubelet 都會通過抓取 cAdvisor 的指標來監控節點的資源使用量,下面我們來具體分析每種情況。

1. 儲存資源不足

下面是 kubelet 預設的關於節點儲存的驅逐觸發條件:

  • nodefs.available<10%(容器 volume 使用的檔案系統的可用空間,包括檔案系統剩餘大小和 inode 數量)
  • imagefs.available<15%(容器映象使用的檔案系統的可用空間,包括檔案系統剩餘大小和 inode 數量)

imagefs 使用量達到閾值時,kubelet 會嘗試刪除不使用的映象來清理磁碟空間。

nodefs 使用量達到閾值時,kubelet 就會拒絕在該節點上執行新 Pod,並向 API Server 註冊一個 DiskPressure condition。然後 kubelet 會嘗試刪除死亡的 Pod 和容器來回收磁碟空間,如果此時 nodefs 使用量仍然沒有低於閾值,kubelet 就會開始驅逐 Pod。從 Kubernetes 1.9 開始,kubelet 驅逐 Pod 的過程中不會參考 Pod 的 QoS,只是根據 Pod 的 nodefs 使用量來進行排名,並選取使用量最多的 Pod 進行驅逐。所以即使 QoS 等級為 Guaranteed 的 Pod 在這個階段也有可能被驅逐(例如 nodefs 使用量最大)。如果驅逐的是 Daemonset

,kubelet 會阻止該 Pod 重啟,直到 nodefs 使用量超過閾值。

如果一個 Pod 中有多個容器,kubelet 會根據 Pod 中所有容器的 nodefs 使用量之和來進行排名。即所有容器的 container_fs_usage_bytes 指標值之和。

舉個栗子,假設某計算節點上執行著一系列已知 QoS 等級和 nodefs 使用量的 Pod:

Pod Name Pod QoS nodefs usage
A Best Effort 800M
B Guaranteed 1.3G
C Burstable 1.2G
D Burstable 700M
E Best Effort 500M
F Guaranteed 1G

當 nodefs 的使用量超過閾值時,kubelet 會根據 Pod 的 nodefs 使用量來對 Pod 進行排名,首先驅逐使用量最多的 Pod。排名如下圖所示:

Pod Name Pod QoS nodefs usage
B Guaranteed 1.3G
C Burstable 1.2G
F Guaranteed 1G
A Best Effort 800M
D Burstable 700M
E Best Effort 500M

可以看到在本例中,QoS 等級為 Guaranteed 的 Pod 最先被驅逐。

2. 記憶體資源不足

下面是 kubelet 預設的關於節點記憶體資源的驅逐觸發條件:

  • memory.available<100Mi

當記憶體使用量超過閾值時,kubelet 就會向 API Server 註冊一個 MemoryPressure condition,此時 kubelet 不會接受新的 QoS 等級為 Best Effort 的 Pod 在該節點上執行,並按照以下順序來驅逐 Pod:

  • Pod 的記憶體使用量是否超過了 request 指定的值
  • 根據 priority 排序,優先順序低的 Pod 最先被驅逐
  • 比較它們的記憶體使用量與 request 指定的值之差。

按照這個順序,可以確保 QoS 等級為 Guaranteed 的 Pod 不會在 QoS 等級為 Best Effort 的 Pod 之前被驅逐,但不能保證它不會在 QoS 等級為 Burstable 的 Pod 之前被驅逐。

如果一個 Pod 中有多個容器,kubelet 會根據 Pod 中所有容器相對於 request 的記憶體使用量與之和來進行排名。即所有容器的 (container_memory_usage_bytes 指標值與 container_resource_requests_memory_bytes 指標值的差)之和。

繼續舉例,假設某計算節點上執行著一系列已知 QoS 等級和記憶體使用量的 Pod:

Pod Name Pod QoS Memory requested Memory limits Memory usage
A Best Effort 0 0 700M
B Guaranteed 2Gi 2Gi 1.9G
C Burstable 1Gi 2Gi 1.8G
D Burstable 1Gi 2Gi 800M
E Best Effort 0 0 300M
F Guaranteed 2Gi 2Gi 1G

當節點的記憶體使用量超過閾值時,kubelet 會根據 Pod 相對於 request 的記憶體使用量來對 Pod 進行排名。排名如下所示:

Pod Name Pod QoS Memory requested Memory limits Memory usage 記憶體相對使用量
C Burstable 1Gi 2Gi 1.8G 800M
A Best Effort 0 0 700M 700M
E Best Effort 0 0 300M 300M
B Guaranteed 2Gi 2Gi 1.9G -100M
D Burstable 1Gi 2Gi 800M -200M
F Guaranteed 2Gi 2Gi 1G -1G

可以看到在本例中,可以看到在本例中,QoS 等級為 Guaranteed 的 Pod 在 QoS 等級為 Burstable 的 Pod 之前被驅逐。

當記憶體資源不足時,kubelet 在驅逐 Pod 時只會考慮 requests 和 Pod 的記憶體使用量,不會考慮 limits。

3. Node OOM (Out Of Memory)

因為 kubelet 預設每 10 秒抓取一次 cAdvisor 的監控資料,所以有可能在 kubelet 驅逐 Pod 回收記憶體之前發生記憶體使用量激增的情況,這時就有可能觸發核心 OOM killer。這時刪除容器的權利就由kubelet 轉交到核心 OOM killer 手裡,但 kubelet 仍然會起到一定的決定作用,它會根據 Pod 的 QoS 來設定其 oom_score_adj 值:

QoS oom_score_adj
Guaranteed -998
Burstable min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999)
pod-infra-container -998
kubelet, docker daemon, systemd service -999

如果該節點在 kubelet 通過驅逐 Pod 回收記憶體之前觸發了 OOM 事件,OOM killer 就會採取行動來降低系統的壓力,它會根據下面的公式來計算 oom_score 的值:

容器使用的記憶體佔系統記憶體的百分比 + oom_score_adj = oom_score

OOM killer 會殺掉 oom_score_adj 值最高的容器,如果有多個容器的 oom_score_adj 值相同,就會殺掉記憶體使用量最多的容器(其實是因為記憶體使用量最多的容器的 oom_score 值最高)。關於 OOM 的更多內容請參考:Kubernetes 記憶體資源限制實戰。

假設某節點執行著 4 個 Pod,且每個 Pod 中只有一個容器。每個 QoS 型別為 Burstable 的 Pod 配置的記憶體 requests 是 4Gi,節點的記憶體大小為 30Gi。每個 Pod 的 oom_score_adj 值如下所示:

Pod Name Pod QoS oom_score_adj
A Best Effort 1000
B Guaranteed -998
C Burstable 867(根據上面的公式計算)
D Best Effort 1000

當呼叫 OOM killer 時,它首先選擇 oom_score_adj 值最高的容器(1000),這裡有兩個容器的 oom_score_adj 值都是 1000,OOM killer 最終會選擇記憶體使用量最多的容器。

4. 總結

  • 因為 kubelet 預設每 10 秒抓取一次 cAdvisor 的監控資料,所以可能在資源使用量低於閾值時,kubelet 仍然在驅逐 Pod。
  • kubelet 將 Pod 從節點上驅逐之後,Kubernetes 會將該 Pod 重新排程到另一個資源充足的節點上。但有時候 Scheduler 會將該 Pod 重新排程到與之前相同的節點上,比如設定了節點親和性,或者該 Pod 以 Daemonset 的形式執行。

現在你應該理解了 kubelet 驅逐 Pod 的原理和過程,如果你在部署應用時設定了恰當的引數,知道了所有的可能性,你就能更好地掌控你的叢集。

相關推薦

Kubernetes Pod 驅逐

原文連結:Kubernetes Pod 驅逐詳解 在 Kubernetes 中,Pod 使用的資源最重要的是 CPU、記憶體和磁碟 IO,這些資源可以被分為可壓縮資源(CPU)和不可壓縮資源(記憶體,磁碟 IO)。可壓縮資源不可能導致 Pod 被驅逐,因為當 Pod 的 CPU 使用量很多時,系統可以通過

通過describe命令學習Kubernetespod屬性

我們可以首先使用kubectl get pods命令得到pod列表,比如我們想研究pod nginx-storage-pod的明細: 使用命令kubectl describe pod nginx-storage-pod > nginx-storage-pod.yaml,

kubernetes之StatefulSet

part 更新 實現 ati partition code 自動創建 svc 解決 概述 RC、Deployment、DaemonSetStatefulSet都是面向無狀態的服務,它們所管理的Pod的IP、名字,啟停順序等都是隨機的,而StatefulSet是什麽?顧名思義

Kubernetes的Configmap

ConfigMap是用來儲存配置檔案的kubernetes資源物件,所有的配置內容都儲存在etcd中。 1.建立ConfigMap 建立ConfigMap的方式有4種: 通過直接在命令列中指定configmap引數建立,即--from-literal

資深實踐篇 |基於Kubernetes 1.61的Kubernetes Scheduler排程

資深實踐篇 |基於Kubernetes 1.61的Kubernetes Scheduler排程詳解 關鍵字標籤:騰訊雲,效能優化,Github 說明:該文轉載自騰訊雲技術社群騰雲閣,已徵求作者本人同意。 原始碼為 k8s v1.6.1 版本,github 上對應的 com

kubernetes容器啟動

如果大家對kubernetes元件以及架構相關分析,可以看我之前的原始碼閱讀,今天只從一個函式分析容器的啟動過程,這個函式就是SyncPod,這個是建立kubelet裡面最核心的一個函數了。這個方法分為五步: // 1. Compute sandbox

kubernetes cni網路

1.CNI介紹 一直以來,kubernetes 並沒有專門的網路模組負責網路配置,它需要使用者在主機上已經配置好網路。 kubernetes 對網路的要求是: 容器之間(包括同一臺主機上的容器,和不同主機的容器)可以互相通訊 容器和叢集中所有的節點也能直

kubernetes監控告警

1. 概述1.1 總體目標從監控平臺本身的業務需求分析來看,我們至少應該希望通過Prometheus平臺獲取到以下監控資料:效能指標 1.容器相關的效能指標資料(如:cpu, memory, filesystem) 2.Pod相關的效能指標資料 3.主機節點相關的效能指標資料服務健康狀態 1.Deployme

超長幹貨 | Kubernetes命名空間

模板 true ext 邏輯 時間 ont 集群 組織 了解 K8s使用命名空間的概念幫助解決集群中在管理對象時的復雜性問題。在本文中,會討論命名空間的工作原理,介紹常用實例,並分享如何使用命名空間來管理K8s對象。最後,介紹名為projects的Rancher特性是如何構

原生Kubernetes監控功能-Part1

Kubernetes是一個開源的容器編排框架,它為我們提供了一種簡單的部署、擴充套件和監控的方法。本文將討論Kubernetes的

kubernetes-pod驅逐機制

1.驅逐策略   kubelet持續監控主機的資源使用情況,並儘量防止計算資源被耗盡。一旦出現資源緊缺的跡象,kubelet就會主動終止部分pod的執行,以回收資源。 2.驅逐訊號   以下是一些kubelet能用來做決策依據的訊號,依據這些訊號來做驅逐行為。   memory : 記憶體;   nodefs

Kubernetes Pod驅逐策略

Kubelet 能夠主動監測和防止計算資源的全面短缺。 在資源短缺的情況下,kubelet 可以主動地結束一個或多個 Pod 以回收短缺的資源。 當 kubelet 結束一個 Pod 時,它將終止 Pod 中的所有容器,而 Pod 的 Phase 將變為 Failed。 如果被驅逐的 Pod 由 Deploy

Kubernetes對象之Pod(附安裝部署方法)

虛擬化技術 kubernetes docker 首先介紹一下K8S是什麽:(引用自K8S中文社區)Kubernetes是容器集群管理系統,是一個開源的平臺,可以實現容器集群的自動化部署、自動擴縮容、維護等功能。通過Kubernetes你可以:快速部署應用快速擴展應用無縫對接新的應用功能節省資源,優

Kubernetes-15:一文Pod、Node排程規則(親和性、汙點、容忍、固定節點)

Kubernetes Pod排程說明 簡介 Scheduler 是 Kubernetes 的排程器,主要任務是把定義的Pod分配到叢集的節點上,聽起來非常簡單,但要考慮需要方面的問題: 公平:如何保證每個節點都能被分配到資源 資源高效利用:叢集所有資源最大化被使用 效率:排程效能要好,能夠儘快的對大批量的P

Kubernetes核心概念之Replication Controller

kubernetes docker 虛擬化 replication controll Replication Controller簡稱RC,它能夠保證Pod持續運行,並且在任何時候都有指定數量的Pod副本,在此基礎上提供一些高級特性,比如滾動升級和彈性伸縮? ? 它在k8s中的架構如圖:? ?

k8s一個完整的監控方案(Heapster+Grafana+InfluxDB) - kubernetes

ear required clust heapster lec beta 成功 use type 1、淺析整個監控流程 heapster以k8s內置的cAdvisor作為數據源收集集群信息,並匯總出有價值的性能數據(Metrics):cpu、內存、網絡流量等,然後將這些數

kubernetes configMap

configMapKubernetes的ConfigMap說明  這篇博文,我們來說一說,關於在kubernetes的pod中自定義配置的問題。  我們知道,在幾乎所有的應用開發中,都會涉及到配置文件的變更,比如說在web的程序中,需要連接數據庫,緩存甚至是隊列等等。而我們的一個應用程序從寫第一行代碼開始,要

Kubernetes核心概念之Service

clusterip ips aml 開放 lan font led IT 架構 Service是k8s中非常重要的組成單元,作用是作為代理把在POD中容器內的服務發布出去,提供一套簡單的發現機制和服務代理,也就是運維常說的‘前端’概念,那麽它如何實現代理功能以及自動

Kubernetes核心概念之Volume存儲數據卷

gin creat 自己的 當前 ges 訪問路徑 服務器 tor type 在Docker中就有數據卷的概念,當容器刪除時,數據也一起會被刪除,想要持久化使用數據,需要把主機上的目錄掛載到Docker中去,在K8S中,數據卷是通過Pod實現持久化的,如果Pod刪除

kubernetes

安裝docker key repo 定義 防火 highlight set wal span 一:定義 kubernetes是一個全新的基於容器技術的分布式架構解決方案,並且是一個一站式的完備分布式系統開發和支撐平臺。 二:安裝k8s集群 1.關閉防火墻 #sy