docker 资源限制+调优详解

ops/2024/10/25 15:30:23/

容器资源限制介绍

下面我将详细讲解 Docker 的各种资源限制及其在生产环境中的实际应用案例。我们将逐一探讨 CPU、内存、磁盘 I/O 和网络带宽的限制,并提供具体的配置示例和解释。

1. CPU 限制

1.1 设置 CPU 份额
  • --cpu-shares:设置容器的 CPU 优先级权重。默认值为 1024。较高的值表示更高的优先级。
    • 作用:当多个容器竞争 CPU 资源时,CPU 份额决定了每个容器可以获得的 CPU 时间比例。
    • 示例
      docker run -d --name container1 --cpu-shares 512 my_image
      docker run -d --name container2 --cpu-shares 1024 my_image
    • 解释:假设宿主机有 1 个 CPU 核心,container1 和 container2 同时需要 CPU 资源,那么 container2 将获得两倍于 container1 的 CPU 时间。
1.2 设置 CPU 配额
  • --cpus:限制容器可以使用的 CPU 核心数。例如,设置为 1.5 表示容器最多可以使用 1.5 个核心。

    • 作用:直接限制容器可以使用的 CPU 核心数,确保容器不会超过指定的核心数。
    • 示例
      docker run -d --name container1 --cpus 1.5 my_image
    • 解释container1 最多可以使用 1.5 个 CPU 核心,即使宿主机有更多的核心可用。
  • --cpu-period--cpu-quota:更细粒度地控制 CPU 时间片。

    • --cpu-period:设置 CPU CFS(Completely Fair Scheduler)调度器的时间周期(单位为微秒,默认为 100000 微秒)。
    • --cpu-quota:设置在每个周期内容器可以使用的 CPU 时间(单位为微秒)。
    • 作用:通过设置周期和配额,可以更精确地控制容器的 CPU 使用。
    • 示例
      docker run -d --name container1 --cpu-period 50000 --cpu-quota 25000 my_image
    • 解释container1 每 50000 微秒可以使用 25000 微秒的 CPU 时间,相当于 50% 的 CPU 使用率。

2. 内存限制

2.1 设置内存限制
  • --memory:限制容器可以使用的最大内存量(单位为字节或带单位的字符串,如 1g 表示 1GB)。

    • 作用:确保容器不会消耗超过指定的内存,防止 OOM(Out of Memory)错误。
    • 示例
      docker run -d --name container1 --memory 512m my_image
    • 解释container1 最多可以使用 512MB 的内存。
  • --memory-swap:设置容器可以使用的总内存(包括物理内存和交换空间)。如果设置为 -1,则不限制交换空间。

    • 作用:控制容器可以使用的总内存,包括物理内存和交换空间。
    • 示例
      docker run -d --name container1 --memory 512m --memory-swap 1g my_image
    • 解释container1 最多可以使用 512MB 的物理内存和 512MB 的交换空间,总共 1GB。
2.2 设置内存预留
  • --memory-reservation:设置容器的内存预留量。当系统内存紧张时,优先保证预留量。
    • 作用:在系统内存紧张时,优先保证某些容器的内存需求。
    • 示例
      docker run -d --name container1 --memory 512m --memory-reservation 256m my_image
    • 解释container1 最多可以使用 512MB 的内存,但在系统内存紧张时,至少保证 256MB 的内存。

3. 磁盘 I/O 限制

3.1 设置块设备 I/O 限制
  • --blkio-weight:设置容器的块设备 I/O 权重(范围为 10 到 1000,默认为 500)。

    • 作用:控制容器的 I/O 优先级。
    • 示例
      docker run -d --name container1 --blkio-weight 300 my_image
    • 解释container1 的 I/O 权重为 300,较低的权重意味着较低的 I/O 优先级。
  • --device-read-bps--device-write-bps:限制容器对特定设备的读写速度(单位为字节/秒)。

    • 作用:控制容器对特定设备的读写速度,防止 I/O 负载过高。
    • 示例
      docker run -d --name container1 --device-read-bps /dev/sda:1mb --device-write-bps /dev/sda:1mb my_image
    • 解释container1 对 /dev/sda 设备的读写速度分别限制为 1MB/s。
  • --device-read-iops--device-write-iops:限制容器对特定设备的读写 IOPS(每秒 I/O 操作次数)。

    • 作用:控制容器对特定设备的 I/O 操作次数,防止 I/O 负载过高。
    • 示例
      docker run -d --name container1 --device-read-iops /dev/sda:1000 --device-write-iops /dev/sda:1000 my_image
    • 解释container1 对 /dev/sda 设备的读写 IOPS 分别限制为 1000 次/秒。

