提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 二、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 网络(如
桥接网络或自定义网络)来管理容器间的通信。