容器资源限制 #

资源限制概述 #

为什么需要资源限制? #

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限制
  • 进程数限制
  • 动态更新资源限制
  • 资源监控

下一步 #

接下来,让我们学习 容器监控与日志,了解如何监控容器状态和收集日志。