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 和内存资源,空闲时可以分配给其他容器。 但为了避免"吵闹的邻居"问题(一个容器占用过多资源影响其他容器),建议在生产环境中为每个容器设置合理的资源限制。

相关推荐
hj2862513 小时前
Docker 核心知识点整理(网络 + Dockerfile + 原理 + 命令)
网络·docker·容器
梦想的颜色10 小时前
【Docker原理】Docker 容器一文打尽:生命周期、环境管控、迁移备份、日志进程排查、垃圾清理
运维·docker·容器·容器生命周期·容器日志排查·容器迁移备份·容器进程管理
极客先躯18 小时前
高级java每日一道面试题-2026年03月30日-实战篇[Docker]-如何监控容器的网络流量?
java·运维·docker·容器·prometheus·高级面试
大E帝国子民120 小时前
Docker 部署 RocketMQ 5
docker·容器·rocketmq
江湖有缘21 小时前
【保姆级教程】使用Docker Compose一键搭建Picsur私有图床服务
java·docker·容器
java_logo1 天前
5 分钟共享打印机:用 Docker 一键部署 CUPS
运维·docker·容器·cups·网络打印机·共享打印机·docker部署cups
fen_fen1 天前
Docker部署PostgreSQL10 开启SSL和证书安装文档
docker·容器·ssl
EnCi Zheng1 天前
N3A-一个端口只能给一个程序使用吗?[特殊字符]
网络·nginx·docker
彼岸笙箫1 天前
Centos7离线安装docker
运维·docker·容器
nuo5342021 天前
基础 1 —— Docker 的简介
运维·docker·容器