当前位置: 首页 > news >正文

Docker(二)—— Docker核心功能全解析:网络、资源控制、数据卷与镜像构建实战

文章目录

  • 前言
  • 一、Docker网络管理
    • 1.1 Docker网络实现原理
    • 1.2 Docker端口映射
      • 1.2.1 随机端口映射
      • 1.2.2 指定端口映射
      • 1.2.3 Docker端口映射总结
    • 1.3 Docker的网络模式
      • 1.3.1 host模式(与宿主机共享网络栈)
      • 1.3.2 Container模式(与其他容器共享网络栈)
      • 1.3.3 无网络模式(none)
      • 1.3.4 桥接模式(bridge)
      • 1.3.5 自定义模式
      • 1.3.6 Docker网络模式总结
  • 二、Docker资源控制(Docker优化)
    • 2.1 CPU资源控制
      • 2.1.1 设置CPU使用率上限(--cpu-period / --cpu-quota)
      • 2.1.2 设置CPU占用比(权重 — --cpu-shares)
      • 2.1.3 绑定指定CPU(--cpuset-cpus)
      • 2.1.4 CPU压力测试与验证示例
      • 2.1.5 CPU资源控制注意事项
    • 2.2 内存使用限制
      • 2.2.1 --memory与--memory-swap规则
      • 2.2.2 内存限制示例命令
      • 2.2.3 内存限制验证与OOM行为
      • 2.2.4 内存限制建议与注意
    • 2.3 磁盘IO(blkio/io)控制
      • 2.3.1 常用Docker磁盘IO限制参数
      • 2.3.2 磁盘IO限制验证(dd测试)
      • 2.3.3 磁盘IO控制注意事项
    • 2.4 清理Docker占用的磁盘空间
    • 2.5 Docker资源控制常见命令速查
    • 2.6 Docker资源控制常见陷阱与建议
  • 三、Docker数据卷容器(Data Volumes Containers)
    • 3.1 数据卷
      • 3.1.1 创建与挂载数据卷
      • 3.1.2 在数据卷中写入数据
      • 3.1.3 查看宿主机同步的数据
    • 3.2 数据卷容器
      • 3.2.1 创建数据卷容器
      • 3.2.2 在数据卷容器中写入数据
      • 3.2.3 使用--volumes-from共享数据卷
      • 3.2.4 在新容器中验证共享数据
    • 3.3 数据卷与数据卷容器总结
  • 四、Docker容器互联(使用CentOS镜像)
    • 4.1 创建并运行源容器web1
    • 4.2 创建并运行接收容器web2(--link互联)
    • 4.3 在接收容器web2中测试连接
    • 4.4 Docker容器互联总结
  • 五、Docker镜像的创建
    • 5.1 基于现有镜像创建
      • 5.1.1 启动容器并进行修改
      • 5.1.2 提交容器为新镜像
    • 5.2 基于本地模板创建
      • 5.2.1 下载操作系统模板
      • 5.2.2 导入模板为Docker镜像
    • 5.3 基于Dockerfile创建(重点)
      • 5.3.1 Docker镜像的分层结构与UnionFS
      • 5.3.2 Dockerfile操作常用指令详解(重点)
      • 5.3.3 Dockerfile实战示例(构建Apache镜像)
      • 5.3.4 基于Dockerfile构建镜像
      • 5.3.5 Docker镜像分层与缓存机制解析
    • 5.4 Docker镜像创建方式总结
  • Docker 命令无法补全解决方案
  • 总结

前言

在容器化技术飞速发展的今天,Docker作为最主流的容器引擎,已经成为开发、测试和运维岗位的必备技能。但很多同学在使用Docker时,往往只停留在“拉取镜像、启动容器”的基础操作,对Docker的网络通信、资源限制、数据持久化以及镜像定制等核心功能理解不深,导致在实际项目中遇到各种“卡壳”问题。

本文将从实战角度出发,系统梳理Docker的六大核心模块:网络管理资源控制数据卷容器端口映射容器互联镜像创建,每个模块都包含原理讲解、命令示例和注意事项,帮你打通Docker使用的“任督二脉”。无论你是刚接触Docker的新手,还是需要巩固基础的开发者/运维工程师,这篇文章都能为你提供实用的指导。

一、Docker网络管理

