2013-11-20 5 views
32

Lauf letzte Version von Docker oben auf ubuntu 13,04Limit-Speicher auf einem Docker Behälter funktioniert nicht

[email protected]:~# 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 

Aber wenn ich den Behälter

[email protected]:~# docker run -m=1524288 -i -t ubuntu /bin/bash 
[email protected]:/# free -m 
      total  used  free  shared buffers  cached 
Mem:   1992  608  1383   0   30  341 
-/+ buffers/cache:  237  1755 
Swap:   2047   0  2047 

Ich fange sehe keine Begrenzung von irgendeiner Art, und mein Kernel hat cgroups Speicherlimit aktiviert:

Welche offensichtliche Sache fehlt mir hier?

+0

A Im Anschluss sehe ich einige interessante Unterschiede zwischen dockerisierten Apps auf einem virtualisierten Server gegenüber einer Bare-Metal-Box. Beispielsweise führt OOM Java auf einem virtualisierten Ubuntu-Server aus, auf dem der Java-Dienst im Container ausgeführt wird. Jedoch auf Java - Java respektiert die Speichergrenzen, die über Docker eingestellt werden. [Ich weiß noch nicht genug über Implementierungsdetails zwischen den beiden für gute Schlussfolgerungen, wollte nur teilen] – nerdwaller

Antwort

42

free wird nicht angezeigt, da dies über Cgroups erzwungen wird. Statt auf dem Host (außerhalb des Behälters) Sie überprüfen können /sysfs und der cgroup Speicher

[email protected]:~$ docker run -m=524288 -d -t busybox sleep 3600 
f03a017b174f 
[email protected]:~$ cat /sys/fs/cgroup/memory/lxc/f03a017b174ff1022e0f46bc1b307658c2d96ffef1dd97e7c1929a4ca61ab80f//memory.limit_in_bytes 
524288 

Verwendung Um zu sehen, es nicht genügend Arbeitsspeicher laufen Sie etwas ausführen können, die mehr Speicherplatz als Sie vergeben - zB:

docker run -m=524288 -d -p 8000:8000 -t ubuntu:12.10 /usr/bin/python3 -m http.server 
8480df1d2d5d 
[email protected]:~$ docker ps | grep 0f742445f839 
[email protected]:~$ docker ps -a | grep 0f742445f839 
0f742445f839  ubuntu:12.10  /usr/bin/python3 -m 16 seconds ago  Exit 137        blue_pig 

In dmesg sollten Sie den Behälter und Prozess getötet sehen:

[ 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 
+0

danke jetzt verstehe ich; Der beste Weg besteht also darin, den Cgroup-Speicher zu überprüfen, um die aktuelle Verwendung zu sehen. – Disco

+0

Sie können mehr über die 'cgroup' Speichermetriken lesen Sie hier http://blog.docker.io/2013/10/gathering-lxc-docker-containers-metrics/ Insbesondere die' memory.stat' pseudo-Datei . –

+0

Vielen Dank. Tons mehr über die Konfiguration auf Ubuntu https://github.com/dotcloud/docker/issues/4250 – Barry

20

Links zu diesen nice post auf stressin g Speicherverbrauch des Containers. Hier ist die Zusammenfassung, modifiziert, um ein Bit für Docker statt generic LXC zu arbeiten:

Startcontainer mit einer Speichergrenze:

$ sudo docker -m 512M -it ubuntu /bin/bash 
root# apt-get update && apt-get install -y build-essential 

Erstellen Sie eine Datei foo.c im Inneren des Behälters mit dem folgenden

#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); 
} 

Kompilieren Sie die Datei

gcc -o foo foo.c 

Öffnen Sie ein neues ter luminale den Container Speichernutzung zu überwachen:

$ 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 

den Speicherverbrauch in der

$ ./foo 

Jetzt ist Ihr Behälter max achten Behälter starten. Hinweis: Wenn die Speicherkapazität von malloc nicht mehr ausreicht, wird der Container nicht ausgeführt. Normalerweise wird die Software innerhalb des Containers aufgrund fehlender mallocs abstürzen, aber Software, die resilient ist, wird weiter funktionieren

Endgültige Anmerkung: Docker -m Flag zählt Swap und Ram nicht separat gezählt. Wenn Sie -m 512M verwenden, dann werden einige von diesen 512 Swap, nicht RAM. Wenn Sie möchten, das RAM nur müssen Sie LXC Optionen direkt verwenden (was bedeutet, müssen Sie Docker mit der LXC Ausführung Treiber statt libcontainer laufen)

# 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 (e.g. 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 

Es ist ein bemerkenswerter Unterschied zwischen der Verwendung von Swap im Rahmen der insgesamt und nicht - mit dem foo-programm über tausch zu erreichen ~ 450M schnell und dann langsam verbraucht den rest, während mit nur RAM es springt sofort auf 511M für mich.Bei Swap wird der Speicherverbrauch des Containers bei ~ 60M markiert, sobald ich den Container betrete - das ist im Grunde der Swap, der als "Usage" gezählt wird. Ohne Swap meine Speicherauslastung ist < 10M, wenn ich in den Behälter gelangen

+1

Danke für die klaren Erklärungen! – pygabriel

+0

Ich habe versucht zu sammeln und Docker arbeiten. Collectd stellt jedoch die RAM-Nutzung des Gesamtsystems (Host) statt des beschränkten Arbeitsspeichers von Docker ein. http://StackOverflow.com/q/37881322/1925997 Ich fragte mich, ob diese Option helfen könnte, aber wenn Andockfenster mit '--lxc-conf =" lxc.cgroup.memory.limit_in_bytes = 512M "läuft" "Ich beende up mit 'flag zur Verfügung gestellt, aber nicht definiert: --lxc-conf' error. Irgendeine Idee, wie man das löst? –

+0

Große Antwort !, btw Ich denke, Sie vermissen die 'run' Cimmand in der ersten Zeile Code' '' sudo docker * run * -m 512M -it ubuntu/bin/bash''' – gsalgadotoledo

0

Wenn Sie eine neuere Version von Docker verwenden, dann den Platz für diese Informationen zu suchen ist /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