Docker 容器操作(资源限制、数据卷容器、端口映射、容器互联)

Docker 容器资源限制(CentOS 7)

本文延续 "通俗解释 + 直接抄命令 + 多场景示例 + 验证步骤" 的风格,聚焦 Docker 容器的 CPU、内存、磁盘 IO 资源控制,补充磁盘空间清理技巧,所有操作均在 CentOS 7 测试通过,小白可直接上手实操。

1、资源限制核心说明

容器默认会共享主机所有资源(CPU、内存、磁盘 IO),若不限制,某一个容器可能耗尽主机资源导致其他服务崩溃。资源限制的核心是 "给容器划边界",Docker 通过命令行参数直接配置,无需复杂配置文件。

1.1 CPU 资源控制

CPU 资源限制的核心是 "控制容器能使用多少 CPU 核心、多大比例的计算能力",以下是 4 种常用限制方式,均配实战示例。

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

通俗解释:
  • --cpu-period:CPU 调度周期(单位:微秒,默认 100000,即 100 毫秒),相当于 "每 100 毫秒统计一次 CPU 使用情况"。
  • --cpu-quota:在一个周期内,容器最多能使用的 CPU 时间(单位:微秒)。
  • 换算公式:**CPU 使用率上限 = --cpu-quota /--cpu-period × 100%**例:period=100000,quota=50000 → 50000/100000=50%,即容器最多用 50% 的单个 CPU 核心。
示例命令:

bash

运行

复制代码
# 示例1:限制容器最多使用50%的CPU(单个核心)
docker run -d --name cpu-limit-50 \
--cpu-period 100000 \
--cpu-quota 50000 \
nginx:latest

# 示例2:限制容器最多使用1.5个CPU核心(quota=150000,period=100000)
docker run -d --name cpu-limit-1.5 \
--cpu-period 100000 \
--cpu-quota 150000 \
nginx:latest

# 示例3:限制容器最多使用2个CPU核心(quota=200000)
docker run -d --name cpu-limit-2 \
--cpu-period 100000 \
--cpu-quota 200000 \
nginx:latest

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

通俗解释:
  • 当多个容器竞争 CPU 资源时,按权重分配 CPU 时间(空闲时容器可占用全部 CPU)。
  • 默认权重是 1024,权重比例 = 容器 A 权重:容器 B 权重,例:A=2048,B=1024 → A 占用 CPU 是 B 的 2 倍。
示例命令:

bash

运行

复制代码
# 创建3个Nginx容器,权重分别为2048、1024、1024
docker run -d --name cpu-share-2 \
--cpu-shares 2048 \
nginx:latest

docker run -d --name cpu-share-1-1 \
--cpu-shares 1024 \
nginx:latest

docker run -d --name cpu-share-1-2 \
--cpu-shares 1024 \
nginx:latest
核心逻辑:

当这 3 个容器同时满负荷运行时,CPU 资源分配比例为 2:1:1(cpu-share-2 占 50%,另外两个各占 25%)。

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

通俗解释:
  • 让容器只能使用主机的指定 CPU 核心(避免容器占用关键核心,适合对性能稳定性要求高的场景)。
  • 先查看主机 CPU 核心:lscpu(CentOS 7 命令),核心编号从 0 开始(例:4 核 CPU 编号 0、1、2、3)。
示例命令:

bash

运行

复制代码
# 示例1:绑定容器到CPU核心0(只能用第1个核心)
docker run -d --name cpu-bind-0 \
--cpuset-cpus 0 \
nginx:latest

# 示例2:绑定容器到CPU核心0和2(只能用第1、3个核心)
docker run -d --name cpu-bind-0-2 \
--cpuset-cpus 0,2 \
nginx:latest

# 示例3:绑定容器到CPU核心1-3(连续核心,编号1、2、3)
docker run -d --name cpu-bind-1-3 \
--cpuset-cpus 1-3 \
nginx:latest

1.1.4 压力测试与验证示例(CPU)

前提:安装压力测试工具stress(CentOS 7 主机或容器内均可)

bash

运行

复制代码
# 主机安装stress(用于给容器施压)
yum install -y stress
测试 1:验证 CPU 使用率上限(50%)

bash

运行

复制代码
# 1. 创建限制CPU 50%的容器(用之前的cpu-limit-50,或重新创建)
docker run -it --rm --name cpu-test-50 \
--cpu-period 100000 \
--cpu-quota 50000 \
centos:7 /bin/bash

