cari
RumahOperasi dan penyelenggaraanDocker如何限制docker容器对内存的使用

如何限制docker容器对内存的使用

Feb 02, 2021 am 11:21 AM
dockerIngatanbekas

如何限制docker容器对内存的使用

Docker 容器是一个开源的应用容器引擎,让开发者可以以统一的方式打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何安装了docker引擎的服务器上(包括流行的Linux机器、windows机器),也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。最重要的是,他们不依赖于任何语言、框架包括系统。

默认情况下容器使用的资源是不受限制的。也就是可以使用主机内核调度器所允许的最大资源。但是在容器的使用过程中,经常需要对容器可以使用的主机资源进行限制,本文介绍如何限制容器可以使用的主机内存。

为什么要限制容器对内存的使用?

限制容器不能过多的使用主机的内存是非常重要的。对于 linux 主机来说,一旦内核检测到没有足够的内存可以分配,就会扔出 OOME(Out Of Memmory Exception),并开始杀死一些进程用于释放内存空间。糟糕的是任何进程都可能成为内核猎杀的对象,包括 docker daemon 和其它一些重要的程序。更危险的是如果某个支持系统运行的重要进程被干掉了,整个系统也就宕掉了!这里我们考虑一个比较常见的场景,大量的容器把主机的内存消耗殆尽,OOME 被触发后系统内核立即开始杀进程释放内存。如果内核杀死的第一个进程就是 docker daemon 会怎么样?结果是没有办法管理运行中的容器了,这是不能接受的!
针对这个问题,docker 尝试通过调整 docker daemon 的 OOM 优先级来进行缓解。内核在选择要杀死的进程时会对所有的进程打分,直接杀死得分最高的进程,接着是下一个。当 docker daemon 的 OOM 优先级被降低后(注意容器进程的 OOM 优先级并没有被调整),docker daemon 进程的得分不仅会低于容器进程的得分,还会低于其它一些进程的得分。这样 docker daemon 进程就安全多了。
我们可以通过下面的脚本直观的看一下当前系统中所有进程的得分情况:

#!/bin/bash
for proc in $(find /proc -maxdepth 1 -regex '/proc/[0-9]+'); do
    printf "%2d %5d %s\n" \
        "$(cat $proc/oom_score)" \
        "$(basename $proc)" \
        "$(cat $proc/cmdline | tr '\0' ' ' | head -c 50)"
done 2>/dev/null | sort -nr | head -n 40

此脚本输出得分最高的 40 个进程,并进行了排序:

478ef4822a24313f371e362e35834fe.png

第一列显示进程的得分,mysqld 排到的第一名。显示为 node server.js 的都是容器进程,排名普遍比较靠前。红框中的是 docker daemon 进程,非常的靠后,都排到了 sshd 的后面。

有了上面的机制后是否就可以高枕无忧了呢!不是的,docker 的官方文档中一直强调这只是一种缓解的方案,并且为我们提供了一些降低风险的建议:

  • 通过测试掌握应用对内存的需求

  • 保证运行容器的主机有充足的内存

  • 限制容器可以使用的内存

  • 为主机配置 swap

好了,啰嗦了这么多,其实就是说:通过限制容器使用的内存上限,可以降低主机内存耗尽时带来的各种风险。

压力测试工具 stress

为了测试容器的内存使用情况,笔者在 ubuntu 的镜像中安装了压力测试工作 stress,并新创建了镜像 u-stress。本文演示用的所有容器都会通过 u-stress 镜像创建(本文运行容器的宿主机为 CentOS7)。下面是创建 u-stress 镜像的 Dockerfile:

FROM ubuntu:latest

RUN apt-get update && \
        apt-get install stress

创建镜像的命令为:

$ docker build -t u-stress:latest .

限制内存使用上限

在进入繁琐的设置细节之前我们先完成一个简单的用例:限制容器可以使用的最大内存为 300M。
-m(--memory=) 选项可以完成这样的配置:

$ docker run -it -m 300M --memory-swap -1 --name con1 u-stress /bin/bash

下面的 stress 命令会创建一个进程并通过 malloc 函数分配内存:

# stress --vm 1 --vm-bytes 500M

通过 docker stats 命令查看实际情况:

25f9c2048435121a6083ed9bed17cb1.png

上面的 docker run 命令中通过 -m 选项限制容器使用的内存上限为 300M。同时设置 memory-swap 值为 -1,它表示容器程序使用内存的受限,而可以使用的 swap 空间使用不受限制(宿主机有多少 swap 容器就可以使用多少)。
下面我们通过 top 命令来查看 stress 进程内存的实际情况:

b40e3c0abc55f8dd23e66d94ee3d279.png

上面的截图中先通过 pgrep 命令查询 stress 命令相关的进程,进程号比较大的那个是用来消耗内存的进程,我们就查看它的内存信息。VIRT 是进程虚拟内存的大小,所以它应该是 500M。RES 为实际分配的物理内存数量,我们看到这个值就在 300M 上下浮动。看样子我们已经成功的限制了容器能够使用的物理内存数量。

