-
2021-05-11 11:32:20
linux下查看内存使用情况zz
2008-06-20 10:57
老是忘,贴一篇长长记性
在Linux下查看内存我们一般用free命令:
[root@scs-2 tmp]# free
total used free shared buffers cached
Mem: 3266180 3250004 16176 0 110652 2668236
-/+ buffers/cache: 471116 2795064
Swap: 2048276 80160 1968116
下面是对这些数值的解释:
total:总计物理内存的大小。
used:已使用多大。
free:可用有多少。
Shared:多个进程共享的内存总额。
Buffers/cached:磁盘缓存的大小。
第三行(-/+ buffers/cached):
used:已使用多大。
free:可用有多少。
第四行就不多解释了。
区别:第二行(mem)的used/free与第三行(-/+ buffers/cache) used/free的区别。 这两来看,第一行是从OS的角度来看,因为对于OS,buffers/cached 都是属于被使用,KB,已用内存是3250004KB,其中包括,内核(OS)使用+Application(X, oracle,etc)使第三行所指的是从应用程序角度来看,对于应用程序来说,buffers/cached 是等于可用为了提高文件读取的性能,当应用程序需在用到内存的时候,buffer/cached会很快地被所以从应用程序的角度来说,可用内存=系统free memory+buffers+cached。
如上例:
2795064=16176+110652+2668236
接下来解释什么时候内存会被交换,以及按什么方交换。 当可用内存少于额定值的时如何看额定值:
cat /proc/meminfo
[root@scs-2 tmp]# cat /proc/meminfo
MemTotal: 3266180 kB
MemFree: 17456 kB
Buffers: 111328 kB
Cached: 2664024 kB
SwapCached: 0 kB
Active: 467236 kB
Inactive: 2644928 kB
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 3266180 kB
LowFree: 17456 kB
SwapTotal: 2048276 kB
SwapFree: 1968116 kB
Dirty: 8 kB
Writeback: 0 kB
Mapped: 345360 kB
Slab: 112344 kB
Committed_AS: 535292 kB
PageTables: 2340 kB
VmallocTotal: 536870911 kB
VmallocUsed: 272696 kB
VmallocChunk: 536598175 kB
HugePages_Total: 0
HugePages_Free: 0
Hugepagesize: 2048 kB
用free -m查看的结果:
[root@scs-2 tmp]# free -m
total used free shared buffers cached
Mem: 3189 3173 16 0 107 2605
-/+ buffers/cache: 460 2729
Swap: 2000 78 1921
查看/proc/kcore文件的大小(内存镜像):
[root@scs-2 tmp]# ll -h /proc/kcore
-r-------- 1 root root 4.1G Jun 12 12:04 /proc/kcore
备注:
占用内存的测量
测量一个进程占用了多少内存,linux为我们提供了一个很方便的方法,/proc目录为我上top等工具也通过这里来获取相应的信息。
/proc/meminfo 机器的内存使用信息
/proc/pid/maps pid为进程号,显示当前进程所占用的虚拟地址。
/proc/pid/statm 进程所占用的内存
[root@localhost ~]# cat /proc/self/statm
654 57 44 0 0 334 0
输出解释
CPU 以及CPU0。。。的每行的每个参数意思(以第一行为例)为:
参数 解释 /proc//status
Size (pages) 任务虚拟地址空间的大小 VmSize/4
Resident(pages) 应用程序正在使用的物理内存的大小 VmRSS/4
Shared(pages) 共享页数 0
Trs(pages) 程序所拥有的可执行虚拟内存的大小 VmExe/4
Lrs(pages) 被映像到任务的虚拟内存空间的库的大小 VmLib/4
Drs(pages) 程序数据段和用户态的栈的大小 (VmData+ VmStk )4
dt(pages) 04
查看机器可用内存
/proc/28248/>free
total used free shared buffers cached
Mem: 1023788 926400 97388 0 134668 503688
-/+ buffers/cache: 288044 735744
Swap: 1959920 89608 1870312
我们通过free命令查看机器空闲内存时,会发现free的值很小。这主要是因为,在lin不用白不用,因此它尽可能的cache和buffer一些数据,以方便下次使用。但实际上这使用的。
所以 空闲内存=free+buffers+cached=total-used
更多相关内容 -
docker限制容器的cpu内存使用率
2022-04-29 13:40:30用户内存限制就是对容器能使用的内存和交换分区的大小作出限制。使用时要遵循两条直观的规则:-m,–memory选项的参数最小为 4 M。–memory-swap不是交换分区,而是内存加交换分区的总大小,所以–memory-swap必须比...| –kernel-memory | 核心内存限制。格式同上,最小为 4M |
[](()memory & memory-swap
- 用户内存限制就是对容器能使用的内存和交换分区的大小作出限制。使用时要遵循两条直观的规则:-m,–memory选项的参数最小为 4 M。–memory-swap不是交换分区,而是内存加交换分区的总大小,所以–memory-swap必须比-m,–memory大。在这两条规则下,一般有四种设置方式。
你可能在进行内存限制的实验时发现docker run命令报错:WARNING: Your kernel does not support swap limit capabilities, memory limited without swap.
这是因为宿主机内核的相关功能没有打开。按照下面的设置就行。
step 1:编辑/etc/default/grub文件,将GRUB_CMDLINE_LINUX一行改为GRUB_CMDLINE_LINUX=“cgroup_enable=memory swapaccount=1”
step 2:更新 GRUB,即执行$ sudo update-grub
step 3: 重启系统。
关于内存和缓存的设置分以下4种情况
- 1.不设置
如果不设置-m,–memory和–memory-swap,容器默认可以用完宿舍机的所有内存和 swap 分区。不过注意,如果容器占用宿主机的所有内存和 swap 分区超过一段时间后,会被宿主机系统杀死(如果没有设置–00m-kill-disable=true的话)。
- 2.设置-m,–memory,不设置–memory-swap
给-m或–memory设置一个不小于 4M 的值,假设为 a,不设置–memory-swap,或将–memory-swap设置为 0。这种情况下,容器能使用的内存大小为 a,能使用的交换分区大小也为 a。因为 Docker 默认容器交换分区的大小和内存相同。
如果在容器中运行一个一直不停申请内存的程序,你会观察到该程序最终能占用的内存大小为 2a。
比如$ docker run -m 1G ubuntu:16.04,该容器能使用的内存大小为 1G,能使用的 swap 分区大小也为 1G。容器内的进程能申请到的总内存大小为 2G。
- 3.设置-m,–memory=a,–memory-swap=b,且b > a
给-m设置一个参数 a,给–memory-swap设置一个参数 b。a 时容器能使用的内存大小,b是容器能使用的 内存大小 + swap 分区大小。所以 b 必须大于 a。b -a 即为容器能使用的 swap 分区大小。
比如$ docker run -m 1G --memory-swap 3G ubuntu:16.04,该容器能使用的内存大小为 1G,能使用的 swap 分区大小为 2G。容器内的进程能申请到的总内存大小为 3G。
- 4.设置-m,–memory=a,–memory-swap=-1
给-m参数设置一个正常值,而给–memory-swap设置成 -1。这种情况表示限制容器能使用的内存大小为 a,而不限制容器能使用的 swap 分区大小。
这时候,容器内进程能申请到的内存大小为 a + 宿主机的 swap 大小。
[](()Memory reservation
-
这种 memory reservation 机制不知道怎么翻译比较形象。Memory reservation 是一种软性限制,用于节制容器内存使用。给–memory-reservation设置一个比-m小的值后,虽然容器最多可以使用-m使用的内存大小,但在宿主机内存资源紧张时,在系统的下次内存回收时,系统会回收容器的部分内存页,强迫容器的内存占用回到
--memory-reservation
设置的值大小。 -
没有设置时(默认情况下)
--memory-reservation
的值和-m的限定的值相同。将它设置为 0 会设置的比-m的参数大 等同于没有设置。 -
Memory reservation 是一种软性机制,它不保证任何时刻容器使用的内存不会超过–memory-reservation限定的值,它只是确保容器不会长时间占用超过–memory-reservation限制的内存大小。
例如:
$ docker run -it -m 500M --memory-reservation 200M ubuntu:16.04 /bin/bash
- 如果容器使用了大于 200M 但小于 500M 内存时,下次系统的内存回收会尝试将容器的内存锁紧到 200M 以下。
例如:
$ docker run -it --memory-reservation 1G ubuntu:16.04 /bin/bash
- 容器可以使用尽可能多的内存。–memory-reservation确保容器不会长时间占用太多内存。
[](()OOM killer
-
默认情况下,在出现 out-of-memory(OOM) 错误时,系统会杀死容器内的进程来获取更多空闲内存。这个杀死进程来节省内存的进程,我们姑且叫它 OOM killer。我们可以通过设置–oom-kill-disable选项来禁止 OOM killer 杀死容器内进程。但请确保只有在使用了-m/–memory选项时才使用–oom-kill-disable禁用 OOM killer。如果没有设置-m选项,却禁用了 OOM-killer,可能会造成出现 out-of-memory 错误时,系统通过杀死宿主机进程或获取更改内存。
-
下面的例子限制了容器的内存为 100M 并禁止了 OOM killer:
$ docker run -it -m 100M --oom-kill-disable ubuntu:16.04 /bin/bash
是正确的使用方法。
- 而下面这个容器没设置内存限制,却禁用了 OOM killer 是非常危险的:
$ docker run -it --oom-kill-disable ubuntu:16.04 /bin/bash
-
容器没用内存限制,可能或导致系统无内存可用,并尝试时杀死系统进程来获取更多可用内存。
-
一般一个容器只有一个进程,这个唯一进程被杀死,容器也就被杀死了。我们可以通过–oom-score-adj选项来设置在系统内存不够时,容器被杀死的优先级。负值更教不可能被杀死,而正值更有可能被杀死。
[](()核心内存
-
核心内存和用户内存不同的地方在于核心内存不能被交换出。不能交换出去的特性使得容器可以通过消耗太多内存来堵塞一些系统服务。核心内存包括:
-
stack pages(栈页面)
-
slab pages
-
socket memory pressure
-
tcp memory pressure
-
可以通过设置核心内存限制来约束这些内存。例如,每个进程都要消耗一些栈页面,通过限制核心内存,可以在核心内存使用过多时阻止新进程被创建。
-
核心内存和用户内存并不是独立的,必须在用户内存限制的上下文中限制核心内存。
-
假设用户内存的限制值为 U,核心内存的限制值为 K。有三种可能地限制核心内存的方式:
-
U != 0,不限制核心内存。这是默认的标准设置方式
-
K < U,核心内存时用户内存的子集。这种设置在部署时,每个 cgroup 的内存总量被过度使用。过度使用核心内存限制是绝不推荐的,因为系统还是会用完不能回收的内存。在这种情况下,你可以设置 K,这样 groups 的总数就不会超过总内存了。然后,根据系统服务的质量自有地设置 U。
-
K > U,因为核心内存的变化也会导致用户计数器的变化,容器核心内存和用户内存都会触发回收行为。这种配置可以让管理员以一种统一的视图看待内存。对想跟踪核心内存使用情况的用户也是有用的。
-
例如:
$ docker run -it -m 500M --kernel-memory 50M ubuntu:16.04 /bin/bash
- 容器中的进程最多能使用 500M 内存,在这 500M 中,最多只有 50M 核心内存。
$ docker run -it --kernel-memory 50M ubuntu:16.04 /bin/bash
- 没用设置用户内存限制,所以容器中的进程可以使用尽可能多的内存,但是最多能使用 50M 核心内存。
[](()Swappiness
-
默认情况下,容器的内核可以交换出一定比例的匿名页。–memory-swappiness就是用来设置这个比例的。–memory-swappiness可以设置为从 0 到 100。0 表示关闭匿名页面交换。100 表示所有的匿名页都可以交换。默认情况下,如果不适用–memory-swappiness,则该值从父进程继承而来。
-
例如:
$ docker run -it --memory-swappiness=0 ubuntu:16.04 /bin/bash
- 将–memory-swappiness设置为 0 可以保持容器的工作集,避免交换代理的性能损失。
[](()cpu限制
====================================================================
[](()查看cpu方法
- 最简单的方法就是直接执行命令:
lscpu
有一行内容是 CPU(s),后面就是cpu数量了。
root@ccx ~]# lscpu
A 《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 rchitecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4
On-line CPU(s) list: 0-3
Thread(s) per core: 1
Core(s) per socket: 2
Socket(s): 2
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 60
Model name: Intel® Core™ i5-4210M CPU @ 2.60GHz
Stepping: 3
CPU MHz: 2601.000
BogoMIPS: 5202.00
Virtualization: VT-x
Hypervisor vendor: VMware
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 3072K
NUMA node0 CPU(s): 0-3
- 默认情况下,每个进程都会随机分配在不同的cpu上,以达到均衡。
[](()查看进程运行在某个cpu上
- 既然在说容器使用率,我们就随便创建一个容器,模拟5个后台进程
[root@ccx ~]# docker run -it --rm --name=test hub.c.163.com/library/centos
[root@4f665e5220a7 /]# cat /dev/zero > /dev/null &
[1] 16
[root@4f665e5220a7 /]# cat /dev/zero > /dev/null &
[2] 17
[root@4f665e5220a7 /]# cat /dev/zero > /dev/null &
[3] 18
[root@4f665e5220a7 /]# cat /dev/zero > /dev/null &
[4] 19
[root@4f665e5220a7 /]# cat /dev/zero > /dev/null &
[5] 20
[root@4f665e5220a7 /]#
- 回到主机上,看这几个进程
命令:
ps aux | grep -v grep | grep cat
是可以看到这5个cat后台进程的
[root@ccx ~]# ps aux | grep -v grep | grep cat
gdm 15950 0.0 0.1 362972 4552 ? Sl 09:23 0:00 /usr/libexec/gsd-print-notifications
root 42016 79.6 0.0 4324 344 pts/0 R 10:49 0:57 cat /dev/zero
root 42018 81.6 0.0 4324 344 pts/0 R 10:49 0:58 cat /dev/zero
root 42019 78.0 0.0 4324 348 pts/0 R 10:49 0:55 cat /dev/zero
root 42021 77.9 0.0 4324 344 pts/0 R 10:49 0:54 cat /dev/zero
root 42022 81.3 0.0 4324 344 pts/0 R 10:49 0:56 cat /dev/zero
[root@ccx ~]#
- 查看这5个cat分别运行在几号cpu上
命令:
ps mo pid,comm,psr
pgrep cat``前面的PID是进程,后面的PSR就是cpu号数了
[root@ccx ~]# ps mo pid,comm,psr
pgrep cat
PID COMMAND PSR
42016 cat -
-
-
1
-
42018 cat -
-
-
2
-
42019 cat -
-
-
3
-
42021 cat -
-
-
3
-
42022 cat -
-
-
2
-
[root@ccx ~]#
[](()限制cpu运行号数
[](()说明
- 着的限制cpu并不是限制cpu的使用百分比,而是让容器固定运行在某颗cpu上。
限制cpu运行号数参数:
--cpuset-cpus=cpu1,cpu2,cpu3
【特殊使用,也可以区间限制的,比如想限制在0-5和11号cpu上,则--cpuset-cpus=0-5,11
】[](()限制在单颗cpu上
- 如:我现在运行一个centos的容器,让其固定运行在1号cpu上,并且在开4个cat的后台程序
[root@ccx ~]# docker run -it --rm --cpuset-cpus=1 hub.c.163.com/library/centos
[root@0e40ae45da0d /]# cat /dev/zero > /dev/null &
[1] 15
[root@0e40ae45da0d /]# cat /dev/zero > /dev/null &
[2] 16
[root@0e40ae45da0d /]# cat /dev/zero > /dev/null &
[3] 17
[root@0e40ae45da0d /]# cat /dev/zero > /dev/null &
[4] 18
[root@0e40ae45da0d /]#
- 容器创建完以后重新打开一个终端,查看容器进程是否都限制在1号cpu上了。
测试没问题。
[root@ccx ~]# ps mo pid,comm,psr
pgrep cat
PID COMMAND PSR
20745 cat -
-
-
1
-
20746 cat -
-
-
1
-
20755 cat -
-
-
1
-
20756 cat -
-
-
1
-
[root@ccx ~]#
[](()限制在多颗cpu上
- 如:我现在运行一个centos的容器,让其在0和1号cpu上运行,并且在开4个cat的后台程序
[root@ccx ~]# docker run -it --rm --cpuset-cpus=0,1 hub.c.163.com/library/centos
[root@88a8bb41c82f /]# cat /dev/zero > /dev/null &
[1] 14
[root@88a8bb41c82f /]# cat /dev/zero > /dev/null &
[2] 15
[root@88a8bb41c82f /]# cat /dev/zero > /dev/null &
[3] 16
[root@88a8bb41c82f /]# cat /dev/zero > /dev/null &
[4] 17
[root@88a8bb41c82f /]#
- 容器创建完以后重新打开一个终端,查看容器进程是否都限制在1号cpu上了。
结果可以看到在0好1号cpu上漂浮,没问题。
[root@ccx ~]# ps mo pid,comm,psr
pgrep cat
PID COMMAND PSR
20909 cat -
-
-
1
-
20910 cat -
-
-
0
-
20911 cat -
-
容器内存分析
2020-04-03 13:58:46那么如何准确计算容器或Pod的内存使用率,k8s/docker又是如何计算,本文通过实验与源码阅读相结合来分析容器的内存实际使用量。 预备知识 不管docker还是k8s(通过cadvisor)最终都通过cgroup的memory group来得到内存...背景
在容器化环境中,平台需要提供准确的业务监控指标,已方便业务查看。那么如何准确计算容器或Pod的内存使用率,k8s/docker又是如何计算,本文通过实验与源码阅读相结合来分析容器的内存实际使用量。
预备知识
不管docker还是k8s(通过cadvisor)最终都通过cgroup的memory group来得到内存的原始文件,memory相关的主要文件如下:
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相关的内存
更多信息可参考Pod memory usage in k8s
查看源码
docker stat
docker stat的源码在stats_helpers.go,如下:
func calculateMemUsageUnixNoCache(mem types.MemoryStats) float64 { return float64(mem.Usage - mem.Stats["cache"]) }
内存使用量为
memory.usage=memory.usage_in_bytes-cache
kubectl top
在k8s中,
kubectl top
命令通过metric-server/heapster
获取cadvisor中working_set
的值,来表示Pod实例使用内存大小(不包括pause),metrics-server 中pod内存获取如下:func decodeMemory(target *resource.Quantity, memStats *stats.MemoryStats) error { if memStats == nil || memStats.WorkingSetBytes == nil { return fmt.Errorf("missing memory usage metric") } *target = *uint64Quantity(*memStats.WorkingSetBytes, 0) target.Format = resource.BinarySI return nil }
cadvisor中working_set计算如下:
func setMemoryStats(s *cgroups.Stats, ret *info.ContainerStats) { ret.Memory.Usage = s.MemoryStats.Usage.Usage ret.Memory.MaxUsage = s.MemoryStats.Usage.MaxUsage ret.Memory.Failcnt = s.MemoryStats.Usage.Failcnt if s.MemoryStats.UseHierarchy { ret.Memory.Cache = s.MemoryStats.Stats["total_cache"] ret.Memory.RSS = s.MemoryStats.Stats["total_rss"] ret.Memory.Swap = s.MemoryStats.Stats["total_swap"] ret.Memory.MappedFile = s.MemoryStats.Stats["total_mapped_file"] } else { ret.Memory.Cache = s.MemoryStats.Stats["cache"] ret.Memory.RSS = s.MemoryStats.Stats["rss"] ret.Memory.Swap = s.MemoryStats.Stats["swap"] ret.Memory.MappedFile = s.MemoryStats.Stats["mapped_file"] } if v, ok := s.MemoryStats.Stats["pgfault"]; ok { ret.Memory.ContainerData.Pgfault = v ret.Memory.HierarchicalData.Pgfault = v } if v, ok := s.MemoryStats.Stats["pgmajfault"]; ok { ret.Memory.ContainerData.Pgmajfault = v ret.Memory.HierarchicalData.Pgmajfault = v } workingSet := ret.Memory.Usage if v, ok := s.MemoryStats.Stats["total_inactive_file"]; ok { if workingSet < v { workingSet = 0 } else { workingSet -= v } } ret.Memory.WorkingSet = workingSet }
working_set=memory.usage_in_bytes-total_inactive_file (>=0)
在kubelet中节点内存不足时同样以working_set
判断pod是否OOM的标准实验
- 创建Pod
Pod的资源申请如下:
resources: limits: cpu: "1" memory: 1Gi requests: cpu: "0" memory: "0"
- 查看cgroup内存情况
找到容器某个进程,查看memory cgroup
# cat /proc/16062/cgroup ... 8:memory:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod21a55da5_f9f8_11e9_b051_fa163e7e981a.slice/docker-57ba1991ab4ba50a9b2eaf5bf90e2c20073198d767653becf77d55ee25e1a6f9.scope
进入容器memory cgroup对应的目录
docker-57ba1991ab4ba50a9b2eaf5bf90e2c20073198d767653becf77d55ee25e1a6f9.scope]# ls cgroup.clone_children memory.kmem.failcnt memory.kmem.tcp.limit_in_bytes memory.max_usage_in_bytes memory.move_charge_at_immigrate memory.stat tasks cgroup.event_control memory.kmem.limit_in_bytes memory.kmem.tcp.max_usage_in_bytes memory.memsw.failcnt memory.numa_stat memory.swappiness cgroup.procs memory.kmem.max_usage_in_bytes memory.kmem.tcp.usage_in_bytes memory.memsw.limit_in_bytes memory.oom_control memory.usage_in_bytes memory.failcnt memory.kmem.slabinfo memory.kmem.usage_in_bytes memory.memsw.max_usage_in_bytes memory.pressure_level memory.use_hierarchy memory.force_empty memory.kmem.tcp.failcnt memory.limit_in_bytes memory.memsw.usage_in_bytes memory.soft_limit_in_bytes notify_on_release
查看主要memory文件
# cat memory.limit_in_bytes (容器memory limit值,即1Gi) 1073741824 [root@node01 docker-57ba1991ab4ba50a9b2eaf5bf90e2c20073198d767653becf77d55ee25e1a6f9.scope]# cat memory.kmem.limit_in_bytes (容器内核使用memory limit值) 9223372036854771712 [root@node01 docker-57ba1991ab4ba50a9b2eaf5bf90e2c20073198d767653becf77d55ee25e1a6f9.scope]# [root@node01 docker-57ba1991ab4ba50a9b2eaf5bf90e2c20073198d767653becf77d55ee25e1a6f9.scope]# cat memory.soft_limit_in_bytes 9223372036854771712 [docker-57ba1991ab4ba50a9b2eaf5bf90e2c20073198d767653becf77d55ee25e1a6f9.scope]# cat notify_on_release 0 [docker-57ba1991ab4ba50a9b2eaf5bf90e2c20073198d767653becf77d55ee25e1a6f9.scope]# cat memory.oom_control oom_kill_disable 0 under_oom 0 oom_kill 0 [docker-57ba1991ab4ba50a9b2eaf5bf90e2c20073198d767653becf77d55ee25e1a6f9.scope]# cat memory.usage_in_bytes 2265088 [docker-57ba1991ab4ba50a9b2eaf5bf90e2c20073198d767653becf77d55ee25e1a6f9.scope]# cat memory.kmem.usage_in_bytes 901120 [docker-57ba1991ab4ba50a9b2eaf5bf90e2c20073198d767653becf77d55ee25e1a6f9.scope]# cat memory.stat cache 12288 rss 1351680 rss_huge 0 shmem 4096 mapped_file 4096 dirty 0 writeback 0 swap 0 pgpgin 4544 pgpgout 4211 pgfault 1948 pgmajfault 0 inactive_anon 4096 active_anon 1351680 inactive_file 8192 active_file 0 unevictable 0 hierarchical_memory_limit 1073741824 hierarchical_memsw_limit 1073741824 total_cache 12288 total_rss 1351680 total_rss_huge 0 total_shmem 4096 total_mapped_file 4096 total_dirty 0 total_writeback 0 total_swap 0 total_pgpgin 4544 total_pgpgout 4211 total_pgfault 1948 total_pgmajfault 0 total_inactive_anon 4096 total_active_anon 1351680 total_inactive_file 8192 total_active_file 0 total_unevictable 0
根据memory可得到如下关系:
memory.usage_in_bytes = memory.kmem.usage_in_bytes + rss + cache
即2265088=901120+1351680+12288那么容器的真实内存即:
memory.usage=memory.usage_in_bytes-cache
即rss+kmem_usage
通过
docker stat
查看,与公式相符合CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS 57ba1991ab4b k8s...default_21a55da5-f9f8-11e9-b051-fa163e7e981a_0 0.00% 2.148MiB / 1GiB 0.21% 12MB / 68.8MB 0B / 0B 2
结论
实际环境中,docker与k8s两种内存表示方式不同,一般
docker stat
总体值会小于kubectl top
- docker中内存表示为:
memory.usage = memory.usage_in_bytes - cache
- k8s中:
memory.usage = working_set = memory.usage_in_bytes - total_inactive_file (>=0)
根据cgroup memory关系有:
memory.usage_in_bytes = memory.kmem.usage_in_bytes + rss + cache
真实环境中两种表示相差不大,但更推荐使用
working_set
作为容器内存真实使用量(kubelt判断OOM的依据),
则容器内存使用率可表示为:
container_memory_working_set_bytes / memory.limit_in_bytes
参考
- https://www.kernel.org/doc/Documentation/cgroup-v1/memory.txt
- https://medium.com/@zhimin.wen/memory-limit-of-pod-and-oom-killer-891ee1f1cad8
- 创建Pod
-
获取Docker容器的内存使用情况
2021-02-04 12:04:47一开始以为使用 free -h 得到的就是docker 容器本身的内存使用情况 #容器 root@feb0423bbe52:/sys/fs/cgroup/memory# free -h total used free shared buff/cache available Mem: 62G 21G 267M 423M 41G 40G Swa一开始以为使用
free -h
得到的就是docker 容器本身的内存使用情况#容器 root@feb0423bbe52:/sys/fs/cgroup/memory# free -h total used free shared buff/cache available Mem: 62G 21G 267M 423M 41G 40G Swap: 5.0G 834M 4.2G
看到这个结果产生了疑问,因为和宿主机一模一样啊!
#宿主机 [root@mh-server-22 ~]# free -h total used free shared buff/cache available Mem: 62G 19G 1.2G 337M 41G 42G Swap: 5.0G 835M 4.2G
网上查到说,可以使用
docker stats --no-stream
查看容器内存、CPU使用情况,可以是可以,但是还是不够详细(可能大多数人在这一步就OK了,也没必要往下看了)
我需要知道docker容器自己使用了多少cache memory以及更多信息。
经过各种Google,找到这篇文章 Getting memory usage in Linux and Docker,他也提到在容器里使用
free -h
和在宿主机使用free -h
是一样的,free -h
本质上是读取/proc/meminfo
文件内容。文章中简单的介绍了下Docker背后隔离原理:
According to Docker Overview: The Underlying Technology, processes in a Docker container directly run in their host OS without any virtualization, but they are isolated from the host OS and other containers in effect thanks to these Linux kernel features:
namespaces: Isolate PIDs, hostnames, user IDs, network accesses, IPC, etc.
cgroups: Limit resource usage
UnionFS: Isolate file system
Because of the namespaces, ps command lists processes of Docker containers in addition to other processes in the host OS, while it cannot list processes of host OS or other containers in a docker container.By default, Docker containers have no resource constraints. So, if you run one container in a host and don’t limit resource usage of the container, and this is my case, the container’s “free memory” is same as the host OS’s “free memory”.
核心意思是 资源不隔离。所以 the container’s “free memory” is same as the host OS’s “free memory”.
然而要怎么样才能获取到容器本身的资源信息呢?
进入容器的
/sys/fs/cgroup/memory
这个目录里面有关内存的一些信息。如下:
root@feb0423bbe52:/sys/fs/cgroup/memory# ls cgroup.clone_children memory.force_empty memory.kmem.slabinfo memory.kmem.tcp.usage_in_bytes memory.memsw.failcnt memory.move_charge_at_immigrate memory.soft_limit_in_bytes memory.use_hierarchy cgroup.event_control memory.kmem.failcnt memory.kmem.tcp.failcnt memory.kmem.usage_in_bytes memory.memsw.limit_in_bytes memory.numa_stat memory.stat notify_on_release cgroup.procs memory.kmem.limit_in_bytes memory.kmem.tcp.limit_in_bytes memory.limit_in_bytes memory.memsw.max_usage_in_bytes memory.oom_control memory.swappiness tasks memory.failcnt memory.kmem.max_usage_in_bytes memory.kmem.tcp.max_usage_in_bytes memory.max_usage_in_bytes memory.memsw.usage_in_bytes memory.pressure_level memory.usage_in_bytes root@feb0423bbe52:/sys/fs/cgroup/memory#
查看
memory.stat
文件内容,可以得到很多信息,包括我需要的cache memory:- total_cache 1579098112 : 缓存内存
- total_rss 497885184:已使用内存
附注:memory.stat 每项含义请看这篇文章https://xuxinkun.github.io/2016/05/16/memory-monitor-with-cgroup/
其实portainer.io对容器的统计图表也是读取的
memory.stat
文件: -
Docker容器内存占用过高解决方法
2021-06-18 13:43:55Docker容器内存占用过高 #查看占用过高的应用 docker stats --动态实时显示 docker stats --no-stream --静态显示 #使用top命令查询占用过高的应用 top -c -b -o +%MEM | head -n 20 | tail -15 #修改compose file... -
查看docker容器的内存占用
2018-10-17 15:58:44使用docker stats命令可以查看容器的内存,但是有时候docker stats命令获得的数据可能准确,可以参考下面这种方式 先通过docker ps -a 找到容器的container id 再使用ps -ef 找到容器对应的进程 获得容器对应的pid... -
Docker容器 Cgroup资源分配(CPU和内存资源分配)
2021-03-30 14:14:12文章目录一、Cgroup 是什么?Cgroup 常用模块二、使用stress工具测试CPU和内存三、CPU 周期...2、Docker通过 Cgroup 来控制容器使用的资源配额,包括 CPU、内存、磁盘三大方面,基本覆盖了常见的资源配额和使用量控制。 -
一次K8S容器内存占用居高不下的排查案例
2020-06-28 17:33:42因此为了掌握主动权,可以在部署环境可以配合脚本做 “手动” HPA,当容器内存指标超过约定限制后,起一个新的容器替换,再将原先的容器给释放掉,就可以在预期内替换且业务稳定了。 image 总结 虽然这问题时间跨度... -
检索并观察Kubernetes Pod资源(CPU,内存)的利用率。-Node.js开发
2021-05-27 10:42:06用例需求用法在OOM终止之前将Preoom与Lightship结合使用以正常关闭服务相关项目用例如果节点在kubelet能够回收内存之前经历了系统OOM(内存不足)事件,则oom_killer会使用以下命令识别并杀死容器:相对于调度而言,... -
如何使用阿里云容器服务保障容器的内存资源质量
2022-04-08 10:19:16针对云原生场景下容器使用内存的困扰,阿里云容器服务 ACK 基于 Alibaba Cloud Linux 2 内核提供了容器内存服务质量(Memory QoS)功能,通过调配容器的内存回收和限流机制,保障内存资源公平性,改善应用的运行时... -
内存使用率始终超过90%怎么办?
2020-10-20 19:41:44现象: POD内存使用率超过90% 排查焦点:是否存在内存泄露? 查看pod配置可知该pod共分配5g内存, 通过 jstate -gcutil $(pid)命令可知 1.年轻代大小是1g, 老年代大小是3g 2.年轻代频繁ygc 3.老年代目前fgc总次数是13... -
性能调优-------(六)内存使用率高,5分钟如何快速排查问题(真实场景实战图文讲解)
2018-12-18 18:42:27指标解释:容器的内存使用率是读取物理机cgroup下面的文件的,获取的是整个容器的内存使用率并不是针对某个程序。物理机内存使用率和使用free命令计算结果是一致的。物理机和容器两者内存计算数据是独立的 解决步骤... -
python脚本监控docker容器
2020-12-24 09:09:341、监控CPU使用率 2、监控内存使用状况 3、监控网络流量 具体代码: #!/usr/bin/env python # --*-- coding:UTF-8 --*-- import sys import tab import re import os import time from docker import Client import... -
docker容器的内存资源限制
2020-06-19 09:37:16- 内存资源限制的原理和内存资源限制的选项 - 配置内存资源限制 1、Docker资源限制和Docker资源限制的类型 1)docker资源限制 默认情况docker没有对容器进行资源限制 容器可以无限制从docker宿主机获取计算机硬件... -
Linux:Java应用随着持续运行一段时间后,内存可用率逐渐减少的乌龙事件排查过程
2021-01-09 06:41:48我们有一个应用,在上线之后,监控到内存可用率随着运行时间逐步下降,从上线之初的50%,运行一段时间后下降到20%左右。机器上有其他进程也占内存,我想确定下是否是内存泄漏导致的,查清楚后也能对线上的应用运行... -
查看docker容器占用内存
2020-12-19 20:33:22ps -ef|grep 容器Id[root@wentao-2 order]# ps -ef|grep 3a61cb3fd4f6root 7358 12956 0 09:14 ? 00:00:00 containerd-shim -namespace moby -workdir /var/lib/containerd/io.containerd.runtime.v1.lin... -
docker查看容器的cpu占用率
2019-05-24 20:05:05每个接口进行调用数据时都会产生很大的延时,导致cpu占用率不规则跳动,删除压测的数据,释放了部分数据库数据,但是指标不治本,想着接下来看看mycat,redis好像压测也会因为内存使用完毕爆掉,想着接下来使用kafka... -
Docker篇之查询docker容器的占用内存
2021-07-12 16:19:111、先通过docker ps 查询docker容器跑的进程 ...3、然后执行 top -p 进程PID,即可查询出该容器占用的内存大小 top -p 2932 注: 参数说明如下: PID:进程的ID USER:进程所有者 PR:进程的优先级别,越小越 -
记录处理Docker使用内存不断升高直到重启即堆外内存泄露64M(已解决)
2022-01-11 12:04:23Docker容器16G,堆分配的4G,部署后,随着时间的推移,容器内使用的内存不断升高,YGC有但不频繁,FGC无或一次,两天后内存使用率搞到99%然后重启。然后周而复始。 第一篇文章是这样的,我以为好了,但只是由1天一... -
docker容器java进程内存占用过高问题排查步骤
2022-01-27 14:17:07第一步:进入docker容器内部 docker exec -it fastone-billing-mgr /bin/bash 第二步:执行jps,查询docker容器内的java进程 jps 第三步:执行jstack命令 jstack PID > threadDump.tdump 第四步:执行jmap... -
Metricbeat监听容器CPU利用率,内存等使用情况,发送给ElasticSearch并展示在kibana
2020-01-14 15:13:00简介: Metricbeat是一个轻量级的托运工,你可以在服务器上安装它,...可以获取系统级的 CPU 使用率、内存、文件系统、磁盘 IO 和网络 IO 统计数据,还可针对系统上的每个进程获得与 top 命令类似的统计数据。 ... -
CPU使用率查看方法
2021-09-08 13:49:56为了维护CPU时间,Linux通过事先定义的节拍率(内核中表示为HZ),触发时间中断,并使用全局变量Jiffies记录了开机以来的节拍数。每发生一次时间中断,Jiffies的值就加1。 节拍率HZ是内核的可配选项,可以自定义配置... -
portainerhkb:该项目旨在提供一个功能齐全的 Portainer Docker Bridge,允许用户通过使用 Portainer API ...
2021-08-03 12:00:31容器内存使用 开关上的属性 显示与主机相关的容器 MEMORY 使用情况 计划 容器正常运行时间 开关上的属性 显示容器正常运行时间 计划 请记住,这是一个早期项目,仍然有许多错误需要解决和异常需要处理。 据说 Tha ... -
查看 docker 容器使用的资源
2022-03-23 15:07:04在容器的使用过程中,如果能及时的掌握容器使用的系统资源,无论对开发还是运维工作都是非常有益的。幸运的是 docker 自己就提供了这样的命令:docker stats。 默认输出 docker stats 命令用来显示容器使用的系统... -
docker 查看容器CPU 以及memory实际使用情况
2021-04-06 08:37:53docker stats docker stats --no-stream By default, docker stats will only output results for running containers. If you would like to output stats for all containers you can use the -a or --all flags... -
树莓派上Home Assistant 容器使用命令传感器获取并显示CPU温度、内存使用等信息
2022-04-20 09:28:13树莓派在安装和部署了Home Assistant,如何在Home Assistant内就看到树莓派的CPU使用率和CPU温度、内存消耗等信息?可以试试自定义一个Command Line传感器哦。