Docker容器的网络通信是容器化应用部署的核心环节——容器之间如何通信?容器如何被外部网络访问?不同场景下该选择哪种网络模式?这些问题都需要通过Docker的网络管理机制来解决。

1.1 Docker网络实现原理

Docker的网络通信依赖于Linux桥接技术,其核心是宿主机上虚拟的docker0网桥。具体实现逻辑如下:

  1. 虚拟网桥(docker0):Docker启动时会在宿主机创建一个名为docker0的虚拟网桥,它相当于一个“虚拟交换机”,负责连接宿主机上的所有Docker容器。
  2. Container-IP分配:启动容器时,Docker会从docker0的网段(默认通常是172.17.0.0/16)中分配一个唯一的IP地址(即Container-IP)给容器,并将docker0设置为容器的默认网关。
  3. 容器间通信:同一宿主机内的所有容器都接入docker0网桥,因此容器之间可以通过各自的Container-IP直接通信(无需经过宿主机的物理网卡)。
  4. 外部网络访问限制docker0是宿主机虚拟的网络设备,并非真实的物理网卡,外部网络无法直接通过Container-IP访问容器。若需外部访问,需通过端口映射将容器端口映射到宿主机端口,再通过“宿主机IP:宿主机端口”访问容器。

1.2 Docker端口映射

容器内部的端口默认无法被外部网络访问(因docker0是虚拟网桥),需通过端口映射将容器端口映射到宿主机端口,实现外部访问。Docker支持两种端口映射方式:随机映射(-P)和指定映射(-p)

1.2.1 随机端口映射

使用-P(大写)参数,Docker会自动从32768开始分配一个未使用的宿主机端口,映射到容器暴露的端口(如Nginx的80端口)。适用于无需固定端口的场景(如测试环境)。

实战示例

# 启动Nginx容器,随机映射端口
docker run -d --name test1 -P nginx# 查看端口映射结果(重点看PORTS列)
docker ps -a
# 输出示例:
# CONTAINER ID   IMAGE  COMMAND       CREATED          PORTS                   NAMES
#6fd7a69e7883   nginx          "/docker-entrypoint.…"   15 seconds ago   Up 14 seconds               0.0.0.0:49158->80/tcp, :::49158->80/tcp   test1# 外部访问(替换为宿主机IP)
http://192.168.80.10:49158# 查看容器日志(排查访问问题)
docker logs test1  # 或使用容器ID

在这里插入图片描述

1.2.2 指定端口映射

使用-p(小写)参数,手动指定“宿主机端口:容器端口”,适用于需要固定访问端口的场景(如生产环境的Web服务)。

实战示例

# 启动Nginx容器,指定宿主机43000端口→容器80端口
docker run -d --name test2 -p 43000:80 nginx# 查看端口映射结果
docker ps -a
# 输出示例:
# CONTAINER ID   IMAGE  COMMAND       CREATED          PORTS                   NAMES
# b3369e74b2a8   nginx     "/docker-entrypoint.…"   25 seconds ago   Up 23 seconds   0.0.0.0:43000->80/tcp, :::43000->80/tcp   test2# 外部访问(固定端口43000)
http://192.168.80.10:43000# 查看容器日志(排查访问问题)
docker logs test2  # 或使用容器ID

在这里插入图片描述

1.2.3 Docker端口映射总结

映射方式参数特点适用场景
随机映射-P自动分配宿主机端口(32768+)测试环境、无需固定端口
指定映射-p 宿主机端口:容器端口手动指定端口,固定访问地址生产环境、需要固定端口的服务

注意:宿主机端口需未被占用,若端口冲突,容器启动会失败,需更换宿主机端口。

1.3 Docker的网络模式

使用docker run创建容器时,可通过--net--network参数指定容器的网络模式,不同模式对应不同的网络隔离与通信能力。Docker支持5种核心网络模式,以下逐一解析。

1.3.1 host模式(与宿主机共享网络栈)

  • 原理:类似VMware的“桥接模式”,容器不创建独立的Network Namespace(网络命名空间),而是与宿主机共享同一个网络栈。因此,容器不会虚拟自己的网卡、配置独立IP,而是直接使用宿主机的IP和端口
  • 特点:网络性能最优(无额外网络转发开销),但容器会占用宿主机的端口,存在端口冲突风险。
  • 适用场景:需要高性能网络的应用(如数据库)
  • 实战命令
    # 启动Nginx容器,使用host模式
    docker run -d --name nginx-host --network host nginx
    # 访问容器:直接通过宿主机IP(无需端口映射,容器用宿主机80端口)
    # http://宿主机IP:80
    
    在这里插入图片描述
    在这里插入图片描述

