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 自动化、可复用、易维护 需学习指令语法 生产环境、规模化部署
相关推荐
木子.李3471 天前
ssh连接远程服务器相关总结
运维·服务器·ssh
晚风吹人醒.1 天前
SSH远程管理及访问控制
linux·运维·ssh·scp·xshell·访问控制·远程管理
DigitalOcean1 天前
DigitalOcean容器注册表推出多注册表支持功能
容器
necessary6531 天前
使用Clion查看linux环境中的PG源码
linux·运维·服务器
江湖有缘1 天前
Jump个人仪表盘Docker化部署教程:从0到 搭建专属导航页
运维·docker·容器
Lam㊣1 天前
Centos 7 系统docker:更换镜像源
linux·docker·centos
FL16238631291 天前
win11+WSL+Ubuntu-xrdp+远程桌面闪退+黑屏闪退解决
linux·运维·ubuntu
挖土机_0081 天前
Kubernetes 1.35 原地扩容(In-Place Pod Resize)完整解析:机制、差异与实战示例
docker·kubernetes
AOwhisky1 天前
Linux逻辑卷管理:从“固定隔间”到“弹性存储池”的智慧
linux·运维·服务器
05大叔1 天前
大事件Day02
运维·服务器