限制可用的 swap 大小

强调一下 --memory-swap 是必须要与 --memory 一起使用的。

正常情况下, --memory-swap 的值包含容器可用内存和可用 swap。所以 --memory="300m" --memory-swap="1g" 的含义为:
容器可以使用 300M 的物理内存,并且可以使用 700M(1G -300M) 的 swap。--memory-swap 居然是容器可以使用的物理内存和可以使用的 swap 之和!

把 --memory-swap 设置为 0 和不设置是一样的,此时如果设置了 --memory,容器可以使用的 swap 大小为 --memory 值的两倍。

如果 --memory-swap 的值和 --memory 相同,则容器不能使用 swap。下面的 demo 演示了在没有 swap 可用的情况下向系统申请大量内存的场景:

$ docker run -it --rm -m 300M --memory-swap=300M u-stress /bin/bash
# stress --vm 1 --vm-bytes 500M

0329f51777da2c55e84c5beabea0a4a.png

demo 中容器的物理内存被限制在 300M,但是进程却希望申请到 500M 的物理内存。在没有 swap 可用的情况下,进程直接被 OOM kill 了。如果有足够的 swap,程序至少还可以正常的运行。

我们可以通过 --oom-kill-disable 选项强行阻止 OOM kill 的发生,但是笔者认为 OOM kill 是一种健康的行为,为什么要阻止它呢?

除了限制可用 swap 的大小,还可以设置容器使用 swap 的紧迫程度,这一点和主机的 swappiness 是一样的。容器默认会继承主机的 swappiness,如果要显式的为容器设置 swappiness 值,可以使用 --memory-swappiness 选项。

总结

通过限制容器可用的物理内存,可以避免容器内服务异常导致大量消耗主机内存的情况(此时让容器重启是较好的策略),因此可以降低主机内存被耗尽带来的风险。

相关推荐:docker入门教程

Atas ialah kandungan terperinci 如何限制docker容器对内存的使用. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan
Artikel ini dikembalikan pada:博客园. Jika ada pelanggaran, sila hubungi admin@php.cn Padam
Mengapa menggunakan Docker? Faedah dan kelebihan dijelaskanMengapa menggunakan Docker? Faedah dan kelebihan dijelaskanApr 25, 2025 am 12:05 AM

Alasan untuk menggunakan Docker adalah bahawa ia menyediakan persekitaran yang cekap, mudah alih dan konsisten untuk membungkus, mengedarkan, dan menjalankan aplikasi. 1) Docker adalah platform kontena yang membolehkan pemaju untuk membungkus aplikasi dan kebergantungan mereka ke dalam bekas ringan, mudah alih. 2) Ia berdasarkan teknologi kontena Linux dan sistem fail bersama untuk memastikan permulaan yang cepat dan operasi yang cekap. 3) Docker menyokong pembinaan pelbagai peringkat, mengoptimumkan saiz imej dan kelajuan penempatan. 4) Menggunakan Docker dapat memudahkan proses pembangunan dan penempatan, meningkatkan kecekapan dan memastikan konsistensi di seluruh persekitaran.

Docker in Action: Contoh Dunia dan Kes Gunakan SeduniaDocker in Action: Contoh Dunia dan Kes Gunakan SeduniaApr 24, 2025 am 12:10 AM

Senario aplikasi Docker dalam projek sebenar termasuk memudahkan penggunaan, menguruskan aplikasi multi-kontainer dan pengoptimuman prestasi. 1.Docker memudahkan penggunaan aplikasi, seperti menggunakan DockerFile untuk menggunakan aplikasi Node.js. 2. DockerCompose menguruskan aplikasi multi-kontainer, seperti perkhidmatan web dan pangkalan data dalam seni bina microservice. 3. Pengoptimuman Prestasi menggunakan pembinaan pelbagai peringkat untuk mengurangkan saiz imej dan memantau status kontena melalui pemeriksaan kesihatan.

Docker vs Kubernet: Gunakan Kes dan SenarioDocker vs Kubernet: Gunakan Kes dan SenarioApr 23, 2025 am 12:11 AM

Pilih Docker dalam persekitaran kecil atau persekitaran pembangunan, dan Kubernet dalam persekitaran projek atau pengeluaran yang besar. 1.Docker sesuai untuk lelaran dan ujian pesat, 2. Kubernetes menyediakan keupayaan orkestra kontena yang kuat, sesuai untuk mengurus dan memperluaskan aplikasi besar.

Docker on Linux: Containerization untuk Sistem LinuxDocker on Linux: Containerization untuk Sistem LinuxApr 22, 2025 am 12:03 AM

