Docker 的 MemorySwap 到底限制什么:区分宿主机压力与容器内存上限
运行容器化应用时,看到浏览器页面超时或服务偶尔没有响应,第一反应往往是“把重试次数调大”。但如果底层进程已经被系统终止,重试不会恢复进程,只会把一次资源问题变成长时间等待。排查的第一步,应是分清宿主机和容器两个层面的限制。
一、先看宿主机是否还有余量
free -h 可以概览内存和 Swap,但不应只盯着 free 一列。Linux 会利用空闲内存缓存文件,MemAvailable 通常更接近应用还能使用多少内存。再配合 swapon --show 和 vmstat 1 5,观察换入、换出是否持续活跃。Swap 使用量高不一定等于机器正在卡顿;持续换页、I/O 等待升高,才说明需要结合负载进一步分析。
二、MemorySwap 不是“额外 Swap 大小”
Docker 的 --memory 限制内存,--memory-swap 表示内存与 Swap 的合计上限。例如:
docker run --memory=1g --memory-swap=1g IMAGE
docker run --memory=1g --memory-swap=2g IMAGE
第一种配置中两者相等,容器没有可用的 Swap 额度。第二种配置允许最多约 1 GiB 内存,再加约 1 GiB Swap;不是允许额外使用 2 GiB Swap。主机本身还必须提供可用 Swap。在 cgroup v2 环境里,可以同时查看 memory.max 与 memory.swap.max,不要把两个字段当成同一种上限。
三、确认是哪一种 OOM
可以先检查容器状态:
docker inspect -f '{{.State.OOMKilled}} {{.RestartCount}}' CONTAINER
journalctl -k --since '1 hour ago'
内核记录中的整机 OOM 与 memory cgroup OOM,需要分开判断。前者表示宿主机资源竞争已无法满足分配;后者则可能是某个容器触及自己的额度,即使宿主机仍有余量也会发生。还要注意:被杀掉的可能只是容器里的一个渲染进程,主进程和健康接口仍然存活,所以“容器没重启”并不能证明没有发生 OOM。
四、修复要对应资源边界
若是单容器上限过小,应先核对进程峰值和业务需求,再调整额度;若是整机压力,应检查所有服务的合计占用,不能只给一个容器不断加预算。增加宿主机 Swap 能为允许换页的进程提供缓冲,但不会自动解除某个容器的禁换页设置,也不等于增加物理内存。创建交换文件前还要检查磁盘余量,不能用填满根盘的方式救内存。
最后,恢复进程后要验证真实业务路径,而不只看健康接口。对发布文章、提交表单等操作,超时也可能意味着服务端已经接收:应先只读核对结果,再决定下一步,避免把基础设施故障变成重复提交。
- 点赞
- 收藏
- 关注作者
评论(0)