1. 概述
在 Kubernetes 集群中,如果对内存使用管理不当,可能会导致 Pod 被意外驱逐。最坏的情况下,甚至可能引发整个集群的不稳定。幸运的是,Kubernetes 提供了多种指标来监控集群中 Pod 的内存使用情况。
在本文中,我们将深入理解 Kubernetes 收集的各类容器内存指标,并学习如何正确解读这些指标的含义,帮助我们更好地进行内存资源监控与问题排查。
2. Kubernetes 指标收集机制
Kubernetes 使用一种分层结构来收集和暴露容器的资源指标。
在最底层,每个节点上运行的 kubelet 会启动一个名为 cAdvisor(Container Advisor) 的组件。cAdvisor 会从节点上的容器运行时(container runtime)中收集资源使用情况,包括 CPU、内存、文件系统和网络等信息。这些指标通过 REST API 的方式暴露出来。
然后,Kubernetes 集群中的 metrics-server 会从各个节点的 cAdvisor 中收集并聚合这些指标。这些聚合后的数据可以用于自动扩缩容(如 Horizontal Pod Autoscaler),也可以通过 kubectl top
命令查看当前资源使用情况。
3. Linux 内核内存相关术语
由于 Kubernetes 依赖 Linux 的 cgroup 机制来管理容器资源,因此理解一些 Linux 内存术语有助于我们更好地解读容器内存指标。
3.1. 匿名内存(Anonymous Memory)
匿名内存是指不与任何文件关联的内存,例如程序运行时的堆栈、堆内存,或者通过 mmap 创建的匿名映射内存。
这类内存无法通过简单释放来回收,一旦使用过多,容易导致内存压力。
3.2. 页面缓存(Page Cache)
页面缓存是 Linux 用于缓存文件内容的内存区域。当程序读取磁盘文件时,系统会将内容缓存到内存中,以便下次读取更快。
⚠️ 注意:页面缓存是可以被回收的。即使一个容器使用了很多内存,只要大部分是页面缓存,也不一定意味着存在问题。
4. 容器内存相关指标详解
metrics-server 暴露了多个容器级别的内存指标,它们帮助我们监控容器的内存使用情况,并在出现问题时提供诊断依据。
4.1. container_memory_usage_bytes
- 含义:容器使用的总内存(包括匿名内存、页面缓存等)。
- 特点:
- 包含可回收内存(如页面缓存)。
- 指标值高不一定意味着内存压力大。
- ✅ 适用场景:用于监控整体内存使用趋势。
4.2. container_memory_cache
- 含义:容器用于缓存的内存大小(主要是页面缓存)。
- 特点:
- 可回收,内存压力时会被系统回收。
- ✅ 适用场景:用于分析缓存使用情况,辅助判断是否可以优化缓存策略。
4.3. container_memory_mapped_file
- 含义:容器通过 mmap 映射到内存的文件大小。
- 特点:
- 属于匿名内存的一部分。
- 用于文件映射,提升 I/O 性能。
- ✅ 适用场景:用于分析文件映射对内存的影响。
4.4. container_memory_rss
- 含义:容器使用的实际物理内存,包括匿名内存和 swap 缓存。
- 特点:
- 不包含页面缓存。
- 这部分内存不可回收,一旦使用过多,容易触发 OOM。
- ✅ 适用场景:用于监控不可回收内存使用情况,判断是否存在内存泄漏风险。
4.5. container_memory_working_set_bytes
- 含义:容器当前实际需要使用的内存,包括活跃的匿名内存和活跃的页面缓存。
- 计算方式:
container_memory_usage_bytes
减去非活跃的页面缓存。
- 特点:
- 更贴近实际内存使用情况。
- 比
container_memory_rss
更全面。
- ✅ 适用场景:推荐用于监控 OOM 风险。
5. 监控 OOM(Out of Memory)事件的指标
当我们为容器设置了内存限制后,Linux 的 cgroup 机制会强制执行这个限制。
当容器内存使用接近限制时,系统会尝试回收页面缓存。如果内存压力持续存在,最终会触发 OOM Killer,杀死容器进程。
在 Kubernetes 中,OOM 被杀的 Pod 会显示为 OOMKilled
状态,例如:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
memory-demo-7dc48cf8b4-2xrfs 1/1 OOMKilled 0 3m
如何预防 OOM?
推荐使用 container_memory_working_set_bytes
作为监控指标:
- 当该值持续上升,且系统无法回收活跃页面缓存时,说明不可回收内存在增长。
- 一旦接近内存限制,就可能触发 OOM。
⚠️ 踩坑提醒:不要只看 container_memory_usage_bytes
,因为它包含可回收内存,容易误导判断。
6. 总结
本文介绍了 Kubernetes 集群中内存指标的收集机制,并详细解读了几个关键的容器内存指标:
指标名称 | 描述 | 是否推荐用于 OOM 监控 |
---|---|---|
container_memory_usage_bytes |
总内存使用(含可回收内存) | ❌ |
container_memory_cache |
页面缓存 | ❌ |
container_memory_mapped_file |
文件映射内存 | ❌ |
container_memory_rss |
实际物理内存(不含缓存) | ⚠️ |
container_memory_working_set_bytes |
实际使用的内存(活跃内存) | ✅ 推荐 |
在实际监控中,推荐使用 container_memory_working_set_bytes
作为判断 OOM 风险的核心指标,并结合其他指标辅助分析。这样可以更准确地识别内存压力,避免容器被意外杀死。