容器里的 fork 炸弹会不会拖垮整台机器?--pids-limit 到底限制什么,线程算不算?这篇在受限的容器里实测:cgroup 的 pids.max、线程计数、fork 炸弹被关在多大的范围内。
不限制:pids.max=max pids.current=2 --pids-limit 100:pids.max=100 pids.current=2 --pids-limit -1:pids.max=max pids.current=2
--pids-limit 100 对应 pids.max = 100;不设置或设 -1 就是 max。Docker 默认不限制进程数。
--pids-limit 50,不停创建线程:创建了 49 个线程后失败:can't start new thread | pids.current = 50
--pids-limit 50 下创建线程,到第 50 个(含主线程)就失败了,报 can't start new thread。线程多的程序(Java、Go 的大量线程)设置过小的 pids-limit 会遇到这种错误。
3 秒后在容器里 docker exec 读 pids.current / pids.events:退出码 0;65 | max 35 docker stats 的 PIDS 列:64 个进程;CPU 0.00%;内存 1.391MiB / 128MiB docker stop -t 2:退出码 0,用时 2151 ms 虚拟机里的其它容器和 docker 命令是否正常?docker ps 退出码 0
--pids-limit 64 把炸弹限制在 64 个进程里,cgroup 的 pids.events 记录了 35 次因上限失败的 fork;docker stats 显示 64 个进程、内存仅 1.391MiB,docker stop 和 docker ps 都正常。我同时加了 128m 内存和 1 个 CPU 的限制作为保险,所以这个实验没有单独验证「只靠 pids-limit」能保护多少资源,也没有在没有限制的容器里跑炸弹(那样会危险)。