当你安装Docker时,它会自动创建三个网络,使用docker network ls
命令可以列出这些网络:
[root@master ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
8ec195128f2b bridge bridge local
cce37a6963d8 host host local
5f91f09783a0 none null local
而docker的网络模式则有4种。我们在启动docker容器时可以使用用 --net 选项指定容器的网络模式:host模式、none模、bridge模式、container模式,使用 --net=container:NAME_or_ID指定
host模式
这个模式类似于虚拟机中的桥接模式,和宿主机共用一个Network Namespace,容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口
Container模式
很好理解,指定新创建的容器和已经存在的一个容器共享一个Network Namespace
none模式
none 模式就是container 没有任何的网络,不给它创建网络,我们可以自己去自定义实现
Bridge模式
当Docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中
那么docker容器是如何与外界通信的呢?
假设我们在容器中ping我的博客shiyujun.cn。IP包首先从容器发往自己的默认网关docker0,包到达docker0后,也就到达了主机上。然后会查询主机的路由表,发现包应该从主机的eth0发往主机的网关上。接着包会转发给eth0,并从eth0发出去。在发出去之前,会有Iptable规则对包做SNAT
转换,将源地址换为eth0的地址。这样,在外界看来,这个包就是从宿主机上发出来的
那么外界的流量是如何进入容器的呢?
我们知道,容器启动后都需要与宿主机绑定一个端口,而当外界流量请求到那个端口时Iptable规则发现这个端口数容器使用的,就会进行DNAT
转换将包发送到eth0,然后eth0会转发到docker0紧接着就到达了具体的容器中了