🌈 个人主页:Zfox_
🔥 系列专栏:Docker

一:🔥 网络概述

🦋 为什么需要 Docker 网络管理?

Docker 容器默认运行在 隔离的网络命名空间(Network Namespace) 中,彼此之间、与宿主机、与外部世界 默认无法通信。然而,真实业务场景中存在大量网络交互需求:

场景问题需求
多容器协作Web 容器如何连接 MySQL 容器?容器间通信
外部访问服务如何让浏览器访问容器中的 Nginx?容器对外暴露服务
容器与宿主机交互宿主机脚本如何调用容器 API?容器 ↔ 宿主机通信
安全隔离某些容器(如日志收集器)不需要网络完全禁用网络
定制拓扑需要模拟多子网、VLAN 或集群网络高级网络定制
性能优化高频通信场景(如微服务)需低延迟绕过 NAT,直连网络

结论:Docker 网络管理的核心目标是——在“隔离”与“连通”之间取得平衡,按需提供通信能力,同时保障安全与性能。

🦋 Docker 网络架构

Docker 容器网络是为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作系统的网络环境中独立出来,形成容器自有的网络设备、IP 协议栈、端口套接字、IP路由表、防火墙等等与网络相关的模块。

Docker 为实现容器网络,主要采用的架构由三部分组成:CNM、Libnetwork 和驱动。

2.1 CNM

Docker 网络架构采用的设计规范是 CNM(Container Network Model),其是 Docker 官方提出的容器网络抽象模型,定义了三个核心组件:

组件作用类比
Sandbox容器的完整虚拟网络栈
(含 IP、路由表、DNS、防火墙、网络接口等)
容器的“网络操作系统”
Endpoint虚拟网络接口,用于接入网络
一个 Endpoint 只能属于一个 Network
容器可有多个 Endpoint(接入多个网络)
容器的“网卡”
Network虚拟子网,同一 Network 内的容器可直接通信
不同 Network 默认隔离(除非配置路由)
容器的“局域网”

📌 关键理解

  • 容器通过 Endpoint 加入 Network
  • Sandbox 封装了整个网络环境,实现与宿主机隔离;
  • 容器跨网络通信需多 Endpoint网关/路由

CNM 架构示意图

  • 如上图所示,容器 B 有两个 Endpoint 并且分别接入 Networkd A 和 Network B。
  • 那么容器 A 和容器 B 之间是可以实现通信的,因为都接入了 NetworkA。
  • 但是容器 A 和容器 C 不可以通过容器 B 的两个 Endpoint 通信 ——Endpoint 仅用于接入,不具备路由器功能。
2.2 Libnetwork
  • 由 Docker 官方用 Go 语言开发的开源库,是 CNM 的一个标准实现
  • dockerd(Docker Daemon)的核心网络模块
  • 实现了 CNM 全部组件,并扩展了:
    • 本地服务发现(基于 DNS)
    • Ingress 负载均衡(Swarm 模式)
    • 网络控制面与管理面

💡 Libnetwork 是 Docker 支持多种网络驱动的统一接口层


2.3 网络驱动(Drivers)

驱动负责实际创建网络设备、配置路由、实现隔离数据层相关内容)等底层操作。Docker 支持多种内置及第三方驱动:

驱动类型说明适用场景
bridge创建 Linux 网桥(docker0),默认驱动单机多容器通信
host容器共享宿主机网络命名空间高性能、无 NAT 场景
overlay基于 VXLAN 实现跨主机虚拟网络Docker Swarm 集群
macvlan为容器分配真实 MAC 地址,直连物理网络需要容器像物理机一样接入网络
ipvlan类似 Macvlan,但共享宿主机 MAC,更节省资源大规模容器部署
none不配置任何网络完全隔离的容器(如离线计算)
第三方驱动Calico、Flannel、Weave 等Kubernetes 或高级 CNI 场景

🌐 驱动 = 网络能力的“插件”,Libnetwork 调用驱动创建资源。

🦋 Docker 常见网络模式

