Docker 网络模型/overlay 跨主机网络

之前说了overylay fs,但是运行一个容器进程还需要最后一步,就是它的网络配置。

docker本身在创建之初就有自己的网络驱动器,叫container network manager,CNM,本身这个CNM会支持多种模式。

下面来看看,为了让容器模拟成虚拟机还需要做什么配置。

容器网络


none 模式:你可以全权去处理自己的网络配置,它不帮你做任何的配置,但是它帮你将网络的namespace创建出来,如果上层有kubernetes,那么kubernetes本身是希望自己去调用自己的网络插件去配置网络的,也就是会使用Null方式去创建容器镜像。

host 模式:namespace会分很多种,其中就包含了网络的namespace,所谓host模式就是虽然创建了一个容器,但是我的容器进程是没有自己独立的网络配置的,复用的是主机的网络。

container 模式:可以启动一个新的容器,新的容器不要自己的网络,但是希望复用其他容器的网络,这样模式会起到什么作用呢?可以运行多个容器进程,这多个容器进程会复用一个网络,这样在运行的时候共享同一个网络namespace,这样都可以通过localhost去调用,彼此网络上可见。

默认的 bridge 模式:.......

上面是单台的情况下,容器如何和外面的网络互联互通。

如果跨主机网络。一台主机上面容器和另外一台主机上面容器,它们之间如何互相通信。

一种常用的就是overlay:通常容器网络和基础架构底层网络,它是两个网络,容器网络在基础架构这里是不认的,容器会有一个自己的子网,这个子网在底层网络里面是不能路由的,容器网络里面的网络请求是没办法在基础架构里面,这种数据包是传递不过去的。

当容器里面出来的数据包,在主机要往外传输的时候,在主机这里封一层,在原始数据包基础上通过各种协议再加一个包头。这个包头会将当前的主机地址作为原地址,把对端的主机地址作为目标地址。封装好的数据包就可以在基础架构里面进行传输了,这个包到对端主机之后,有一个解包的过程,就是将外层主机这一层数据包解开,然后内部就剩下容器数据包头,这样包就可以传递到对端的容器。

这种封包解包的技术叫做overylay。

还有一种是underylay:就是容器网络和主机网络是一样的,容器的ip段在主机这里也知道如何路由的,也就是在基础架构层知道如何路由,这样的话数据包就可以自由的传输,它的局限性在容器网络和主机网络会共用,但是容器对ip的消耗是巨大的,如果你要使用underlay网络,那就需要对网络进行一个很好的规划,比如ip多大的网段分给容器,多大的网段分给基础架构。

NULL模式


 在安装完docker,docker会在主机上面安装一个bridge设备,桥接设备,这个设备主要是用来连接主机上面所有容器的,所谓的桥接设备可以理解为类似的集线器,这个设备上面有很多网口,当你将一台主机它的网线连到这个bridge设备上之后,或者多台主机连接到bridge之后,他们之间就互通了。

[root@docker ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.024253e8f7ac	no	

可以看到有docker0这样一个设备。要让容器的网络和主机的网络互通,第一为容器配置网络,为容器的网络浅显出来,到主机的namespace,插到docker0的bridge上面,这样主机网络就可以和容器网络实现互通。

  

默认模式  网桥和NAT


在自己的主机上面有eth0网卡,上面有主机的ip,docker本身会启动docker0的bridge,默认以172,17.0.1作为网关弟子配置在bridge上面,启动任意一个容器docker会默认的从这个IP段选一个ip给到这个容器,同时创建虚拟链路veth pair,一端插在docker0上面,一端插在容器网络namespace里面,并且配给里面的eth0,bridge设备可以将上面所有的网口做连接的容器都互通起来,所以所有的容器都是互通的。

如果要将容器内的服务发布到主机外面,通过-p来将主机的端口映射到容器内部,最底层的实现逻辑是通过主机上面的iptable来做一个端口转发。

 underlay


在每台主机上有自己的bridge,这个bridge上面有自己的ip,会给这个bridge一个ip,当用户去运行每个容器的时候,在同一个ip段为每个容器分配一个ip,eth0是没有配置ip的,ip配置到网桥上面了,下层路由是认识这个ip段的,只需要、在这个ip段内选取ip配置容器,容器的ip和主机的ip实际上没有本质区别,只要基础架构网络能够认识这个IP段,那么这个IP就可以出去,能够到对端的容器里面。

所谓underlay就是不划分独立的容器网络,而是容器网络融入到我的基础架构网络里面,好处是方案会简单,局限是要去做规划,因为容器对ip的需求非常大,这就需要规划好整个的ip分配,避免造成ip的浪费。

overlay


常用的模式是vxlan,可能在虚拟化技术里面vxlan是更加常用的一种方式。

 抛开容器,有两台虚机,第一台虚机的ip是100,第二台是101,底层基础网段是165的网段,虚拟机是10.1网段,这个网段在基础架构这一层是无法路由的,这就需要基于vxlan的技术,这个包在经过主机往外发送的时候,一般会有vtep设备,这个vetp设备用来干嘛呢?

相当于将原始包进行一个封包,首先vetp设备会知道虚机10.1.1.100,它所在的主机ip,也知道对端虚机所在的主机ip,所以这个包经过vetp设备之后,它就在原始包的基础之上,加了一层vxlan的包头,vxlan的包头事实上它本身是udp协议,加了vxlan的id,这个udp的包头就封装了外层的原始ip,就是在原来的原始包基础之上加了一层包头,这个包的原始ip就是这个主机的ip,目标ip就是对端的主机ip。

封装完之后,所有的路由设备,它是知道主机的路由信息的,当你请求的目标ip为hostb的时候,路由器知道往哪边转发。

这个包就被转到了对端vetp设备,在经过vetp设备之后,看到是IP vxlan的包,它就会将外层的包拆掉,只留里层的包。到host b之后如图就剩下里面的部分了,主机的那层被扒掉了没有了。所以hostb就会去校验目标ip是什么,发现目标IP为10.1.1.101那么就到虚拟机里面去了。

所以从虚拟机层面来看,100要将请求发送到101,他认为是直接过去的,但是事实上正真的数据包传输,是经历的封包,路由解包的过程。

有些网络插件是支持overlay的,比如说flannel, 或者是calico都支持overlay模式的。

以flannel为例,它会在每台主机上面,会有一个flanneld的设备,容器网络要做互相调用的时候,也就是一个pod访问另外一个pod,那么这个包就需要往外走,容器网络在基础架构又是不可路由的网络,那么使用overlay模式,这个包会从容器网络出来,要经由主机网络往外发的时候,这个包就会被flanneld设备去处理,处理的时候就相当于在外面加了一个udp包头,然后再去封装ip包头,那么ip包头里面放了原主机的ip和目标主机的IP。

这个包封装好了之后,这个包就经由底层网络,传到对端主机上面,然后再由对端的flanneld去处理,flanneld会将外层包去掉,然后将内层的包交由pod去处理。

可以通过抓包工具去抓取这些包,通过看它的包头,就能够理解这种overlay的包到底是什么样的一个格式。

上面是一个flanneld的包案例,本身是通过flannel这种网络模式去ping对端的容器ip,ping本身是icmp包,所以icmp包会在整个包的最内层,在这基础之上又封装了一个udp的包头,有个udp的协议,有自己的端口。在上面有层ip包,ip包里面列好了源和目标的ip。这就是overlay工作原理。

当然overlay有很多技术,比如vxlan IPIP GRE,各有利弊。

猜你喜欢

转载自blog.csdn.net/qq_34556414/article/details/125365998