14进阶:资源限制与性能

第 14 关 资源限制与性能
本关的产出:给容器划出 CPU 与内存的上限,知道超了会怎样,也学会对运行中的容器直接改。
14.1 不设上限,它会用光
容器默认没有 CPU 和内存上限。一个内存泄漏的服务、一段死循环、一次没控制住的并发,都能把宿主机的资源吃光——然后系统的 OOM killer 开始动手,被杀的不一定是那个容器,可能是同机器上别的进程。
这和第 13 关的边界不同:那关管「能做什么」(权限),这关管「能用多少」(配额)。两道不同的闸。
14.2 CPU:先分清「封顶」和「排队」
两种限制,作用完全不同:
docker run --cpus=1.5 nginxdocker run --cpu-shares=512 nginx--cpus=1.5:硬上限。最多用到 1.5 个核的算力,超了就被限流,哪怕机器闲着也不会多给。--cpu-shares=512:相对权重,默认 1024。它只在抢 CPU 的时候起作用——机器闲时,你照样能用满;几个容器一起抢时,按权重分。它不是上限。--cpuset-cpus="0,1":把容器绑在指定的核上,不让它到处跑。
一句话:要「封顶」用 --cpus,要「抢的时候优先」用 --cpu-shares。
14.3 内存:超了会被杀
docker run --memory=512m nginx--memory 是硬上限。容器的内存一旦碰到它,内核的 OOM killer 会杀掉容器里的进程——容器随后退出,就是第 12 关那个 137,docker inspect 里 State.OOMKilled 为 true。
另外两个:
--memory-swap:内存 + swap 的总量。设成和--memory一样,就是不许用 swap;不写时,一般允许用和内存一样多的 swap。--memory-reservation:软上限。平时可以超,系统内存吃紧时才尽量压回来。
易踩的坑:--memory 是上限,不是「预留」。写小了,程序不是变慢,而是莫名其妙被杀——日志里往往什么都没有,因为进程是被内核直接干掉的。看到容器莫名退出,先查 OOMKilled(第 12 关)。
14.4 看它现在吃多少
docker stats实时列出每个容器的 CPU、内存、网络、磁盘读写。不想一直刷,加 --no-stream 只取一次:
docker stats --no-stream要观察:CPU % 是可以超过 100% 的——它是「占了一个核的百分之多少」,8 核跑满就是 800%。内存那栏对照 MEM USAGE / LIMIT 看,离上限还有多远。
14.5 运行中改:docker update
第 2 关为了说清「环境变量改不了」,提过一句「CPU、内存这类运行参数另外有命令」。就是它:
docker update --cpus=0.5 --memory=256m <容器>不用停、不用重建,改完立即生效。
但别把它想成「改配置」的万能命令——Docker 没有这样一个统一操作。每样东西各有各的走法:
| 想改的东西 | 怎么改 |
|---|---|
| CPU、内存、pids 上限、重启策略、ulimit | docker update,运行中直接改 |
| 名字 | docker rename(第 2 关) |
| 接哪张网 | docker network connect / disconnect(第 5 关) |
| 环境变量、端口、挂载、启动命令 | 只能删掉重建 |
所以第 2 关那句「环境变量没有」要读准:不是「配置都改不了」,而是每一项要单独看——有的有专门命令,有的只能重建。
14.6 平台:Docker Desktop 还有一层上限
容器上限是在跑引擎的那台机器上执行的。macOS、Windows 上,那台机器是 Docker 的虚拟机——虚拟机自己也有总配额(Docker Desktop 的 Settings → Resources)。
所以会出现这种情况:你给容器 --memory=8g,可虚拟机总共只分到 4g,容器实际拿不到 8g。
怎么确认:docker info 里的总内存,就是虚拟机的总内存(第 1 关用它看过服务端信息),不是你这台 Mac 的内存。
这一关的产出:会给容器划 CPU 和内存的上限、看得懂 docker stats、也能对运行中的容器直接调。下一关往最底下走——namespace、cgroups、overlayfs 这些一直在背后干活的东西,一次性看清。
本关命令速查
资源限制与查看,见 命令速查表 · 资源限制。
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!





