一、虚拟机网络模式
在理解docker网络隔离前,先看下之前虚拟机里对网络的处理,VirtualBox中有4中网络连接方式:
- NAT
- Bridged Adapter
- Internal
- Host-only Adapter
VMWare中有三种,其实他跟VMWare 的网络连接方式都是一样概念,只是比VMWare多了Internal方式。
要让自己(或别人)理解深刻,方法就是做比较和打比方,比较之间的不同和相同,拿熟知的事物打比方。先来一张图,通过这张图就很容易看出这4种方式的区别:
NAT:Network Address Translation,网络地址转换,NAT模式是最简单的实现虚拟机上网的方式,虚拟机访问网络的所有数据都是由主机提供的,虚拟机并不真实存在于网络中,主机与网络中的任何机器都不能查看和访问到虚拟机的存在。虚拟机可以访问主机能访问到的所有网络,但是对于主机以及主机网络上的其他机器,虚拟机又是不可见的,甚至主机也访问不到虚拟机。
Bridged Adapter(网桥模式)是通过主机网卡,架设了一条桥,直接连入到网络中了。因此,它使得虚拟机能被分配到一个网络中独立的IP,所有网络功能完全和在网络中的真实机器一样。网桥模式下的虚拟机,你把它认为是真实计算机就行了。
Internal(内网模式)就是内部网络模式:虚拟机与外网完全断开,只实现虚拟机于虚拟机之间的内部网络模式。
Host-only Adapter(主机模式)是一种比较复杂的模式,前面几种模式所实现的功能,在这种模式下,通过虚拟机及网卡的设置都可以被实现。我们可以理解为虚拟机在主机中模拟出一张专供虚拟机使用的网卡,所有虚拟机都是连接到该网卡上的,我们可以通过设置这张网卡来实现上网及其他很多功能,比如(网卡共享、网卡桥接等)。
二、docker的4种网络模式
Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的Network Namespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。docker根据如何为容器分配Network Namespace分为4种网络模式。
•bridge模式,使用--net=bridge指定,默认设置。
bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上。在bridge模式下,连在同一网桥上的容器可以相互通信(若出于安全考虑,也可以禁止它们之间通信,方法是在DOCKER_OPTS变量中设置--icc=false,这样只有使用--link才能使两个容器通信)。默认docker容器对外是不可见的,外部主机访问主机的ip端口,然后通过DNAT转换到docker容器的ip和端口,从而间接的访问docker容器服务。也可以通过pipework等工具设置每个容器ip对外部主机可见。
•host模式,使用--net=host指定。
启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。容器中应用的ip和端口和宿主主机共用。
•container模式,使用--net=container:NAME_or_ID指定。
指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。
•none模式,使用--net=none指定。
这种模式下,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。