44

Ubuntu 13.04 (Raring Ringtail) 上で最新バージョンの 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

ここで私が見逃している明らかなことは何ですか?

4

6 に答える 6

52

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
于 2013-11-21T03:36:50.090 に答える
25

コンテナのメモリ使用量の強調に関するこの素敵な投稿にリンクしています。一般的な LXC ではなく、Docker で動作するように少し変更した要約を次に示します。

メモリ制限のあるコンテナーを起動します。

$ sudo docker run -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フラグは、スワップと RAM を別々にカウントしません。使用する-m 512Mと、その 512 の一部が RAM ではなくスワップになります。RAM のみが必要な場合は、LXC オプションを直接使用する必要があります (つまり、libcontainer の代わりに LXC 実行ドライバーを使用して Docker を実行する必要があります)。

# 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 maximum RAM (for example, 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 を合計の一部として使用する場合と使用しない場合には顕著な違いがあります。swap を使用すると、上記の foo プログラムはすぐに ~450 MB に達し、その後ゆっくりと残りを消費しますが、RAM のみを使用すると、すぐに 511 MB にジャンプします。スワップを使用すると、コンテナーに入るとすぐにコンテナーのメモリ消費量が最大 60 MB とマークされます。これは基本的に、スワップが「使用量」としてカウントされることです。スワップを使用しない場合、コンテナーに入ったときのメモリ使用量は 10 MB 未満です。

于 2014-10-21T08:24:48.550 に答える
1

新しいバージョンの Docker を使用している場合、その情報を探す場所は次の/sys/fs/cgroup/memory/docker/<container_id>/memory.limit_in_bytesとおりです。

docker run --memory="198m" redis
docker ps --no-trunc` # to get the container long_id
313105b341eed869bcc355c4b3903b2ede2606a8f1b7154e64f913113db8b44a
cat /sys/fs/cgroup/memory/docker/313105b341eed869bcc355c4b3903b2ede2606a8f1b7154e64f913113db8b44a/memory.limit_in_bytes
207618048 # in bytes
于 2017-01-24T12:04:42.433 に答える