Docker 资源调度限制

文章目录


一, Docker 资源分配机制:

  1. CPU 共享(默认行为):
go 复制代码
# 默认情况下,所有容器平等竞争 CPU
docker run --name container1 nginx
docker run --name container2 nginx

# 容器会竞争使用所有可用的 CPU 核心
# 空闲时,一个容器可以使用所有 CPU
# 繁忙时,CPU 时间会根据权重分配
  1. 内存共享(但有重要限制):
go 复制代码
# 默认情况下,容器可以使用所有可用内存(但有限制)
# 这可能导致容器互相竞争,最终触发 OOM Killer

Docker 的资源限制机制:

Docker 的资源限制是弹性防滥用机制:内存和存储空间设置硬性使用上限,CPU 和 I/O 采用上限约束与权重分配相结合的双层调度策略。

CPU 限制示例:

c 复制代码
# 1. 设置 CPU 权重(相对比例)
# 容器1 的权重是容器2 的两倍
docker run -d --name container1 --cpu-shares=512 nginx
docker run -d --name container2 --cpu-shares=256 nginx

# 2. 限制使用特定 CPU 核心
docker run -d --name container1 --cpuset-cpus="0-1" nginx  # 使用 CPU 0 和 1
docker run -d --name container2 --cpuset-cpus="2-3" nginx  # 使用 CPU 2 和 3

# 3. 限制 CPU 使用率
docker run -d --name container1 --cpus="1.5" nginx  # 最多使用 1.5 个 CPU 核心
docker run -d --name container2 --cpus="0.5" nginx  # 最多使用 0.5 个 CPU 核心

# 4. 使用 CPU 配额(更精细控制)
docker run -d --name container1 \
  --cpu-period=100000 \
  --cpu-quota=50000 \
  nginx  # 每 100ms 周期内最多使用 50ms CPU 时间

内存限制示例:

c 复制代码
# 1. 设置内存硬限制
docker run -d --name container1 -m 512m nginx  # 最大 512MB
docker run -d --name container2 -m 256m nginx  # 最大 256MB

# 2. 设置内存+交换分区限制
docker run -d --name container1 -m 512m --memory-swap=1g nginx

# 3. 设置内存预留(软限制)
docker run -d --name container1 --memory-reservation=256m nginx

# 4. 设置 OOM 优先级
docker run -d --name container1 --oom-score-adj=500 nginx  # 更可能被 OOM Killer 杀死
docker run -d --name container2 --oom-score-adj=-100 nginx # 更不可能被 OOM Killer 杀死

二,Docker 资源调度的工作原理:

  1. CPU 调度:
c 复制代码
# 查看容器的 CPU 使用情况
docker stats

# 输出示例:
# CONTAINER   CPU %   MEM USAGE / LIMIT   MEM %   NET I/O   BLOCK I/O
# container1  45.5%   256MiB / 1GiB       25.0%   ...       ...
# container2  22.3%   128MiB / 512MiB     25.0%   ...       ...
  1. 内存管理:
  • 未设置限制:容器可以使用所有可用内存,可能导致系统不稳定
  • 设置了限制:容器不能超过限制,超过会被 OOM Killer 终止
  • 内存回收:当系统内存紧张时,会优先回收未设置限制的容器的内存

Docker Compose 资源限制示例:

bash 复制代码
yaml
version: '3'
services:
  app1:
    image: nginx
    deploy:
      resources:
        limits:
          cpus: '0.5'      # 最多使用 0.5 个 CPU 核心
          memory: 512M     # 内存硬限制
        reservations:
          cpus: '0.1'      # 至少保留 0.1 个 CPU 核心
          memory: 128M     # 内存软限制
  
  app2:
    image: nginx
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 1G
        reservations:
          cpus: '0.2'
          memory: 256M

三,实际场景示例:

  • 场景1:开发环境(动态共享)
c 复制代码
# 开发环境通常不设限制,容器动态共享资源
docker-compose up -d

# 所有容器平等竞争 CPU 和内存
# 空闲时,一个容器可以占用大部分资源
# 繁忙时,资源会根据需求动态分配
  • 场景2:生产环境(严格限制)

生产环境需要严格限制,避免互相影响

c 复制代码
docker run -d \
  --name production-app \
  --cpus="2.0" \
  -m "2g" \
  --memory-reservation="1g" \
  --restart=always \
  myapp:latest
  • 场景3:混合负载(优先级调度)
c 复制代码
# 重要服务分配更多资源
docker run -d --name critical-app --cpu-shares=1024 -m 4g critical-app

# 次要服务分配较少资源
docker run -d --name background-job --cpu-shares=256 -m 1g background-job

四,关键点总结:

五,最佳实践建议:

  1. 开发环境:可以不设限制,便于开发测试
  2. 生产环境:必须设置资源限制,防止单个容器影响整个系统
  3. 监控资源:使用 docker stats 或监控工具观察资源使用
  4. 设置合理的限制:根据应用需求设置,不要过于严格或宽松

结论:

Docker 容器可以共享操作系统的 CPU 和内存资源,空闲时可以分配给其他容器。 但为了避免"吵闹的邻居"问题(一个容器占用过多资源影响其他容器),建议在生产环境中为每个容器设置合理的资源限制。

相关推荐
座山雕~5 小时前
docker---部署与常用命令
运维·docker·容器
TroubleBoy丶7 小时前
麒麟V10-ARM架构Docker启动报错
运维·docker·容器·arm·麒麟v10
陈平安Java and C9 小时前
Docker File部分镜像制作实操
docker
螺旋小蜗10 小时前
docker-compose文件属性(3)顶部元素networks
运维·docker·容器
ICT董老师10 小时前
Kubernetes从私有镜像仓库拉取容器镜像时的身份验证
ubuntu·docker·云原生·容器·kubernetes
goodlook012311 小时前
open-java21镜像构建
java·运维·docker·容器
别多香了13 小时前
k8s管理
docker·容器·kubernetes
林_学13 小时前
Docker Desktop 全卸了,新项目上线从3天缩短到3分钟
运维·docker·容器
陈平安Java and C13 小时前
Docker镜像原理
运维·docker·容器