一文搞懂docker网络

概念

基于对Network Namespace的控制,docker可以为在容器创建隔离的网络环境,在隔离的网络环境下,容器具有完全独立的网络栈,与宿主机隔离,也可以使容器共享主机或者其他容器的网络命名空间,基本可以满足开发者在各种场景下的需要。按docker官方的说法,docker容器的网络有以下几种模式:

  • Bridge 模式:默认模式,适用于大多数场景。
  • Host 模式:高性能,直接使用宿主机网络。
  • None 模式:无网络,仅适用于本地任务。
  • Overlay 模式:跨主机通信,适用于分布式应用。
  • Macvlan 模式:直接接入物理网络,适用于 IoT 设备。
  • Custom Network:灵活配置,适用于复杂网络需求。
  • Container 网络模式:共享网络,适用于日志代理等场景。

当我们安装docker之后,默认会创建三个网络模式

[root@master]:~$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
653123c201c5   bridge    bridge    local
bf70d98b37ce   host      host      local
b0cd5e45bf65   none      null      local

Docker提供了以下常用的网络模式:

  • Bridge模式(桥接模式):默认的网络模式,容器通过虚拟网桥连接到主机的物理网络接口上,可以通过端口映射将容器的端口映射到主机上。

  • Host模式(主机模式):容器与主机共享网络命名空间,容器直接使用主机的网络栈,可以轻松访问主机上的网络资源,但会损失一定的隔离性。

  • None模式(无网络模式):容器不连接到任何网络,只能通过内部与其他容器进行通信,不能与外部进行网络通信。

Docker网络相关命令

在讲述正文之前,先看下Docker网络的相关命令

docker network ls:列出所有的网络

示例:

[root@master]:~$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
4c46875a7300   bridge    bridge    local
bf70d98b37ce   host      host      local
b0cd5e45bf65   none      null      loca

docker network create:创建docker网络

docker network create默认创建桥接网络,有以下常用选项

  • --driver, -d:指定网络类型,默认是bridge
  • --subnet:指定网段,采用CIDR表示法
  • --gateway:指定网关
  • --ip-range:指定IP范围
  • --internal:创建一个内部网络,该网络中的容器无法访问外部网络。
  • --attachable:允许独立的容器(非服务模式下的容器)连接到该网络
  • --aux-address:为网络分配辅助 IP 地址

示例:

# 创建一个名为 my_network 的桥接网络
docker network create my_network

# 创建一个my_bridge_network的网络,指定网络类型未bridge
docker network create -d bridge my_bridge_network

# 创建my_ip_range_network的网络,指定网段为192.168.10.0/24,IP范围192.168.10.128/25,网关192.168.10.1
docker network create --subnet=192.168.10.0/24 --ip-range=192.168.10.128/25 --gateway=192.168.10.1 my_ip_range_network

# 创建一个内部网络,该网络中的容器无法访问外部网络
docker network create --internal my_internal_network

docker network inspect:查看网络的详细信息

docker network inspect可以简写为docker inspect

示例:

