导读:本期聚焦于USDT程序员创作的《CentOS下如何对Docker容器进行CPU和内存资源限制配置?》,敬请观看详情。一台服务器上跑了十几个容器,某个应用突然内存暴涨把宿主机拖垮,这种事故并不少见。Docker提供了CPU份额、内存上限、IO权重等一系列资源控制参数,配合CentOS的cgroups机制,可以精确限制每个容器能使用的资源量。本文围绕CentOS环境,讲解docker run命令中常用资源参数的含义,包括cpu-shares、memory、memory-swap的换算关系,演示如何通过docker update动态调整运行中容器的限制,并结合cpuset实现CPU绑核。文中还会给出验证配置是否生效的查看方法,以及参数设置不当可能触发的OOM问题排查思路,帮助读者搭建更稳定的容器化运行环境。

Docker容器默认没有资源上限,一个失控的容器可以吃光宿主机的CPU和内存,进而影响同一台机器上的其他服务。CentOS作为国内使用量很大的服务器系统,其内核默认开启的cgroups功能正好是Docker实现资源限制的底层基础。本文将从参数含义、配置命令、动态调整和常见问题四个方面,详细介绍如何在CentOS上对容器做CPU、内存等资源限制。

CentOS下如何对Docker容器进行CPU和内存资源限制配置?

一、资源限制的底层机制:cgroups

Docker本身并不实现资源隔离,真正干活的是Linux内核的控制组(Control Groups,简称cgroups)。cgroups可以对一组进程的CPU时间、内存、块设备IO、网络等资源进行限额和统计。Docker在启动容器时,会在/sys/fs/cgroup目录下为容器创建对应的cgroup节点,把容器内所有进程都挂到这个节点上,资源限制参数最终会写入该节点的配置文件。

CentOS 7默认使用cgroups v1,各个资源控制器(cpu、memory、blkio等)各自独立成树;CentOS 8及之后的版本内核支持cgroups v2,Docker较新版本也可以切换使用。两者在目录结构上有差异,但Docker命令层面是屏蔽掉的,用户只需要关注docker run的参数即可。可以通过下面的命令确认宿主机的cgroups版本:

# 查看cgroups版本,输出cgroup2fs表示v2,tmpfs表示v1
stat -fc %T /sys/fs/cgroup/

# 查看当前系统支持的资源控制器
cat /proc/cgroups

理解这一点很重要,因为当资源限制行为和预期不符时,往往需要到cgroups文件系统里核对实际写入的值。比如容器ID前12位对应的目录下,cpu.cfs_quota_us和cpu.cfs_period_us的比值就决定了容器能使用的CPU核数上限。

二、CPU限制:shares、quota和cpuset三种方式

Docker提供三种角度的CPU控制手段,含义各不相同,容易混淆。--cpu-shares设置的是相对权重,默认值1024。它只在CPU竞争激烈时才起作用:假如两个容器的shares分别是1024和512,那么争抢时前者能拿到大约三分之二的CPU时间。宿主机空闲时,shares为512的容器同样可以跑满CPU,这一点很多人理解有误。

--cpus(对应--cpu-period和--cpu-quota)是硬性上限,比如--cpus=1.5表示容器最多使用1.5个核的计算能力,无论宿主机是否空闲都不能突破。--cpuset-cpus则是把容器绑定到指定的CPU核心上运行,适合需要避免进程在核心间迁移、减少缓存失效的场景。三种方式可以组合使用,示例命令如下:

# 相对权重限制,竞争时按2:1分配
docker run -d --name web1 --cpu-shares=1024 nginx:alpine

# 硬限制最多使用1.5核
docker run -d --name web2 --cpus=1.5 nginx:alpine

# 绑定到第0和第2个核心
docker run -d --name web3 --cpuset-cpus=0,2 nginx:alpine

# 组合使用:绑定核心且最多用1核
docker run -d --name web4 --cpuset-cpus=0 --cpus=1 nginx:alpine

验证CPU限制是否生效,可以在容器内跑一个死循环压测,同时在宿主机用top命令观察。如果容器配了--cpus=0.5,那么无论压测多猛,容器进程的CPU占用率都不会超过50%。需要注意,宿主机本身要留出足够的CPU给系统进程和其他容器,把所有核心都绑给容器是常见的错误做法。

三、内存限制与OOM行为处理

内存限制的核心参数是-m或--memory,例如-m 512m表示容器最多使用512MB物理内存。与之配套的--memory-swap含义稍微绕一点:它限制的是内存加交换分区的总量。如果只设置-m 512m而不设置swap,Docker默认--memory-swap等于内存的两倍,即容器还能额外使用512MB的swap。若想彻底禁用swap,需要显式指定--memory-swap=512m,让swap可用量等于0。

# 限制内存512MB,且不允许使用swap
docker run -d --name app1 \
  -m 512m \
  --memory-swap 512m \
  --memory-reservation 256m \
  myapp:latest

其中--memory-reservation是一个软限制,当宿主机内存紧张时,内核会尽量把容器压到这个水位以下,它不保证强制执行,但适合作为保护性配置。当容器实际用内存超过硬限制时,内核的OOM Killer会杀掉容器内占用内存最多的进程,容器随之退出,docker inspect可以看到OOMKilled字段为true。排查这类问题不能一味调大限制,应先用docker stats观察容器的真实内存曲线,判断是应用泄漏还是限制值设置过低。

四、运行中容器的动态调整与监控

线上容器往往不能随意重启,Docker提供了docker update命令来动态修改运行中容器的资源限制,支持内存、CPU、blkio权重等参数。这在扩容场景非常实用,比如发现某个容器内存吃紧,可以直接把上限从512MB提到1GB:

# 动态调整运行中容器的限制
docker update --memory 1g --memory-swap 1g app1
docker update --cpus 2 app1

# 查看当前所有容器的资源占用
docker stats --no-stream

# 查看某个容器的详细限制值
docker inspect app1 --format '{{.HostConfig.Memory}} {{.HostConfig.NanoCpus}}'

需要注意docker update修改内存时只能调大不能调小到低于当前实际占用,否则命令会报错。日常监控方面,docker stats输出的CPU百分比是相对宿主机总核数的,一个8核机器上限制为2核的容器,压满时显示约250%而不是100%,读数据时要换算清楚。对于块设备IO,还可以用--device-read-bps、--blkio-weight等参数限制读写速率和权重,避免某个日志类容器把磁盘带宽占满。综合运用这些参数,再配合容器编排工具统一管理,就能在CentOS上构建出资源分配清晰、互不干扰的容器运行环境。

CentOSDocker容器资源限制修改时间:2026-09-09 16:39:17

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0909/53476.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。