<返回目录     Powered by claude/xia兄

第12课: 资源限制

为什么需要资源限制?

内存限制

# 限制容器最大内存为512MB
docker run -d --memory="512m" nginx

# 限制内存和swap总量
docker run -d --memory="512m" --memory-swap="1g" nginx

# 禁用swap
docker run -d --memory="512m" --memory-swap="512m" nginx

# 内存预留(软限制)
docker run -d --memory="1g" --memory-reservation="512m" nginx

# OOM时不杀死容器(不推荐)
docker run -d --memory="512m" --oom-kill-disable nginx
内存单位:

CPU限制

# 限制CPU份额(相对权重,默认1024)
docker run -d --cpu-shares=512 nginx

# 限制使用的CPU核心数
docker run -d --cpus="1.5" nginx

# 指定使用哪些CPU核心
docker run -d --cpuset-cpus="0,1" nginx
docker run -d --cpuset-cpus="0-3" nginx

# CPU配额(100000为100%)
docker run -d --cpu-period=100000 --cpu-quota=50000 nginx  # 限制50% CPU

磁盘IO限制

# 限制读写速率(字节/秒)
docker run -d \
  --device-read-bps /dev/sda:10mb \
  --device-write-bps /dev/sda:10mb \
  nginx

# 限制读写IOPS
docker run -d \
  --device-read-iops /dev/sda:1000 \
  --device-write-iops /dev/sda:1000 \
  nginx

# 限制块IO权重(10-1000,默认500)
docker run -d --blkio-weight 300 nginx

查看资源使用情况

# 实时查看所有容器资源使用
docker stats

# 查看特定容器
docker stats mycontainer

# 不持续刷新,只显示一次
docker stats --no-stream

# 格式化输出
docker stats --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"

# 查看容器详细信息
docker inspect mycontainer | grep -A 10 "Memory"

Docker Compose资源限制

version: '3.8'

services:
  web:
    image: nginx
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M

  db:
    image: mysql
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G
        reservations:
          cpus: '1'
          memory: 1G
    environment:
      MYSQL_ROOT_PASSWORD: secret

实战示例 - Web应用资源配置

# Nginx前端服务器(轻量级)
docker run -d \
  --name nginx \
  --memory="256m" \
  --memory-reservation="128m" \
  --cpus="0.5" \
  -p 80:80 \
  nginx:alpine

# Python应用服务器(中等)
docker run -d \
  --name webapp \
  --memory="1g" \
  --memory-reservation="512m" \
  --cpus="1" \
  myapp:latest

# MySQL数据库(重量级)
docker run -d \
  --name mysql \
  --memory="2g" \
  --memory-reservation="1g" \
  --cpus="2" \
  -e MYSQL_ROOT_PASSWORD=secret \
  mysql:8.0

# Redis缓存(轻量级)
docker run -d \
  --name redis \
  --memory="512m" \
  --cpus="0.5" \
  redis:alpine

PID限制

# 限制容器可创建的进程数
docker run -d --pids-limit=100 nginx

# 查看容器进程数
docker exec mycontainer ps aux | wc -l

网络带宽限制

# Docker本身不直接支持网络带宽限制
# 需要使用tc(traffic control)工具

# 在主机上限制容器网络
# 获取容器网络接口
docker exec mycontainer cat /sys/class/net/eth0/iflink

# 使用tc限制带宽
tc qdisc add dev veth123456 root tbf rate 1mbit burst 32kbit latency 400ms

资源监控和告警

# 使用cAdvisor监控容器
docker run -d \
  --name=cadvisor \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --publish=8080:8080 \
  google/cadvisor:latest

# 访问 http://localhost:8080 查看监控数据

完整监控方案

version: '3.8'

services:
  # 应用容器
  app:
    image: myapp
    deploy:
      resources:
        limits:
          cpus: '1'
          memory: 1G

  # Prometheus监控
  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"

  # cAdvisor收集容器指标
  cadvisor:
    image: google/cadvisor
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
    ports:
      - "8080:8080"

  # Grafana可视化
  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin

压力测试

# 使用stress工具测试资源限制
docker run -it --rm \
  --memory="512m" \
  --cpus="1" \
  progrium/stress \
  --cpu 2 --io 1 --vm 2 --vm-bytes 256M --timeout 30s

# 观察容器被OOM杀死
docker run -it --rm \
  --memory="100m" \
  progrium/stress \
  --vm 1 --vm-bytes 200M

动态调整资源限制

# 更新运行中容器的资源限制
docker update --memory="1g" --cpus="2" mycontainer

# 批量更新
docker update --memory="512m" $(docker ps -q)

# 查看更新后的配置
docker inspect mycontainer | grep -A 5 "Memory"

资源配额最佳实践

常见问题排查

# 容器被OOM杀死
docker inspect mycontainer | grep OOMKilled

# 查看容器退出原因
docker inspect mycontainer | grep -A 5 "State"

# 查看系统日志
dmesg | grep -i oom
journalctl -u docker | grep -i oom

# 查看容器资源限制
docker inspect mycontainer | grep -A 20 "HostConfig"

推荐资源配置

# 小型Web应用
--memory="256m" --cpus="0.5"

# 中型应用服务器
--memory="1g" --cpus="1"

# 数据库服务
--memory="2g" --cpus="2"

# 大数据处理
--memory="4g" --cpus="4"

# 开发环境
--memory="512m" --cpus="1"

实践练习

  1. 启动一个限制512MB内存的容器,观察资源使用
  2. 使用stress工具测试内存限制,观察OOM行为
  3. 配置Docker Compose为不同服务设置资源限制
  4. 使用docker stats实时监控容器资源使用
  5. 搭建Prometheus+Grafana监控系统
  6. 动态调整运行中容器的资源限制