🌈 个人主页: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)
高性能/无 NAT host 网络(慎用)
跨主机容器通信 Docker Swarm + overlay 或 Kubernetes + CNI
调试网络问题 container 模式 + nicolaka/netshoot 镜像
完全隔离 none 网络
暴露服务给外部 -p 端口映射(bridge 模式)或 host 模式
避免端口冲突 使用自定义 bridge + 服务发现(容器名解析)

二:🔥 网络管理命令

命令 别名 功能
docker network create 创建网络
docker network connect 连接网络
docker network disconnect 断开网络
docker network ls docker network list 列出网络
docker network prune 删除不使用的网络
docker network inspect 查看网络详情
docker network rm docker 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】存储卷 的理解, 觉得这篇博客对你有帮助的,可以点赞收藏关注支持一波~ 😉
在这里插入图片描述

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