1.3.2 Container模式(与其他容器共享网络栈)

  • 原理:新创建的容器不与宿主机共享网络,而是与已存在的某个容器共享同一个Network Namespace。两个容器共享IP、端口范围,但文件系统、进程列表等其他资源仍保持隔离;可通过lo回环网卡直接通信。

  • 适用场景:需要两个容器紧密协作(如“应用容器+日志收集容器”),且希望避免端口映射的场景。

  • 实战案例

    # 1. 先创建基础容器test1-container(CentOS 7)
    docker run -itd --name test1-container centos:7 /bin/bash# 2. 查看test1-container的进程号(用于后续验证网络命名空间)
    docker inspect -f '{{.State.Pid}}' test1-container  # 输出示例:1753# 3. 查看test1-container的网络命名空间(记录net对应的编号,如4026532575)
    ls -l /proc/1753/ns
    # 输出示例:
    # lrwxrwxrwx 1 root root 0 1月   7 11:27 net -> net:[4026532504]
    

    在这里插入图片描述

    # 4. 创建test2-container,指定与test1-container共享网络
    docker run -itd --name test2-container --net=container:test1-container centos:7 /bin/bash# 5. 验证网络命名空间共享(test2-container的net编号与test1-container一致)
    docker inspect -f '{{.State.Pid}}' test2-container  # 输出示例:1844
    ls -l /proc/1844/ns
    # 输出示例:
    # lrwxrwxrwx 1 root root 0 1月   7 12:27 net -> net:[4026532504]
    

    在这里插入图片描述

1.3.3 无网络模式(none)

  • 原理:容器拥有独立的Network Namespace,但Docker不为其配置任何网络(无网卡、无IP、无路由),仅保留lo回环网卡(用于容器内部进程通信)。
  • 特点:完全封闭的网络环境,无法联网,安全性极高。
  • 适用场景:不需要网络通信的离线任务(如本地数据处理、加密计算)。
  • 实战命令
    docker run -itd --name test-none --network none centos:7 /bin/bash
    # 进入容器查看网络(仅lo网卡)
    docker exec -it test-none ip addr
    

1.3.4 桥接模式(bridge)

  • 原理:Docker的默认网络模式(不指定--net时默认使用),类似VMware的“NAT模式”。容器拥有独立的Network Namespace,并通过docker0网桥与宿主机通信,具体流程,如下:
    1. Docker启动时创建docker0虚拟网桥;
    2. 为每个容器分配Container-IP,并设置docker0的IP地址为容器的默认网关。
    3. 在主机上创建一对veth pair(虚拟网卡对)(连接两个不同的网络命名空间):一端作为容器内的eth0网卡,另一端放在主机中, 以 * 这样类似的名字命名,并将这个网络设备加入到 docker0 网桥;
    4. 通过iptablesnat表配置端口转发,实现容器与外部网络的通信。
  • 补充说明virbr0docker0的区别——virbr0是Linux虚拟化技术(如KVM、VirtualBox)创建的虚拟网桥,用于虚拟机通信;docker0仅用于Docker容器。
  • 总结:bridge网络模式中,容器运行在同一宿主机内的虚拟网桥上,可以通过容器互相通信,与宿主机网络隔离。

1.3.5 自定义模式

Docker允许用户创建自定义网络,支持三种驱动:

  • bridge:类似默认bridge模式,但增加了DNS解析(容器可通过名称通信)、网络隔离等功能。单机网络模式,适合在一台宿主机、内容器互联;
  • overlay:用于跨主机容器通信(Docker Swarm集群场景);
  • macvlan:容器像一台物理机一样直接获取宿主机的所在的网络的IP(容器像物理机一样直接连接局域网)

实战:创建自定义bridge网络并指定IP
默认bridge模式不支持手动指定Container-IP,需通过自定义网络实现:

# 1. 创建自定义bridge网络(子网172.18.0.0/16,网卡名docker1)
docker network create --subnet=172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork
# 参数说明:
# --subnet:指定网络子网;
# --opt "com.docker.network.bridge.name":指定宿主机上的网卡名(默认是br-xxx格式,不易记);
# mynetwork:自定义网络名称。# 2. 启动容器时指定自定义网络和IP
docker run -itd --name test4 --net mynetwork --ip 172.18.0.10 centos:7 /bin/bash# 3. 验证IP(进入容器查看)
docker exec -it test4 ip addr  # 应显示172.18.0.10
docker inspect test4

