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 网络(如

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


总结

相关推荐
路由侠内网穿透.11 小时前
fnOS 飞牛云 NAS 本地部署私人影视库 MoonTV 并实现外部访问
运维·服务器·网络·数据库·网络协议
直饮水观察哨11 小时前
商用净水器亲测对比,哪个更专业?
容器
Doro再努力11 小时前
【Linux05】Linux权限管理深度解析(二)
linux·运维·服务器
Gofarlic_oms112 小时前
通过Kisssoft API接口实现许可证管理自动化集成
大数据·运维·人工智能·分布式·架构·自动化
Suchadar12 小时前
Docker基础命令(二)——数据卷管理端口映射与容器互联
运维·docker·容器
firstacui12 小时前
Docker容器网络管理与容器数据卷管理
运维·docker·容器
江畔何人初13 小时前
/etc/profile,.profile,.bashrc三者区分
linux·运维·云原生
codeRichLife14 小时前
docker拷贝,导入/导出等常用命令
docker
会飞的土拨鼠呀14 小时前
Ubuntu系统缺少 iptables 工具
linux·运维·ubuntu
前端玖耀里14 小时前
详细介绍Linux命令dig和nslookup
linux·运维·服务器