# 2. 在容器内执行压力测试(启动1个CPU密集型进程)
stress --cpu 1  # 模拟1个CPU满负荷运行

# 3. 另开一个终端,在主机查看容器CPU占用
docker stats cpu-test-50
# 观察结果:CPU使用率稳定在50%左右,不会超过上限
测试 2:验证 CPU 权重(2:1:1)

bash

运行

复制代码
# 1. 启动3个带权重的容器(用之前的cpu-share-2、cpu-share-1-1、cpu-share-1-2)
# 2. 分别进入3个容器,执行压力测试(每个容器启动1个CPU进程)
docker exec -it cpu-share-2 stress --cpu 1
docker exec -it cpu-share-1-1 stress --cpu 1
docker exec -it cpu-share-1-2 stress --cpu 1

# 3. 主机查看实时CPU占用
docker stats
# 观察结果:cpu-share-2占用≈50%,另外两个各≈25%,符合权重比例
测试 3:验证 CPU 绑定

bash

运行

复制代码
# 1. 创建绑定CPU 0的容器
docker run -it --rm --name cpu-bind-test \
--cpuset-cpus 0 \
centos:7 /bin/bash

# 2. 容器内执行压力测试
stress --cpu 1

# 3. 主机查看CPU核心占用(用top命令,按1展开核心)
top
# 观察结果:只有CPU核心0的使用率接近100%,其他核心基本空闲

1.1.5 注意事项(CPU)

  1. --cpu-shares是 "相对权重",不是绝对限制:CPU 空闲时,低权重容器也能占用全部 CPU;只有竞争时才按比例分配。
  2. --cpu-period默认 100000 微秒(100ms),一般无需修改,修改后需确保--cpu-quota ≤ --cpu-period×CPU核心数
  3. 绑定 CPU 核心(--cpuset-cpus)时,核心编号从 0 开始,需先通过lscpu确认主机核心数,避免超出范围。
  4. 多 CPU 核心场景下,--cpu-quota可超过--cpu-period(例:quota=200000,period=100000 → 支持 2 个核心满负荷)。

1.2 内存使用限制

内存限制是最常用的资源控制,避免容器耗尽主机内存导致系统崩溃,核心参数是--memory(简称-m)和--memory-swap

1.2.1 --memory 与 --memory-swap 规则

通俗解释:
  • --memory(-m):容器能使用的最大物理内存(单位:b、k、m、g,例:1g=1024m)。
  • --memory-swap:容器能使用的物理内存 + 交换分区(swap) 总大小,规则如下:
    1. 不指定--memory-swap:默认是--memory的 2 倍(例:-m 1g → swap=1g,总可用 2g)。
    2. --memory-swap = --memory:禁用 swap(容器只能用物理内存)。
    3. --memory-swap = -1:不限制 swap(容器可使用主机所有 swap 空间)。
    4. --memory-swap > --memory:总可用内存 = swap 大小(例:-m 1g --memory-swap 3g → 物理内存 1g + swap 2g)。

1.2.2 示例命令

bash

运行

复制代码
# 示例1:限制容器最大物理内存1g(默认swap=1g,总可用2g)
docker run -d --name mem-limit-1g \
-m 1g \
nginx:latest

# 示例2:限制物理内存512m,禁用swap(swap=512m,总可用=物理内存)
docker run -d --name mem-no-swap \
-m 512m \
--memory-swap 512m \
nginx:latest

# 示例3:限制物理内存1g,swap=2g(总可用3g)
docker run -d --name mem-swap-3g \
-m 1g \
--memory-swap 3g \
nginx:latest

# 示例4:限制物理内存2g,不限制swap(--memory-swap=-1)
docker run -d --name mem-unlimited-swap \
-m 2g \
--memory-swap -1 \
nginx:latest

# 示例5:限制内存+设置内存不足时的策略(OOM killer禁用,容器会阻塞而非崩溃)
docker run -d --name mem-oom-disable \
-m 512m \
--memory-swappiness 0 \  # 容器尽量不用swap
--oom-kill-disable \     # 禁用OOM杀死容器(需主机开启configurable_oom_adj)
nginx:latest

1.2.3 验证与观察

方法 1:用docker stats实时查看内存占用

bash

运行

复制代码
# 查看指定容器内存使用
docker stats mem-limit-1g

# 查看所有容器内存使用
docker stats
方法 2:进入容器查看内存状态

