当你使用Docker时,你会发现需要了解很多关于网络的知识。Docker作为目前最火的轻量级容器引擎,因此,我们有必要深入了解Docker的网络知识,以满足更高的网络需求。本文介绍了Docker的4种网络模式。
1、首先我们先简单描述一下容器的这几种网络模式:
网络模式 | 简介 |
Bridge | 此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信。 |
none | 该模式关闭了容器的网络功能。 |
Host | 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。 |
Container | 创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。 |
![6c74050be883ff4a3216b6da19e6007b.png](https://i-blog.csdnimg.cn/blog_migrate/8fc643949957015fd9391a9b32421c71.png)
3、我们在使用docker run创建Docker容器时,可以用 --net 参数指定容器的网络模式(如果不指定的话默认是Bridge模式)
Docker可以指定以下4种网络模式:
host模式:使用 --net host 指定。
none模式:使用 --net none 指定。
bridge模式:使用 --net bridge 指定,默认。
container模式:使用 --net container:NAME_or_ID 指定。
二、Host模式
相当于Vmware中的桥接模式,与宿主机在同一个网络中,但没有独立IP地址。众所周知,Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,NetworkNamespace隔离网络等。一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的Network Namespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
三、Bridge模式
相当于Vmware中的Nat模式,容器使用独立network Namespace,并连接到docker0虚拟网卡(Docker进程首次启动时会在当前节点上创建一个名为docker0的桥设备,并默认配置其使用172.17.0.0/16网络,改网络是Bridge模式的一种实现,也是创建容器是默认使用的网络),通过docker0网桥以及Iptables nat表配置与宿主机通信;bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上。
接下来介绍一下docker0虚拟网桥的工作方式:
当Docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。接下来就要为容器分配IP了,Docker会从RFC1918所定义的私有IP网段中,选择一个和宿主机不同的IP地址和子网分配给docker0,连接到docker0的容器就从这个子网中选择一个未占用的IP使用。如一般Docker会使用172.17.0.0/16这个网段,并将172.17.0.1/16分配给docker0网桥(在主机上使用ifconfig命令是可以看到docker0的,可以认为它是网桥的管理接口,在宿主机上作为一块虚拟网卡使用)。单机环境下的网络拓扑如下,主机地址为10.10.0.186/24。
Bridge 桥接模式的实现步骤主要如下:
1、 Docker Daemon(守护进程) 利用 veth pair 技术,在宿主机上创建两个虚拟网络接口设备,假设为veth0 和 veth1。而 veth pair 技术的特性可以保证无论哪一个veth 接收到网络报文,都会将报文传输给另一方。
2、Docker Daemon 将 veth0 附加到 Docker Daemon 创建的 docker0 网桥上。保证宿主机的网络报文可以发往 veth0;
3、 Docker Daemon 将 veth1 添加到 Docker 容器所属的 namespace 下,并被改名为 eth0。如此一来,保证宿主机的网络报文若发往 veth0,则立即会被 eth0 接收,实现宿主机到Docker 容器网络的联通性,同时,也保证 Docker 容器单独使用 eth0,实现容器网络环境的隔离性。
bridge 桥接模式下的 Docker 容器在使用时,并非为开发者包办了一切。最明显的是,该模式下 Docker 容器不具有一个公有 IP,即和宿主机的 eth0 不处于同一个网段。导致的结果是宿主机以外的世界不能直接和容器进行通信。虽然 NAT 模式经过中间处理实现了这一点,但是 NAT 模式仍然存在问题与不便,如:容器均需要在宿主机上竞争端口,容器内部服务的访问者需要使用服务发现获知服务的外部端口等。另外 NAT 模式由于是在三层网络上的实现手段,故肯定会影响网络的传输效率。
END
⇣⇣⇣关注【容器迷宫】扩展我们的小知识⇣⇣⇣
![490eaa67c661ca67eaa110c95d1021ea.png](https://i-blog.csdnimg.cn/blog_migrate/a1e8b2e168a160346c47ab89641c5704.jpeg)