在Ubuntu 13.04上运行Docker的最新版本
root@docker:~# docker version Client version: 0.6.6 Go version (client): go1.2rc3 Git commit (client): 6d42040 Server version: 0.6.6 Git commit (server): 6d42040 Go version (server): go1.2rc3 Last stable version: 0.6.6
但是当我启动容器时
root@docker:~# docker run -m=1524288 -i -t ubuntu /bin/bash root@7b09f638871a:/# free -m total used free shared buffers cached Mem: 1992 608 1383 0 30 341 -/+ buffers/cache: 237 1755 Swap: 2047 0 2047
我没有看到任何限制,我的内核启用了cgroups内存限制:
kernel /boot/vmlinuz-3.8.0-33-generic ro console=tty0 root=/dev/xvda1 cgroup_enable=memory swapaccount=1
我在这里错过了什么明显的东西?
free
将不会显示,因为这是通过cgroups强制执行。 而不是在主机上(容器外),你可以使用/sysfs
和cgroup内存来检查
vagrant@precise64:~$ docker run -m=524288 -d -t busybox sleep 3600 f03a017b174f vagrant@precise64:~$ cat /sys/fs/cgroup/memory/lxc/f03a017b174ff1022e0f46bc1b307658c2d96ffef1dd97e7c1929a4ca61ab80f//memory.limit_in_bytes 524288
看到内存不足,你可以运行一些比你分配的内存更多的内存 – 例如:
docker run -m=524288 -d -p 8000:8000 -t ubuntu:12.10 /usr/bin/python3 -m http.server 8480df1d2d5d vagrant@precise64:~$ docker ps | grep 0f742445f839 vagrant@precise64:~$ docker ps -a | grep 0f742445f839 0f742445f839 ubuntu:12.10 /usr/bin/python3 -m 16 seconds ago Exit 137 blue_pig
在dmesg
你应该看到容器和进程被杀死了:
[ 583.447974] Pid: 1954, comm: python3 Tainted: GF O 3.8.0-33-generic #48~precise1-Ubuntu [ 583.447980] Call Trace: [ 583.447998] [<ffffffff816df13a>] dump_header+0x83/0xbb [ 583.448108] [<ffffffff816df1c7>] oom_kill_process.part.6+0x55/0x2cf [ 583.448124] [<ffffffff81067265>] ? has_ns_capability_noaudit+0x15/0x20 [ 583.448137] [<ffffffff81191cc1>] ? mem_cgroup_iter+0x1b1/0x200 [ 583.448150] [<ffffffff8113893d>] oom_kill_process+0x4d/0x50 [ 583.448171] [<ffffffff816e1cf5>] mem_cgroup_out_of_memory+0x1f6/0x241 [ 583.448187] [<ffffffff816e1e7f>] mem_cgroup_handle_oom+0x13f/0x24a [ 583.448200] [<ffffffff8119000d>] ? mem_cgroup_margin+0xad/0xb0 [ 583.448212] [<ffffffff811949d0>] ? mem_cgroup_charge_common+0xa0/0xa0 [ 583.448224] [<ffffffff81193ff3>] mem_cgroup_do_charge+0x143/0x170 [ 583.448236] [<ffffffff81194125>] __mem_cgroup_try_charge+0x105/0x350 [ 583.448249] [<ffffffff81194987>] mem_cgroup_charge_common+0x57/0xa0 [ 583.448261] [<ffffffff8119517a>] mem_cgroup_newpage_charge+0x2a/0x30 [ 583.448275] [<ffffffff8115b4d3>] do_anonymous_page.isra.35+0xa3/0x2f0 [ 583.448288] [<ffffffff8115f759>] handle_pte_fault+0x209/0x230 [ 583.448301] [<ffffffff81160bb0>] handle_mm_fault+0x2a0/0x3e0 [ 583.448320] [<ffffffff816f844f>] __do_page_fault+0x1af/0x560 [ 583.448341] [<ffffffffa02b0a80>] ? vfsub_read_u+0x30/0x40 [aufs] [ 583.448358] [<ffffffffa02ba3a7>] ? aufs_read+0x107/0x140 [aufs] [ 583.448371] [<ffffffff8119bb50>] ? vfs_read+0xb0/0x180 [ 583.448384] [<ffffffff816f880e>] do_page_fault+0xe/0x10 [ 583.448396] [<ffffffff816f4bd8>] page_fault+0x28/0x30 [ 583.448405] Task in /lxc/0f742445f8397ee7928c56bcd5c05ac29dcc6747c6d1c3bdda80d8e688fae949 killed as a result of limit of /lxc/0f742445f8397ee7928c56bcd5c05ac29dcc6747c6d1c3bdda80d8e688fae949 [ 583.448412] memory: usage 416kB, limit 512kB, failcnt 342
链接到这个不错的文章强调容器内存使用情况。 下面是总结,修改了一下,为docker而不是通用的LXC工作:
启动具有内存限制的容器:
$ sudo docker -m 512M -it ubuntu /bin/bash root# apt-get update && apt-get install -y build-essential
使用以下命令在容器内创建一个文件foo.c
#include <stdlib.h> #include <stdio.h> int main(void) { int i; for (i=0; i<65536; i++) { char *q = malloc(65536); printf ("Malloced: %ld\n", 65536*i); } sleep(9999999); }
编译文件
gcc -o foo foo.c
打开一个新的终端来监视容器的内存使用情况:
$ cd /sys/fs/cgroup/memory/lxc/{{containerID}} $ while true; do echo -n "Mem Usage (mb): " && expr `cat memory.usage_in_bytes` / 1024 / 1024; echo -n "Mem+swap Usage (mb): " && expr `cat memory.limit_in_bytes` / 1024 / 1024; sleep 1; done
启动容器中的内存消耗
$ ./foo
现在看你的容器最大。 注意:当内存不足时,malloc的开始会失败,否则容器将保持独立。 通常情况下,容器内的软件会由于malloc失败而崩溃,但是弹性的软件将继续运行
最后注意:Docker的-m标志不会分别计算swap和ram。 如果你使用-m 512M
那么512的一部分将被交换,而不是RAM。 如果你只需要RAM,你将需要直接使用LXC选项(这意味着你将需要运行docker与LXC执行驱动程序而不是libcontainer)
# Same as docker -m 512m sudo docker run --lxc-conf="lxc.cgroup.memory.limit_in_bytes=512M" -it ubuntu /bin/bash # Set total to equal max RAM (eg don't use swap) sudo docker run --lxc-conf="lxc.cgroup.memory.max_usage_in_bytes=512M" --lxc-conf="lxc.cgroup.memory.limit_in_bytes=512M" -it ubuntu /bin/bash
使用swap作为总体的一部分有一个显着的区别,而不是把foo程序快速的交换到450M以上,然后慢慢地消耗剩下的部分,而只用RAM就立即跳到511M。 使用交换时,容器的内存消耗在我进入容器时被标记为〜60M – 这基本上是交换被计为“使用”。 没有交换,当我输入容器时,我的内存使用量<10M
如果您使用的是较新版本的Docker,那么查找该信息的位置是/sys/fs/cgroup/memory/docker/<container_id>/memory.limit_in_bytes
。
docker run --memory="198m" redis
docker ps --no-trunc
#获取容器long_id
313105b341eed869bcc355c4b3903b2ede2606a8f1b7154e64f913113db8b44a
cat /sys/fs/cgroup/memory/docker/313105b341eed869bcc355c4b3903b2ede2606a8f1b7154e64f913113db8b44a/memory.limit_in_bytes
207618048#以字节为单位