Skip to content
DAILY QUOTE

“ ”

Docker网络

1.准备环境

学习Docker网络前,可以先清空前面创建的容器和镜像。

bash
#1.删除全部容器
docker rm -f $(docker ps -aq)

#2.删除全部镜像
docker rmi -f $(docker images -aq)

2.Docker默认网络

查看Docker默认网络:

Docker默认会有3个网络:

  • bridge
  • host
  • none

核心问题:Docker是如何处理容器网络访问的?

2.1启动一个Tomcat容器

bash
docker run -d -P --name tomcat01 tomcat

2.2查看容器内部网络地址

bash
docker exec -it 容器id ip addr

示例输出:

bash
root@1711e56cc521:/usr/local/tomcat# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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@if126: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1200 qdisc noqueue state UP group default
    link/ether 7e:cb:80:3e:56:b0 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

结论:容器启动时,Docker会给容器分配一个eth0网卡和一个IP地址。

2.3测试宿主机和容器连通

宿主机可以ping通容器内部IP,容器内部也可以访问外部网络。

bash
ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.074 ms

3.docker0和veth-pair原理

每启动一个Docker容器,Docker都会给容器分配一个IP。只要安装了Docker,宿主机上就会有一个docker0网卡。

Docker默认网络使用桥接模式,底层使用veth-pair技术。

参考链接:https://www.cnblogs.com/bakari/p/10613710.html

再次查看ip addr

再启动一个容器,会发现又多了一对网卡:

说明:

  • veth-pair是一对虚拟网络设备接口,成对出现。
  • 一端连接容器,一端连接宿主机网桥。
  • 正因为这种成对特性,veth-pair可以充当桥梁,连接各种虚拟网络设备。
  • Docker容器之间的连接、OpenStack和OVS连接都可以使用veth-pair技术。

4.容器之间的网络连通

4.1获取容器IP

bash
docker exec -it tomcat01 ip addr

示例:

bash
550: eth0@if551: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever

4.2测试容器互相ping

tomcat02pingtomcat01

bash
ubuntu@Mystpet:~$ docker exec -it tomcat02 ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.054 ms

结论:容器和容器之间可以互相ping通。

网络模型图:

说明:

  • tomcat01tomcat02共用同一个路由器,也就是docker0
  • 不指定网络时,所有容器默认都通过docker0路由。
  • Docker会给容器分配一个默认可用IP。

小结:

Docker使用Linux桥接。宿主机中的docker0就是Docker容器的默认网桥。

Docker中的网络接口都是虚拟的,虚拟网络转发效率较高,适合容器间内网通信。

容器删除后,对应的一对虚拟网卡也会被删除。

5.1使用场景

假设项目中配置了数据库地址:

text
database url = ip

如果数据库容器IP变了,项目不重启就无法继续访问。更好的方式是按容器名称访问。

默认情况下,docker0不支持直接通过容器名访问。

bash
ubuntu@Mystpet:~$ docker exec -it tomcat02 ping tomca01
ping: tomca01: Name or service not known

5.2使用--link连接容器

运行tomcat03,并让它链接tomcat02

bash
docker run -d -P --name tomcat03 --link tomcat02 tomcat

tomcat03可以通过名称访问tomcat02

bash
docker exec -it tomcat03 ping tomcat02

但是反向不一定可以:

bash
ubuntu@Mystpet:~$ docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known

5.3--link原理

查看网络信息:

查看tomcat03

查看tomcat03容器内的/etc/hosts

bash
ubuntu@Mystpet:~$ docker exec -it tomcat03 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.4	tomcat02 527eb4cb08a8
172.17.0.5	861d7b137615

本质:--link就是在容器的/etc/hosts中增加目标容器的IP和名称映射。

现在已经不建议使用--link,更推荐使用自定义网络。

Docker0的问题:默认不支持通过容器名直接访问。

6.自定义网络

6.1docker network命令