[root@master]:~$ docker inspect bridge
[
    {
        "Name": "bridge",
        "Id": "4c46875a7300333dafcbc6e6fea5d6313b9096ea48bb5098b07ad5302a145358",
        "Created": "2025-04-25T11:06:30.998734581+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv4": true,
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

docker network connect:将指定容器连接到指定网络

示例:

docker network connect my_network my_container

docker network disconnect: 将指定容器断开连接到指定网络

示例:

docker network disconnect my_network my_container

docker network rm:删除指定的网络

该命令可以删除一个或多个指定的网络

# 删除一个网络
docker network rm my_network

# 删除多个网络
docker network rm my_network1 ... my_networkN

Docker网络类型之bridge

bridge 网络本质上是一个 Linux 桥接设备(bridge device),它就像一个虚拟的交换机,允许连接到该网络的容器之间进行通信。当创建一个 Docker 容器并将其连接到 bridge 网络时,Docker 会为容器分配一个 IP 地址,并且通过桥接设备将容器的网络接口连接到这个虚拟交换机上,从而实现容器间的网络通信。

当我们安装docker之后,默认会在宿主机上创建一个docker0的网卡设备,这个docker0的网卡设备就是用来给bridge设备来使用的。

[root@master]:~$ ip addr
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 46:d4:9c:a4:ee:07 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever

当创建一个 Docker 容器的时候,同时会创建了一对 veth pair接口(当数据包发送到一个接口时,另外一个接口也可以收到相同的数据包)。这对接口一端在容器内,即 eth0;另一端在本地并被挂载到docker0 网桥,名称以 veth 开头(例如 vethAQI2QT)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信。Docker 就创建了在主机和所有容器之间一个虚拟共享网络。

image

当我们创建一个容器来观察一下变化

# 创建容器
[root@master]:~$ docker run -d -p 82:80 --name nginx nginx
2add24bef3ec5a26ceb3b5a95ab0a5ff8cbe9883aed9e1cc10d345d97b3b9050

[root@master]:~$ docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                 NAMES
2add24bef3ec   nginx     "/docker-entrypoint.…"   5 seconds ago   Up 5 seconds   0.0.0.0:82->80/tcp, [::]:82->80/tcp   nginx

# 发现新增了一个vethe9f90c1@if2的虚拟网络接口
[root@master]:~$ ip addr
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 46:d4:9c:a4:ee:07 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::44d4:9cff:fea4:ee07/64 scope link
       valid_lft forever preferred_lft forever
4: vethe9f90c1@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether 8a:5a:e7:db:44:9a brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::885a:e7ff:fedb:449a/64 scope link
       valid_lft forever preferred_lft forever

继续查看一下容器的IP地址和bridge网络、docker0设备有什么联系

# 查看容器的网络设置,发现使用的bridge类型,且Gateway和IPAddress都属于默认创建的bridge网络的范畴
[root@master]:~$ docker inspect nginx | jq .[].NetworkSettings.Networks
{
  "bridge": {
    "IPAMConfig": null,
    "Links": null,
    "Aliases": null,
    "MacAddress": "a2:6a:08:83:12:4a",
    "DriverOpts": null,
    "GwPriority": 0,
    "NetworkID": "4c46875a7300333dafcbc6e6fea5d6313b9096ea48bb5098b07ad5302a145358",
    "EndpointID": "e15e87b83f30dfc6414e88502c5626239a9f938443ef7e2c51c65b2e5bfe5877",
    "Gateway": "172.17.0.1",
    "IPAddress": "172.17.0.2",
    "IPPrefixLen": 16,
    "IPv6Gateway": "",
    "GlobalIPv6Address": "",
    "GlobalIPv6PrefixLen": 0,
    "DNSNames": null
  }
}

#查看bridge网络
[root@master]:~$ docker inspect bridge
[
    {
        "Name": "bridge",
        "Id": "4c46875a7300333dafcbc6e6fea5d6313b9096ea48bb5098b07ad5302a145358",
        "Created": "2025-04-25T11:06:30.998734581+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv4": true,
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "2add24bef3ec5a26ceb3b5a95ab0a5ff8cbe9883aed9e1cc10d345d97b3b9050": {
                "Name": "nginx",
                "EndpointID": "e15e87b83f30dfc6414e88502c5626239a9f938443ef7e2c51c65b2e5bfe5877",
                "MacAddress": "a2:6a:08:83:12:4a",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]
# 查看docker0网卡
[root@master]:~$ ip addr
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 46:d4:9c:a4:ee:07 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::44d4:9cff:fea4:ee07/64 scope link
       valid_lft forever preferred_lft forever

从上面能够看到容器的网关172.17.0.1是bridge网络的网关,容器IP地址172.17.0.2是bridge网络的网段范围,且bridge网络的Containers中包含着我们新创建的容器nginx

Docker网络类型之host

相当于Vmware中的NAT模式,与宿主机在同一个网络中,但没有独立IP地址。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。可以通过 --net=host 指定使用 host 网络。
image

创建容器查看:

# --net指定网络类型,当使用host网络类型时,-p选项是不生效的,所以这里不指定-p选项,
# 使用host网络类型默认是使用镜像的端口直接映射到宿主机中
[root@master]:~$ docker run -d --net host --name nginx_host nginx
057b3e0cd6d6cea318d93d1b0f25bbac0e7f287c84b469c6b64e69c794a69262

# 查看宿主机的网络设备变化,并没有创建额外的网络设备
[root@master]:~$ ip addr

# 查看容器的IP地址
# 这里发现IPAddress和Gateway都是空的,这里是直接使用宿主机的IP和网关
[root@master]:~$ docker inspect nginx_host | jq .[].NetworkSettings.Networks
{
  "host": {
    "IPAMConfig": null,
    "Links": null,
    "Aliases": null,
    "MacAddress": "",
    "DriverOpts": null,
    "GwPriority": 0,
    "NetworkID": "bf70d98b37ce8fb4925a62540dfb75682f85e72dfa5f413256192dfc661f051b",
    "EndpointID": "7a1dfc95e37fc753b0edea128df4a8c3c813909bee4c03a33bf02129c90903ef",
    "Gateway": "",
    "IPAddress": "",
    "IPPrefixLen": 0,
    "IPv6Gateway": "",
    "GlobalIPv6Address": "",
    "GlobalIPv6PrefixLen": 0,
    "DNSNames": null
  }
}

查看容器的IP地址和宿主机的IP地址

# 容器的IP地址
[root@master]:~$ docker exec -it nginx_host hostname -I
172.25.193.185 172.17.0.1

#宿主机的IP地址
[root@master]:~$ hostname -I
172.25.193.185 172.17.0.1

查看容器的hosts文件和宿主机的hosts文件

# 查看宿主机的hosts文件
[root@master]:~$ cat /etc/hosts
127.0.0.1       localhost
127.0.1.1       5CG422112V-QCA. 5CG422112V-QCA
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

# 查看容器内部的hosts解析
[root@master]:~$ docker exec -it nginx_host cat /etc/hosts
127.0.0.1       localhost
127.0.1.1       5CG422112V-QCA. 5CG422112V-QCA
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

访问测试:

# 直接访问本地的80端口,因为nginx的端口是80
[root@master]:~$ curl localhost:80
<!DOCTYPE html>
<html>
xxxx
</html>

通过上述的验证,可以发现host网络类型是没有自己独立的IP地址、网关这些信息,而是使用宿主机的IP地址

Docker网络类型值container

Docker网络container模式是指定其和已经存在的某个容器共享一个 Network Namespace,此时这两个容器共同使用同一网卡、主机名、IP 地址、容器间通讯可直接通过本地回环 lo 接口通讯。但这两个容器在其他的资源上,如文件系统、进程列表等还是隔离的。

使用container模式时,注意避免使用端口号一致镜像创建容器,否则会导致端口号冲突!!!
image

创建容器查看

#创建容器,--net container:nginx指定依赖nginx的容器
[root@master]:~$ docker run -d --net container:nginx --name tomcat_container tomcat:8
392726502e8caa4e9d13f0106effe2dabfff344882023063afd2a4205665fc31

# 查看nginx_container的网络设置,发现是空的,这里表示nginx_container容器的网络设置和nginx容器的一致
[root@master]:~$ docker inspect tomcat_container | jq .[].NetworkSettings.Networks
{}

# 查看nginx的网络设置
[root@master]:~$ docker inspect nginx | jq .[].NetworkSettings.Networks
{
  "bridge": {
    "IPAMConfig": null,
    "Links": null,
    "Aliases": null,
    "MacAddress": "a2:6a:08:83:12:4a",
    "DriverOpts": null,
    "GwPriority": 0,
    "NetworkID": "4c46875a7300333dafcbc6e6fea5d6313b9096ea48bb5098b07ad5302a145358",
    "EndpointID": "e15e87b83f30dfc6414e88502c5626239a9f938443ef7e2c51c65b2e5bfe5877",
    "Gateway": "172.17.0.1",
    "IPAddress": "172.17.0.2",
    "IPPrefixLen": 16,
    "IPv6Gateway": "",
    "GlobalIPv6Address": "",
    "GlobalIPv6PrefixLen": 0,
    "DNSNames": null
  }
}

查看tomcat_container和nginx两个容器hosts文件

# 查看tomcat_container的hosts文件
[root@master]:~$ docker exec -it tomcat_container cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::  ip6-localnet
ff00::  ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      2add24bef3ec
# 查看nginx的hosts文件
[root@master]:~$ docker exec -it nginx cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::  ip6-localnet
ff00::  ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2      2add24bef3ec

查看tomcat_container和nginx两个容器IP地址

[root@master]:~$ docker exec -it tomcat_container hostname -I
172.17.0.2
[root@master]:~$ docker exec -it nginx hostname -I
172.17.0.2

访问测试

# 访问tomcat
[root@master]:~$ curl 172.17.0.2:8080
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/8.5.100</h3></body></html>

# 访问nginx
# 直接访问本地的80端口,因为nginx的端口是80
[root@master]:~$ curl 172.17.0.2:80
<!DOCTYPE html>
<html>
xxxx
</html>

通过上述的验证,可以发现container网络类型的容器,是依赖源容器的网卡设备的

Docker网络类型之none

容器有自己的网络命名空间,但不做任何配置,它与宿主机、与其他容器都不连通的。可以认为none网络类型是没有任何网络的,一般用于执行本地任务。

创建容器查看

# 创建容器,--net none指定网络类型为none
[root@master]:~$ docker run -d --name tomcat --net none tomcat:8
214870040e5542aec45baf6210ab506bbbee99bc908f0046881ff762c337f4fb

# 查看网络
[root@master]:~$ docker inspect tomcat | jq .[].NetworkSettings.Networks
{
  "none": {
    "IPAMConfig": null,
    "Links": null,
    "Aliases": null,
    "MacAddress": "",
    "DriverOpts": null,
    "GwPriority": 0,
    "NetworkID": "b0cd5e45bf657efd288c4177963f6b75691839f207cc28b9ade94558d57f591c",
    "EndpointID": "35224d75c0a50380b1cbaabfdd634052ebed0487b82e02a3a23adc6ea7c6cef4",
    "Gateway": "",
    "IPAddress": "",
    "IPPrefixLen": 0,
    "IPv6Gateway": "",
    "GlobalIPv6Address": "",
    "GlobalIPv6PrefixLen": 0,
    "DNSNames": null
  }
}

查看IP地址和hosts文件

[root@master]:~$ docker exec -it tomcat cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::  ip6-localnet
ff00::  ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
# 发现IP是空的
[root@master]:~$ docker exec -it tomcat hostname -I

[root@master]:~$

Docker网络类型之自定义网络

Docker的自定义网络提供了更灵活、可控的容器网络管理方式,允许用户根据需求创建独立的网络环境,优化容器间通信和隔离性。

为什么需要自定义网络?

默认网络(bridge/host/none)的局限性:

  • 默认桥接网络(bridge):容器间只能通过 IP 通信,无法通过容器名称直接访问。
  • 隔离性不足:所有容器默认共享同一个桥接网络,缺乏项目间的隔离。
  • 功能限制:默认网络不支持自定义子网、DNS、静态IP等高级配置。

自定义网络的优势:

  • 容器名称直接通信:同一自定义网络内的容器可通过容器名或别名互相访问。
  • 网络隔离性:不同自定义网络中的容器默认无法通信,增强安全性。
  • 灵活配置:支持自定义子网、网关、IP 地址范围、DNS 等。

自定义网络bridge的创建与使用

通过docker network create创建bridge网络,当我们创建bridge网络之后,Docker默认会在宿主机中创建一个br-随机数的网桥设备

示例:

# 创建网络
[root@master]:~$ docker network create --driver bridge --subnet 172.18.0.0/16 --gateway 172.18.0.1 bridge_01
856370f701c1b665272a2a5420051d544e3117cf752d801ff316cca17cdcdd70

# 查看网络
[root@master]:~$ docker network ls
NETWORK ID     NAME        DRIVER    SCOPE
4c46875a7300   bridge      bridge    local
856370f701c1   bridge_01   bridge    local
bf70d98b37ce   host        host      local
b0cd5e45bf65   none        null      local

# 查看网桥设备
[root@master]:~$ ip addr
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 46:d4:9c:a4:ee:07 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::44d4:9cff:fea4:ee07/64 scope link
       valid_lft forever preferred_lft forever
### 新创建的网桥设备,该设备和docker0的作用一致
5: br-856370f701c1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether ae:e5:74:0c:e9:31 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global br-856370f701c1
       valid_lft forever preferred_lft forever

创建容器使用自定义网络

# 创建两个容器,使用--net指定自定义网络
[root@master]:~$ docker run -d -p 89:80 --name nginx_bridge1 --net bridge_01 nginx
050740ed8395bb76449318e4613f0f535ae3520a24acca273935df32511decac

[root@master]:~$ docker run -d -p 8089:8080 --name tomcat_bridge1 --net bridge_01 tomcat:8
310698f33e70575a80bea21583f0ab04c7a6af2d9986008795f17cba4eb46954

测试DNS解析

# 进入nginx_bridge1容器
[root@master]:~$ docker exec -it nginx_bridge1 bash
# 下载ping工具
root@050740ed8395:/# apt update -y && apt install -y iputils-ping
# 测试ping,直接指定同一个网络的另一个容器名称即可
root@050740ed8395:/# ping -4 tomcat_bridge1
PING tomcat_bridge1 (172.18.0.3) 56(84) bytes of data.
64 bytes from tomcat_bridge1.bridge_01 (172.18.0.3): icmp_seq=1 ttl=64 time=0.470 ms
64 bytes from tomcat_bridge1.bridge_01 (172.18.0.3): icmp_seq=2 ttl=64 time=0.086 ms
64 bytes from tomcat_bridge1.bridge_01 (172.18.0.3): icmp_seq=3 ttl=64 time=0.080 ms
64 bytes from tomcat_bridge1.bridge_01 (172.18.0.3): icmp_seq=4 ttl=64 time=0.076 ms

分配静态IP
docker run时通过--ip分配静态IP

# 运行容器
[root@master]:~$ docker run -d -p 8090:8080 --name tomcat_bridge_ip --net bridge_01 --ip 172.18.0.10 tomcat:8
8e219dee6db6cc0ffa497646bbb4109223d30205cd9231f830490429a78effc3

# 查看容器IP地址
[root@master]:~$ docker inspect tomcat_bridge_ip | jq .[].NetworkSettings.Networks.[].IPAddress
"172.18.0.10"

自定义其它的网络类型可自行测试

Docker网络类型之Overlay

Docker 的 Overlay 网络 是专为多主机容器通信设计的网络模式,尤其适用于 Docker Swarm 集群环境,允许不同物理主机上的容器直接互联,仿佛它们在同一局域网中。

Overlay 网络的核心作用

  • 跨主机通信:允许运行在不同宿主机上的容器直接通过虚拟网络通信。
  • 服务发现与负载均衡:与 Docker Swarm 集成,支持服务动态扩缩容和自动负载均衡。
  • 加密通信(可选):支持 TLS 加密容器间流量,提升安全性。

Overlay 网络的工作原理

  • VXLAN 封装:Overlay 网络通过 VXLAN(虚拟扩展局域网) 技术,将容器数据包封装在宿主机的 UDP 包中传输,穿透底层物理网络。
  • 控制平面:依赖 Docker Swarm 的 Gossip 协议 和 KV 存储(如 etcd)同步网络状态(如 IP 分配、服务映射)。

与其他网络类型的对比

特性 Overlay网络 Bridge 网络 Host 网络
跨主机通信 ❌(单机) ❌(单机)
隔离性 网络级隔离 网络级隔离 无隔离
性能损耗 较高(VXLAN 封装) 最低(无虚拟化)
适用场景 集群、多主机 单机容器互联 高性能单机容器

Overlay网络依赖于docker集群,相较于docker集群我们更喜欢用kubenetes集群,所以在这就不过多讲解Overlay网络

Docker网络类型之Macvlan网络

Docker 的 Macvlan 网络 允许容器直接绑定到宿主机的物理网络接口,使每个容器拥有独立的 MAC 地址和直接分配的 IP 地址(与宿主机在同一子网)。这种模式让容器表现得像物理设备一样接入网络,无需 NAT 或端口映射,适用于对网络性能要求高且需直接暴露到局域网的场景。

Macvlan 的核心特性

  • 直接物理网络接入:容器直接使用物理网络接口(如 eth0、ens33),获得与宿主机同子网的 IP。
  • 独立 MAC 地址:每个容器有唯一的 MAC 地址,外部设备可通过 ARP 直接发现容器。
  • 高性能:绕过 Docker 的虚拟网桥和 NAT,降低延迟。
  • 隔离性:容器间默认无法直接通信(除非通过外部网络)。

Macvlan 的两种模式

Macvlan Bridge 模式

原理:在物理接口上创建虚拟子接口,容器通过虚拟接口接入物理网络。

适用场景:同一物理网络内需要容器直接通信。

Macvlan 802.1q Trunk 模式

原理:通过 VLAN 标签(如 eth0.10)将流量划分到不同子网。

创建与使用 Macvlan 网络

创建 Macvlan 网络

# 创建名为 macvlan_net 的 Macvlan 网络
[root@master]]# docker network create \
             -d macvlan \              #指定网络类型
             --subnet=10.0.0.0/24 \    #指定网段,这里和宿主机的网段保持一致
             --gateway=10.0.0.1 \      #指定网络网关,这里和宿主机保持一致
             --ip-range=10.0.0.48/28 \ #IP范围,可选
             -o parent=ens33 \         #宿主机网卡设备
             macvlan_net
c445578df1644b1a9fdb6c42b0ca3a16a0ad9e93dd838b2b4d41b90f904ce09a

# 查看网络详细信息
[root@master]]# docker inspect macvlan_net
[
    {
        "Name": "macvlan_net",
        "Id": "c445578df1644b1a9fdb6c42b0ca3a16a0ad9e93dd838b2b4d41b90f904ce09a",
        "Created": "2025-04-20T15:53:38.185154888+08:00",
        "Scope": "local",
        "Driver": "macvlan",
        "EnableIPv4": true,
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "10.0.0.0/24",
                    "IPRange": "10.0.0.48/28",
                    "Gateway": "10.0.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "parent": "ens33"
        },
        "Labels": {}
    }
]

运行容器

# 不用指定端口
[root@master]]# docker run -d --name nginx_web --net macvlan_net nginx
1014b93180a5a1b0f53a739a473b568a4fa483511fbdd9d67397041d13c212af

# 查看容器的IP
[root@master]]# docker exec -it nginx_web hostname -I
10.0.0.48

测试外部网络访问容器
http://10.0.0.48/
image

与其它网络类型对比

特性 Macvlan Bridge 网络 Host 网络
IP 分配 物理网络直接分配 Docker 内部子网 共享宿主机 IP
性能 高(无 NAT) 中等(NAT 开销) 最高(无虚拟化)
外部访问 直接通过物理网络 需端口映射或 NAT 直接共享宿主机端口
适用场景 需直连物理网络的服务 单机容器互联 高性能单机容器
posted @ 2025-04-25 22:07  huangSir-devops  阅读(228)  评论(0)    收藏  举报
作者:你的名字
出处:你的博客链接
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。