3.1 Bridge 网络(默认模式)
  • 原理

    • Docker 启动时自动创建 docker0 网桥(ip addr show docker0 可查看);
    • 每个容器启动时分配虚拟网卡 veth,一端在容器内(eth0),一端挂到 docker0
    • 容器 IP 默认为 172.17.0.0/16(可自定义子网)。
  • 通信方式

    • 容器 ↔ 容器:同 bridge 网络内,通过 IP 或容器名(Docker 内置 DNS)直接通信;
    • 容器 ↔ 外部:通过 iptables SNAT/DNAT 实现端口映射(-p 8080:80);
    • 外部 ↔ 容器:访问 宿主机IP:8080 → 被转发到容器 80 端口。
  • 优点:隔离性好、配置简单

  • 缺点:跨主机通信需额外方案(如 overlay)

🛠 自定义 bridge 网络(推荐)

docker network create --driver bridge --subnet=172.20.0.0/16 mynet
docker run --network mynet --name web nginx
docker run --network mynet --name db mysql
# web 可直接 ping db
3.2 Host 网络模式
  • 原理:容器不创建 Network Namespace,直接使用宿主机的网络栈;

  • 表现

    • 容器内 ip addr 与宿主机完全一致;
    • 无 NAT、无端口映射,性能最高
    • 容器端口直接占用宿主机端口(如 nginx 监听 80,宿主机 80 就被占)。
  • 适用场景

    • 网络性能敏感(如高性能代理、监控 agent);
    • 需要使用特殊协议(如 raw socket、ICMP)。
  • ⚠️ 风险

    • 端口冲突风险高;
    • 安全隔离弱(网络层面无隔离)。
docker run --network host nginx  # 宿主机 80 端口直接被占用
3.3 Container 网络模式
  • 原理:新容器共享另一个容器的 Network Namespace

  • 表现

    • 两者 IP、端口、网络接口完全一致;
    • 进程可通过 lo(127.0.0.1)互相访问;
    • 文件系统、进程、用户等仍隔离。
  • 典型用途

    • Sidecar 模式:主容器(App) + 监控容器(共享网络,采集 metrics);
    • 调试:运行 netshoot 容器共享目标容器网络,进行 tcpdumpdig 等操作。
docker run -d --name app nginx
docker run -it --network container:app nicolaka/netshoot  # 进入后可直接 curl localhost
3.4 None 网络模式
  • 原理:容器有 Network Namespace,但不配置任何网络设备

  • 表现

    • 容器内只有 lo 接口(127.0.0.1);
    • 无法访问外部,也无法被访问;
    • 完全网络隔离。
  • 适用场景

    • 离线计算任务(如加密、批处理);
    • 安全要求极高的沙箱环境。
docker run --network none alpine ip addr  # 只显示 lo
3.5 Overlay 网络(跨主机通信)
  • 前提:必须使用 Docker Swarm 模式docker swarm init);
  • 原理
    • 基于 VXLAN 封装,实现跨主机 L2 网络;
    • 所有加入 Swarm 的节点自动建立 overlay 网络;
    • 服务发现、负载均衡由 Docker 内置 DNS 和 Ingress 实现。

image.png

  • 特点
    • 容器 IP 在整个集群唯一;
    • 支持加密(--opt encrypted);
    • 服务可通过服务名跨主机访问。
# Swarm manager 上
docker network create --driver overlay my-overlay
docker service create --network my-overlay --name web nginx

🌐 注意:Overlay 不适用于单机 docker run,仅用于 Swarm 服务。

🦋 Docker 默认网络设备:docker0

  • 安装 Docker 时自动创建的 Linux 网桥(bridge)
  • 默认子网:172.17.0.0/16
  • 所有使用默认 bridge 网络的容器都连接到 docker0
  • 宿主机通过 iptables 规则实现:
    • SNAT:容器访问外网(源地址转为宿主机 IP);
    • DNAT:外部访问容器(通过 -p 映射的端口)。
# 查看 docker0
ip addr show docker0

