· cloud

Pod memory usage in k8s

在K8s中,Pod的内容资源使用是由Cadvisor来采集的,相关指标由很多,究竟我们需要关系哪些指标。

Cadvisor内存使用率指标

Cadvisor 中有关 pod 内存使用率的指标如下:

指标说明
container_memory_cacheNumber of bytes of page cache memory.
container_memory_rssSize of RSS in bytes.(包括匿名映射页和交换区缓存)
container_memory_swapContainer swap usage in bytes.
container_memory_usage_bytesCurrent memory usage in bytes,including all memory regardless ofwhen it was accessed. (包括 cache, rss, swap 等)
container_memory_max_usage_bytesMaximum memory usage recorded in bytes.
container_memory_working_set_bytesCurrent working set in bytes. (工作区内存使用量=活跃的匿名与和缓存,以及 file-baked 页 <=container_memory_usage_bytes)
container_memory_failcntNumber of memory usage hits limits.
container_memory_failures_totalCumulative count of memory allocation failures.

指标有如下关系:

container_memory_max_usage_bytes > container_memory_usage_bytes >= container_memory_working_set_bytes > container_memory_rss

Cadvisor中指标对应的代码:

type MemoryStats struct { // Current memory usage, this includes all memory regardless of when it was // accessed. // Units: Bytes. Usage uint64 json:"usage"

// Maximum memory usage recorded.
	// Units: Bytes.
	MaxUsage uint64 `json:"max_usage"`

	// Number of bytes of page cache memory.
	// Units: Bytes.
	Cache uint64 `json:"cache"`

	// The amount of anonymous and swap cache memory (includes transparent
	// hugepages).
	// Units: Bytes.
	RSS uint64 `json:"rss"`

	// The amount of swap currently used by the processes in this cgroup
	// Units: Bytes.
	Swap uint64 `json:"swap"`

	// The amount of working set memory, this includes recently accessed memory,
	// dirty memory, and kernel memory. Working set is <= "usage".
	// Units: Bytes.
	WorkingSet uint64 `json:"working_set"`

	Failcnt uint64 `json:"failcnt"`

	ContainerData    MemoryStatsMemoryData `json:"container_data,omitempty"`
	HierarchicalData MemoryStatsMemoryData `json:"hierarchical_data,omitempty"`
}

这篇文章解释的很好

You might think that memory utilization is easily tracked with container_memory_usage_bytes, however, this metric also includes cached (think filesystem cache) items that can be evicted under memory pressure. The better metric is container_memory_working_set_bytes as this is what the OOM killer is watching for.

kubelet 是通过 watch container_memory_working_set_bytes 来判断是否 OOM, 所以用working_set来评价容器内存使用量更科学。

Cgroup中的内存指标

cgroup 目录相关文件

文件名说明cadvisor 中对应指标
memory.usage_in_bytes已使用的内存量(包含 cache 和 buffer)(字节),相当于 linux 的 used_memecontainer_memory_usage_bytes
memory.limit_in_bytes限制的内存总量(字节),相当于 linux 的 total_mem
memory.failcnt申请内存失败次数计数
memory.memsw.usage_in_bytes已使用的内存和 swap(字节)
memory.memsw.limit_in_bytes限制的内存和 swap 容量(字节)
memory.memsw.failcnt申请内存和 swap 失败次数计数
memory.stat内存相关状态

memory.stat中包含有的内存信息

统计描述cadvisor 中对应指标
cache页缓存,包括 tmpfs(shmem),单位为字节container_memory_cache
rss匿名和 swap 缓存,不包括 tmpfs(shmem),单位为字节container_memory_rss
mapped_filememory-mapped 映射的文件大小,包括 tmpfs(shmem),单位为字节
pgpgin存入内存中的页数
pgpgout从内存中读出的页数
swapswap 用量,单位为字节container_memory_swap
active_anon在活跃的最近最少使用(least-recently-used,LRU)列表中的匿名和 swap 缓存,包括 tmpfs(shmem),单位为字节
inactive_anon不活跃的 LRU 列表中的匿名和 swap 缓存,包括 tmpfs(shmem),单位为字节
active_file活跃 LRU 列表中的 file-backed 内存,以字节为单位
inactive_file不活跃 LRU 列表中的 file-backed 内存,以字节为单位
unevictable无法再生的内存,以字节为单位
hierarchical_memory_limit包含 memory cgroup 的层级的内存限制,单位为字节
hierarchical_memsw_limit包含 memory cgroup 的层级的内存加 swap 限制,单位为字节

Cgroup的相关内存指标有如下关系:

active_anon + inactive_anon = anonymous memory + file cache for tmpfs + swap cache = rss + file cache for tmpfs
active_file + inactive_file = cache - size of tmpfs
working set = usage - total_inactive(k8s根据workingset 来判断是否驱逐pod)

mstat 看到的 active/inactive memory 就分别是active listinactive list中的内存大小。如果 inactive list很大,表明在必要时可以回收的页面很多;而如果inactive list很小,说明可以回收的页面不多。

Active/inactive memory 是针对用户进程所占用的内存而言的,内核占用的内存(包括 slab)不在其中。 至于在源代码中看到的 ACTIVE_ANON 和 ACTIVE_FILE,分别表示 anonymous pages 和 file-backed pages。

用户进程的内存页分为两种:与文件关联的内存(比如程序文件、数据文件所对应的内存页)和与文件无关的内存(比如进程的堆栈,用 malloc 申请的内存),前者称为file-backed pages,后者称为anonymous pages。File-backed pages 在发生换页(page-in 或 page-out)时,是从它对应的文件读入或写出;anonymous pages 在发生换页时,是对交换区进行读/写操作。