docker网络

docker网络

1 docker网络类型

docker网络

Docker安装时会自动的在Docker host上创建三种网络,我们可以使用docker network ls查看。这三种网络分别是none网络、host网络、bridge网络,bridge网络是我们在创建容器时默认使用的网络。

复制代码
[root@ws ~]# docker network ls
NETWORK ID     NAME            DRIVER    SCOPE
38c3edc35477   bridge          bridge    local
ce68bd41327a   harbor_harbor   bridge    local
4f77756645cb   host            host      local
6fc2732f43cb   none            null      local
docker网络-None网络

故名思议,none网络就是什么都没有的网络。在这个网络下的容器除了lo,没有其他任何网卡。容器创建时,可以通过--network=none指定使用none网络,通过下面这个示例可以看出,创建容器时指定容器网络类型为none时,容器内只有一个lo网络

复制代码
[root@ws ~]# docker run -it --name ws --rm --network=none busybox:latest 
/ # 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

none网络是个封闭的网络,使用了这种网络类型的容器无法在网络层被访问。封闭意味着隔离,一些对安全性要求高并且不需要

联网的应用可以使用none网络。比如某个容器的唯一用途是生成随机密码,就可以放到none网络中避免密码被窃取。

docker网络-Host网络

使用host网络的容器共享Docker host的网络栈,容器的网络配置与Docker host完全一样。可以通network=host指定使用host网络。可以通过以下示例看到,创建容器指定容器网络为host时,容器直接共享了Docker host的网络,能够获取到Docker host的网络信息。

复制代码
[root@ws ~]# docker run -it --name ws --rm --network=host busybox:latest 
/ # 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: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:0c:29:a3:2a:18 brd ff:ff:ff:ff:ff:ff
    inet 192.168.110.10/24 brd 192.168.110.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::8996:f378:c212:f88b/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue qlen 1000
    link/ether 52:54:00:81:b2:5b brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 qlen 1000
    link/ether 52:54:00:81:b2:5b brd ff:ff:ff:ff:ff:ff
5: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue 
    link/ether 02:42:6a:a8:65:b3 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::42:6aff:fea8:65b3/64 scope link 
       valid_lft forever preferred_lft forever
12: br-ce68bd41327a: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue 
    link/ether 02:42:4f:73:8f:7f brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global br-ce68bd41327a
       valid_lft forever preferred_lft forever
    inet6 fe80::42:4fff:fe73:8f7f/64 scope link 
       valid_lft forever preferred_lft forever

直接使用Docker host的网络最大的好处就是性能,如果容器对网络传输效率有较高要求,则可以选择host网络。当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突问题,Docker host上已经使用的端口就不能再用了。

这次我们使用httpd镜像创建容器,如下示例,可以看出容器中的80端口已经绑定到Docker host的

网络上,如果Docker host自身也有80端口的应用,那么就会与容器的80产生冲突。

复制代码
[root@ws ~]# yum -y install httpd
[root@ws ~]# systemctl restart httpd.service 
[root@ws ~]# docker run -it --name ws --rm --network=host nginx:latest 
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2025/10/10 07:38:15 [emerg] 1#1: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
2025/10/10 07:38:15 [emerg] 1#1: bind() to [::]:80 failed (98: Address already in use)
docker网络-Bridge网络

Docker安装时会创建一个命名为docker0的linux bridge。如果不指定--network,创建的容器默认都会挂到docker0上。如下示例,docker0上没有任何其他网络设备。