# 查看 NAT 规则
iptables -t nat -L -n
应用场景
场景推荐方案
单机多容器通信自定义 bridge 网络(避免用默认 bridge)
高性能/无 NAThost 网络(慎用)
跨主机容器通信Docker Swarm + overlay 或 Kubernetes + CNI
调试网络问题container 模式 + nicolaka/netshoot 镜像
完全隔离none 网络
暴露服务给外部-p 端口映射(bridge 模式)或 host 模式
避免端口冲突使用自定义 bridge + 服务发现(容器名解析)

二:🔥 网络管理命令

命令别名功能
docker network create创建网络
docker network connect连接网络
docker network disconnect断开网络
docker network lsdocker network list列出网络
docker network prune删除不使用的网络
docker network inspect查看网络详情
docker network rmdocker network remove删除 1 个或者多个网络

1. docker network create

语法

docker network create [OPTIONS] NETWORK

参数

  • -d, --driver:网络驱动
  • --gateway:网关地址
  • --subnet:子网
  • --ipv6:启用 IPv6

示例

docker network create mynet1 --subnet=192.168.0.0/16

image-20251227215804350

2. docker network inspect

语法

docker network inspect [OPTIONS] NETWORK [NETWORK...]

参数

  • -f, --format:指定格式

示例一:查看网络详情

lighthouse@VM-8-10-ubuntu:~$ docker network inspect mynet1
[
    {
        "Name": "mynet1",
        "Id": "a7fc6cfd6af30956770df68c7fecce2cd3b8290fa3bdc44d9b090e884d60d450",
        "Created": "2025-12-27T21:56:46.812639142+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv4": true,
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

示例二:查看容器相关的网络信息

docker network inspect bridge

image-20251227215944435

3. docker network connect

语法

docker network connect [OPTIONS] NETWORK CONTAINER

参数

  • --ip:指定 IP 地址
  • --ip6:指定 IPv6 地址

示例

① 创建一个桥接网络 和 busybox 容器

# 创建桥接网络
lighthouse@VM-8-10-ubuntu:~$ docker network create mynet2 --subnet=10.2.0.0/16
88b986f876c0f55ca621966ff7b3a6fb26ae19fb19c46e2585a7a74816a4f2e1

# 创建 busybox 容器
lighthouse@VM-8-10-ubuntu:~$ docker run -dit --name busybox1 busybox:1.35.0
8050d5670d6c7ffa00236a15f0631ef33f4026a83e2831ff54a3423382a68b15

② 进入到busybox进行网段的查看

docker exec -it busybox1 sh

ifconfig

image-20251227220704792

③ 进行网络和容器的链接操作

docker network connect mynet2 busybox1

ifconfig

image-20251227220849926

可以发现多了一个eth1,我们往这个容器中加入了mynet2网络了

④ 我们可以查看下这个网络的具体信息

docker network inspect mynet2

image-20251227221015401

此时就可以看到这个网络连接的容器了

4. docker network disconnect

语法

docker network disconnect [OPTIONS] NETWORK CONTAINER

参数

  • -f:强制退出

示例:在上面的操作中,我们将mynet2这个网络添加到了容器busybox中了,现在把 mynet2 踢出该容器

docker network disconnect mynet2 busybox1

指定网络和容器名称即可,再次进入到容器中查看

docker exec -it busybox1 sh

ifconfig

image-20251227221226664

可以看到我们之前链接的网段消失了,并且我们对网络数据进行查看操作,也可以发现没有连接了,如下:

image-20251227221318562

5. docker network prune

作用:删除不使用的网络

语法

docker network prune [OPTIONS]

参数

  • -f, --force:不提示

示例

docker network prune

image-20251227221419392

6. docker network rm

作用:删除网络

语法

docker network rm NETWORK [NETWORK...]

参数

  • -f:强制退出

示例

docker network rm mynet

注意:与容器连接的网络无法直接删除(因为此时这个网络有容器)

7. docker network ls

作用:列出网络

语法

docker network ls [OPTIONS]

参数

  • -f, --filter:指定过滤条件
  • --format:指定格式
  • --no-trunc:不截断
  • -q, --quiet:仅仅显示 id

示例

lighthouse@VM-8-10-ubuntu:~$ docker network ls
NETWORK ID     NAME                  DRIVER    SCOPE
160d83476f8b   bridge                bridge    local
87c6f08d6a64   host                  host      local
9c17335e3703   none                  null      local
77056c935362   redis-cluster_mynet   bridge    local
e85c16584ecb   redis-data_default    bridge    local

8. 示例操作

演示:两种网络加入当时以及差异

① 创建网络并制定IP地址段

docker network create mynet --subnet=10.15.0.0/16

② 用两种方式创建两个容器,创建容器1,并且加入网络

# 创建容器一, 加入该网络
docker run -itd --network mynet --name busybox1 busybox:1.35.0
lighthouse@VM-8-10-ubuntu:~$ docker run -itd --network mynet --name busybox1 busybox:1.35.0
52fd14804e54471394fdbc6020161a7aa3672adb23329cccf7a4e568825b5261

# 检查容器一是否与网络连接成功
lighthouse@VM-8-10-ubuntu:~$ docker inspect mynet
[
    {
        "Name": "mynet",
        "Id": "696ecb0824afbed44d94c36c6b390c3f96e8b332156b95ee510f692d7df23186",
        "Created": "2025-12-27T22:21:35.162020943+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv4": true,
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "10.15.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "52fd14804e54471394fdbc6020161a7aa3672adb23329cccf7a4e568825b5261": {
                "Name": "busybox1",
                "EndpointID": "ff79731fd8c29d583a0090779d3913ee912714fd342876ff74d2143d5faf4d67",
                "MacAddress": "6e:fb:07:f4:f4:25",
                "IPv4Address": "10.15.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

# 查看容器配置
lighthouse@VM-8-10-ubuntu:~$ docker inspect mynet
[
	# .....
            "Networks": {
                "mynet": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "MacAddress": "6e:fb:07:f4:f4:25",
                    "DriverOpts": null,
                    "GwPriority": 0,
                    "NetworkID": "696ecb0824afbed44d94c36c6b390c3f96e8b332156b95ee510f692d7df23186",
                    "EndpointID": "ff79731fd8c29d583a0090779d3913ee912714fd342876ff74d2143d5faf4d67",
                    "Gateway": "10.15.0.1",
                    "IPAddress": "10.15.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "DNSNames": [
                        "busybox1",
                        "52fd14804e54"
                    ]
                }
            }
        }
    }
]

