天天看點

Docker 資源限制之記憶體

<a href="http://people.seas.harvard.edu/~apw/stress/" target="_blank">stress</a>

通過如下 Dockerfile 建構簡單的測試鏡像

<a href="https://docs.docker.com/engine/reference/run/#runtime-constraints-on-resources" target="_blank">Runtime constraints on resources</a>

目前 Docker 支援記憶體資源限制選項

Whether to disable OOM Killer for the container or not.

Kernel memory limit (format: <code>&lt;number&gt;[&lt;unit&gt;]</code>). Number is a positive integer. Unit can be one of <code>b</code>, <code>k</code>, <code>m</code>, or <code>g</code>. Minimum is 4M.

kernel memory 沒有特殊需求,則無需額外設定

Memory soft limit (format: <code>&lt;number&gt;[&lt;unit&gt;]</code>). Number is a positive integer. Unit can be one of <code>b</code>, <code>k</code>, <code>m</code>, or <code>g</code>.

Size of <code>/dev/shm</code>. The format is <code>&lt;number&gt;&lt;unit&gt;</code>. number must be greater than 0. Unit is optional and can be <code>b</code> (bytes), <code>k</code> (kilobytes), <code>m</code> (megabytes), or <code>g</code>(gigabytes). If you omit the unit, the system uses bytes. If you omit the size entirely, the system uses <code>64m</code>.

根據實際需求設定,這裡不作過多的介紹

Tune a container’s memory swappiness behavior. Accepts an integer between 0 and 100.

Total memory limit (memory + swap, format: <code>&lt;number&gt;[&lt;unit&gt;]</code>). Number is a positive integer. Unit can be one of <code>b</code>, <code>k</code>, <code>m</code>, or <code>g</code>.

Memory limit (format: <code>&lt;number&gt;[&lt;unit&gt;]</code>). Number is a positive integer. Unit can be one of <code>b</code>, <code>k</code>, <code>m</code>, or <code>g</code>. Minimum is 4M.

<code>-m</code>, <code>--memory=""</code>

<code>--memory-swap=""</code>

<code>--memory-swappiness=""</code>

<code>--shm-size=""</code>

<code>--memory-reservation=""</code>

<code>--kernel-memory=""</code>

<code>--oom-kill-disable=false</code>

預設啟動一個 container,對于容器的記憶體是沒有任何限制的。

<code>docker run -it --rm -m 100M --memory-swap -1 ubuntu-stress:latest /bin/bash</code>

指定限制記憶體大小并且設定 memory-swap 值為 -1,表示容器程式使用記憶體受限,而 swap 空間使用不受限制(宿主 swap 支援使用多少則容器即可使用多少。如果 <code>--memory-swap</code> 設定小于 <code>--memory</code>則設定不生效,使用預設設定)。

使用 <code>docker stats</code> 檢視目前容器記憶體資源使用:

通過 <code>top</code> 實時監控 stress 程序記憶體占用:

也可以通過如下指令擷取 stress 程序的 swap 占用:

<code>docker run -it --rm -m 100M ubuntu-stress:latest /bin/bash</code>

按照官方文檔的了解,如果指定 <code>-m</code> 記憶體限制時不添加 <code>--memory-swap</code> 選項,則表示容器中程式可以使用 100M 記憶體和 100M swap 記憶體。預設情況下,<code>--memory-swap</code> 會被設定成 memory 的 2倍。

We set memory limit(300M) only, this means the processes in the container can use 300M memory and 300M swap memory, by default, the total virtual memory size <code>--memory-swap</code> will be set as double of memory, in this case, memory + swap would be 2*300M, so processes can use 300M swap memory as well.

如果按照以上方式運作容器提示如下資訊:

To enable memory and swap on system using GNU GRUB (GNU GRand Unified Bootloader), do the following:

<code>$ sudo update-grub</code>

<code>GRUB_CMDLINE_LINUX="cgroup_enable=memory swapaccount=1"</code>

Log into Ubuntu as a user with sudo privileges.

Edit the /etc/default/grub file.

Set the GRUB_CMDLINE_LINUX value as follows:

Save and close the file.

Update GRUB.

Reboot your system.

<code>docker stats</code> 和 top 擷取資源占用情況:

<code>docker run -it -m 100M --memory-swap 400M ubuntu-stress:latest /bin/bash</code>

根據實際測試可以了解,<code>-m</code> 為實體記憶體上限,而 <code>--memory-swap</code> 則是 memory + swap 之和,當壓測值是 <code>--memory-swap</code> 上限時,則容器中的程序會被直接 OOM kill。

swappiness 可以認為是宿主 <code>/proc/sys/vm/swappiness</code> 設定:

<code>--memory-swappiness=0</code> 表示禁用容器 swap 功能(這點不同于主控端,主控端 swappiness 設定為 0 也不保證 swap 不會被使用):

<code>docker run -it --rm -m 100M --memory-swappiness=0 ubuntu-stress:latest /bin/bash</code>

<code>--memory-reservation ...</code> 選項可以了解為記憶體的軟限制。如果不設定 <code>-m</code> 選項,那麼容器使用記憶體可以了解為是不受限的。按照官方的說法,memory reservation 設定可以確定容器不會長時間占用大量記憶體。

但是如果是以下的這種沒有對容器作任何資源限制的情況,添加 <code>--oom-kill-disable</code> 選項就比較 危險 了:

因為此時容器記憶體沒有限制,并且不會被 oom kill,此時系統則會 kill 系統程序用于釋放記憶體。

Kernel memory is fundamentally different than user memory as kernel memory can’t be swapped out. The inability to swap makes it possible for the container to block system services by consuming too much kernel memory. Kernel memory includes:

stack pages

slab pages

sockets memory pressure

tcp memory pressure

這裡直接引用 Docker 官方介紹,如果無特殊需求,kernel-memory 一般無需設定,這裡不作過多說明。

<code>github.com/opencontainers/runc/libcontainer/cgroups/fs/memory.go</code>

附測試:

檢視宿主對應 container cgroup 對應值:

本文轉自 zbill 51CTO部落格,原文連結:http://blog.opskumu.com/docker-memory-limit.html,如需轉載請自行聯系原作者