bash

运行

复制代码
# 进入mem-limit-1g容器
docker exec -it mem-limit-1g /bin/bash

# 容器内查看内存信息(CentOS 7容器需先安装free命令)
yum install -y procps
free -m  # 单位:MB
# 观察结果:total内存≈1024m(即1g),符合限制
方法 3:压力测试验证内存限制

bash

运行

复制代码
# 1. 创建限制内存512m的容器
docker run -it --rm --name mem-test \
-m 512m \
centos:7 /bin/bash

# 2. 容器内安装stress,执行内存压力测试(申请600m内存,超出限制)
yum install -y stress
stress --vm 1 --vm-bytes 600m  # --vm 1:1个内存进程;--vm-bytes 600m:申请600m内存

# 3. 观察结果:容器会被OOM killer杀死(或阻塞),主机查看日志
docker logs mem-test
# 日志会显示"out of memory"相关信息

1.2.4 建议与注意

  1. 必须设置内存限制:生产环境中,所有容器都应指定-m,避免单个容器耗尽主机内存。
  2. swap 设置建议:
    • 数据库、缓存类容器(如 MySQL、Redis):禁用 swap(--memory-swap=--memory),避免 swap 读写影响性能。
    • 普通应用容器:swap 可设为物理内存的 1-2 倍,留缓冲。
  3. --memory-swappiness:取值 0-100,默认 60,值越低容器越倾向于用物理内存,建议数据库容器设为 0。
  4. 内存不足时的处理:禁用 OOM killer(--oom-kill-disable)需谨慎,可能导致容器阻塞,建议结合监控工具及时扩容。

1.3 磁盘 IO(blkio /io)控制

磁盘 IO 限制用于控制容器对磁盘的读写速度,避免单个容器占用过多 IO 资源导致其他服务读写缓慢,Docker 通过--blkio-*系列参数实现。

1.3.1 常用 Docker 参数(blkio)

参数 作用 示例
--blkio-weight 磁盘 IO 权重(相对比例,默认 500,范围 10-1000) --blkio-weight 800(高权重)
--blkio-weight-device 对指定设备设置 IO 权重 --blkio-weight-device "/dev/sda:800"
--device-read-bps 限制设备最大读速度(单位:b、k、m、g) --device-read-bps "/dev/sda:100m"(读速≤100MB/s)
--device-write-bps 限制设备最大写速度 --device-write-bps "/dev/sda:50m"(写速≤50MB/s)
--device-read-iops 限制设备最大读 IOPS(每秒 IO 次数) --device-read-iops "/dev/sda:1000"
--device-write-iops 限制设备最大写 IOPS --device-write-iops "/dev/sda:500"
前提:确认主机磁盘设备名

bash

运行

复制代码
# 查看主机磁盘设备(CentOS 7)
lsblk  # 常用设备如/dev/sda、/dev/vda(云服务器)

1.3.2 验证(用 dd 测试写速)

测试 1:限制磁盘写速≤50MB/s

bash

运行

复制代码
# 1. 创建限制写速的容器(假设主机磁盘是/dev/sda)
docker run -it --rm --name blkio-test \
--device-write-bps "/dev/sda:50m" \
centos:7 /bin/bash

# 2. 容器内用dd命令测试写速度(写1个500MB的文件)
dd if=/dev/zero of=/tmp/test.img bs=100M count=5 oflag=direct
# 解释:
# if=/dev/zero:输入源(空数据)
# of=/tmp/test.img:输出文件
# bs=100M:块大小100MB
# count=5:共5块,总大小500MB
# oflag=direct:直接写磁盘,避免缓存影响测试结果

# 3. 观察输出:写速会稳定在50MB/s左右,不会超过限制
# 示例输出:5+0 records in; 5+0 records out; 524288000 bytes (524 MB) copied, 10.0012 s, 52.4 MB/s
测试 2:验证 IO 权重(2:1)

bash

运行

复制代码
# 1. 创建两个容器,IO权重分别为800和400(比例2:1)
docker run -it --rm --name blkio-weight-800 \
--blkio-weight 800 \
centos:7 /bin/bash

docker run -it --rm --name blkio-weight-400 \
--blkio-weight 400 \
centos:7 /bin/bash

# 2. 同时在两个容器内执行dd写测试(相同参数)
# 容器1(800权重):
dd if=/dev/zero of=/tmp/test1.img bs=100M count=10 oflag=direct