4. 网络带宽限制

4.1 使用 tc 工具

Docker 本身没有直接提供网络带宽限制的功能,但可以通过 tc(Traffic Control)工具来实现。

  1. 安装 tc 工具

    apt-get update && apt-get install -y iproute2
  2. 设置网络带宽限制

    tc qdisc add dev eth0 root handle 1: htb default 11
    tc class add dev eth0 parent 1: classid 1:1 htb rate 1mbit
    tc class add dev eth0 parent 1:1 classid 1:11 htb rate 1mbit
  3. 容器的网络接口绑定到 tc 规则

    docker run -d --name my_container --net=none my_image
    container_id=$(docker inspect -f '{{.Id}}' my_container)
    veth_pair=$(ip link show | grep $container_id | awk '{print $2}' | cut -d '@' -f 1)
    ip link set $veth_pair netns $(docker inspect -f '{{.State.Pid}}' my_container)
    ip netns exec $(docker inspect -f '{{.State.Pid}}' my_container) ip link set lo up
    ip netns exec $(docker inspect -f '{{.State.Pid}}' my_container) ip link set $veth_pair up
    ip netns exec $(docker inspect -f '{{.State.Pid}}' my_container) tc qdisc add dev $veth_pair root handle 1: htb default 11
    ip netns exec $(docker inspect -f '{{.State.Pid}}' my_container) tc class add dev $veth_pair parent 1: classid 1:1 htb rate 1mbit
    ip netns exec $(docker inspect -f '{{.State.Pid}}' my_container) tc class add dev $veth_pair parent 1:1 classid 1:11 htb rate 1mbit

5. 其他资源限制

5.1 设置 PIDs 限制
  • --pids-limit:限制容器可以创建的最大进程数。
    • 作用:防止容器创建过多的进程,导致系统资源耗尽。
    • 示例
      docker run -d --name container1 --pids-limit 100 my_image
    • 解释container1 最多可以创建 100 个进程。
5.2 设置内核参数
  • --ulimit:设置容器的 ulimit 参数,如文件描述符数量。
    • 作用:控制容器的资源使用,防止资源耗尽。
    • 示例
      docker run -d --name container1 --ulimit nofile=1024:1024 my_image
    • 解释container1 的文件描述符数量限制为 1024。

生产实际案例

案例 1:Web 应用服务器

假设你有一个 Web 应用服务器,需要确保其不会消耗过多的 CPU 和内存资源,同时限制其磁盘 I/O 操作。

docker run -d --name web_app \--cpus 2 \--memory 1g \--memory-swap 2g \--device-read-bps /dev/sda:10mb \--device-write-bps /dev/sda:10mb \my_web_app_image
  • 解释
    • --cpus 2:限制 web_app 容器最多使用 2 个 CPU 核心。
    • --memory 1g:限制 web_app 容器最多使用 1GB 的内存。
    • --memory-swap 2g:限制 web_app 容器最多使用 2GB 的总内存(包括物理内存和交换空间)。
    • --device-read-bps /dev/sda:10mb 和 --device-write-bps /dev/sda:10mb:限制 web_app 容器对 /dev/sda 设备的读写速度分别为 10MB/s。
案例 2:数据库服务器

假设你有一个数据库服务器,需要确保其有足够的内存和 CPU 资源,同时限制其磁盘 I/O 操作。

docker run -d --name db_server \--cpus 4 \--memory 8g \--memory-swap -1 \--device-read-bps /dev/sda:50mb \--device-write-bps /dev/sda:50mb \my_db_image
  • 解释
    • --cpus 4:限制 db_server 容器最多使用 4 个 CPU 核心。
    • --memory 8g:限制 db_server 容器最多使用 8GB 的内存。
    • --memory-swap -1:不限制 db_server 容器的交换空间。
    • --device-read-bps /dev/sda:50mb 和 --device-write-bps /dev/sda:50mb:限制 db_server 容器对 /dev/sda 设备的读写速度分别为 50MB/s。
