1.驅逐策略
kubelet持續監控主機的資源使用情況,並盡量防止計算資源被耗盡。一旦出現資源緊缺的跡象,kubelet就會主動終止部分pod的運行,以回收資源。
2.驅逐信號
以下是一些kubelet能用來做決策依據的信號,依據這些信號來做驅逐行為。
memory : 內存;
nodefs: 指node自身的存儲,存儲daemon的運行日志等,一般指root分區/;
imagefs: 指docker daemon用於存儲image和容器可寫層(writable layer)的磁盤;
Eviction Signal | Condition | Description |
---|---|---|
memory.available |
MemoryPressue | memory.available := node.status.capacity[memory] - node.stats.memory.workingSet |
nodefs.available |
DiskPressure |
|
nodefs.inodesFree |
DiskPressure | nodefs.inodesFree := node.stats.fs.inodesFree |
imagefs.available |
DiskPressure | imagefs.available := node.stats.runtime.imagefs.available (鏡像以及容器可寫層等) |
imagefs.inodesFree |
DiskPressure | imagefs.inodesFree := node.stats.runtime.imagefs.inodesFree |
memory.available的值不是根據系統的free 收集,取值來自於cgroupfs,free -m命令不支持在容器中工作,
cgroup.event_control #用於eventfd的接口 memory.usage_in_bytes #顯示當前已用的內存 memory.limit_in_bytes #設置/顯示當前限制的內存額度 memory.failcnt #顯示內存使用量達到限制值的次數 memory.max_usage_in_bytes #歷史內存最大使用量 memory.soft_limit_in_bytes #設置/顯示當前限制的內存軟額度 memory.stat #顯示當前cgroup的內存使用情況 memory.use_hierarchy #設置/顯示是否將子cgroup的內存使用情況統計到當前cgroup里面 memory.force_empty #觸發系統立即盡可能的回收當前cgroup中可以回收的內存 memory.pressure_level #設置內存壓力的通知事件,配合cgroup.event_control一起使用 memory.swappiness #設置和顯示當前的swappiness memory.move_charge_at_immigrate #設置當進程移動到其他cgroup中時,它所占用的內存是否也隨着移動過去 memory.oom_control #設置/顯示oom controls相關的配置 memory.numa_stat #顯示numa相關的內存
查看系統總memory:
cat /proc/meminfo |grep MemTotal
查看當前已使用memory的方法:
#cat /sys/fs/cgroup/memory/memory.usage_in_bytes
查看當前cgroup使用memory情況:
cat /sys/fs/cgroup/memory/memory.stat |grep total_inactive_file
3.軟驅逐和硬驅逐
如果一個節點有10Gi內存,我們希望在內存不足1Gi時候進行驅逐,可以用下面兩種方式進行定位驅逐閾值:
memory.available<10% memory.available<1Gi
1.軟驅逐(Soft Eviction):配合驅逐寬限期(eviction-soft-grace-period和eviction-max-pod-grace-period)一起使用。系統資源達到軟驅逐閾值並在超過寬限期之后才會執行驅逐動作。
--eviction-soft:描述驅逐閾值,例如:memory.available<1.5G --eviction-soft-grace-period:驅逐寬限期,memory.available=1m30s --eviction-max-pod-grace-period:終止pod最大寬限時間,單位s
2.硬驅逐(Hard Eviction ):系統資源達到硬驅逐閾值時立即執行驅逐動作。
這些驅逐閾值可以使用百分比,也可以使用絕對值,如:
--eviction-hard=memory.available<500Mi,nodefs.available<1Gi,imagefs.available<100Gi --eviction-minimum-reclaim="memory.available=0Mi,nodefs.available=500Mi,imagefs.available=2Gi"` --system-reserved=memory=1.5Gi
4.回收Node級別資源
- 驅逐Node級別資源
-
- 配置了 imagefs 閾值時
- 達到 nodefs 閾值:刪除已停止的 Pod
- 達到 imagefs 閾值:刪除未使用的鏡像
- 未配置 imagefs 閾值時
- 達到 nodefs閾值時,按照刪除已停止的 Pod 和刪除未使用鏡像的順序清理資源
- 配置了 imagefs 閾值時
- 驅逐用戶 Pod
- 驅逐順序為:BestEffort、Burstable、Guaranteed
- 配置了 imagefs 閾值時
- 達到 nodefs 閾值,基於 nodefs 用量驅逐(local volume + logs)
- 達到 imagefs 閾值,基於 imagefs 用量驅逐(容器可寫層)
- 未配置 imagefs 閾值時
- 達到 nodefs閾值時,按照總磁盤使用驅逐(local volume + logs + 容器可寫層)
除了驅逐之外,Kubelet 還支持一系列的容器和鏡像垃圾回收選項,它們未來將會被驅逐替代:
垃圾回收參數 | 驅逐參數 | 解釋 |
---|---|---|
--image-gc-high-threshold |
--eviction-hard 或 --eviction-soft |
現存的驅逐回收信號可以觸發鏡像垃圾回收 |
--image-gc-low-threshold |
--eviction-minimum-reclaim |
驅逐回收實現相同行為 |
--minimum-image-ttl-duration |
由於驅逐不包括TTL配置,所以它還會繼續支持 | |
--maximum-dead-containers |
一旦舊日志存儲在容器上下文之外,就會被棄用 | |
--maximum-dead-containers-per-container |
一旦舊日志存儲在容器上下文之外,就會被棄用 | |
--minimum-container-ttl-duration |
一旦舊日志存儲在容器上下文之外,就會被棄用 | |
--low-diskspace-threshold-mb |
--eviction-hard or eviction-soft |
驅逐回收將磁盤閾值泛化到其他資源 |
--outofdisk-transition-frequency |
--eviction-pressure-transition-period |
驅逐回收將磁盤壓力轉換到其他資源 |
5.節點資源緊缺情況下系統行為
1.Scheduler行為
Master上的scheduler不再向該節點調度pod,節點狀況與調度行為的對應關系如下:
MemoryPressure:不再調度新的BestEffort pod到這個節點 DiskPressure:不再向這一節點調度pod
2.Node的OOM行為
kubelet根據pod的Qos為每個容器設置一個oom_score_adj,如果kubelet無法在系統OOM之前回收足夠的內存。則oom_killer會根據內存使用比例來計算oom_score,最后結果和oom_score_adj相加,得分最高的pod將會首先被驅逐。