# 容器2(400权重):
dd if=/dev/zero of=/tmp/test2.img bs=100M count=10 oflag=direct

# 3. 观察结果:权重800的容器写速约是400的2倍

1.3.3 注意事项(blkio)

  1. 设备名必须准确:--device-write-bps等参数需指定主机实际磁盘设备(如 /dev/sda),否则限制不生效。
  2. 存储驱动兼容性:overlay2(Docker 默认存储驱动)对 blkio 参数支持较好,devicemapper 等驱动可能部分参数不生效。
  3. oflag=direct:测试时需加该参数,避免系统缓存导致测试结果不准。
  4. 权重是相对值:只有多个容器竞争磁盘 IO 时,权重才生效;空闲时,低权重容器也能满速读写。

1.4 清理 Docker 占用的磁盘空间(补充)

Docker 运行久了会产生大量无用镜像、容器、卷、日志,导致磁盘空间不足,以下是常用清理命令(小白谨慎操作,先确认无用再清理)。

1. 查看 Docker 磁盘占用情况

bash

运行

复制代码
docker system df  # 查看镜像、容器、卷、构建缓存的占用

2. 针对性清理命令

bash

运行

复制代码
# 示例1:删除所有停止的容器(最常用,安全)
docker rm $(docker ps -a -q -f status=exited)

# 示例2:删除所有未使用的镜像(无容器引用的镜像,-a表示全部)
docker image prune -a  # 执行后需输入y确认

# 示例3:删除所有未使用的卷(数据卷,谨慎!确保无重要数据)
docker volume prune  # 需输入y确认

# 示例4:删除所有未使用的网络
docker network prune

# 示例5:清理所有构建缓存(Docker 18.09+支持)
docker builder prune

# 示例6:一键清理所有未使用的资源(镜像、容器、卷、网络)
docker system prune -a  # 高危!会删除所有无容器引用的资源,谨慎使用

3. 清理 Docker 日志(单独清理)

bash

运行

