压力驱逐机制
kubelet 监控节点的CPU、内存、磁盘工具和文件系统的inode等资源。
这些资源中的一个或者多个达到压力水位,kubelet会主动使节点上的一个或多个Pod失效,以收回资源。驱逐的方式是将Pod的 PodPhase 设置为 Failed,来终止 Pod。
节点压力驱逐时,kubelet 会考虑是:
软驱逐条件(有宽限期 viction-max-pod-grace-period),
还是硬驱逐 (宽限期为 0)
如Pod是由控制器管理,Pod终止后,Pod控制器会创建新的Pod来替代被驱逐的Pod。
驱逐的条件:
| 驱逐信号 | 描述 |
|---|---|
| memory.available | memory.available := node.status.capacity[memory] - node.stats.memory.workingSet |
| nodefs.available | nodefs.available := node.stats.fs.available |
| nodefs.inodesFree | nodefs.inodesFree := node.stats.fs.inodesFree |
| imagefs.available | imagefs.available := node.stats.runtime.imagefs.available |
| imagefs.inodesFree | imagefs.inodesFree := node.stats.runtime.imagefs.inodesFree |
关于可用内存 memory.available
我们可以参考如下脚本来加深认识
#!/bin/bash#!/usr/bin/env bash# This script reproduces what the kubelet does# to calculate memory.available relative to root cgroup.# current memory usagememory_capacity_in_kb=$(cat /proc/meminfo | grep MemTotal | awk '{print $2}')memory_capacity_in_bytes=$((memory_capacity_in_kb * 1024))memory_usage_in_bytes=$(cat /sys/fs/cgroup/memory/memory.usage_in_bytes)memory_total_inactive_file=$(cat /sys/fs/cgroup/memory/memory.stat | grep total_inactive_file | awk '{print $2}')memory_working_set=${memory_usage_in_bytes}if [ "$memory_working_set" -lt "$memory_total_inactive_file" ];thenmemory_working_set=0elsememory_working_set=$((memory_usage_in_bytes - memory_total_inactive_file))fimemory_available_in_bytes=$((memory_capacity_in_bytes - memory_working_set))memory_available_in_kb=$((memory_available_in_bytes / 1024))memory_available_in_mb=$((memory_available_in_kb / 1024))echo "memory.capacity_in_bytes $memory_capacity_in_bytes"echo "memory.usage_in_bytes $memory_usage_in_bytes"echo "memory.total_inactive_file $memory_total_inactive_file"echo "memory.working_set $memory_working_set"echo "memory.available_in_bytes $memory_available_in_bytes"echo "memory.available_in_kb $memory_available_in_kb"echo "memory.available_in_mb $memory_available_in_mb"
可以看到 memory.available 的值来自 cgroupfs, 而不是像 free 这样的工具呈现的数值。
node.status.capacity[memory] 是节点内存总量,参照 /proc/meminfo 中的 MemTotal
node.stats.memory.workingSet 是已工作负载占用内存,计算方式为:
memory_usage_in_bytes - memory_total_inactive_file
即:使用中的内存,减去可释放的缓存(未激活的匿名缓存页),这应该是一个很合理的可用内存算法。
nodefs是—root-dir目录所在分区,imagefs是docker安装目录所在的分区
