Docker网络模式学习

最后更新于 2023-06-28 464 次阅读


Docker本身拥有4种网络模式:Bridge(桥接模式)、none(不配置网络)、host(主机网络)、container(容器网络连通)

一.常用网络信息的命令

#查看当前docker的网络信息
docker network ls 
​
#使用上边的命令查询到的网络id,或者bridge、host或者是自己创建的自定义网络
docker network inspect 网络id或者网络名称 
​
#创建自定义网络
docker network create [option] 
​
#在docker run时可以加上--net这一个参数改变容器的网络,可以自定义网络,也可以是其他网络模式
docker run --net mynetwork01 centos
--net 自定义网络/网络模式
​
#手动配置容器的DNS
docker run --dns 114.114.114.114 <image-name>
​
​

二.Bridge模式

1.简介

Docker的网络使用了Linux的Veth-pair技术,docker本身在启动的时候,会创建一个自身的虚拟网卡docker0,这个docker0本身是可以作为一个路由器,来连通docker的各个容器之间的网络。

每个容器在创建时,默认都会创建1对虚拟网卡,从 docker0 子网中分配一个 IP 给容器使用,并设置 docker0 的 IP 地址为容器的默认网关。在主机上创建一对虚拟网卡 veth pair 设备,Docker 将 veth pair 设备的一端放在新创建的容器中,并命名为 eth0(容器的网卡),另一端放在主机中,以 vethxxx 这样类似的名字命名,并将这个网络设备加入到 docker0 网桥中。可以通过 brctl show 命令查看,例如下图

bridge 模式是 docker 的默认网络模式,不写--network 参数,就是 bridge 模式。使用 docker run -p 时,docker 实际是在 iptables 做了 DNAT 规则,实现端口转发功能。可以使用 iptables -t nat -vnL 查看当前服务器上DNAT的信息,例如下图,宿主机的8080映射了容器的8080端口。

2.自定义网络

在默认的Bridge模式下,如果我创建了两个容器,假设centos01容器想要ping通centos02容器,需要知道centos02容器的IP才可以ping,没办法通过ping容器名字来ping通02容器。正如下图,我创建了两个容器。

如下图所示,centos01和02容器皆可以通过ping对方的IP然后ping通对方。但是我们有时候在生产环境中,我们的容器经过重启后,可能IP会发生变化,如果我们容器之间只能通过知道ip来ping的话,有时就会相当被动,如果此时我们容器之间可以通过容器名来直接ping通对方的话,那在一些生产环境里变会十分方便。

此时我们可以创建一个自定义网络,其好处就是,在创建自定义网络,并将相应的容器添加进去后,可以实现容器间直接ping容器名来ping通容器

#首先先自定义一个网络,网络模式也是选择bridge模式

docker network create --driver 网络模式 --subnet 网段/子网掩码 --gateway 网关 网络名
#例如:docker network create --driver bridge --subnet 192.100.1.0/24 --gateway 192.100.1.1 mynetwork01 
​
​#然后将我们的对应的容器,添加进这个自定义网络中
​
docker run -P -it --name centos01 --net mynetwork01 centos /bin/bash
​
docker run -P -it --name centos02 --net mynetwork01 centos /bin/bash
​
#然后进行ping测试
​
docker exec centos01 ping centos02
​
docker exec centos02 ping centos01

如下图,可见已经可以通过容器名来ping通了

3.docker不同网络的连通

docker中,若是想实现不同自定义网络之间的互联(相当于不同vlan之间想要连接),我们又该如何操作?

如上图所示这种情况,我们可以使用docker network conect"命令来达成我们的目的。

docker network connect [option] network container
​
#例如上图中的redis:
docker netwrok connect mysql ridis1

docker netwrok connect mysql ridis2
​
#上图中的mysql
docker network connect redis mysql1

docker network connect redis mysql2

为什么可以这样呢?我们inspect一下ridis1的网络信息,看看发生了什么

可见在添加了docker network connect命令后,docker给redis容器添加了mysql网络的IP,所以就实现了两个不同自定义网络下的容器的网络互通。

三.none模式

在none模式下,容器不会自己配置网口、Ip、路由等信息。需要我们自己为docker容器添加网口及IP。

这种网络模式下容器只有 lo 回环网络,没有其他网卡。none 模式可以在容器创建时通过--network none 来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。

四.host模式

host(主机)模式下,容器不会创建自己的虚拟网卡,而是和宿主机共用一个物理网卡和端口。若是宿主机已经使用的端口,则容器没有办法再使用,网络隔离性较差。

但是容器的文件系统、进程列表还是和宿主机是隔离开的。

配置命令为:

docker run --net host <image-name>

五.container模式

container(容器)模式下,允许一个容器共享另一个容器的网络。

新创建的容器不会创建自己的网卡和IP,而是可以直接使用另外一个容器的IP和端口范围。两个容器的进程可以通过lo网卡设备通信。

docker run --net container:container-ID <image-name>
​
#例:docker run  -it --name centos2 --net container:centos1 centos /bin/bash

如下图,centos1的ip地址为192.100.1.2,然后让我们看看centos2共享centos1后的网络信息

在centos2中,网口设定这一块值均为空

但是网口模式这里显示模式为“container”,且跟随的容器id恰巧为centos1的容器ID,所以可知centos2和centos1共享的是一个网络配置

六.Veth-pair是什么

veth pair 全称是 Virtual Ethernet Pair,是一个成对的端口,所有从这对端口一 端进入的数据包都将从另一端出来,反之也是一样。 引入 veth pair 是为了在不同的 Network Namespace 直接进行通信,利用它可以直接将两个 Network Namespace 连接起来。

所以在bridge模式中,数据可以在容器和docker0之间的veth端口中穿梭。