可以看到我们这里显示的是 mynet 网络

③ 创建容器二:不加入创建的网络

docker run -itd --name busybox2 busybox:1.35.0
lighthouse@VM-8-10-ubuntu:~$ docker run -itd --name busybox2 busybox:1.35.0
465a54f61a2f3e40e6cdf71a2d6cdc778f432c7be5199889541df715ab7c02c1

查看配置

docker inspect busybox2

image-20251227224429215

可以看到我们这里显示的是bridge网络,因此可以得到一个结论:

  • 不指定网络进行容器创建的话会加入到bridge网络
  • 而 bridge网络网关是172.17.0.1

也就是不指定网络会加入 docker 0桥

ifconfig

image-20251227224642452

因此如果所有容器都不指定网络的话,那么我们是可以通过 docker 0 桥进行通信的

④ 接下来我们将这个后来创建的容器加入到网络 mynet 中

docker network connect mynet busybox2

输入进行查看是否连接成功了

docker inspect mynet

image-20251227230148399

⑤ 然后解除网络,如下:

lighthouse@VM-8-10-ubuntu:~$ docker network disconnect mynet busybox1
lighthouse@VM-8-10-ubuntu:~$ docker network disconnect mynet busybox2
lighthouse@VM-8-10-ubuntu:~$ docker inspect mynet
[
    {
        "Name": "mynet",
        "Id": "696ecb0824afbed44d94c36c6b390c3f96e8b332156b95ee510f692d7df23186",
        "Created": "2025-12-27T22:21:35.162020943+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv4": true,
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "10.15.0.0/16"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

三:🔥 四种网络模式

🦋 Bridge

Docker Bridge 网络使用内置的 bridge 驱动,基于 Linux 内核中的 Linux bridge 技术。作为链路层设备,bridge 网络在网段之间转发流量,可以是硬件或软件设备。Docker 使用软件网桥 docker0,允许同一网桥网络中的容器通信,同时隔离未连接网桥网络的容器。

Docker Container 的 bridge 桥接模式可以参考下图

image.png

默认 Bridge 网络

  • 创建容器时,若未指定 --network 参数,容器默认加入名为 bridge 的网络。
  • bridge 网络映射到内核中的 docker0 网桥。

生活案例

  • Bridge 网络如同立交桥,连接不同方向的通道。
1.1 容器间通信

① 创建容器

docker container run -itd --name c1 busybox:1.35.0
docker container run -itd --name c2 busybox:1.35.0

② 查看容器 IP

docker container exec -it c1 ip a
docker container exec -it c2 ip a

img

③ 容器间通信测试

docker container exec -it c1 ping 172.17.0.4

img

1.2 创建自定义 Bridge
  • 使用 docker network create -d bridge new-bridge 创建新的 bridge 网络。
  • 通过 --network 参数指定容器连接到自定义 bridge。

示例命令

① 创建自定义 bridge:

docker network create -d bridge new-bridge
  • -d bridge:指定驱动类型为 bridge(桥接网络),这是 Docker 默认的网络驱动
  • new-bridge:创建的网络名称

② 创建容器并连接到自定义 bridge:

docker container run -itd --name c3 --network new-bridge busybox:1.35.0

③ 查看自定义 bridge 网络信息:

docker network inspect new-bridge


lighthouse@VM-8-10-ubuntu:~$ docker network inspect new-bridge
[
    {
        "Name": "new-bridge",
        "Id": "8b25507d6ad36732ab6d816134a1f610acc1ec6f14aea2d6188995e67037e106",
        "Created": "2025-12-28T21:28:53.283308684+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv4": true,
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16", # !!!!! 自定义 Bridge 的 IP地址
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "0008fecc96d88f7d848c7ab7d8eaaaa946ca985d06aa0141845772c4730bd05f": {
                "Name": "c3",
                "EndpointID": "4de64ee6c181fd7905ac7896ace4a838ed838f6303b801ceebd1e6408cbbf53f",
                "MacAddress": "92:c6:73:f2:7f:4c",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

查看 new-bridge 网络信息会发现这个网络的子 网 IP 是 172.18.0.0/16,它表示如果我们创建容器并连接到该网络上,就会给该容 器分配一个 172.18.xx.xx 这个网段的 IP 地址。

④ 连接到自定义Bridge网络 2.0

  1. 使用--network选项:在运行容器时,通过 -network选项指定要连接的网络( 172.18.xx.xx )。如果不指定,容器将默认连接到名为 **bridge(172.17.0.1/16)**的网络。

    # 创建名为c3的容器,并指定连接到new-bridge网络
    docker container run -itd --name c4 --network new-bridge busybox:1.35.0
    
  2. 查看容器网络信息:使用docker container inspect命令查看容器的网络配置,确认容器已连接到指定的网络。

    # 查看容器的网络相关信息
    docker container inspect c4 | grep "Networks" -A 17
    
    
    lighthouse@VM-8-10-ubuntu:~$ docker container inspect c4 | grep "Networks" -A 17
                "Networks": {
                    "new-bridge": {
                        "IPAMConfig": null,
                        "Links": null,
                        "Aliases": null,
                        "MacAddress": "96:b3:4d:b5:dd:e5",
                        "DriverOpts": null,
                        "GwPriority": 0,
                        "NetworkID": "8b25507d6ad36732ab6d816134a1f610acc1ec6f14aea2d6188995e67037e106",
                        "EndpointID": "3b1dad3998977073bca48c4fb353775f92f2dbc69547c9a8648420eca78ec9d6",
                        "Gateway": "172.18.0.1",
                        "IPAddress": "172.18.0.2",
                        "IPPrefixLen": 16,
                        "IPv6Gateway": "",
                        "GlobalIPv6Address": "",
                        "GlobalIPv6PrefixLen": 0,
                        "DNSNames": [
                            "c4",
    
1.3 DNS解析

概念:Docker 自定义桥接网络支持 DNS 解析服务

  • Docker DNS服务:Docker自定义桥接网络支持通过Docker DNS服务进行域名解析。
  • 这意味着可以直接使用容器名进行通信,因为DNS服务可以解析容器名到IP地址的映射。而默认的bridge网络不支持DNS。

准备实验环境

① 创建两个容器并连接到自定义网络

# 创建网络
docker network create -d bridge new-bridge

# 创建容器,并指定连接到new-bridge网络
docker container run -itd --name c1 --network new-bridge busybox:1.35.0
docker container run -itd --name c2 --network new-bridge busybox:1.35.0

# 查看当前容器列表
lighthouse@VM-8-10-ubuntu:~$ docker container ls
CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS          PORTS                                                                                          NAMES
aaa3b30dd8b8   busybox:1.35.0   "sh"                     33 seconds ago   Up 32 seconds                                                                                                  c2
d456867c1947   busybox:1.35.0   "sh"                     46 seconds ago   Up 45 seconds                                                                                                  c1

② 查看网络连接的容器

# 查看 bridge 网络连接的容器
docker network inspect bridge | grep "Containers" -A 20
 
# 查看 new-bridge 网络连接的容器
docker network inspect new-bridge | grep "Containers" -A 20

image-20251228214429913

③ 进入到 c1 容器中,进行域名 Ping,如下:

lighthouse@VM-8-10-ubuntu:~$ docker exec -it c1 sh
/ # ping c2
PING c2 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.117 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.062 ms
^C
--- c2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.062/0.089/0.117 ms

④ 或者也可以换种方法来查看是否支持 DNS 解析服务

查看 c1c2 容器的 IP 地址

# 查看 c1 容器的 IP 地址
lighthouse@VM-8-10-ubuntu:~$ docker container exec -it c1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0@if95: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 9a:15:0d:10:87:cc brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever
 
# 查看 c2 容器的 IP 地址
lighthouse@VM-8-10-ubuntu:~$ docker container exec -it c2 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0@if96: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether fa:1b:04:56:dc:c2 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever

测试 c1 容器与 c2 容器的通信

# c1 容器 ping c2 容器的 IP 地址
docker container exec -it c1 ping 172.18.0.3
 
# c3 容器 ping c4 容器名
docker container exec -it c1 ping c2

image-20251228215149886

结论:自定义的 new-bridge 网络支持 DNS 解析服务


端口暴露和转发

1. 暴露方式

  • -P:将指定的容器端口映射至主机所有地址的一个动态端口。
  • -p <hostPort>:<containerPort>:将容器端口 <containerPort> 映射至指定的主机端口 <hostPort>

2. 端口转发

连接 bridge 网络的容器只能与连接在当前网络中的容器进行通信。如果一个容器想要对外提供一些网络服务,需要进行端口转发。

示例:启动一个 nginx 容器,并将容器的 80 端口映射到宿主机的 8088 端口。

docker container run --name test-nginx --rm -d -p 8088:80 nginx
  • --rm:运行完自动删除该容器。
  • --name:指定容器名。

img

如下图所示,两个容器内部均开放 80 端口,它 们分别映射到宿主机的 8088 和 8089 端口

  • 即表示任何发送到 8088 端口的流量都会转发到----> Container 1 容器的 80 端口
  • 发送到 8089 端口的流程都会转发到----> Container 2 容器的 80 端口

img

🦋 Host

2.1 网络介绍

Docker 容器运行默认都会分配独立的 Network Namespace。但如果基于 host 网络模式,容器将不会获得一个独立的 Network Namespace,而是和宿主机共用同一个 Network Namespace。容器将不会虚拟出自己的网卡、IP 等,而是直接使用宿主机的 IP 和端口

img

Docker Container 的 other container 网络模式实现逻辑如下:

  1. 查找 other container(即需要被共享网络环境的容器)的网络 namespace;

  2. 将新创建的 Docker Container(也是需要共享其他网络的容器)的 namespace,

使用 other container 的 namespace

2.2 网络示例

① 创建一个容器加入到bridge网络,一个容器加入到host网络

# bridge 网络
docker container run -itd --name busybox1 --network bridge busybox:1.35.0   
# host 网络
docker container run -itd --name busybox2 --network host busybox:1.35.0   

② 查看容器的网络信息,如下:

# 查看 busybox1 的网络信息
docker container exec busybox1 ip a
 
# 查看 busybox2 的网络信息
docker container exec busybox2 ip a

image-20251228230742470

🦋 Container

3.1 网络介绍

  • 定义container 网络模式是一种特殊的网络模式,其中新创建的容器会共享另一个容器的网络命名空间。

3.2 特点

  • 容器之间的网络隔离性介于 bridge 模式和 host 模式之间。
  • 共享网络环境的容器之间没有网络隔离,但与宿主机和其他容器之间存在网络隔离。
  • 传输效率较高,容器可以通过 localhost 访问共享网络命名空间的其他容器。

实现逻辑

  • 查找需要被共享网络环境的容器(other container)的网络命名空间。
  • 将新创建的容器的网络命名空间设置为 other container 的网络命名空间。

3.3 操作案例

① 创建两个容器,第二个容器通过第一个容器网络进行创建

# 这个容器加入到了bridge网络中
docker run -itd --name busybox1 busybox:1.35.0   

# 通过容器加入到第一个容器所处在的网络中
docker run -itd --name busybox2 --network container:busybox1 busybox:1.35.0 

② 查看容器的 IP 信息

# 查看 busybox1 的网络信息
lighthouse@VM-8-10-ubuntu:~$ docker container exec busybox1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0@if98: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 96:bb:ee:08:0f:52 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.5/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
 
# 查看 busybox2 的网络信息
lighthouse@VM-8-10-ubuntu:~$ docker container exec busybox2 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0@if98: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 96:bb:ee:08:0f:52 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.5/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

现在我们将busybox1这个容器停止掉

docker stop busybox1

停掉 之后来到busybox2看到这个网络信息,发现第二个容器只有一个本地的ip地址了,外部的桥接地址消失了,如下:

lighthouse@VM-8-10-ubuntu:~$ docker container exec busybox2 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever

结论:busybox2eth0 网卡消失,只剩本地回环网络

重启容器 netcontainer1 netcontainer2,再次查看网络信息

docker restart busybox1
docker restart busybox2
docker exec -it busybox2 sh
  • 将两个容器都进行重启操作的话,那么又恢复了正常了

3.4 使用场景

  • 高效率网络传输:容器可以通过 localhost 访问 共享网络命名空间(namespace) 的其他容器,传输效率较高。
  • 依赖关系:两个容器之间存在依赖,如果依赖容器重启,会导致另一个容器的网络不可用。

🦋 None

4.1 网络介绍

  • 定义none 网络模式下,容器没有任何网络接口,除了本地回环网络(lo)。

特点

  • 适合对安全性要求较高的应用,避免网络通信带来的安全风险。
  • 容器无法与其他网络进行通信。

4.2 操作案例

① 启动一个容器并且指定为none网络

docker run -itd --name busybox3 --network none busybox:1.35.0

② 检查链接none网络的容器

docker inspect none

image-20251228231321407

③ 查看容器的网络信息

# 方式一
lighthouse@VM-8-10-ubuntu:~$ docker exec -it busybox3 sh
/ # ifconfig
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # ping www.baidu.com
ping: bad address 'www.baidu.com'

# 方式二
lighthouse@VM-8-10-ubuntu:~$ docker container exec -it busybox3 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever

4.3 使用场景

  • 高安全性需求:针对一些对安全性要求较高且不需要联网的应用,如生成随机密码,避免生成的密码被第三方获取。
  • 第三方应用:一些第三方应用可能需要 Docker 创建一个没有

对于第五种常见网络类型,将在之后的 k8s 专栏中讲解~

四:🔥 共勉

😋 以上就是我对 【Docker#7】存储卷 的理解, 觉得这篇博客对你有帮助的,可以点赞收藏关注支持一波~ 😉
在这里插入图片描述

更多推荐