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

相关推荐
问简7 小时前
docker 镜像相关
运维·docker·容器
Benszen8 小时前
Docker容器化技术实战指南
运维·docker·容器
Hommy888 小时前
【开源剪映小助手】Docker 部署
docker·容器·开源·github·aigc
斯普信云原生组10 小时前
Prometheus 环境监控虚机 Redis 方案(生产实操版)
运维·docker·容器
喵了几个咪10 小时前
如何在 Superset Docker 容器中安装 MySQL 驱动
mysql·docker·容器·superset
工具罗某人10 小时前
docker compose部署kafka集群搭建
docker·容器·kafka
sbjdhjd16 小时前
Docker | 核心概念科普 + 保姆级部署
linux·运维·服务器·docker·云原生·面试·eureka
摇滚侠16 小时前
Vmvare 虚拟机安装 Linux CentOS 7 操作系统 一键安装 Docker 1Panel 一键安装 MySQL Redis OpenClaw
linux·docker·centos
comedate17 小时前
【OpenClaw】 Open-WebUI Docker 部署连接本地 Ollama 技术文档
docker·ollama·openwebui·openclaw
川trans17 小时前
基于 Docker & K8s 的 MySQL 容器化部署与应用关联实践
mysql·docker·kubernetes