案例 3:批处理作业

假设你有一个批处理作业,需要在短时间内消耗大量 CPU 和内存资源,但不需要长期运行。

docker run -d --name batch_job \--cpus 8 \--memory 16g \--memory-swap -1 \--pids-limit 500 \my_batch_job_image
  • 解释
    • --cpus 8:限制 batch_job 容器最多使用 8 个 CPU 核心。
    • --memory 16g:限制 batch_job 容器最多使用 16GB 的内存。
    • --memory-swap -1:不限制 batch_job 容器的交换空间。
    • --pids-limit 500:限制 batch_job 容器最多创建 500 个进程。
案例 4:缓存服务

假设你有一个缓存服务,需要确保其不会消耗过多的内存资源,同时限制其网络带宽。

docker run -d --name cache_service \--memory 2g \--memory-swap 2g \--ulimit nofile=65536:65536 \my_cache_image
  • 解释
    • --memory 2g:限制 cache_service 容器最多使用 2GB 的内存。
    • --memory-swap 2g:限制 cache_service 容器最多使用 2GB 的总内存(包括物理内存和交换空间)。
    • --ulimit nofile=65536:65536:限制 cache_service 容器的文件描述符数量为 65536。

最后,完结撒花~后续会有更多内容 ,敬请期待 


http://www.ppmy.cn/ops/128371.html

相关文章

重修设计模式-行为型-迭代器模式

重修设计模式-行为型-迭代器模式 提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。 迭代器模式(Iterator Pattern)将容器的遍历操作从容器类中拆分出来,放到迭代器类中,让两者的职责更加单一。…

在Nodejs中使用MySQL数据库

简介 MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,属于Oracle旗下产品。MySQL是最流行的关系型数据库管理系统之一,在WEB应用方面,MySQL是最好的RDBMS(Relational Database Management System&#xff0…

Rust编程语言变量的所有权(ownership)

文章目录 什么是所有权所有权规则转让所有权变量与数据交互的方式(一):移动变量与数据交互的方式(二):克隆只在栈上的数据:拷贝所有权与函数返回值与作用域引用和借用可变引用悬垂引用(Dangling References)引用的规则什么是所有权 所有权(ownership)是Rust 的核心功能之一…

执行Django项目的数据库迁移命令时报错:(1050, “Table ‘django_session‘ already exists“);如何破?

一、问题描述: 当我们写Django时,由于自己的操作不当,导致执行数据库迁移命令时报错,报错的种类有很多,例如: 迁移文件冲突:可能你有多个迁移文件试图创建同一个表。数据库状态与迁移文件不同…

OJ练习:判断环形链表、返回入环的第一个节点

目录 1. 判断环形链表1.1 判断环形链表拓展 2. 返回入环首节点解法一解法二 1. 判断环形链表 题目来自 141.环形链表 - 力扣(LeetCode) 解题思路:使用快慢指针。 定义一个慢指针slow指向头节点,每次向前走一步定义一个快指针fast指…

使用 NumPy 和 Matplotlib 实现交互式数据可视化

使用 NumPy 和 Matplotlib 实现交互式数据可视化 在数据分析中,交互式可视化可以更好地帮助我们探索和理解数据。虽然 Matplotlib 是静态绘图库,但结合一些技巧和 Matplotlib 的交互功能(widgets、event handlers),我…

2000-2020年各地级市人类需求指数数据

2000-2020年各地级市人类需求指数数据 1、年份:2000、2010、2020年 2、指标:城市名称、HMDI2000、HMDI2010、HMDI2020 3、范围:341个地级市 4、说明:各城市的人类需求指数项目旨在全面评估Z国城市居民在不同社会发展阶段对自然…

前端性能优化之Canvas优化

元素是众多广泛使用的网络 2D 图像渲染标准之一。它被广泛用于游戏及复杂的图像可视化中。然而,随着网站和应用将 canvas 画布推至极限,性能开始成为问题。 Canvas 上下文切换 Canvas 绘制 API 都是在上下文context上进行调用,context不是一个普通的对象,当我们对其赋值的…