2013-11-20 5 views
32

Запуск последней версии грузчиком на вершине убунту 13,04Ограничение памяти на Docker контейнере не работает

[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 

Но когда я начинаю контейнер

[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 

Я не вижу никакого ограничения из любого типа, и мое ядро ​​имеет ограничение на доступ к ячейкам памяти:

kernel /boot/vmlinuz-3.8.0-33-generic ro console=tty0 root=/dev/xvda1 cgroup_enable=memory swapaccount=1 

Какая очевидная вещь мне здесь отсутствует?

+0

следите за этим, я вижу некоторые интересные различия между докционированными приложениями на виртуализованном сервере, стилями которого является бокс-металл. Например, OOM убьет Java на виртуализированном сервере ubuntu, на котором запущена служба Java в контейнере. Однако на металле Java соблюдает ограничения памяти, установленные через докер. [Я еще недостаточно знаю о деталях реализации между ними для хороших выводов, просто хотел поделиться) – nerdwaller

ответ

42

free не будет отображаться, поскольку это осуществляется через группы. Вместо того, чтобы на хосте (вне контейнера) вы можете проверить с помощью /sysfs и памяти контрольной группы

[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 

Чтобы увидеть его запустить из памяти вы можете запустить что-то, что будет использовать больше памяти, чем выделить - например:

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 

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

спасибо, теперь я понимаю; поэтому лучше всего проверить память cgroup, чтобы увидеть текущее использование. – Disco

+0

Подробнее о показателях памяти 'cgroup' можно узнать здесь http://blog.docker.io/2013/10/gathering-lxc-docker-containers-metrics/ В частности, псевдофайл file.stat , –

+0

Большое спасибо. Тонны более подробно о настройке этого на Ubuntu https://github.com/dotcloud/docker/issues/4250 – Barry

20

Связывание с этой nice post на stressin g использования памяти контейнера. Вот резюме, модифицирована немного работать грузчиком вместо родового LXC:

Launch контейнер с лимитом памяти:

$ 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 начнет сбой, но в противном случае контейнер остается в покое. Обычно программное обеспечение внутри контейнера вылетает из строя из-за сбоев в работе mallocs, но программное обеспечение, которое является устойчивым, будет продолжать работать.

Заключительное примечание. Флаг -m докера не учитывает подкачку и штырь отдельно. Если вы используете -m 512M, тогда некоторые из этих 512 будут свопами, а не ОЗУ. Если вы хотите только RAM вам нужно будет использовать параметры LXC непосредственно (что означает, что вам нужно будет запустить докер с драйвером исполнения 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 (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 

Существует заметная разница между использованием свопа как часть total и not - с заменой программы foo выше достижения ~ 450M быстро, а затем медленно потребляет оставшуюся часть, тогда как только с ОЗУ она сразу переходит на 511M для меня.При обмене потребление памяти контейнера помечено на уровне ~ 60 м, как только я вхожу в контейнер - это в основном своп, который считается «использованием». Без обмена моего использование памяти < 10M, когда я в контейнер

+1

Спасибо за четкие объяснения! – pygabriel

+0

Я пытался получить сборщик и докер. Однако Collectd публикует использование ОЗУ всей системы (хоста) вместо памяти с закрытой докере. http://stackoverflow.com/q/37881322/1925997 Мне было интересно, может ли этот параметр помочь, но при запуске docker с '--lxc-conf =" lxc.cgroup.memory.limit_in_bytes = 512M "' Я заканчиваю с флажком 'flag, но не определен: -lxc-conf'. Любая идея, как это решить? –

+0

Отличный ответ !, кстати, я думаю, вы пропустили 'run' cimmand в первой строке кода' '' sudo docker * run * -m 512M -it ubuntu/bin/bash''' – gsalgadotoledo

0

Если вы используете более новую версию грузчика, то место, чтобы искать что информация является /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 
Смежные вопросы