第24章 Docker资源管理

24.1 资源管理概述

24.1.1 为什么需要资源管理

容器化环境中,资源管理防止单个容器消耗所有系统资源,保证服务质量和系统稳定性。

典型问题场景:

  • 内存泄漏容器导致宿主机OOM
  • CPU争抢引起响应延迟
  • 磁盘I/O竞争影响数据库性能

24.1.2 Cgroups架构基础

Docker通过Linux Cgroups实现资源隔离,主要子系统包括:

  • cpu: CPU时间限制
  • memory: 内存限制
  • blkio: 磁盘I/O限制
  • cpuset: CPU核心绑定

24.2 CPU资源管理

24.2.1 核心参数对比

参数 作用 示例
--cpus 限制CPU核心数(最常用) --cpus=1.5
--cpu-shares CPU权重(相对值,默认1024) --cpu-shares=512
--cpuset-cpus 绑定特定CPU核心 --cpuset-cpus=0-3

24.2.2 基本使用示例

bash 复制代码
# 限制1个CPU核心
docker run -d --cpus=1 nginx

# 权重分配(仅CPU争抢时生效)
docker run -d --cpu-shares=2048 app-high  # 高优先级
docker run -d --cpu-shares=512 app-low    # 低优先级

# NUMA优化 - 绑定CPU和内存节点
docker run -d --cpuset-cpus=0-7 --cpuset-mems=0 postgres

# ROCm GPU优化 - 绑定到GPU相同NUMA节点
docker run -it --device=/dev/kfd --device=/dev/dri \
  --cpuset-cpus=8-15 --cpuset-mems=1 \
  rocm/pytorch:latest

24.3 内存资源管理

24.3.1 核心参数

参数 作用 示例
--memory / -m 内存硬限制 -m 512m
--memory-reservation 内存软限制(弹性) --memory-reservation=256m
--memory-swap 内存+Swap总限制 --memory-swap=1g
--memory-swappiness Swap倾向(0-100) --memory-swappiness=0

24.3.2 基本使用

bash 复制代码
# 硬限制512MB
docker run -d -m 512m nginx

# 禁用Swap(数据库推荐)
docker run -d -m 4g --memory-swap=4g --memory-swappiness=0 postgres

# 弹性内存:保证1GB,最多2GB
docker run -d -m 2g --memory-reservation=1g myapp

# 查看内存使用
docker stats --no-stream

Swap配置规则:

bash 复制代码
# 可用Swap = --memory-swap - --memory

# 完全禁用Swap
docker run -d -m 512m --memory-swap=512m nginx

# 允许512MB Swap
docker run -d -m 512m --memory-swap=1g nginx

# 无限制Swap
docker run -d -m 512m --memory-swap=-1 nginx

24.4 磁盘I/O管理

24.4.1 核心参数

参数 作用 示例
--device-read-bps 读取速率限制 --device-read-bps=/dev/sda:10mb
--device-write-bps 写入速率限制 --device-write-bps=/dev/sda:5mb
--device-read-iops 读取IOPS限制 --device-read-iops=/dev/sda:1000
--device-write-iops 写入IOPS限制 --device-write-iops=/dev/sda:500

24.4.2 使用示例

bash 复制代码
# 限制日志容器I/O,避免影响主应用
docker run -d --device-write-bps=/dev/sda:10mb \
  -v /var/log/app:/logs log-processor

# 备份容器限制读写速度
docker run --rm \
  --device-read-bps=/dev/sda:20mb \
  --device-write-bps=/dev/sdb:20mb \
  -v /data:/source:ro \
  backup-tool

# 限制数据库副本IOPS
docker run -d \
  --device-read-iops=/dev/sda:1000 \
  --device-write-iops=/dev/sda:500 \
  postgres:15

24.5 资源监控

24.5.1 docker stats命令

bash 复制代码
# 实时监控所有容器
docker stats

# 监控特定容器
docker stats nginx postgres

# 单次输出
docker stats --no-stream

# 自定义格式
docker stats --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}"

输出字段说明:

  • CPU %: CPU使用百分比
  • MEM USAGE: 当前内存/内存限制
  • NET I/O: 网络接收/发送
  • BLOCK I/O: 磁盘读/写
  • PIDS: 进程数

24.5.2 监控脚本

bash 复制代码
#!/bin/bash
# resource-monitor.sh - 资源告警

CPU_THRESHOLD=80
MEM_THRESHOLD=80

docker stats --no-stream --format "{{.Name}},{{.CPUPerc}},{{.MemPerc}}" | \
while IFS=',' read name cpu mem; do
  cpu_val=${cpu%\%}
  mem_val=${mem%\%}
  
  if (( $(echo "$cpu_val > $CPU_THRESHOLD" | bc -l) )); then
    echo "[警告] $name CPU: ${cpu}%"
  fi
  
  if (( $(echo "$mem_val > $MEM_THRESHOLD" | bc -l) )); then
    echo "[警告] $name 内存: ${mem}%"
  fi
done

24.5.3 Prometheus集成

yaml 复制代码
# docker-compose.yml
version: '3.8'
services:
  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro

  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin

24.6 Docker Compose资源配置

yaml 复制代码
# docker-compose.yml
version: '3.8'

services:
  postgres:
    image: postgres:15
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 4G
        reservations:
          cpus: '1.0'
          memory: 2G

  webapp:
    image: myapp:latest
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 1G
        reservations:
          cpus: '0.5'
          memory: 512M

  redis:
    image: redis:7-alpine
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
    command: redis-server --maxmemory 450mb

24.7 实战案例

24.7.1 ROCm多租户GPU资源隔离

