硬驱逐条件 {#hard-eviction-thresholds}
website Kubernetes website and documentation repo: 项目地址: https://gitcode.com/gh_mirrors/webs/website
硬驱逐条件没有宽限期。当达到硬驱逐条件时, kubelet 会立即杀死 pod,而不会正常终止以回收紧缺的资源。
你可以使用 eviction-hard
标志来配置一组硬驱逐条件, 例如 memory.available<1Gi
。
kubelet 具有以下默认硬驱逐条件:
memory.available<100Mi
(Linux 节点)memory.available<500Mi
(Windows 节点)nodefs.available<10%
imagefs.available<15%
nodefs.inodesFree<5%
(Linux 节点)imagefs.inodesFree<5%
(Linux 节点)
驱逐监控间隔 {#eviction-monitoring-interval}
kubelet 根据其配置的 housekeeping-interval
(默认为 10s
)评估驱逐条件。
节点状况 {#node-conditions}
kubelet 会报告节点状况以反映节点由于满足硬性或软性驱逐条件而面临压力。
驱逐信号的节点状况 {#node-condition-for-eviction-signals}
你可以配置 kubelet 以报告与驱逐信号相对应的节点状况。
对于每个驱逐信号,你可以指定一个自定义的 eviction-pressure-transition-period
, 该参数定义 kubelet 在将该状况转换为不同状态之前必须等待的时间。
kubelet 使用配置的周期来确定在报告指示节点处于压力下的节点状况之前, 节点必须保持压力状态的时间。
当节点不再处于压力之下并且信号低于定义的阈值达到配置的周期后,节点状况将更改为 Normal
。
磁盘压力的节点状况 {#node-conditions-for-disk-pressure}
对于具有专用 imagefs
文件系统用于容器镜像的节点,kubelet 会报告以下磁盘压力节点状况:
| 节点状况 | 驱逐信号 | 描述 | |----------------|------------------------------------------------------------------------|--------------------------------------------------------------------| | MemoryPressure
| memory.available
| 节点上的可用内存已满足驱逐条件 | | DiskPressure
| nodefs.available
、nodefs.inodesFree
、imagefs.available
或 imagefs.inodesFree
| 节点文件系统或镜像文件系统上的可用磁盘空间和 inode 已满足驱逐条件 | | PIDPressure
| pid.available
| (Linux)节点上的可用进程标识符已满足驱逐条件 |
kubelet 按照配置的 --node-status-update-frequency
(默认为 10s
)更新这些节点状况。
节点状况的振荡 {#oscillation-of-node-conditions}
如果节点在软驱逐条件的上下振荡,但没有超过与其关联的宽限期, 则会导致相应的节点状况不断在 true
和 false
之间振荡,从而导致错误的调度决策。
为了防止这种振荡,你可以使用 eviction-pressure-transition-period
标志, 该标志控制 kubelet 在脱离压力状况之前必须等待的时间。 过渡周期不会阻止对超过其驱逐条件且不满足其关联宽限期要求的资源进行驱逐, 但它确实会软化向调度程序报告节点状况以防止它们做出错误的调度分配。
调度器 {#scheduler}
当节点处于磁盘压力之下时,该节点会报告状况。 调度器将该状况视为一个信号, 避免将其他 Pod 调度到受影响的节点上。
基于污点的驱逐 {#taint-based-evictions}
kubelet 可以根据节点状况选择性地添加污点。 调度器在决定 Pod 的放置位置时会考虑节点污点。
有关详细信息,请参阅 根据状况为节点添加污点。
节点内存不足行为 {#node-out-of-memory-behavior}
如果节点在 kubelet 能够回收内存之前遇到系统内存不足 (OOM) 事件, 则节点依赖 oom_killer 来响应。
你可以配置 kubelet 根据容器所属 Pod 的服务质量 (QoS) 等级为容器设置 oom_score_adj
值。 kubelet 按如下方式设置此值:
| QoS 等级 | oom_score_adj
值 | |-----------------------|-------------------| | Guaranteed
| -997 | | BestEffort
| 1000 | | Burstable
| min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999) |
如果 kubelet 在节点遇到 OOM 之前无法回收内存, 则 oom_killer
根据它在节点上使用的内存百分比计算 oom_score
, 然后加上 oom_score_adj
得到容器的有效 oom_score
。 然后它会杀死得分最高的容器。
这意味着相对于其调度请求消耗大量内存的低 QoS Pod 中的容器将首先被杀死。
与 Pod 驱逐不同,如果容器被 OOM 杀死,kubelet 可以根据其 RestartPolicy
重新启动它。
最佳实践 {#best-practices}
以下部分描述了驱逐配置的最佳实践。
可调度资源和驱逐策略 {#schedulable-resources-and-eviction-policies}
当你使用驱逐策略配置 kubelet 时,你应该确保调度程序不会根据节点的容量调度比节点所能处理的更多的 Pod。
考虑以下场景:
- 节点内存容量:
10GiB
- 操作员希望为系统守护进程(内核、
kubelet
等)保留 10% 的内存容量 - 操作员希望在内存利用率达到 95% 时驱逐 Pod,以减少系统颠簸和系统 OOM 的发生概率
为了促成这个场景,kubelet 应该像下面这样启动:
--eviction-hard=memory.available<500Mi
--system-reserved=memory=1.5Gi
在此配置中,隐含的理解是“系统保留”应包括驱逐条件所涵盖的内存量。
要达到该容量,要么某个 Pod 使用的内存超过其请求,要么系统使用的内存超过 500Mi + 1.5Gi = 2GiB
。
此配置可确保当可用内存低于驱逐条件时,调度程序不会将超过节点处理能力的 Pod 放置在节点上。
DaemonSet 和节点压力驱逐 {#daemonsets-and-node-pressure-eviction}
Pod 优先级是做出驱逐决定的主要因素,如果不指定优先级, kubelet 在做出驱逐决定时不会按 QoS 等级对 Pod 进行排序。 也就是说,在节点压力驱逐期间,DaemonSet 中的 Pod 与常规 Pod 相比, 既不会被优先驱逐,也不会被避免驱逐。
但是,DaemonSet Pod 确实有能力指定优先级。 如果你使用优先级来表达所需的驱逐顺序, 则应将 DaemonSet Pod 的 PriorityClass 设置为比普通 Pod 更高的优先级。 你还可以使用较低的优先级或默认优先级来防止 DaemonSet Pod 驱逐常规 Pod。
临时存储限制 {#ephemeral-storage-limitation}
如果 kubelet 为 Pod 管理本地临时存储,则 kubelet 会监控该存储作为其整体资源压力计算的一部分。
kubelet 使用以下内容测量临时存储:
emptyDir
卷,除了 tmpfsemptyDir
卷- 保存节点级日志的目录
- 保存容器镜像层和容器可写层的目录
如果 Pod 使用的临时存储超过了你允许的量,kubelet 会设置一个驱逐信号来触发 Pod 驱逐。
有关更多信息,请参阅 临时存储消耗。
已知问题 {#known-issues}
以下部分描述了与资源不足处理相关的已知问题。
kubelet 可能不会立即发现内存压力 {#kubelet-may-not-observe-memory-pressure-right-away}
kubelet 目前定期轮询 cAdvisor
以收集内存使用统计信息。 如果内存使用量在该窗口内迅速增加,kubelet 可能无法足够快地观察到 MemoryPressure
, 并且 oom_killer
可能仍会被调用。
你可以通过将 --eviction-hard
标志设置为适当的值来缓解此问题以预测内存压力, 或者通过调整 --housekeeping-interval
以更频繁地轮询。
active_file
内存不被视为可用内存 {#active_file-memory-is-not-considered-as-available-memory}
在 Linux 上,内核跟踪活动 LRU 列表上基于文件来虚拟的内存的字节数作为 active_file
统计信息。 kubelet 在计算 memory.available
时将 active_file
内存视为不可用(不可回收)。 大量使用页面缓存(例如,读取或写入大文件)的进程可能会导致节点上的内存压力, 而 memory.available
不会显示这种压力。 如果你预期工作负载会大量使用页面缓存,则可以通过设置较低的驱逐条件来补偿这一点。
你可以通过以下方式缓解此问题:
- 通过
--eviction-hard=memory.available<X
标志降低驱逐条件以考虑active_file
- 或者设置
--eviction-soft
并等待驱逐在宽限期内触发
website Kubernetes website and documentation repo: 项目地址: https://gitcode.com/gh_mirrors/webs/website
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考