Skip to content

Docker网络 ​

Docker启动后会产生一个名为docker0的虚拟网桥:
Alt text

1. Docker网络作用 ​

  1. 容器间的互联和通信以及端口映射
  2. 容器IP变动时候可以通过服务名直接网络通信而不受到影响

2. 网络命令 ​

2.1 查看网络 ​

sh
docker network ls

2.2 查看网络源数据 ​

sh
docker network inspect  XXX网络名字

2.3 删除网络 ​

sh
docker network rm XXX网络名字

3. 网络模式 ​

Alt text 查看正在运行的redis容器的网络模式

sh
[root@hadoop102 ~]# docker inspect c19fb3bc7494 | tail -n 20
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "MacAddress": "02:42:ac:11:00:03",
                    "NetworkID": "017827bae454e64c93a78cd51f7b3f37f683e7dff62bea9ee1b092936c2f0878",
                    "EndpointID": "5b524f0151731167c135bdb4c8aa7e93bf694c4cdef0b5b3b55492804b92d130",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.3",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "DriverOpts": null,
                    "DNSNames": null
                }
            }
        }
    }
]

docker容器内部的ip是有可能会发生改变的, 比如其中一个容器下线,再次启动可能是其他IP。

4. bridge模式 ​

使用--network bridge指定,默认使用docker0。Docker服务默认会创建一个docker0网桥(其上有一个docker0内部接口),该桥接网络的名称为docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。Docker默认指定了docker0接口的IP地址和子网掩码,让主机和容器之间可以通过网桥相互通信。

sh
# 查看bridge网络的详细信息,并通过grep获取名称项
[root@hadoop102 ~]# docker network inspect bridge | grep name
            "com.docker.network.bridge.name": "docker0",

Alt text

  1. Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
  2. docker run的时候,没有指定network的话默认使用的网桥模式就是bridge,使用的就是docker0。在宿主机ifconfig,就可以看到docker0和自己create的network(后面讲)eth0,eth1,eth2……代表网卡一,网卡二,网卡三……,lo代表127.0.0.1,即localhost,inet addr用来表示网卡的IP地址
  3. 网桥docker0创建一对对等虚拟设备接口一个叫veth,另一个叫eth0,成对匹配。
    • 整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口叫veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair)
    • 每个容器实例内部也有一块网卡,每个接口叫eth0
    • docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。

通过上述,将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一个网络下,会从这个网关下各自拿到分配的ip,此时两个容器的网络是互通的。

5. host模式 ​

使用--network host指定, 直接使用宿主机的IP地址与外界进行通信,不再需要额外进行NAT转换。容器将不会获得一个独立的Network Namespace, 而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口。 Alt text

sh
## 不需要-p参数
docker run -d --network host --name tomcat83 billygoo/tomcat8-jdk8

6. none模式 ​

使用--network none指定。在none模式下,并不为Docker容器进行任何网络配置。 也就是说,这个Docker容器没有网卡、IP、路由等信息,只有一个lo。需要我们自己为Docker容器添加网卡、配置IP等。

sh
[root@hadoop102 ~]# docker run -d -it --network none --name alpine1 alpine:3.16
[root@hadoop102 ~]# docker exec -it da207a81357d /bin/sh

Alt text

7. container模式 ​

使用--network container:NAME或者容器ID指定。新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。
Alt text

提示

Alpine Linux是一款独立的、非商业的通用Linux发行版,专为追求安全性、简单性和资源效率的用户而设计。可能很多人没听说过这个Linux发行版本,但是经常用Docker的朋友可能都用过,因为他小,简单,安全而著称,所以作为基础镜像是非常好的一个选择,可谓是麻雀虽小但五脏俱全,镜像非常小巧,不到6M的大小,所以特别适合容器打包。

8. 自定义网络 ​

8.1 自定义需求 ​

使用默认的Docker网络,按照IP地址ping是OK的,按照服务名ping结果不通。 Alt text

8.2 配置自定义网路 ​

  1. 创建自定义网路
sh
[root@hadoop102 ~]# docker network create dev_net 
3db075ce3bc34b05448dee7e172dd4e3a26806c6174c0d08619b57b93e86046d
[root@hadoop102 ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
017827bae454   bridge    bridge    local
3db075ce3bc3   dev_net   bridge    local
ee24cae03bfd   host      host      local
5b30b1f952c6   none      null      local
  1. 新建容器加入上一步新建的自定义网络
sh
[root@hadoop102 ~]# docker run -d -it --network dev_net --name alpine1 alpine:3.16
f84ed5e6a7f92802f1b16ae65e926edf9fdf964556b137b370f20daaaf6cebc4
[root@hadoop102 ~]# docker run -d -it --network dev_net --name alpine2 alpine:3.16
e583a2d879f25fa48936406f19fe86c4b911da0c14c39eb775eb7ecf1e029030
  1. 测试网络
sh
[root@hadoop102 ~]# docker exec -it alpine2 /bin/sh
/ # ping alpine1
PING alpine1 (172.18.0.2): 56 data bytes
64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.064 ms
64 bytes from 172.18.0.2: seq=1 ttl=64 time=0.079 ms
64 bytes from 172.18.0.2: seq=2 ttl=64 time=0.088 ms
64 bytes from 172.18.0.2: seq=3 ttl=64 time=0.094 ms
^C
--- alpine1 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.064/0.081/0.094 ms
/ # ping alpine2
PING alpine2 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.040 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.066 ms
64 bytes from 172.18.0.3: seq=2 ttl=64 time=0.060 ms
^C
--- alpine2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.040/0.055/0.066 ms

自定义网络会维护好主机名和ip的对应关系(ip和域名都能通)

8.3 容器固定IP ​

  1. 创建自定义网络
sh
docker network create –driver bridge –subnet 172.28.0.0/16 –gateway 172.28.0.1 my_custom_network
  1. 容器分配固定IP 启动一个容器时,可以使用–network选项将容器连接到先前创建的自定义网络,并通过–ip选项为其指定一个IP地址。
sh
docker run -d –name my_contAIner –network my_custom_network –ip 172.28.0.2 my_image
  1. 验证IP是否固定
    容器运行后,可以使用docker inspect命令或访问指定IP的服务验证这个容器是否成功被分配到了固定的IP地址。
sh
docker inspect -f ‘{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}’ my_container