容器资源限制 #
资源限制概述 #
为什么需要资源限制? #
text
┌─────────────────────────────────────────────────────┐
│ 资源限制的重要性 │
├─────────────────────────────────────────────────────┤
│ │
│ 1. 防止单个容器占用过多资源 │
│ 2. 保证其他容器的正常运行 │
│ 3. 提高系统整体稳定性 │
│ 4. 实现公平的资源分配 │
│ 5. 控制成本和预算 │
│ │
└─────────────────────────────────────────────────────┘
资源限制类型 #
| 资源类型 | 限制参数 | 说明 |
|---|---|---|
| CPU | –cpus, --cpu-shares | CPU使用限制 |
| 内存 | -m, --memory-swap | 内存使用限制 |
| 磁盘IO | –device-read-bps | 磁盘读写限制 |
| 网络 | –net-limit | 网络带宽限制 |
| PID | –pids-limit | 进程数量限制 |
内存限制 #
基本内存限制 #
bash
# 限制内存为512MB
docker run -m 512m nginx
# 限制内存为1GB
docker run --memory=1g nginx
# 完整写法
docker run --memory=512m nginx
内存限制参数 #
| 参数 | 说明 |
|---|---|
| -m, --memory | 内存限制 |
| –memory-swap | 总内存限制(内存+交换) |
| –memory-reservation | 内存软限制 |
| –memory-swappiness | 使用交换分区倾向 |
| –oom-kill-disable | 禁用OOM Killer |
| –oom-score-adj | OOM优先级调整 |
内存交换限制 #
bash
# 限制内存512MB,交换内存512MB(总共1GB)
docker run -m 512m --memory-swap=1g nginx
# 禁用交换
docker run -m 512m --memory-swap=512m nginx
# 设置交换分区使用倾向(0-100)
docker run -m 512m --memory-swappiness=0 nginx
内存软限制 #
bash
# 设置软限制(在内存紧张时生效)
docker run -m 1g --memory-reservation=512m nginx
OOM控制 #
bash
# 禁用OOM Killer(不推荐)
docker run -m 512m --oom-kill-disable nginx
# 调整OOM优先级(-1000到1000,值越小越不容易被杀死)
docker run -m 512m --oom-score-adj=-500 nginx
查看内存限制 #
bash
# 查看容器内存限制
docker inspect --format '{{.HostConfig.Memory}}' mycontainer
# 查看内存使用
docker stats mycontainer --no-stream
CPU限制 #
CPU数量限制 #
bash
# 限制使用1.5个CPU
docker run --cpus=1.5 nginx
# 限制使用0.5个CPU
docker run --cpus=0.5 nginx
# 指定CPU核心
docker run --cpuset-cpus=0 nginx # 使用CPU 0
docker run --cpuset-cpus=0,2 nginx # 使用CPU 0和2
docker run --cpuset-cpus=0-3 nginx # 使用CPU 0-3
CPU份额 #
bash
# 设置CPU份额(默认1024)
docker run --cpu-shares=512 nginx
# 相对权重示例
# 容器A: --cpu-shares=1024 (获得2/3 CPU时间)
# 容器B: --cpu-shares=512 (获得1/3 CPU时间)
CPU限制参数 #
| 参数 | 说明 |
|---|---|
| –cpus | CPU数量限制 |
| –cpu-shares | CPU份额(相对权重) |
| –cpuset-cpus | 指定使用的CPU核心 |
| –cpu-period | CFS调度周期(微秒) |
| –cpu-quota | CFS调度配额(微秒) |
| –cpu-rt-runtime | 实时调度运行时间 |
| –cpu-rt-period | 实时调度周期 |
CPU周期和配额 #
bash
# 使用period和quota设置CPU限制
# quota/period = CPU数量
docker run --cpu-period=100000 --cpu-quota=50000 nginx # 相当于0.5个CPU
docker run --cpu-period=100000 --cpu-quota=150000 nginx # 相当于1.5个CPU
查看CPU限制 #
bash
# 查看CPU限制
docker inspect --format '{{.HostConfig.NanoCpus}}' mycontainer
docker inspect --format '{{.HostConfig.CpuShares}}' mycontainer
docker inspect --format '{{.HostConfig.CpusetCpus}}' mycontainer
磁盘IO限制 #
IO限制参数 #
| 参数 | 说明 |
|---|---|
| –device-read-bps | 读速率限制 |
| –device-write-bps | 写速率限制 |
| –device-read-iops | 读IOPS限制 |
| –device-write-iops | 写IOPS限制 |
读写速率限制 #
bash
# 限制读速率为10MB/s
docker run --device-read-bps=/dev/sda:10mb nginx
# 限制写速率为10MB/s
docker run --device-write-bps=/dev/sda:10mb nginx
# 同时限制读写
docker run \
--device-read-bps=/dev/sda:10mb \
--device-write-bps=/dev/sda:10mb \
nginx
IOPS限制 #
bash
# 限制读IOPS为1000
docker run --device-read-iops=/dev/sda:1000 nginx
# 限制写IOPS为500
docker run --device-write-iops=/dev/sda:500 nginx
进程数限制 #
PID限制 #
bash
# 限制最大进程数为100
docker run --pids-limit=100 nginx
# 无限制
docker run --pids-limit=-1 nginx
应用场景 #
bash
# 防止fork炸弹
docker run --pids-limit=100 myapp
# 限制工作进程数量
docker run --pids-limit=50 worker-app
资源限制组合 #
综合限制示例 #
bash
# 完整的资源限制
docker run -d \
--name myapp \
--memory=1g \
--memory-swap=2g \
--memory-reservation=512m \
--cpus=2 \
--cpuset-cpus=0,1 \
--cpu-shares=1024 \
--device-read-bps=/dev/sda:50mb \
--device-write-bps=/dev/sda:50mb \
--pids-limit=200 \
myapp:v1.0
Docker Compose配置 #
yaml
version: '3.8'
services:
web:
image: nginx
deploy:
resources:
limits:
cpus: '1.5'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
Docker Compose v2格式 #
yaml
version: '3.8'
services:
web:
image: nginx
mem_limit: 1g
memswap_limit: 2g
mem_reservation: 512m
cpus: 1.5
cpu_shares: 1024
cpuset: 0,1
pids_limit: 200
动态更新资源限制 #
docker update命令 #
bash
# 更新内存限制
docker update -m 2g mycontainer
# 更新CPU限制
docker update --cpus=2 mycontainer
# 同时更新多个限制
docker update \
--memory=2g \
--cpus=2 \
--cpu-shares=2048 \
mycontainer
更新限制的限制 #
bash
# 可以更新的参数
docker update --memory
docker update --memory-swap
docker update --cpus
docker update --cpu-shares
docker update --cpu-period
docker update --cpu-quota
docker update --cpuset-cpus
docker update --restart-policy
# 不能更新的参数(需要重建容器)
# --device-read-bps
# --device-write-bps
# --pids-limit
查看资源使用 #
docker stats #
bash
# 实时查看所有容器资源使用
docker stats
# 查看指定容器
docker stats mycontainer
# 只显示一次
docker stats --no-stream
# 自定义格式
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
输出示例 #
text
CONTAINER ID NAME CPU % MEM USAGE / LIMIT NET I/O BLOCK I/O
abc123def456 myapp 1.50% 256MiB / 1GiB 1.2MB / 500kB 50MB / 10MB
查看详细资源信息 #
bash
# 查看容器资源限制配置
docker inspect --format '{{json .HostConfig}}' mycontainer | jq
# 查看内存限制
docker inspect --format '{{.HostConfig.Memory}}' mycontainer
# 查看CPU限制
docker inspect --format '{{.HostConfig.NanoCpus}}' mycontainer
docker inspect --format '{{.HostConfig.CpuShares}}' mycontainer
资源限制最佳实践 #
1. 设置合理的限制 #
bash
# 先观察资源使用,再设置限制
docker stats mycontainer
# 设置略高于实际使用的限制
docker run -m 1g --memory-reservation=512m myapp
2. 使用软限制和硬限制 #
bash
# 硬限制: 绝对不能超过
# 软限制: 内存紧张时尽量遵守
docker run -m 1g --memory-reservation=512m myapp
3. 预留资源 #
yaml
# docker-compose.yml
services:
web:
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '1'
memory: 1G
4. 监控和告警 #
bash
#!/bin/bash
# monitor-resources.sh
THRESHOLD=90
while true; do
# 获取内存使用百分比
mem_usage=$(docker stats --no-stream --format "{{.MemPerc}}" mycontainer | tr -d '%')
if (( $(echo "$mem_usage > $THRESHOLD" | bc -l) )); then
echo "Warning: Memory usage is ${mem_usage}%"
# 发送告警
fi
sleep 60
done
5. 处理OOM #
bash
# 查看OOM事件
docker events --filter 'event=oom'
# 查看容器是否被OOM杀死
docker inspect --format '{{.State.OOMKilled}}' mycontainer
# 调整OOM策略而不是禁用
docker run -m 1g --oom-score-adj=-500 myapp
小结 #
本节学习了Docker容器的资源限制:
- 内存限制配置
- CPU限制配置
- 磁盘IO限制
- 进程数限制
- 动态更新资源限制
- 资源监控
下一步 #
接下来,让我们学习 容器监控与日志,了解如何监控容器状态和收集日志。