Docker adalah penting pada Linux kerana Linux adalah platform asalnya yang menyediakan alat yang kaya dan sokongan masyarakat. 1. Pasang Docker: Gunakan sudoapt-getupdate dan sudoapt-getinstalldocker-cedocker-ce-clicotainerd.io. 2. Buat dan Menguruskan Bekas: Gunakan arahan Dockerrun, seperti Dockerrun-D-Namemynginx-P80: 80nginx. 3. Tulis Dockerfile: Mengoptimumkan saiz imej dan gunakan pembinaan pelbagai peringkat. 4. Pengoptimuman dan penyahpepijatan: Gunakan dockerlog dan dockerex

Docker: Alat kontena, Kubernet: OrkestratorDocker: Alat kontena, Kubernet: OrkestratorApr 21, 2025 am 12:01 AM

Docker adalah alat kontena, dan Kubernetes adalah alat orkestrasi kontena. 1. Aplikasi pakej Docker dan kebergantungan mereka ke dalam bekas yang boleh dijalankan di mana-mana persekitaran yang dibolehkan Docker. 2. Kubernetes menguruskan bekas ini, melaksanakan penggunaan automatik, skala dan pengurusan, dan membuat aplikasi berjalan dengan cekap.

Tujuan Docker: Memudahkan penggunaan aplikasiTujuan Docker: Memudahkan penggunaan aplikasiApr 20, 2025 am 12:09 AM

Tujuan Docker adalah untuk memudahkan penggunaan aplikasi dan memastikan aplikasi berjalan secara konsisten dalam persekitaran yang berbeza melalui teknologi kontena. 1) Docker menyelesaikan masalah perbezaan alam sekitar dengan aplikasi pembungkusan dan kebergantungan ke dalam bekas. 2) Buat imej menggunakan Dockerfile untuk memastikan aplikasi berjalan secara konsisten di mana -mana sahaja. 3) Prinsip kerja Docker adalah berdasarkan imej dan bekas, dan menggunakan ruang nama dan kumpulan kawalan kernel Linux untuk mencapai pengasingan dan pengurusan sumber. 4) Penggunaan asas termasuk menarik dan menjalankan imej dari DockerHub, dan penggunaan lanjutan melibatkan menguruskan aplikasi multi-kontainer menggunakan dockercompose. 5) Kesalahan biasa seperti kegagalan bangunan imej dan kegagalan kontena untuk memulakan, anda boleh debug melalui log dan konfigurasi rangkaian. 6) Pembinaan Pengoptimuman Prestasi

Linux dan Docker: Docker pada pengagihan Linux yang berbezaLinux dan Docker: Docker pada pengagihan Linux yang berbezaApr 19, 2025 am 12:10 AM

Kaedah memasang dan menggunakan Docker di Ubuntu, Centos, dan Debian adalah berbeza. 1) Ubuntu: Gunakan Pengurus Pakej APT, perintah itu adalah sudoapt-getupdate && sudoapt-getinstalldocker.io. 2) Centos: Gunakan Pengurus Pakej Yum dan anda perlu menambah repositori Docker. Perintah itu adalah Sudoyumininstall-yyum-utils && sudoyum-config-manager --add-repohttps: //download.docker.com/lin

Menguasai Docker: Panduan untuk Pengguna LinuxMenguasai Docker: Panduan untuk Pengguna LinuxApr 18, 2025 am 12:08 AM

Menggunakan Docker di Linux dapat meningkatkan kecekapan pembangunan dan memudahkan penggunaan aplikasi. 1) Tarik Ubuntu Imej: dockerpullubuntu. 2) Jalankan Ubuntu Container: Dockerrun-itubuntu/bin/bash. 3) Buat dockerfile yang mengandungi nginx: fromubuntu; runapt-getupdate && apt-getinstall-ynginx; dedoman80. 4) Bina imej: dockerbuild-tmy-nginx. 5) Jalankan bekas: Dockerrun-D-P8080: 80

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Penyesuai Pelayan SAP NetWeaver untuk Eclipse

Penyesuai Pelayan SAP NetWeaver untuk Eclipse

Integrasikan Eclipse dengan pelayan aplikasi SAP NetWeaver.

Versi Mac WebStorm

Versi Mac WebStorm

Alat pembangunan JavaScript yang berguna

SublimeText3 Linux versi baharu

SublimeText3 Linux versi baharu

SublimeText3 Linux versi terkini

MinGW - GNU Minimalis untuk Windows

MinGW - GNU Minimalis untuk Windows

Projek ini dalam proses untuk dipindahkan ke osdn.net/projects/mingw, anda boleh terus mengikuti kami di sana. MinGW: Port Windows asli bagi GNU Compiler Collection (GCC), perpustakaan import yang boleh diedarkan secara bebas dan fail pengepala untuk membina aplikasi Windows asli termasuk sambungan kepada masa jalan MSVC untuk menyokong fungsi C99. Semua perisian MinGW boleh dijalankan pada platform Windows 64-bit.