复制代码
[root@ws ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
br-ce68bd41327a		8000.02424f738f7f	no		
docker0		8000.02426aa865b3	no		
virbr0		8000.52540081b25b	yes		virbr0-nic

我们新创建一个容器,一个新的网络接口veth98c678e被挂到了docker0上,veth98c678e就是新创建容器的虚

拟网卡。由于在创建容器的时候使用了--rm参数,退出容器时会自动的删除容器,需要开启多个终端进行示例操作。

复制代码
[root@ws ~]# docker run -it --name ws --rm busybox:latest 
/ # 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
79: eth0@if80: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@ws ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
br-ce68bd41327a		8000.02424f738f7f	no		
docker0		8000.02426aa865b3	no		veth407bcd5
virbr0		8000.52540081b25b	yes		virbr0-nic

容器有一个网卡eth0@if7。实际上eth0@if7和veth98c678e是一对veth pair。veth pair是一种成对出现的特殊网络设备,可以把它们想象成由一根虚拟网线连接起来的一对网卡,网卡的一头(eth0@if7)在容器中,(veth98c678e)挂在网桥 docker0 上,其效果就是将eth0@if7也挂在了 docker0 上。

我们还看到eth0@if7已经配置了IP:172.17.0.2,让我们通过docker network inspect bridge看一下

bridge网络的配置信息:

复制代码
[root@ws ~]# docker network inspect bridge 
[
    {
        "Name": "bridge",
        "Id": "38c3edc3547795ad0e0f9f43e1a0cec0f51739f922ee9662ccc60366fb73e0f7",
        "Created": "2025-10-10T11:20:57.726938968+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "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": {
            "0af53eb66decf4227473142693c9eed1141c8e97d3020589f277c48f522a1993": {
                "Name": "ws",
                "EndpointID": "65cf4b18473d1896042177bae1fc610b5bd2ac853e0a5adad2ccdd286cc606eb",
                "MacAddress": "02:42:ac:11:00:02",
                "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": {}
    }
]

原来bridge网络配置的subnet就是172.17.0.0/16,并且网关是172.17.0.1。容器创建时,Docker会

自动从172.17.0.0/16中分配一个IP,这里16位的掩码保证有足够多的IP可以供容器使用。

自定义Bridge网络

之前我们所使用的网络都是安装Docker时默认生成的网络。我们可通过bridge驱动创建类似前面默认的 bridge

网络,示例如下,网络名称为wsluoqi,类型为bridge,地址池为172.19.0.0/16,网关为172.19.0.1。

复制代码
[root@ws ~]# docker network create --driver bridge --subnet 172.19.0.0/16 --gateway 172.19.0.1 wsluoqi
e4eff40797eb7be1f7e9d9087f89eb13109915b2bf7ff8c5463290c94e2d9cd8
[root@ws ~]# docker network ls
NETWORK ID     NAME            DRIVER    SCOPE
38c3edc35477   bridge          bridge    local
ce68bd41327a   harbor_harbor   bridge    local
4f77756645cb   host            host      local
6fc2732f43cb   none            null      local
e4eff40797eb   wsluoqi         bridge    local

创建新的容器,指定使用wsluoqi网络,还可以使用--ip指定容器所使用的ip,这个ip要是wsluoqi地址池中的ip。如果不指定ip,那么wsluoqi会自动给容器分配ip。

复制代码
[root@ws ~]# docker run -it --name ws --rm --network=wsluoqi  --ip 172.19.0.100 busybox:latest 
/ # 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
84: eth0@if85: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:13:00:64 brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.100/16 brd 172.19.255.255 scope global eth0
       valid_lft forever preferred_lft forever

如果创建一个容器a1,使用的默认bridge网络,再创建第二个容器a2,使用的wsluoqi网络,这种情况下两

个容器之间是不能够直接通讯的。只有指定了相同的网络的容器才能够互通。其实我们可以为容器指定多个网络,实现容器之间的通讯,示例如下,创建新的容器,指定wsluoqi网络,使用connect参数为该容器添加默认bridge网络,或者其他的bridge网络

复制代码
[root@ws ~]# docker run -it --name a1 --rm busybox:latest 
/ # 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
86: eth0@if87: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@ws ~]# docker run -it --name a2 --rm --network=wsluoqi busybox:latest 
/ # 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
88: eth0@if89: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:13:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.2/16 brd 172.19.255.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@ws ~]# docker network connect bridge a2
/ # 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
88: eth0@if89: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:13:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.2/16 brd 172.19.255.255 scope global eth0
       valid_lft forever preferred_lft forever
90: eth1@if91: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth1
       valid_lft forever preferred_lft forever
/ # ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.198 ms
64 bytes from 172.17.0.2: seq=1 ttl=64 time=0.144 ms
64 bytes from 172.17.0.2: seq=2 ttl=64 time=0.122 ms
64 bytes from 172.17.0.2: seq=3 ttl=64 time=0.176 ms
64 bytes from 172.17.0.2: seq=4 ttl=64 time=0.174 ms
64 bytes from 172.17.0.2: seq=5 ttl=64 time=0.102 ms
64 bytes from 172.17.0.2: seq=6 ttl=64 time=0.121 ms
^C
--- 172.17.0.2 ping statistics ---
7 packets transmitted, 7 packets received, 0% packet loss
round-trip min/avg/max = 0.102/0.148/0.198 ms

2 docker容器之间的访问方式

容器访问

容器之间访问可以使用以下方式

1、基于IP地址进行访问

2、基于容器名进行访问

3、多个容器共享同一个网络协议栈

注意:只有在同一个Docker网络中的容器才能够互相通讯;只有使用了默认的Bridge网络的容器是

无法使用基于容器名的方式进行容器互访的。

基于IP地址进行访问

创建一个新的容器a1,使用wsluoqi网络,容器获取的ip为172.19.0.2