在这里插入图片描述
在这里插入图片描述

# 管理 Linux 桥接网络
brctl show
# 管理 Docker 容器网络
docker network ls

在这里插入图片描述

1.3.6 Docker网络模式总结

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

额外附加

  1. Overlay:这是Docker Swarm模式的网络,主要用于在多个主机上创建一个分布式网络。容器间即便在不同的主机也能完成通信,相当于在跨主机的容器之间创建了一个覆盖网络。
  2. Macvlan:Macvlan模式可以让容器直接连接到主机的物理网络,每个Macvlan接口都有一个唯一的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)。
  • 实战示例

    # 方式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。
  • 实战示例
    # 创建两个不同权重的容器
    docker run -itd --name c1 --cpu-shares 512 centos:7
    docker run -itd --name c2 --cpu-shares 1024 centos:7
    
    # 验证:在容器内运行压力测试工具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核心(硬亲和性),避免进程在不同核心间切换,提升性能稳定性。
  • 实战示例
    # 将容器绑定到宿主机第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压力测试与验证示例

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

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

    # /cpu.sh
    #!/bin/bash
    i=0
    while true; do let i++; done
    
  • 在容器内运行 ./cpu.sh,在宿主机观察 topdocker stats

    docker exec -it <container> bash
    ./cpu.sh
    
  • 分别进入容器,进行压力测试

    yum install -y epel-release
    yum install -y stress
    stress -c 4				#产生四个进程,每个进程都反复不停的计算随机数的平方根
    
  • 修改 cgroups 手工测试(示例):

    # 找到容器对应的 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资源控制注意事项

  1. --cpu-shares权重,非硬限制(CPU空闲时,容器可使用超过权重的资源);
  2. --cpu-quota/--cpus硬限制,容器无法突破设定的CPU上限(quota = -1 表示无限制);
  3. --cpuset-cpus适合对性能稳定性要求高的场景(避免与其他进程抢核)(如数据库容器)。
  4. 在多核宿主机上理解 quota/period 的含义(单位是 “相对于 1 个 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 内存限制示例命令

# 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行为

  • 验证内存限制

    # 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.2.4 内存限制建议与注意

  1. 生产环境必须为容器设置内存限制,避免单个容器把宿主机内存耗尽;
  2. 内存敏感型应用(如Redis、MySQL)建议禁用swap(--memory-swap=--memory),避免swap导致性能下降;
  3. 配合容器健康检查和重启策略(如--restart=on-failure),应对OOM后的容器恢复。
  4. 在 cgroup v2 环境下内存控制文件名/行为可能与 v1 略有不同(检查 /sys/fs/cgroup 结构)。

2.3 磁盘IO(blkio/io)控制

Docker基于cgroupsblkio控制器(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

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

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

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

# 容器内执行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运行一段时间后,会积累停止的容器、未使用的镜像、网络和构建缓存,可通过以下命令清理:

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

在这里插入图片描述

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

# 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资源控制常见陷阱与建议

  1. 权重vs限额--cpu-shares是相对权重(争用时生效),--cpu-quota/--cpus是硬限额(强制限制);
  2. cgroup版本差异:CentOS 7默认用cgroup v1,CentOS 8+或新内核可能用cgroup v2,控制器名称和参数不同(如blkio→io);
  3. IO 限制依赖底层设备:在云/虚拟机上测试时,注意底层虚拟磁盘的行为。
  4. 生产环境监控:建议搭配Prometheus+Grafana+cAdvisor监控容器资源,及时发现资源瓶颈;
  5. 权限控制:修改/sys/fs/cgroup目录下的配置需root权限,优先使用docker run参数配置,避免直接修改系统文件。

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

容器的文件系统是临时的——容器删除后,内部数据会丢失。Docker的数据卷(Data Volumes)机制解决了这一问题,实现数据持久化;而数据卷容器则进一步简化了多容器间的数据共享。

3.1 数据卷

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

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

3.1.1 创建与挂载数据卷

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

# 挂载宿主机/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
  • --name web1: 给容器指定一个名称 web1
  • -it centos:7 /bin/bash: 使用 centos:7 镜像启动容器并进入交互式 shell。

在这里插入图片描述

3.1.2 在数据卷中写入数据

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

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

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

3.1.3 查看宿主机同步的数据

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

# 宿主机执行
cat /opt/www/abc.txt  # 输出:this is web1

在这里插入图片描述

3.2 数据卷容器

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

3.2.1 创建数据卷容器

# 创建数据卷容器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容器,在数据卷中写入测试数据:

# 进入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的数据卷:

# 创建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中写入的数据:

# 进入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,作为通信的发起方:

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

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

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

# 启动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的通信(无需知道web1Container-IP):

# 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镜像的创建

Docker镜像是容器的“模板”,包含容器运行所需的程序、库、配置等。创建Docker镜像主要有三种方式:基于现有容器创建基于本地模板创建基于Dockerfile创建(最常用、最灵活)。

5.1 基于现有镜像创建

该方式是“先修改容器,再将修改后的容器提交为新镜像”,适用于快速定制简单镜像。

5.1.1 启动容器并进行修改

# 1. 启动一个CentOS 7容器(交互式)
docker create -it --name mycentos centos:7 /bin/bash  # 创建容器
docker start <容器ID>  # 启动容器
docker exec -it <容器ID> bash  # 进入容器# 2. 修改容器内部的环境(例如安装软件包、修改配置文件等),然后退出容器
# 安装OpenJDK 8
yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel
# 验证java版本
java-version
yum clean all

5.1.2 提交容器为新镜像

使用docker commit命令将修改后的容器提交为新镜像,格式:docker commit -m "提交说明" -a "作者" 容器ID 新镜像名:标签

# 提交容器(容器ID替换为实际ID)
docker commit -m "openjdk8" -a "simon" 1450d38ffda5 openjdk:8# 查看新镜像
docker images
# 输出示例:
# REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
# openjdk      8         4ee649b7cf2b   5 seconds ago   469MB

在这里插入图片描述

5.2 基于本地模板创建

通过导入现成的操作系统模板(如OpenVZ模板)创建镜像,适用于快速获取特定系统环境的场景。

5.2.1 下载操作系统模板

从OpenVZ官网下载模板(以Debian 7为例):

# 使用wget下载模板
wget http://download.openvz.org/template/precreated/debian-7.0-x86-minimal.tar.gz
# 或使用curl下载
curl -L http://download.openvz.org/template/precreated/debian-7.0-x86-minimal.tar.gz -o debian-7.tar.gz

5.2.2 导入模板为Docker镜像

使用docker import命令导入模板:

# 将模板文件导入为镜像(镜像名debian:test)
cat debian-7.0-x86-minimal.tar.gz | docker import - debian:test# 查看镜像
docker images
# 输出示例:
# REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
# debian       test      5120c6b1c973   4 seconds ago   215MB

在这里插入图片描述

5.3 基于Dockerfile创建(重点)

Dockerfile是一个包含一系列指令的文本文件,每条指令对应镜像的一层,通过docker build命令自动构建镜像。这种方式支持自动化、可重复构建,是生产环境中创建镜像的首选方式。

5.3.1 Docker镜像的分层结构与UnionFS

Docker镜像基于UnionFS(联合文件系统) 构建,具有以下特点:

  • 分层存储:每一条Dockerfile指令生成一层镜像,层与层之间相互独立;
  • 只读特性:所有镜像层都是只读的,容器启动时会在镜像层之上添加一层“可读写层”(容器层);
  • 缓存机制:Docker会缓存已构建的镜像层,若指令或文件未变化,直接复用缓存,加速构建。

为什么Docker中的CentOS镜像只有200MB左右?
传统CentOS系统镜像约4GB,而Docker镜像仅保留rootfs(根文件系统,包含/bin/etc等核心目录),共享宿主机的bootfs(引导文件系统,包含内核),因此体积大幅缩小。

5.3.2 Dockerfile操作常用指令详解(重点)

Dockerfile指令按功能可分为基础镜像指令镜像操作指令容器启动指令等,以下是常用指令:

  1. FROM
    指定新镜像基于的基础镜像,Dockerfile 的第一条指令必须为 FROM

    FROM centos:7
    
  2. MAINTAINER
    指定镜像的维护者信息:

    MAINTAINER "Simon Cai <simoncwh@example.com>" 
    
  3. RUN
    执行命令并将结果提交到镜像中。常用来安装软件包、修改配置等。

    RUN yum install -y httpd
    
  4. ENTRYPOINT
    设置容器启动时默认执行的命令(不可被覆盖,优先级高于CMD):

    ENTRYPOINT ["httpd", "-D", "FOREGROUND"]
    
  5. CMD
    容器启动时执行的默认命令。CMD 指令会被 docker run 命令后指定的命令覆盖。

    CMD ["httpd", "-D", "FOREGROUND"]
    
  6. EXPOSE
    声明容器内的端口(仅文档说明,不实际映射):

    EXPOSE 80
    
  7. ENV
    设置环境变量(容器内可使用):

    ENV MY_VAR=my_value
    
  8. ADD
    将文件或目录从宿主机复制到镜像中,支持从 URL 下载文件,并能自动解压归档文件:

    ADD myfile.tar.gz /app
    
  9. COPY
    将本地文件或目录复制到镜像中(仅本地文件,无解压):

    COPY . /app
    
  10. VOLUME
    声明容器内的挂载点(创建匿名卷):

    VOLUME ["/data"]
    
  11. USER
    设置容器内运行命令时的用户:

    USER root
    
  12. WORKDIR
    设置后续指令的工作目录(类似cd):

    WORKDIR /app
    
  13. ONBUILD
    设置当该镜像作为基础镜像时,后续 Dockerfile 执行的命令:

    ONBUILD RUN echo "Building from base image"
    
  14. HEALTHCHECK
    设置容器的健康检查:

    HEALTHCHECK CMD curl --fail http://localhost:8080 || exit 1
    

关键指令区别

  • RUN vs CMD vs ENTRYPOINT
    • RUN:构建镜像时执行(如安装软件);
    • CMD:容器启动时执行,可被docker run后的命令覆盖(如docker run xxx bash会覆盖CMD);
    • ENTRYPOINT:容器启动时执行,不可被覆盖,若需传参需用docker run --entrypoint
  • ADD vs COPY
    • ADD支持URL下载和自动解压(如.tar.gz),功能更丰富;
    • COPY仅复制本地文件,功能简单,推荐优先使用(避免意外解压)。

5.3.3 Dockerfile实战示例(构建Apache镜像)

以构建一个基于CentOS 7的Apache(httpd)镜像为例,完整流程如下:

  1. 创建工作目录
mkdir -p /opt/apache && cd /opt/apache
  1. 编写Dockerfile
vim Dockerfile
#基于的基础镜像
FROM centos:7
#维护镜像的用户信息
MAINTAINER this is apache image <cwh>
#镜像操作指令安装apache软件,需提前准备国内源文件
ADD CentOS-Base.repo /etc/yum.repos.d/
RUN yum clean all
#RUN yum -y update
RUN yum -y install httpd
#开启 80 端口
EXPOSE 80
#复制网站首页文件
ADD index.html /var/www/html/index.html//方法一:
#将执行脚本复制到镜像中
ADD run.sh /opt/run.sh
#启动容器时执行脚本
CMD sh /opt/run.sh//方法二:
ENTRYPOINT [ "/usr/sbin/apachectl" ]
CMD ["-D", "FOREGROUND"]//方法三
# 启动 httpd 服务
CMD ["/usr/sbin/httpd", "-D", "FOREGROUND"]
准备执行脚本(方式一)
vim run.sh
#!/bin/bash
rm -rf /run/httpd/*							#清理httpd的缓存
/usr/sbin/apachectl -D FOREGROUND			#指定为前台运行
#因为Docker容器仅在它的1号进程(PID为1)运行时,会保持运行。如果1号进程退出了,Docker容器也就退出了。# 准备网站页面
echo "this is test web" > index.html

在这里插入图片描述

5.3.4 基于Dockerfile构建镜像

使用docker build命令构建镜像,格式:docker build -t 镜像名:标签 构建上下文路径.表示当前目录为构建上下文)。

# 构建镜像(镜像名httpd:centos,标签centos)注意末尾的.
docker build -t httpd:centos ./# 查看构建的镜像
docker images
# 输出示例:
# REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
# httpd        centos    9e154b3b93e6   8 seconds ago    493MB
# 新镜像运行容器
docker run -d -p 1216:80 httpd:centos# 测试
http://192.168.10.14:1216/

在这里插入图片描述
在这里插入图片描述

5.3.5 Docker镜像分层与缓存机制解析

  • 分层机制:Dockerfile中的每条指令对应一层镜像,例如:
    1. FROM centos:7 → 基础层;
    2. RUN yum install -y httpd → 安装层;
    3. COPY index.html /var/www/html/ → 复制层。
  • 缓存机制
    • 若Dockerfile指令未变化,且依赖的文件(如index.html)未修改,Docker会复用缓存层;
    • 若某一层指令或文件变化,该层及之后的所有层都会重新构建(缓存失效)。
  • 镜像层是不可变的
    • 删除容器时只会删除其上面的读写层,底层的镜像层不会丢失。
  • 优化建议
    1. 频繁变化的指令(如COPY)放在Dockerfile末尾,减少重新构建的层数;
    2. 合并RUN指令(用&&连接),减少镜像层数(如合并yum installyum clean);
    3. 使用.dockerignore文件排除不需要的文件(如node_modules、日志文件),减小构建上下文体积。

5.4 Docker镜像创建方式总结

  • 基于现有镜像创建:通过修改容器并提交为新的镜像。
  • 基于本地模板创建:从模板文件导入创建镜像。
  • 基于 Dockerfile 创建:通过编写 Dockerfile 来定制镜像,支持自动化构建。

Docker 命令无法补全解决方案

  1. 首先安装 bash-completion 包:
yum install -y bash-completion
  1. 重新加载 bash 配置使补全生效:
source /etc/profile.d/bash_completion.sh
  1. 之后测试 Docker 命令补全是否正常工作:
docker run --cpu-  # 按Tab键应该会显示补全选项

总结

本文系统梳理了Docker的六大核心功能:网络管理、资源控制、数据卷容器、端口映射、容器互联和镜像创建,每个模块都从“原理+实战”角度出发,提供了可直接复用的命令和配置示例。

Docker的核心价值在于“隔离”与“标准化”——通过网络隔离实现容器间通信控制,通过资源限制避免宿主机资源耗尽,通过数据卷实现数据持久化,通过Dockerfile实现镜像的标准化构建。这些功能看似独立,实则相辅相成,共同构成了Docker容器化应用的基础。

建议大家在学习过程中“边学边练”:每掌握一个知识点,就动手执行命令验证效果(如创建自定义网络、设置CPU限制、编写Dockerfile),只有通过实战才能真正理解Docker的底层逻辑。后续我还会分享Docker Compose、Docker Swarm等容器编排工具的使用,欢迎持续关注!

http://www.dtcms.com/a/415875.html

相关文章:

  • 百度网站大全首页网站源码免费下载
  • 网站的策划建设方案书负面信息网站
  • 绍兴网站建设方案推广微信公众平台绑定网站
  • 计算机网路-TCP
  • 做网站用哪个预装系统源码建站之网站建设
  • Hadoop完全分布式配置
  • 实用主义观点下的函数式编程思想
  • 服务器及网站建设的特点温州品牌网站建设
  • H618-开发板运行第一个Hello World
  • 青岛网站建设市场分析安徽龙山建设网站
  • 珠海网站建设王道下拉惠太原网站seo外包
  • 门户网站怎么做seo乐清网站
  • 贪心:保卫花园
  • 东莞专业微网站建设价格哪个浏览器可以进wordpress
  • HashMap和Hashtable
  • 做个网站得花多少钱建成区违法建设治理网站
  • 革新深层水平位移监测——安锐科技推出全新节段式位移计,以模块化设计显著降低成本
  • 赣州企业网站在那做网站域名的管理密码如何索取
  • 网站建设与管理大纲天津科技公司网站
  • 网站开发与维护是什么企业网站需要什么功能
  • 【有源码】基于python+spark的餐饮外卖平台综合分析系统-基于Hadoop生态的外卖平台数据治理与分析系统
  • 【心力建设】《毛选》里的心法
  • 浙江网站建设有哪些合肥seo排名优化
  • 如何制作课程网站模板用python做网站的步骤
  • 光纤测温技术:原理与应用全解析
  • ICICLE-Snark:目前最快的 Groth16 实现
  • 做网站建设的公司seo优化网站推广
  • 网站原型设计和版式设计湖南手机版建站系统开发
  • 黔南网站建设做网站多大上行速度
  • m 外贸网站阿里巴巴可以做公司网站吗