复制代码
# 1. 查看容器日志大小(例:查看nginx-test容器日志)
du -sh /var/lib/docker/containers/$(docker inspect -f '{{.Id}}' nginx-test)/*.log

# 2. 清空单个容器日志(不停止容器)
truncate -s 0 /var/lib/docker/containers/$(docker inspect -f '{{.Id}}' nginx-test)/*.log

# 3. 批量清空所有容器日志
for container_id in $(docker ps -a -q); do
  truncate -s 0 /var/lib/docker/containers/$container_id/*.log 2>/dev/null
done

1.5 常见命令速查

资源类型 操作 命令示例
CPU 限制使用率 50% docker run -d --cpu-period 100000 --cpu-quota 50000 nginx
CPU 权重 2:1 docker run -d --cpu-shares 2048 nginx + docker run -d --cpu-shares 1024 nginx
CPU 绑定核心 0、2 docker run -d --cpuset-cpus 0,2 nginx
内存 限制 1g,禁用 swap docker run -d -m 1g --memory-swap 1g nginx
内存 限制 512m,swap 1g docker run -d -m 512m --memory-swap 1.5g nginx
磁盘 IO 写速≤50MB/s docker run -d --device-write-bps "/dev/sda:50m" nginx
磁盘 IO IO 权重 800 docker run -d --blkio-weight 800 nginx
清理 删除停止的容器 docker rm $(docker ps -a -q -f status=exited)
清理 删除未使用镜像 docker image prune -a

1.6 常见陷阱与建议

1. 常见陷阱

  • 陷阱 1:--cpu-shares当绝对限制用:实际是相对权重,CPU 空闲时低权重容器也能满速。
  • 陷阱 2:--memory-swap不设置:默认是--memory的 2 倍,可能导致容器使用过多 swap,影响性能。
  • 陷阱 3:磁盘 IO 限制不指定设备名:参数生效,测试时看不到限制效果。
  • 陷阱 4:清理命令误操作:docker system prune -a会删除有用的未运行镜像,建议先docker images确认。
  • 陷阱 5:内存限制太小:容器启动失败或频繁 OOM,需根据应用需求合理设置(如 MySQL 至少 1g)。

2. 实用建议

  1. 生产环境容器必设资源限制:CPU、内存是核心,磁盘 IO 按需设置(如数据库容器建议限制)。
  2. 资源限制留缓冲:如应用正常使用 512m 内存,限制设为 768m,避免峰值时 OOM。
  3. 结合监控工具:用docker stats实时查看,或部署 Prometheus+Grafana 长期监控资源使用。
  4. 定期清理磁盘:建议每周执行一次docker system prune -a(先备份重要镜像)。
  5. 避免过度限制:资源限制过严会导致应用性能下降,需根据主机配置和应用需求平衡。
  6. 测试环境验证:新容器部署前,先在测试环境用压力工具验证资源限制是否生效,再上生产。

2、数据卷容器 (Data Volumes Containers)

核心背景

容器默认的文件系统是「临时的」------ 容器删除后,内部数据会全部丢失。数据卷(Data Volume) 是宿主机的目录 / 文件,挂载到容器内,实现数据持久化;数据卷容器 是专门用来管理数据卷的容器,供其他容器共享数据(适合多容器协作场景,比如 Web 容器 + 数据库容器共享配置)。

2.1 数据卷(基础:单容器数据持久化)

2.1.1 创建与挂载数据卷
通俗解释
  • 数据卷无需提前创建,docker run -v 命令会自动创建;
  • 格式:docker run -v 宿主机路径:容器内路径 [其他参数] 镜像名(宿主机路径不存在会自动创建);
  • 也可创建「匿名数据卷」(只指定容器内路径,宿主机路径由 Docker 自动分配)。
示例命令

bash

运行

复制代码
# 示例1:挂载宿主机目录到容器(推荐,路径可控)
# 1. 宿主机创建数据目录
mkdir -p /opt/docker-data/test-volume
# 2. 启动CentOS容器,挂载该目录到容器的/opt/data
docker run -it --name volume-test \
-v /opt/docker-data/test-volume:/opt/data \
centos:7 /bin/bash

# 示例2:创建匿名数据卷(只指定容器内路径,宿主机路径自动生成)
docker run -it --name volume-anon \
-v /opt/anon-data \
centos:7 /bin/bash
2.1.2 在数据卷中写入数据

bash

运行

复制代码
# 进入volume-test容器(若已退出,先启动:docker start volume-test && docker exec -it volume-test /bin/bash)
cd /opt/data  # 容器内挂载目录
echo "Hello Docker Volume" > test.txt  # 写入数据
ls /opt/data  # 查看:能看到test.txt
exit  # 退出容器(数据不会丢失)
2.1.3 查看宿主机的数据

bash

运行

复制代码
# 示例1:查看宿主机挂载目录的内容(对应示例1的挂载)
cat /opt/docker-data/test-volume/test.txt
# 输出:Hello Docker Volume(验证数据同步)

# 示例2:查看匿名数据卷在宿主机的实际路径(关键!)
# 步骤1:查看容器的挂载信息(找到匿名卷的宿主机路径)
docker inspect volume-test | grep -A 10 "Mounts"
# 输出示例(重点看"Source"字段):
# "Mounts": [
#     {
#         "Type": "volume",
#         "Name": "7f92b1234567890abcdef",  # 匿名卷名称
#         "Source": "/var/lib/docker/volumes/7f92b1234567890abcdef/_data",  # 宿主机实际路径
#         "Destination": "/opt/anon-data",  # 容器内路径
#         ...
#     }
# ]
# 步骤2:访问宿主机路径查看数据
cat /var/lib/docker/volumes/7f92b1234567890abcdef/_data/xxx.txt  # 替换为实际文件名

2.2 数据卷容器(进阶:多容器共享数据)

2.2.1 创建数据卷容器
通俗解释

数据卷容器本身不运行业务,只挂载数据卷,供其他容器通过 --volumes-from 共享其数据卷,实现多容器数据互通。

示例命令

bash

运行

复制代码
# 创建数据卷容器(命名为data-volume-container,挂载宿主机/opt/docker-data/share到容器/opt/share-data)
docker run -it --name data-volume-container \
-v /opt/docker-data/share:/opt/share-data \
centos:7 /bin/bash
# 此时容器处于运行状态,保持终端打开(或加-d后台运行:docker run -d --name ...)
2.2.2 在数据卷容器中写入数据

bash

运行

复制代码
# 在data-volume-container容器内操作
cd /opt/share-data
echo "共享数据:Hello Multi Containers" > share.txt
ls /opt/share-data  # 看到share.txt
# 无需退出,保持容器运行(后台运行的话忽略此步)
2.2.3 使用 --volumes-from 共享数据卷

bash

运行

复制代码
# 新开终端,创建第一个共享容器web1(继承data-volume-container的数据卷)
docker run -it --name web1 \
--volumes-from data-volume-container \
centos:7 /bin/bash

# 再新开终端,创建第二个共享容器web2(同样继承)
docker run -it --name web2 \
--volumes-from data-volume-container \
centos:7 /bin/bash
2.2.4 在新容器中查看共享数据

bash

运行

复制代码
# 在web1容器内查看
cat /opt/share-data/share.txt
# 输出:共享数据:Hello Multi Containers

# 在web2容器内修改数据
echo "web2修改了共享数据" >> /opt/share-data/share.txt

# 回到data-volume-container容器查看
cat /opt/share-data/share.txt
# 输出:
# 共享数据:Hello Multi Containers
# web2修改了共享数据
# 验证:多容器数据实时同步

2.3 数据卷 / 数据卷容器总结

类型 核心优势 适用场景 注意事项
普通数据卷 数据持久化、宿主机路径可控 单容器数据持久化(如 Nginx 配置) 宿主机路径需手动管理,避免误删
匿名数据卷 无需手动创建宿主机路径 临时数据存储 宿主机路径不直观,不易管理
数据卷容器 多容器数据共享、统一管理 微服务协作(如 Web + 数据库) 数据卷容器需保持运行(或至少不删除)

3、端口映射(让外部访问容器内服务)

核心背景

容器有自己的内网 IP(默认只能宿主机访问),端口映射将「宿主机端口」和「容器端口」绑定,实现外部(如浏览器、其他服务器)访问容器内的服务(如 Nginx、MySQL)。

3.1 随机端口映射

通俗解释

Docker 自动分配宿主机的「未使用端口」映射到容器指定端口,适合测试场景(无需手动选端口)。

示例命令

bash

运行

复制代码
# 启动Nginx容器,随机映射容器80端口到宿主机随机端口(-P 大写P)
docker run -d --name nginx-random-port -P nginx:latest

# 查看映射的端口(关键!)
docker ps  # 输出中PORTS列示例:0.0.0.0:49153->80/tcp
# 解释:宿主机49153端口映射到容器80端口

# 验证访问(CentOS 7本地)
curl http://localhost:49153  # 输出Nginx默认页面HTML

3.2 指定端口映射(生产环境常用)

3.2.1 单个端口映射
格式

docker run -p 宿主机端口:容器端口 [其他参数] 镜像名

示例命令

bash

运行

复制代码
# 启动Nginx容器,宿主机8080端口映射到容器80端口
docker run -d --name nginx-fixed-port -p 8080:80 nginx:latest

# 验证访问
curl http://localhost:8080  # 或浏览器访问http://服务器IP:8080
3.2.2 多个端口映射
场景

容器内运行多个服务(如 Nginx 80 + Tomcat 8080),需映射多个端口。

示例命令

bash

运行

复制代码
# 启动Tomcat容器,同时映射8080(Tomcat)和8009(AJP)端口
docker run -d --name tomcat-multi-port \
-p 8080:8080 \
-p 8009:8009 \
tomcat:8

# 验证
curl http://localhost:8080  # 输出Tomcat默认页面
3.2.3 验证端口映射

bash

运行

复制代码
# 方法1:查看容器端口映射详情
docker inspect nginx-fixed-port | grep -A 10 "Ports"

# 方法2:宿主机查看端口监听(CentOS 7)
netstat -tnlp | grep 8080  # 输出:tcp6       0      0 :::8080                 :::*                    LISTEN      12345/docker-proxy

4、容器互联(使用 CentOS 镜像,容器间通信)

核心背景

默认情况下,同一宿主机的容器可通过「容器 IP」通信,但 IP 可能变化;Docker 的--link参数(或自定义网络)可让容器通过「容器名」通信(更稳定),以下用--link实战(CentOS 7 环境)。

4.1 创建并运行源容器 web1

bash

运行

复制代码
# 启动web1容器(后台运行,命名为web1)
docker run -d --name web1 centos:7 /bin/bash -c "while true; do echo 'Hello from web1' > /tmp/hello.txt; sleep 1; done"
# 解释:/bin/bash -c "循环命令" 让容器保持运行(否则CentOS容器启动后会立即退出)

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

bash

运行

复制代码
# 启动web2容器,通过--link互联web1(格式:--link 源容器名:别名,别名可选)
docker run -it --name web2 --link web1:web1 centos:7 /bin/bash
# 解释:--link web1:web1 表示web2可通过"web1"这个名称访问web1容器

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

bash

运行

复制代码
# 步骤1:测试DNS解析(容器名→IP,互联核心)
ping web1  # 输出:64 bytes from web1 (172.17.0.2): icmp_seq=1 ttl=64 time=0.050 ms(能ping通)

# 步骤2:访问web1的文件(需先在web1启动ssh,或用共享目录,这里用另一种方式)
# 先在宿主机查看web1的IP
docker inspect web1 | grep "IPAddress"  # 示例:"IPAddress": "172.17.0.2"

# 在web2容器内,通过IP访问web1(验证通信)
curl http://172.17.0.2  # 若web1运行了Web服务,可直接访问;这里仅验证网络连通性:
telnet 172.17.0.2 22  # 即使没开ssh,也能验证端口是否可达(无报错即网络通)

# 进阶:在web1安装httpd,web2访问其服务
# 1. 进入web1容器
docker exec -it web1 /bin/bash
# 2. 安装httpd并启动
yum install -y httpd
echo "Web1: Hello Container Link" > /var/www/html/index.html
systemctl start httpd
# 3. 回到web2容器,访问web1的80端口
curl web1  # 输出:Web1: Hello Container Link(通过容器名访问,无需IP!)

5、Docker 镜像的创建(3 种方式,Dockerfile 重点)

核心背景

默认镜像(如 centos:7、nginx:latest)可能不满足定制化需求(比如预装 Java、Nginx),需手动创建自定义镜像,3 种方式从易到难,Dockerfile 是生产环境核心。

5.1 基于现有镜像创建(手动修改 + 提交,适合临时定制)

5.1.1 启动容器并做修改

bash

运行

复制代码
# 1. 启动基础CentOS 7容器
docker run -it --name custom-centos centos:7 /bin/bash

# 2. 容器内做定制化修改(例:安装vim、wget)
yum install -y vim wget
# 验证:vim --version(能输出版本即安装成功)

# 3. 退出容器(保持修改)
exit
5.1.2 提交容器为新的镜像
格式

docker commit -m "提交说明" -a "作者信息" 容器名/容器ID 新镜像名:标签

示例命令

bash

运行

复制代码
# 提交custom-centos容器为新镜像:my-centos:v1.0
docker commit -m "CentOS 7 + vim + wget" -a "Docker小白" custom-centos my-centos:v1.0

# 验证:查看新镜像
docker images | grep my-centos  # 输出:my-centos   v1.0   1234567890ab   2 minutes ago   250MB

# 测试新镜像:启动容器,验证vim是否存在
docker run -it --rm my-centos:v1.0 vim --version  # 输出版本信息,验证成功

5.2 基于本地模板创建(导入操作系统模板,适合特殊系统)

5.2.1 下载操作系统模板

bash

运行

复制代码
# 示例:下载CentOS 7的模板文件(.tar.gz格式)
wget https://download.openvz.org/template/precreated/centos-7-x86_64-minimal.tar.gz
# 若下载慢,可替换国内镜像源(如阿里云镜像)
5.2.2 导入为 Docker 镜像
格式

docker import 模板文件.tar.gz 新镜像名:标签

示例命令

bash

运行

复制代码
# 导入模板为镜像:my-centos-template:v1.0
docker import centos-7-x86_64-minimal.tar.gz my-centos-template:v1.0

# 验证
docker images | grep my-centos-template
# 启动容器测试
docker run -it --rm my-centos-template:v1.0 /bin/bash

5.3 基于 Dockerfile 创建(重点:自动化、可复用)

5.3.1 Docker 镜像的分层结构(通俗解释)
  • Docker 镜像由「多层只读层」组成,每层对应 Dockerfile 的一条指令;
  • 容器启动时,会在镜像顶层加一层「可写层」(容器的所有修改都在这层,镜像本身只读);
  • 分层优势:复用层(比如多个镜像共享 CentOS 基础层)、减少存储空间、加速构建 / 传输。
5.3.2 Dockerfile 常用指令(每个指令配示例 + 解释)
指令 作用 示例
FROM 指定基础镜像(必须是第一条指令) FROM centos:7
MAINTAINER 指定镜像作者(可选,推荐用 LABEL 替代) LABEL maintainer="docker@example.com"
RUN 执行命令(镜像构建时运行,分层执行) RUN yum install -y nginx
COPY 复制宿主机文件 / 目录到容器内(本地文件,不能跨主机) COPY index.html /usr/share/nginx/html/
ADD 复制文件 / 目录(支持解压压缩包、下载远程文件) ADD test.tar.gz /opt/(自动解压)
WORKDIR 设置容器工作目录(后续指令都基于此目录) WORKDIR /usr/share/nginx/html
ENV 设置环境变量(容器内生效,构建时也可引用) ENV NGINX_PORT=80
EXPOSE 声明容器暴露的端口(仅声明,不映射) EXPOSE 80
CMD 容器启动时执行的命令(只能有 1 条,多则最后一条生效,可被 run 覆盖) CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT 容器启动时的入口命令(不可被 run 覆盖,适合固定启动逻辑) ENTRYPOINT ["nginx"]
实战:用 Dockerfile 构建「CentOS 7 + Nginx + 自定义页面」镜像
步骤 1:创建 Dockerfile 工作目录

bash

运行

复制代码
mkdir -p /opt/docker-build/nginx && cd /opt/docker-build/nginx
步骤 2:编写 Dockerfile(核心!)

bash

运行

复制代码
# 新建Dockerfile文件(用vim编辑)
vim Dockerfile

# 粘贴以下内容(每行带注释,小白能看懂)
# 1. 指定基础镜像
FROM centos:7

# 2. 声明作者
LABEL maintainer="docker-beginner@example.com"

# 3. 安装Nginx(CentOS 7需先装epel源)
RUN yum install -y epel-release && \
    yum install -y nginx && \
    yum clean all  # 清理yum缓存,减小镜像体积

# 4. 设置环境变量
ENV NGINX_HTML=/usr/share/nginx/html

# 5. 复制自定义页面到容器(宿主机先创建index.html)
COPY index.html $NGINX_HTML/

# 6. 声明暴露80端口
EXPOSE 80

# 7. 容器启动时启动Nginx(前台运行,避免容器退出)
CMD ["nginx", "-g", "daemon off;"]
步骤 3:创建自定义页面

bash

运行

复制代码
# 在Dockerfile同目录下创建index.html
echo "<h1>My Custom Nginx Image (Built by Dockerfile)</h1>" > index.html
步骤 4:构建镜像(核心命令:docker build)

bash

运行

复制代码
# 格式:docker build -t 镜像名:标签 构建上下文(.表示当前目录)
docker build -t my-nginx:v1.0 .

# 构建过程会输出每一步的日志,成功后提示:Successfully built 1234567890ab
步骤 5:测试自定义镜像

bash

运行

复制代码
# 启动容器,映射80端口
docker run -d --name my-nginx-test -p 80:80 my-nginx:v1.0

# 验证访问
curl http://localhost  # 输出:<h1>My Custom Nginx Image (Built by Dockerfile)</h1>
5.3.3 Dockerfile 构建注意事项(小白避坑)
  1. RUN指令尽量合并(用&&),减少镜像层数(例:RUN yum install -y a && yum install -y b);
  2. 清理缓存(如yum clean all),减小镜像体积;
  3. COPY vs ADD:优先用COPY(仅复制文件),ADD仅在需要解压 / 下载时用;
  4. CMDENTRYPOINTCMD可被docker run命令覆盖(例:docker run my-nginx:v1.0 /bin/bash会覆盖 CMD),ENTRYPOINT不可覆盖(适合固定启动逻辑);
  5. 构建上下文:docker build后的.表示「当前目录」是构建上下文,Dockerfile 中COPY/ADD只能引用上下文内的文件(不能引用../上级目录)。

5.3.4 镜像创建方式对比

创建方式 优点 缺点 适用场景
基于现有镜像提交 简单、手动修改灵活 不可复用、无构建记录、镜像大 临时定制、快速测试
基于本地模板导入 支持特殊系统模板 模板来源有限、定制化程度低 特殊操作系统镜像创建
基于 Dockerfile 自动化、可复用、易维护 需学习指令语法 生产环境、规模化部署
相关推荐
irisart2 小时前
第二章【NGINX 开源功能】—— 七层反向代理(下)
运维·nginx
prettyxian2 小时前
【linux】进程概念(2)Linux进程的生命密码:从fork到完全独立
linux·运维·服务器
Trouvaille ~2 小时前
【Linux】库制作与原理(一):静态库与动态库的制作使用
linux·运维·服务器·c语言·汇编·动静态库·编译链接
热爱专研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