如下内容参考:https://docs.docker.com/network/#network-drivershtml
Docker容器和服务如此强大的缘由之一是您能够将它们链接在一块儿,或者将它们链接到非Docker工做负载。Docker容器和服务甚至不须要知道它们部署在Docker上,或者它们的对等体是否也是Docker工做负载。不管您的Docker主机是运行Linux,Windows仍是二者兼而有之,您均可以使用Docker以与平台无关的方式管理它们。docker
Docker的网络子系统是可插拔的,使用驱动程序。默认状况下存在多个驱动程序,并提供核心网络功能:网络
bridge
:默认网络驱动程序。若是未指定驱动程序,则这是您要建立的网络类型。当您的应用程序在须要通讯的独立容器中运行时,一般会使用桥接网络。见 桥接网络。session
host
:对于独立容器,移除了容器和Docker主机之间的网络隔离,并直接使用主机的网络。host
仅适用于Docker 17.06及更高版本上的群集服务。请参阅 使用主机网络。dom
overlay
:overlay网络将多个Docker守护程序链接在一块儿,并使群集服务可以相互通讯。您还可使用overlay网络来促进群集服务和独立容器之间的通讯,或者在不一样Docker守护程序上的两个独立容器之间进行通讯。此策略无需在这些容器之间执行OS级别的路由。请参阅overlay网络。ide
macvlan
:Macvlan网络容许您为容器分配MAC地址,使其显示为网络上的物理设备。Docker守护程序经过其MAC地址将流量路由到容器。macvlan
在处理指望直接链接到物理网络的传统应用程序时,使用驱动程序有时是最佳选择,而不是经过Docker主机的网络堆栈进行路由。见 Macvlan网络。ui
none
:对于此容器,禁用全部网络。一般与自定义网络驱动程序一块儿使用。none
不适用于群组服务。请参阅 禁用容器网络。spa
网络插件:您可使用Docker安装和使用第三方网络插件。这些插件可从 Docker Store 或第三方供应商处得到。有关安装和使用给定网络插件的信息,请参阅供应商的文档。插件
只有在使用Docker EE并使用通用控制平面(UCP)管理Docker服务时,才能实现如下两个功能:3d
该HTTP路由网格 可让你分享多个服务之间的相同的网络IP地址和端口。根据客户端的请求,UCP使用主机名和端口的组合将流量路由到适当的服务。
会话粘性容许您在HTTP标头中指定信息,UCP用于将后续请求路由到同一服务任务,适用于须要有状态会话的应用程序。
如今您已了解Docker网络的基础知识,请使用如下教程加深理解:
在单机docker环境下,网络模式主要有4种。
Bridge模式是Docker默认的网络设置,此模式会为每个容器分配Network Namespace、设置IP等,并将并将一个主机上的Docker容器链接到一个虚拟网桥上。
当Docker server启动时,会在宿主机上建立一个名为docker0的虚拟网桥,此主机上启动的Docker容器会链接到这个虚拟网桥上。虚拟网桥的工做方式和物理交换机相似,这样主机上的全部容器就经过交换机连在了一个二层网络中。
接下来就要为容器分配IP了,Docker会从RFC1918所定义的私有IP网段中,选择一个和宿主机不一样的IP地址和子网分配给docker0,链接到docker0的容器就从这个子网中选择一个未占用的IP使用。如通常Docker会使用172.17.0.0/16这个网段,并将172.17.0.1/16分配给docker0网桥。
从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上建立一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新建立的容器中,并命名为eth0(容器的网卡),另外一端放在主机中,以vethxxx这样相似的名字命名,并将这个网络设备加入到docker0网桥中。能够经过brctl show命令查看。
bridge模式是docker的默认网络模式,不写--net参数,就是bridge模式。使用docker run -p时,docker实际是在iptables作了DNAT规则,实现端口转发功能。可使用iptables -t nat -vnL查看。
例子:
a、建立一个bridge:test-bs
b、建立2个container链接到test-bs
c、查看test-bs
[root@localhost mnt]# docker network inspect test-bs
[
{
"Name": "test-bs",
"Id": "ddad9fadb9d2defb77fc104afe38864bda800f24badbcc3200cd811fd491d31e",
"Created": "2018-11-18T20:51:35.991550414+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.18.0.0/16",
"Gateway": "172.18.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"01229f1d1846d95c28c24e4495c2b341536e4b0eb03e85edb2e0a8a4e9fb2761": {
"Name": "bs3",
"EndpointID": "2c3a2fecda6097f5478fa46b97f59e11b02d7d1ed38235d93d0f5cc03a225af4",
"MacAddress": "02:42:ac:12:00:02",
"IPv4Address": "172.18.0.2/16",
"IPv6Address": ""
},
"da62f9854b9577dca817d73695388e1e4c5aaf695da87deb0bd5189e6a660582": {
"Name": "bs4",
"EndpointID": "3b692c438994636144eb3646338bc748935e5967b538185bcac9cfadf28a763c",
"MacAddress": "02:42:ac:12:00:03",
"IPv4Address": "172.18.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
从上面能够看到,test-bs下面有2个容器,bs3和bs4,ip地址分别为172.18.0.2/16和172.18.0.3/16。
若是启动容器的时候使用host模式,那么这个容器将不会得到一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出本身的网卡,配置本身的IP等,而是使用宿主机的IP和端口。可是,容器的其余方面,如文件系统、进程列表等仍是和宿主机隔离的。
建立一个容器,host模式:
docker run -itd --name bs5 -h bs5 --net=host busybox
进入容器后,查看网络:
发现网络环境和宿主机如出一辙。
使用none模式,Docker容器拥有本身的Network Namespace,可是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。须要咱们本身为Docker容器添加网卡、配置IP等。
建立一个none模式的容器:
从上图能够看出,none模式不会配置任何网络,须要本身配置。
container模式指定新建立的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新建立的容器不会建立本身的网卡,配置本身的 IP,而是和一个指定的容器共享 IP、端口范围等。一样,两个容器除了网络方面,其余的如文件系统、进程列表等仍是隔离的。两个容器的进程能够经过 lo 网卡设备通讯。
原理图以下:
建立一个container模式的容器:
进入容器查看,发现新建的容器和容器bs4如出一辙!
Docker主要经过netfilter/iptables实现网络通讯。
一、 容器访问网络的原理主要依赖docker0(宿主机)和veth pair(容器)以及防火墙的SNAT和DNAT来实现和外部网络的交流。
二、容器要出外网,经过veth pair设备先进入到宿主机,而后在宿主机中经过SNAT,将源IP替换为Docker0的出口ip路由出去。
三、外界要访问容器,先会到达容器的eth0,而后容器会根据要访问的目标地址进行DNAT,经过宿主机上的路由进行转发到内部容器,返回给外界。
容器经过将服务的实际端口在宿主机上进行端口映射,外部客户端经过链接宿主机的映射端口来访问容器内的服务。