docker网络详解

docker网络是docker非常重要的一部分知识,也是docker集群必备的,所以这篇文章就详细说一下有关docker网络的相关知识。

首先安装Docker时,它会自动创建三个网络,bridge(创建容器默认连接到此网络)、 none 、host

网络模式 简介
Host 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
Bridge 此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,通过docker0网桥以及Iptables nat表配置与宿主机通信。
None 该模式关闭了容器的网络功能。
Container 创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围。
自定义网络

下面分别介绍一下Docker的各个网络模式。

一、docker四种网络模式

1.1 Host模式

相当于Vmware中的NAT模式,与宿主机在同一个网络中,但没有独立IP地址。

众所周知,Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。

一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的Network Namespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。

例如,我们在172.25.6.1/24的机器上用host模式启动一个ubuntu容器

1.2 Container模式

在理解了host模式后,这个模式也就好理解了。这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。

1.3 None模式

该模式将容器放置在它自己的网络栈中,但是并不进行任何配置。实际上,该模式关闭了容器的网络功能,在以下两种情况下是有用的:容器并不需要网络(例如只需要写磁盘卷的批处理任务)。

1.4 Bridge模式

相当于Vmware中的Briage模式,容器使用独立network Namespace,并连接到docker0虚拟网卡(默认模式)。通过docker0网桥以及Iptables nat表配置与宿主机通信;bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上。下面着重介绍一下此模式。

二、Bridge模式

2.1 Bridge模式的拓扑

当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。

2.2 Docker:网络模式详解

Docker完成以上网络配置的过程大致是这样的:

(1)在主机上创建一对虚拟网卡veth pair设备。veth设备总是成对出现的,它们组成了一个数据的通道,数据从一个设备进入,就会从另一个设备出来。因此,veth设备常用来连接两个网络设备。
(2)Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0。另一端放在主机中,以veth65f9这样类似的名字命名,并将这个网络设备加入到docker0网桥中
(3)从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。
运行容器:

进入容器查看:

你会发现每当你创建一个容器,系统都会在本机创建一个veth虚拟网卡,然后在docker容器内部创建一个与之配对的eth0(默认根据docker0网段分配一个ip地址给容器),以此来完成容器与容器,容器与主机之间的通信。

画图说明就是这个样子:

2.3 bridge模式下容器的通信

在bridge模式下,连在同一网桥上的容器可以相互通信(若出于安全考虑,也可以禁止它们之间通信,方法是在DOCKER_OPTS变量中设置–icc=false,这样只有使用–link才能使两个容器通信)。

Docker可以开启容器间通信(意味着默认配置–icc=true),也就是说,宿主机上的所有容器可以不受任何限制地相互通信,这可能导致拒绝服务攻击。进一步地,Docker可以通过–ip_forward和–iptables两个选项控制容器间、容器和外部世界的通信。

容器也可以与外部通信,我们看一下主机上的Iptable规则,可以看到这么一条

-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

这条规则会将源地址为172.17.0.0/16的包(也就是从Docker容器产生的包),并且不是从docker0网卡发出的,进行源地址转换,转换成主机网卡的地址。这么说可能不太好理解,举一个例子说明一下。假设主机有一块网卡为eth0,IP地址为10.10.101.105/24,网关为10.10.101.254。从主机上一个IP为172.17.0.1/16的容器中ping百度(180.76.3.151)。IP包首先从容器发往自己的默认网关docker0,包到达docker0后,也就到达了主机上。然后会查询主机的路由表,发现包应该从主机的eth0发往主机的网关10.10.105.254/24。接着包会转发给eth0,并从eth0发出去(主机的ip_forward转发应该已经打开)。这时候,上面的Iptable规则就会起作用,对包做SNAT转换,将源地址换为eth0的地址。这样,在外界看来,这个包就是从10.10.101.105上发出来的,Docker容器对外是不可见的。

那么,外面的机器是如何访问Docker容器的服务呢?我们首先用下面命令创建一个含有web应用的容器,将容器的80端口映射到主机的80端口。

docker run --name=nginx_bridge --net=bridge -p 80:80 -d nginx

然后查看Iptable规则的变化,发现多了这样一条规则:

-A DOCKER ! -i docker0 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.2:80

此条规则就是对主机eth0收到的目的端口为80的tcp流量进行DNAT转换,将流量发往172.17.0.2:80,也就是我们上面创建的Docker容器。所以,外界只需访问10.10.101.105:80就可以访问到容器中的服务。

除此之外,我们还可以自定义Docker使用的IP地址、DNS等信息,甚至使用自己定义的网桥,但是其工作方式还是一样的。

三、自定义网络

以上我们使用的都是默认的bridge网络,利用默认的docker0虚拟网卡作为路由器以及veth-pair技术将各个容器联通,但有个很大的缺点就是这些容器只能通过ip ping通,不可以通过容器名进行Ping通,而且还会将所有容器全部放在一个网段当中不易管理,这其实在以后的很多实际生产环境当中是很不方便的,因此今天我们还要讲一个生产环境当中最常用的一个docker网络,也就是自定义网络。

3.1创建自定义网络mynet

3.2查看创建好的自定义网络



通过docker network inspect mynet可以看到关于mynet的详细信息。

3.3启动容器并指定网络为mynet

启动tomcat01和tomcat02 --net mynet,会发现mynet自定义网络中添加了tomcat01和tomcat02。

3.4测试容器间通信
会发现无论是ping ip还是容器名,只要是在同一个自定义网络下的容器都可以ping通

3.5如何实现不同网络下的容器互通

以上是同一个自定义网络的容器之间相互通信,如果想要实现不同网络之间的互通就要用到docker network connect命令

首先创建两个默认docker0下的两个容器

然后用我们刚才mynet下的容器去Ping该容器,发现无法ping通

用docker network connect命令将两个不同虚拟网络下的容器进行联通操作


然后查看mynet网络,会发现不同网络的tomcat01被添加到mynet当中

再次ping测试,发现两个不同网络的容器也可以ping通了

至此docker网络就讲解的差不多了,了解了这部分知识以后,对以后的docker集群的搭建和维护工作会有很大的帮助,希望这篇文章可以帮助到学习docker的小伙伴们。

posted @ 2020-09-14 00:04  渡边灬  阅读(1953)  评论(0编辑  收藏  举报
/* 看板娘 */