Docker容器在Debian上的资源限制设置方法
在Debian系统上,可以通过多种方式为Docker容器设置资源限制(包括CPU、内存、磁盘I/O、网络带宽等),以下是常用且有效的配置方式:
docker run命令参数(临时生效)这是最直接的临时配置方式,适用于单次启动容器的场景。
--cpus=<value>:限制容器可使用的CPU核心数(如--cpus=2表示2个核心,--cpus=1.5表示1.5个核心)。--cpu-shares=<value>:设置CPU相对权重(默认1024,值越大分配的CPU时间越多,适用于多容器竞争场景)。--cpuset-cpus=<cpu_list>:指定容器可使用的具体CPU核心(如--cpuset-cpus="0,2"表示仅使用第0和第2核心)。--memory=<size>:设置容器内存最大使用量(如--memory=512m表示512MB,--memory=2g表示2GB)。--memory-swap=<size>:设置容器可使用的内存+交换分区总量(若等于--memory值,则禁止使用swap;若不设置,容器可使用宿主机剩余swap)。--blkio-weight=<value>:设置磁盘IO权重(范围10-1000,默认500,值越大优先级越高)。--device-read-bps=<device>:<rate>/--device-write-bps=<device>:<rate>:限制设备读/写速率(如--device-read-bps=/dev/sda:1mb表示限制/dev/sda读取速率为1MB/s)。tc命令(Traffic Control)配置,后续会详细介绍。若使用Docker Compose管理容器,可通过docker-compose.yml文件的deploy.resources字段设置资源限制(需Swarm模式或Compose v3+)。
version: '3'
services:
my_service:
image: nginx:latest
deploy:
resources:
limits: # 硬限制(超过将触发OOM Killer或CPU节流)
cpus: '0.5' # 限制0.5个CPU核心
memory: 512M # 限制内存不超过512MB
reservations: # 软限制(保证的最小资源,不保证一定能分配到)
cpus: '0.25' # 保证至少0.25个CPU核心
memory: 256M # 保证至少256MB内存
关键说明:
limits是容器资源使用的上限,超过会触发系统保护机制;reservations是容器启动时需要的最小资源,Docker会检查系统是否有足够资源满足该值后再启动容器。Docker底层依赖Linux cgroups(控制组)实现资源限制,可通过手动操作cgroups实现更细粒度的配置(如调整已运行容器的限制)。
/sys/fs/cgroup/<subsystem>/docker/<container_id>/(如cpu、memory子系统)。# 设置容器cpu.cfs_quota_us(配额)和cpu.cfs_period_us(周期),限制为0.5个核心
echo 50000 > /sys/fs/cgroup/cpu/docker/<container_id>/cpu.cfs_quota_us
echo 100000 > /sys/fs/cgroup/cpu/docker/<container_id>/cpu.cfs_period_us
# 设置容器内存上限为512MB
echo 536870912 > /sys/fs/cgroup/memory/docker/<container_id>/memory.limit_in_bytes
container_id(通过docker inspect --format '{{.Id}}' <container_name>获取),且重启容器后配置会丢失,适合临时调试。若需要为所有容器设置默认资源限制,可修改Docker Daemon的配置文件/etc/docker/daemon.json。
{
"default-ulimits": { # 默认ulimit设置(如文件描述符)
"nofile": {
"Name": "nofile",
"Soft": 1024,
"Hard": 2048
}
},
"exec-opts": ["native.cgroupdriver=systemd"], # 使用systemd作为cgroup驱动
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}
生效步骤:
sudo systemctl daemon-reload
sudo systemctl restart docker
default-ulimits中的设置(如文件描述符限制)。若通过systemd管理Docker服务(如将容器作为系统服务运行),可在systemd服务文件中设置资源限制。
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo nano /etc/systemd/system/docker.service.d/override.conf
[Service]
CPUQuota=50% # 限制CPU使用率为50%
MemoryLimit=512M # 限制内存使用量为512MB
sudo systemctl daemon-reload
sudo systemctl restart docker
注意:这种方式会影响整个Docker服务,而非单个容器,适合需要限制Docker整体资源占用的场景。
Docker本身不提供直接的网络带宽限制参数,需通过Linux的tc(Traffic Control)工具实现。
CONTAINER_ID=$(docker ps -qf "name=my_container")
PID=$(docker inspect --format '{{.State.Pid}}' $CONTAINER_ID)
# 添加htb队列规则
sudo tc qdisc add dev eth0 root handle 1: htb default 11
# 添加父类(总带宽1Gbit)
sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 1gbit
# 添加子类(限制1Mbit)
sudo tc class add dev eth0 parent 1:1 classid 1:11 htb rate 1mbit
# 将容器流量过滤到子类
sudo tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dst $(docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $CONTAINER_ID) flowid 1:11
说明:
eth0为宿主机实际网卡名称;docker stats命令实时查看容器资源占用,或结合Prometheus+Grafana进行长期监控;reservations保证最小资源;对于非关键服务,设置limits防止资源滥用。