复制代码
[root@ws ~]# docker run -it --name a1 --rm --network=wsluoqi busybox:latest 
/ # 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
92: eth0@if93: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:13:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.2/16 brd 172.19.255.255 scope global eth0
       valid_lft forever preferred_lft forever

再创建第二个容器a2,使用的也是wsluoqi网络,直接ping第一个容器a1的IP,示例如下。

复制代码
[root@ws ~]# docker run -it --name a2 --rm --network=wsluoqi busybox:latest 
/ # 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
94: eth0@if95: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:13:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.3/16 brd 172.19.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # ping 172.19.0.2
PING 172.19.0.2 (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.317 ms
64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.110 ms
64 bytes from 172.19.0.2: seq=2 ttl=64 time=0.126 ms
^C
--- 172.19.0.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.110/0.184/0.317 ms

通过以上两个示例得知,在同一个网络中的容器,是可以使用IP进行互相访问的。

基于容器名进行访问

通过IP访问容器虽然满足了通信的需求,但还是不够灵活。因为我们在部署应用之前可能无法确定IP,部署之后再

指定要访问的IP会比较麻烦。对于这个问题,可以通过Docker自带的DNS服务解决。

从Docker 1.10版本开始,Docker daemon实现了一个内嵌的DNS server,使容器可以直接通过"容器名"通

信。方法很简单,只要在启动时用--name为容器命名就可以了,示例如下。

复制代码
[root@ws ~]# docker run -it --name a1 --rm --network=wsluoqi busybox:latest 
[root@ws ~]# docker run -it --name a2 --rm --network=wsluoqi busybox:latest 
/ # 
/ # ping a2
PING a2 (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.973 ms
64 bytes from 172.19.0.3: seq=1 ttl=64 time=0.126 ms
^C
--- a2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.126/0.549/0.973 ms
/ # 

通过以上示例得知,创建容器时,使用--name定义容器名称,当容器启动时,Docker daemon会把容器名与容

器获取的IP进行绑定,写入到Docker DNS中,这样容器之间访问就可以基于容器名实现了,如果容器停止了,该容器所对应的DNS信息就会从Docker DNS中删除。使用Docker DNS有个限制,只能在新创建的bridge网络中使用。

joined容器

Joined(联合)容器是另一种实现容器间通信的方式。joined容器非常特别,它可以使两个或多个容器

共享一个网络栈,共享网卡和配置信息,joined容器之间可以通过127.0.0.1直接通信。请看下面的例

子:

复制代码
[root@ws ~]# docker run -itd --name a1  --network=wsluoqi busybox:latest 
c91f89dac292ff31551c9190fa369b9d3e134beb0cc0300f52b3d4b6766782fc
[root@ws ~]# docker run -it --name a2 --rm  --network=container:a1 busybox:latest 
/ # ping a1
PING a1 (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.187 ms
64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.088 ms
^C
--- a1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.088/0.137/0.187 ms
/ # 

使用joined容器的方式实现容器间的通讯,需要注意的是两个容器之间的应用端口容易发生冲突,

两个容器共享一个网络栈,那么容器中的应用在运行时,绑定的IP也是一样。

容器访问外部

1、 容器int_1发送Ping报文包:172.17.0.3 > www.baidu.com

2、docker0收到报文,发现是发送到外网的,交给NAT处理。

3、NAT将源地址换成ens36的IP:192.168.31.106 > www.baidu.com

4、Ping包从ens36发送出去,到达 www.baidu.com

通过 NAT,docker 实现了容器对外网的访问。

外部访问容器

如果想实现外部访问容器,可使用host网络,容器共享Docker host网络栈,就可以实现外部访问容

器。还有一种方法也是我们最常用的使用端口映射。

相关推荐
white-persist4 小时前
SQL 注入详解:从原理到实战
前端·网络·数据库·sql·安全·web安全·原型模式
Lv-D-J4 小时前
mac下Docker安装nacos
docker
wanhengidc4 小时前
云手机的挂机功能涉及到哪些内容
运维·服务器·网络·游戏·智能手机
AORO20254 小时前
防爆手机与普通手机的区别!
网络·5g·安全·智能手机·电脑·信息与通信
非凡ghost5 小时前
猫眼浏览器(Chrome内核增强版浏览器)官方便携版
前端·网络·chrome·windows·软件需求
阿拉斯加大闸蟹5 小时前
[SIGCOMM‘25] Revisiting RDMA Reliability for Lossy Fabrics
网络·架构
嗨丶王哪跑5 小时前
网络安全审计技术原理与应用
运维·网络·安全·web安全
RTC老炮5 小时前
webrtc弱网-RobustThroughputEstimator源码分析与算法原理
网络·算法·webrtc
吃鱼吃鱼吃不动了5 小时前
什么是负载均衡?
开发语言·php