Docker(三)——Docker资源控制+Docker数据卷容器 +Docker容器互联

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 二、Docker资源控制(Docker优化)
    • [2.1 CPU资源控制](#2.1 CPU资源控制)
      • [2.1.1 设置CPU使用率上限(--cpu-period / --cpu-quota)](#2.1.1 设置CPU使用率上限(–cpu-period / --cpu-quota))
      • [2.1.2 设置CPU占用比(权重 --- --cpu-shares)](#2.1.2 设置CPU占用比(权重 — --cpu-shares))
      • [2.1.3 绑定指定CPU(--cpuset-cpus)](#2.1.3 绑定指定CPU(–cpuset-cpus))
      • [2.1.4 CPU压力测试与验证示例](#2.1.4 CPU压力测试与验证示例)
      • [2.1.5 CPU资源控制注意事项](#2.1.5 CPU资源控制注意事项)
    • [2.2 内存使用限制](#2.2 内存使用限制)
      • [2.2.1 --memory与--memory-swap规则](#2.2.1 --memory与–memory-swap规则)
      • [2.2.2 内存限制示例命令](#2.2.2 内存限制示例命令)
      • [2.2.3 内存限制验证与OOM行为](#2.2.3 内存限制验证与OOM行为)
    • [2.3 磁盘IO(blkio/io)控制](#2.3 磁盘IO(blkio/io)控制)
      • [2.3.1 常用Docker磁盘IO限制参数](#2.3.1 常用Docker磁盘IO限制参数)
      • 参数说明表格
      • [2.3.2 磁盘IO限制验证(dd测试)](#2.3.2 磁盘IO限制验证(dd测试))
      • [2.3.3 磁盘IO控制注意事项](#2.3.3 磁盘IO控制注意事项)
    • [2.4 清理Docker占用的磁盘空间](#2.4 清理Docker占用的磁盘空间)
    • [2.5 Docker资源控制常见命令速查](#2.5 Docker资源控制常见命令速查)
    • [2.6 Docker资源控制常见陷阱与建议](#2.6 Docker资源控制常见陷阱与建议)
  • [三、Docker数据卷容器(Data Volumes Containers)](#三、Docker数据卷容器(Data Volumes Containers))
    • [3.1 数据卷](#3.1 数据卷)
    • [3.1.1 创建与挂载数据卷](#3.1.1 创建与挂载数据卷)
      • [3.1.2 在数据卷中写入数据](#3.1.2 在数据卷中写入数据)
      • [3.1.3 查看宿主机同步的数据](#3.1.3 查看宿主机同步的数据)
    • [3.2 数据卷容器](#3.2 数据卷容器)
      • [3.2.1 创建数据卷容器](#3.2.1 创建数据卷容器)
      • [3.2.2 在数据卷容器中写入数据](#3.2.2 在数据卷容器中写入数据)
      • [3.2.3 使用--volumes-from共享数据卷](#3.2.3 使用–volumes-from共享数据卷)
      • [3.2.4 在新容器中验证共享数据](#3.2.4 在新容器中验证共享数据)
    • [3.3 数据卷与数据卷容器总结](#3.3 数据卷与数据卷容器总结)
    • 四、Docker容器互联(使用CentOS镜像)
    • [4.1 创建并运行源容器web1](#4.1 创建并运行源容器web1)
    • [4.2 创建并运行接收容器web2(--link互联)](#4.2 创建并运行接收容器web2(–link互联))
    • [4.3 在接收容器web2中测试连接](#4.3 在接收容器web2中测试连接)
    • [4.4 Docker容器互联总结](#4.4 Docker容器互联总结)
  • 总结

前言


Docker网络模式总结

网络模式 核心特点 适用场景
host 共享宿主机网络栈,无端口映射 对网络性能要求高,无端口冲突风险的场景
container 共享其他容器网络,隔离其他资源 容器间紧密协作(如应用+日志收集)
none 无网络配置,仅lo网卡 离线任务、高安全性需求
bridge 默认模式,独立网络栈+docker0网桥 单主机容器通信,常规场景
自定义 支持DNS、跨主机、MAC模拟 集群部署、复杂网络隔离

二、Docker资源控制(Docker优化)

避免单容器占用过多宿主机资源(如CPU、内存),Docker基于Linux的cgroups(Control Groups)机制实现资源限制。

cgroups是Linux内核提供的资源管理工具,支持限制、统计、优先级分配等功能。

cgroups 的 4 大功能(简要):

  • 资源限制:限制任务使用的总资源量。
  • 优先级分配:如通过 cpu 时间片和 IO 带宽分配优先级。
  • 资源统计:统计 cpu 时长、内存用量等。
  • 任务控制:对 cgroup 中的进程执行挂起/恢复等操作。

2.1 CPU资源控制

2.1.1 设置CPU使用率上限(--cpu-period / --cpu-quota)

  • 原理:Linux使用CFS(完全公平调度器)调度CPU,通过两个参数控制容器CPU使用率:

    --cpu-period:调度周期(单位:微秒,默认100000,即100ms);

    --cpu-quota:容器在一个周期内可使用的CPU时间(单位:微秒,默认-1,即无限制);

    计算公式:可用CPU核心数 = cpu-quota / cpu-period(如50000/100000=0.5,即50%的单核CPU)。

    实战示例:

bash 复制代码
# 方式1:使用--cpu-quota(限制为50%单核CPU)
docker run -itd --name test6 --cpu-quota 50000 centos:7 /bin/bash

# 方式2:使用--cpus(更直观,Docker 1.13+支持)
docker run -itd --name cputest --cpus="0.5" centos:7 /bin/bash
# 说明:--cpus="0.5" 等价于 --cpu-period=100000 --cpu-quota=50000

# 进行压测并在宿主机查看cpu使用率
docker stats
  • 注意:若宿主机有4个逻辑核,0.5个CPU相当于整机CPU能力的12.5%(0.5/4=0.125)。

  • 最小值/范围:--cpu-period 有效范围通常 1000 ~ 1000000(单位 us)。--cpu-quota 必须 >= 1000(1 ms)或者 -1(不限制)。

2.1.2 设置CPU占用比(权重 --- --cpu-shares)

  • 原理:--cpu-shares指定CPU使用的相对权重(默认1024),仅在CPU资源紧张(容器争用CPU)时生效,并非硬限制。例如:
    容器A(--cpu-shares 512)与容器B(--cpu-shares 1024)争用CPU时,分配比约为1:2。
bash 复制代码
# 创建两个不同权重的容器
docker run -itd --name c1 --cpu-shares 512 centos:7
docker run -itd --name c2 --cpu-shares 1024 centos:7
bash 复制代码
# 验证:在容器内运行压力测试工具stress
# 1. 进入容器安装stress(先在容器内设置阿里源)
docker cp CentOS-Base.repo c1:/etc/yum.repos.d/
docker exec -it c1 bash
yum install -y epel-release && yum install -y stress

# 2. 每个容器启动4个CPU压力进程
stress -c 4  # 在c1和c2中分别执行

# 3. 宿主机查看CPU分配(倾向于1:2)
docker stats

2.1.3 绑定指定CPU(--cpuset-cpus)

原理:将容器进程绑定到宿主机的指定CPU核心(硬亲和性),避免进程在不同核心间切换,提升性能稳定性。

实战示例:

bash 复制代码
# 将容器绑定到宿主机第1、3个核心(核心编号从0开始)
docker run -itd --name test7 --cpuset-cpus "1,3" centos:7 /bin/bash

# 验证:宿主机查看核心利用率
top  # 按键盘1键,查看CPU1和CPU3的使用率
# 或进入容器运行 taskset -p <pid>

2.1.4 CPU压力测试与验证示例

在容器内创建一个繁忙循环脚本:

bash 复制代码
# /cpu.sh
#!/bin/bash
i=0
while true; do let i++; done

在容器内运行 ./cpu.sh,在宿主机观察 top 与 docker stats:

bash 复制代码
docker exec -it <container> bash
./cpu.sh

分别进入容器,进行压力测试

bash 复制代码
yum install -y epel-release
yum install -y stress
stress -c 4				#产生四个进程,每个进程都反复不停的计算随机数的平方根
bash 复制代码
yum install -y epel-release && yum install -y stress

修改 cgroups 手工测试(示例):

bash 复制代码
# 找到容器对应的 cgroup 路径(容器ID替换)
cd /sys/fs/cgroup/cpu/docker/<container-id>/
cat cpu.cfs_period_us
cat cpu.cfs_quota_us
echo 50000 > cpu.cfs_quota_us   # 设置配额(临时生效)

2.1.5 CPU资源控制注意事项

cpu-shares是权重,非硬限制(CPU空闲时,容器可使用超过权重的资源);

--cpu-quota/--cpus是硬限制,容器无法突破设定的CPU上限(quota = -1 表示无限制);

--cpuset-cpus适合对性能稳定性要求高的场景(避免与其他进程抢核)(如数据库容器)。

在多核宿主机上理解 quota/period 的含义(单位是 "相对于 1 个 CPU 的份额")。

通过自定义脚本模拟CPU高负载,验证资源限制效果:

2.2 内存使用限制

内存限制通过-m/--memory和--memory-swap参数实现,避免容器耗尽宿主机内存。

2.2.1 --memory与--memory-swap规则

--memory:限制容器可使用的物理内存(如-m 512m表示512MB);

--memory-swap:限制容器可使用的物理内存+交换分区(swap) 总量,需与--memory配合使用

  • 核心规则:
    1.示例-m 300m --memory-swap=1g:物理内存300MB,swap可用700MB(1G-300M);
    2.不设置--memory-swap:默认swap为--memory的2倍(如-m 512m,swap默认1024MB);
    3.--memory-swap=-1:swap无限制(使用宿主机所有可用swap);
    4.--memory-swap=--memory:容器不可使用swap(物理内存用尽触发OOM)

2.2.2 内存限制示例命令

bash 复制代码
# 1. 限制物理内存512MB(swap默认1024MB)
docker run -itd --name memtest -m 512m centos:7 /bin/bash

# 2. 限制物理内存300MB,swap总量1GB(swap可用700MB)
docker run -itd --name memtest2 -m 300m --memory-swap=1g centos:7 /bin/bash

2.2.3 内存限制验证与OOM行为

  • 验证内存限制:
bash 复制代码
# 1. 宿主机查看容器内存限制(替换为容器ID)
cd /sys/fs/cgroup/memory/docker/<容器ID>/
cat memory.limit_in_bytes  # 输出内存限制(单位:字节,512MB=536870912字节)
cat memory.usage_in_bytes  # 输出当前内存使用量

# 2. 容器内模拟内存高负载(使用stress)
docker exec -it memtest bash
stress --vm 1 --vm-bytes 600m  # 尝试使用600MB内存(超过512MB限制)
  • OOM行为:若容器内存超过限制且无swap可用,内核会触发OOM Killer杀死容器,可通过docker logs查看日志或者 dmesg 来确认 OOM 事件。

2.3 磁盘IO(blkio/io)控制

Docker基于cgroups的blkio控制器(cgroup v1)或io控制器(cgroup v2)限制容器的磁盘读写速率和IOPS(每秒输入输出次数)。

2.3.1 常用Docker磁盘IO限制参数

参数说明表格

参数 作用 示例
--device-read-bps 限制设备读速率(单位:B/s、KB/s、MB/s) --device-read-bps /dev/sda:1M
--device-write-bps 限制设备写速率 --device-write-bps /dev/sda:1M
--device-read-iops 限制设备读IOPS(次数) --device-read-iops /dev/sda:100
--device-write-iops 限制设备写IOPS(次数) --device-write-iops /dev/sda:100

实战示例:限制容器对/dev/sda(宿主机磁盘)的写速率为1MB/s

bash 复制代码
docker run -it --name iotest --device-write-bps /dev/sda:1MB centos:7 /bin/bash

2.3.2 磁盘IO限制验证(dd测试)

通过dd命令(跳过文件系统缓存)测试写速率:

bash 复制代码
# 容器内执行dd命令(写入10个1MB的块)跳过文件系统缓存
dd if=/dev/zero of=test.out bs=1M count=10 oflag=direct

# 输出示例(写速约1MB/s,符合限制):
# 10485760 bytes (10 MB) copied, 10.0028 s, 1.0 MB/s

2.3.3 磁盘IO控制注意事项

1.限制需指定具体块设备路径(如/dev/sda),路径错误会导致限制失效;

2.云环境或虚拟化环境中,底层存储(如AWS EBS、阿里云云盘)可能有自身IO限制,容器层限制需结合底层限制配置;

3.cgroup v2环境中,IO限制参数不同(如使用--device-io-max),需参考对应Docker版本文档。

2.4 清理Docker占用的磁盘空间

Docker运行一段时间后,会积累停止的容器、未使用的镜像、网络和构建缓存,可通过以下命令清理

bash 复制代码
# 清理所有未使用的资源(停止的容器、未使用的镜像、网络、缓存)
docker system prune -a
# 注意:此命令会删除所有未活跃的资源,执行前确认无需保留!

2.5 Docker资源控制常见命令速查

bash 复制代码
# CPU相关
docker run -itd --name c1 --cpu-shares 512 centos:7  # 权重512
docker run -itd --name c2 --cpu-quota 50000 centos:7  # 50%单核
docker run -itd --name c3 --cpuset-cpus "1,3" centos:7  # 绑定核心1、3
docker run -itd --name c4 --cpus="0.5" centos:7  # 直观指定0.5核

# 内存相关
docker run -itd --name memtest -m 512m centos:7  # 512MB物理内存
docker run -itd --name memtest2 -m 300m --memory-swap=1g centos:7  # 300M+700M swap

# 磁盘IO相关
docker run -it --name iotest --device-write-bps /dev/sda:1MB centos:7  # 写速1MB/s

# 监控与验证
docker stats  # 实时监控容器资源使用
docker exec -it <容器ID> bash  # 进入容器操作
cat /sys/fs/cgroup/cpu/docker/<容器ID>/cpu.cfs_quota_us  # 查看CPU配额
cat /sys/fs/cgroup/memory/docker/<容器ID>/memory.limit_in_bytes  # 查看内存限制

# 清理资源
docker system prune -a  # 清理未使用资源

2.6 Docker资源控制常见陷阱与建议

权重vs限额:--cpu-shares是相对权重(争用时生效),--cpu-quota/--cpus是硬限额(强制限制);

cgroup版本差异:CentOS 7默认用cgroup v1,CentOS 8+或新内核可能用cgroup v2,控制器名称和参数不同(如blkio→io);

IO 限制依赖底层设备:在云/虚拟机上测试时,注意底层虚拟磁盘的行为。

生产环境监控:建议搭配Prometheus+Grafana+cAdvisor监控容器资源,及时发现资源瓶颈;

权限控制:修改/sys/fs/cgroup目录下的配置需root权限,优先使用docker run参数配置,避免直接修改系统文件。

三、Docker数据卷容器(Data Volumes Containers)

容器文件系统临时的------容器删除后,内部数据会丢失。

Docker的数据卷(Data Volumes)机制解决问题,实现数据持久化;而数据卷容器则进一步简化了多容器间的数据共享。

3.1 数据卷

数据卷是容器内的特殊目录,可与宿主机目录或其他容器共享,具备以下特性:

  • 数据持久化:容器删除后,数据卷中的数据不会丢失;
    -双向同步:宿主机与容器对数据卷的修改实时同步;
    -跨容器共享:多个容器可挂载同一个数据卷。

3.1.1 创建与挂载数据卷

通过docker run的-v或--mount参数挂载数据卷,格式:-v 宿主机目录:容器内目录。

bash 复制代码
# 挂载宿主机/var/www目录到容器内/data1目录
docker run -v /opt/www:/data1 --name web1 -it centos:7 /bin/bash
# 参数说明:
# /var/www:宿主机目录(不存在会自动创建);
# /data1:容器内目录(不存在会自动创建);
# web1:容器名称。
  • -v /var/www:/data1: 将宿主机上的 /var/www 目录挂载到容器中的 /data1 目录。

    这样容器内 /data1 的修改会同步到宿主机上的 /var/www。

  • -it centos:7 /bin/bash: 使用 centos:7 镜像启动容器并进入交互式 shell。

3.1.2 在数据卷中写入数据

进入容器后,在数据卷目录(/data1)中创建文件,数据会同步到宿主机:

bash 复制代码
# 容器内执行(写入数据到/data1/abc.txt)
echo "this is web1" > /data1/abc.txt
exit

此时,容器中的 /data1/abc.txt 文件与宿主机中的 /var/www/abc.txt 文件是同步的。即使容器退出,宿主机上的数据依然存在。

3.1.3 查看宿主机同步的数据

退出容器后,查看宿主机/var/www目录,数据已同步:

bash 复制代码
# 宿主机执行
cat /opt/www/abc.txt  # 输出:this is web1

3.2 数据卷容器

专门用于提供数据卷的容器,不运行应用程序,仅作为"数据载体",供其他容器通过--volumes-from挂载其数据卷。适用于多容器共享数据的场景(如微服务中的配置共享、日志存储)。

3.2.1 创建数据卷容器

bash 复制代码
# 创建数据卷容器web2,挂载两个数据卷/data1和/data2
docker run --name web2 -v /data1 -v /data2 -it centos:7 /bin/bash
# 说明:-v /data1 未指定宿主机目录,Docker会在宿主机/var/lib/docker/volumes/下创建匿名卷
  • --name web2: 给容器命名为 web2。
  • -v /data1 -v /data2: 在容器内部挂载了两个数据卷 /data1 和 /data2。这些数据卷不依赖于宿主机,而是仅仅存在于容器内。

3.2.2 在数据卷容器中写入数据

进入web2容器,在数据卷中写入测试数据:

bash 复制代码
# 进入web2容器
docker exec -it web2 bash

# 在/data1和/data2中写入数据
echo "this is web2" > /data1/abc.txt
echo "THIS IS WEB2" > /data2/ABC.txt

3.2.3 使用--volumes-from共享数据卷

创建新容器web3,通过--volumes-from挂载web2的数据卷:

bash 复制代码
# 创建web3,共享web2的所有数据卷
docker run -it --volumes-from web2 --name web3 centos:7 /bin/bash
# 说明:--volumes-from web2 表示继承web2的所有数据卷配置

--volumes-from web2: 这表示将容器 web2 中的所有数据卷挂载到新容器 web3 中。

3.2.4 在新容器中验证共享数据

进入web3容器,查看/data1和/data2目录,可看到web2中写入的数据:

bash 复制代码
# 进入web3容器
docker exec -it web3 bash

# 查看数据
cat /data1/abc.txt  # 输出:this is web2
cat /data2/ABC.txt  # 输出:THIS IS WEB2

3.3 数据卷与数据卷容器总结

1.数据卷 (Data Volumes):解决"容器数据持久化"问题,通过-v挂载宿主机目录;

2.数据卷容器(Data Volumes Containers):解决"多容器数据共享"问题,通过--volumes-from继承数据卷,无需每个容器都挂载宿主机目录;

3.注意:数据卷容器删除后,其数据卷(匿名卷)不会被删除,需手动清理(docker volume rm <卷ID>)。

四、Docker容器互联(使用CentOS镜像)

容器互联是指通过网络让两个或多个容器直接通信,Docker早期通过--link选项实现,适用于简单的单主机容器通信场景(复杂场景建议使用自定义网络)。

4.1 创建并运行源容器web1

首先创建"源容器"web1,作为通信的发起方:

bash 复制代码
# 启动web1容器(后台运行,随机端口映射)
docker run -itd -P --name web1 centos:7 /bin/bash
# 参数说明:
# -itd:交互式+后台运行;
# -P:随机映射端口;
# --name web1:指定容器名称(互联需依赖名称)。

4.2 创建并运行接收容器web2(--link互联)

创建"接收容器"web2,通过--link选项连接web1,格式:--link 源容器名称:源容器别名。

bash 复制代码
# 启动web2,通过--link连接web1(别名为web1)
docker run -itd -P --name web2 --link web1:web1 centos:7 /bin/bash
# 说明:--link web1:web1 表示将web1容器暴露给web2,web2中可通过"web1"这个别名访问web1。

4.3 在接收容器web2中测试连接

进入web2容器,通过ping命令测试与web1的通信(无需知道web1的Container-IP):

bash 复制代码
# 1. 进入web2容器
docker exec -it web2 bash

# 2. 测试与web1的连通性(使用别名web1)
ping web1
# 输出示例(ping通表示互联成功):
# PING web1 (172.17.0.2) 56(84) bytes of data.
# 64 bytes from web1 (172.17.0.2): icmp_seq=1 ttl=64 time=0.068 ms

4.4 Docker容器互联总结

  • 1.核心原理:--link会在接收容器的/etc/hosts文件中添加源容器的别名与Container-IP的映射,因此接收容器可通过别名通信;
  • 2.局限性:--link仅支持单主机容器互联,且不支持动态更新(源容器IP变化后,接收容器的/etc/hosts不会自动更新);
  • 3.替代方案:复杂场景(如跨主机、动态容器)建议使用Docker自定义网络(如overlay),支持DNS自动解析和动态IP更新。

源容器:通过 docker run 启动,并通过 --name 指定一个唯一名称,例如 web1 。

接收容器:通过 docker run 启动,并通过 --link 选项将其与源容器 web1 连接。 --link 会将

源容器暴露为别名,接收容器可以通过该别名与源容器进行通信。

容器间通信:接收容器可以通过源容器的名称进行通信,如在 web2 中通过 ping web1 测试与

web1 的连通性。

这种容器互联的方式适用于简单的容器间网络通信,但在较复杂的场景中,建议使用 Docker 网络(如

桥接网络或自定义网络)来管理容器间的通信。


总结

相关推荐
热爱专研AI的学妹2 小时前
Coze-AI 智能体平台:工作流如何成为智能体的 “自动化引擎”?解锁零代码落地新范式
运维·数据结构·人工智能·自动化
梦想的旅途22 小时前
从 0 到 1:构建外部群自动化的全链路监控大屏
运维·自动化
HIT_Weston2 小时前
73、【Ubuntu】【Hugo】搭建私人博客:Hugo&PaperMod 兼容问题
linux·运维·ubuntu
清平乐的技术专栏2 小时前
新电脑验机工具介绍及避坑指南
运维·电脑
xixiyuguang2 小时前
nginx tar离线安装 ubuntu22.04
运维·nginx
丁丁丁梦涛2 小时前
nginx解决域名代理到IP+端口的平台静态资源和接口地址问题
运维·tcp/ip·nginx
春日见2 小时前
如何提升手眼标定精度?
linux·运维·开发语言·数码相机·matlab
weixin_462446232 小时前
使用 Ubuntu 构建 code-server Docker 镜像的完整指南
linux·ubuntu·docker
2501_939909053 小时前
Docker(2)资源限制及数据卷容器以及容器互联
运维·docker·容器