bash
docker network
connect      Connect a container to a network
create       Creates a new network with a name specified by the
disconnect   Disconnects a container from a network
inspect      Displays detailed information on a network
ls           Lists all the networks created by the user
prune        Remove all unused networks
rm           Deletes one or more networks

查看所有Docker网络:

6.2网络模式

网络模式说明
bridge桥接模式,默认模式,自定义网络默认也是bridge
none不配置网络,一般较少使用
host和宿主机共享网络
container复用其他容器的网络,使用较少,局限较大

6.3默认bridge网络

bash
docker run -d -P --name tomcat01 tomcat

等价于:

bash
docker run -d -P --name tomcat01 --net bridge tomcat

说明:默认bridge就是docker0。它的特点是默认可用,但不能直接通过容器名访问。虽然--link可以解决,但使用起来比较麻烦。

6.4创建自定义网络

bash
docker network create \
  --driver bridge \
  --subnet 192.168.0.0/16 \
  --gateway 192.168.0.1 \
  mynet

参数说明:

参数作用
--driver bridge使用桥接模式
--subnet 192.168.0.0/16指定子网
--gateway 192.168.0.1指定网关
mynet自定义网络名称

示例输出:

bash
26a5afdf4805d7ee0a660b82244929a4226470d99a179355558dca35a2b983ec

查看网络:

bash
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
2e4a9d5f5198   bridge    bridge    local
e3ffc6670683   host      host      local
d44d171e4862   mynet     bridge    local
f58409c2ce62   none      null      local

查看自定义网络详情:

bash
docker network inspect mynet

6.5在自定义网络中启动容器

启动两个Tomcat容器,并加入mynet网络后,再查看网络情况。

bash
ubuntu@Mystpet:~$ docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "d44d171e4862678ae9b7e4cf09a152c042d136d72392092bd5b1c8f92be93e81",
        "Created": "2026-02-10T18:11:07.865260348+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv4": true,
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "IPRange": "",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Containers": {
            "26e87d563eb8ffd888686c819b53292fb2d78e16c5a9da290d082d831a4b8c10": {
                "Name": "tomcat-net-02",
                "EndpointID": "08fc68c4cc940e067f422c94a5baf9e7f91fc4a2db80a8340d27ce8bb9c1f539",
                "MacAddress": "5e:e9:6b:23:f0:14",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "959c3ea439c81e75b8ad3e8940fc3aced00083c9241e06e707099abeb3a13fc0": {
                "Name": "tomcat-net-01",
                "EndpointID": "015c4769b7cfee12e1c9b3009806c42a5c4607e640eca528a862dd4e272783d5",
                "MacAddress": "a6:1c:17:9e:80:c2",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        }
    }
]

测试IP连通:

bash
docker exec -it tomcat-net-01 ping 192.168.0.2

测试容器名连通:

bash
docker exec -it tomcat-net-01 ping tomcat-net-02

结论:使用自定义网络后,不使用--link也可以通过容器名访问。

好处:

  • Redis集群可以使用独立网络,保证集群安全和健康。
  • MySQL集群可以使用独立网络,保证集群安全和健康。

7.网络连通

7.1问题场景

两个不同网络中的容器默认不能直接通信。

启动两个使用默认网络的Tomcat容器:

bash
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat02 tomcat

此时它们和自定义网络mynet中的容器默认不连通。

7.2使用docker network connect连通网络

目标:让tomcat01连通tomcat-net-01,也就是把tomcat01加入mynet网络。

执行命令:

bash
docker network connect mynet tomcat01

说明:

  • 执行后,tomcat01会被加入mynet网络。
  • 一个容器可以拥有两个IP地址,类似服务器同时拥有公网IP和私网IP。

7.3测试连通结果

已经连通的容器可以访问:

bash
docker exec -it tomcat01 ping tomcat-net-01

没有执行connect的容器依旧不能访问:

bash
docker exec -it tomcat02 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known

结论:如果要让容器跨网络访问,就需要使用docker network connect把容器加入目标网络。

8.一键删除Docker网络

删除未被容器使用的Docker网络:

bash
docker network prune