yaml 复制代码
# rocm-multi-tenant.yml
version: '3.8'

services:
  training-high:
    image: rocm/pytorch:latest
    deploy:
      resources:
        limits:
          cpus: '8.0'
          memory: 16G
        reservations:
          cpus: '4.0'
          memory: 8G
    devices:
      - /dev/kfd
      - /dev/dri
    group_add:
      - video
    cpuset_cpus: "0-7"
    cpuset_mems: "0"
    environment:
      - ROCR_VISIBLE_DEVICES=0

  training-normal:
    image: rocm/pytorch:latest
    deploy:
      resources:
        limits:
          cpus: '4.0'
          memory: 8G
    devices:
      - /dev/kfd
      - /dev/dri
    group_add:
      - video
    cpuset_cpus: "8-11"
    environment:
      - ROCR_VISIBLE_DEVICES=1

  inference:
    image: rocm/pytorch:latest
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 4G
    devices:
      - /dev/kfd
      - /dev/dri/renderD128
    group_add:
      - video
    environment:
      - GPU_MAX_HEAP_SIZE=30

监控脚本:

bash 复制代码
#!/bin/bash
# rocm-monitor.sh
while true; do
  echo "=== $(date) ==="
  rocm-smi --showuse
  docker stats --no-stream training-high training-normal inference
  sleep 10
done

24.8 最佳实践

24.8.1 资源配置原则

  1. 始终设置内存限制

    bash 复制代码
    # 避免OOM影响宿主机
    docker run -d -m 512m nginx
  2. 数据库禁用Swap

    bash 复制代码
    docker run -d -m 4g --memory-swap=4g --memory-swappiness=0 postgres
  3. 使用reservation优化资源利用

    bash 复制代码
    docker run -d -m 2g --memory-reservation=1g myapp
  4. NUMA架构使用cpuset绑定

    bash 复制代码
    docker run -d --cpuset-cpus=0-7 --cpuset-mems=0 postgres

24.8.2 应用类型资源参考

应用 内存 CPU I/O 说明
Nginx 128-256MB 0.5-1.0 静态服务
Node.js 512MB-1GB 1.0-2.0 无状态API
PostgreSQL 2-8GB 2.0-4.0 禁用Swap
Redis 1-4GB 0.5-1.0 maxmemory
ROCm训练 8-32GB 4.0-16.0 GPU绑定

24.8.3 监控告警规则

yaml 复制代码
# prometheus-alerts.yml
groups:
  - name: container-alerts
    rules:
      - alert: HighMemoryUsage
        expr: (container_memory_usage_bytes / container_spec_memory_limit_bytes) > 0.8
        for: 5m
        annotations:
          summary: "容器内存超过80%"
      
      - alert: HighCPUUsage
        expr: rate(container_cpu_usage_seconds_total[5m]) > 0.9
        for: 10m
        annotations:
          summary: "容器CPU持续高于90%"

24.8.4 故障诊断脚本

bash 复制代码
#!/bin/bash
# resource-debug.sh
CONTAINER=$1

echo "=== 基本信息 ==="
docker inspect $CONTAINER | jq '{
  Name, Status: .State.Status, 
  OOMKilled: .State.OOMKilled
}'

echo -e "\n=== 资源限制 ==="
docker inspect $CONTAINER | jq '.HostConfig | {
  Memory, MemorySwap, NanoCpus, CpuShares
}'

echo -e "\n=== 当前使用 ==="
docker stats --no-stream $CONTAINER

echo -e "\n=== Top进程 ==="
docker exec $CONTAINER ps aux --sort=-rss | head -n 5

echo -e "\n=== 最近日志 ==="
docker logs --tail 20 $CONTAINER

24.9 总结

24.9.1 核心要点

  • CPU管理 : --cpus限制核心数, --cpu-shares权重分配, --cpuset-cpus核心绑定
  • 内存管理 : --memory硬限制, --memory-reservation弹性分配, 数据库禁用Swap
  • I/O管理 : --device-*-bps速率限制, --device-*-iops IOPS限制
  • 监控 : docker stats实时监控, cAdvisor+Prometheus生产环境

24.9.2 检查清单

  • 所有容器设置内存限制
  • 数据库禁用Swap
  • CPU密集型应用设置CPU限制
  • 关键服务设置资源预留
  • NUMA架构优化cpuset配置
  • 部署资源监控系统
  • 配置告警规则
  • 定期审查资源使用

24.9.3 下一章预告

  • 第25章: Docker安全最佳实践
  • 第26章: Docker故障排查与调优
  • 第27章: 常见问题与解决方案
相关推荐
@hdd11 小时前
工作节点组件详解:kubelet、kube-proxy 与容器运行时
容器·kubernetes
@hdd11 小时前
Kubernetes 网络模型:Pod 通信、Service 网络与 CNI
网络·云原生·容器·kubernetes
Codefengfeng11 小时前
CTF工具篇
linux·运维·服务器
2401_8480097212 小时前
Docker学习后续
docker·云原生·eureka
封奚泽优12 小时前
Docker常用命令(Windows 11)
运维·docker·容器
上海合宙LuatOS12 小时前
LuatOS核心库API——【i2c】I2C 操作
linux·运维·单片机·嵌入式硬件·物联网·计算机外设·硬件工程
前路不黑暗@12 小时前
Java项目:Java脚手架项目的文件服务(八)
java·开发语言·spring boot·学习·spring cloud·docker·maven
2401_8582861115 小时前
OS53.【Linux】System V 共享内存(2)
linux·运维·服务器·共享内存
only_Klein16 小时前
kubernetes-ReplicaSet控制器
容器·kubernetes