Docker网络

Docker网络,第1张

Docker网络

使用docker0网桥,docker0的默认网段是172.17.0.0,网关地址为172.17.0.1,通过bridge模式启动的容器,进入容器日内部并使用ip route show指令可以看到其使用的网关就是docker0的网关地址。

宿主机上通过brctl show docker0可以看到docker0桥接的网卡与启动的容器的veth一致。

容器之间的通讯:

从a容器ping b容器

1、数据包从a容器对应的veth流到docker0

2、docker0广播arp寻找b容器对应的地址

3、b容器的veth收到广播并回复docker0自己就是目标

4、a容器与b容器建立连接并实现通信

容器与外网通讯

1、veth数据流到docker0网桥

2、docker0网桥流量流向eth0

3、eth0流量流向对应的目标

只要是eth0可以访问到的,容器就可以访问到

直接使用宿主机的网络,无法指定出入的流量以及暴露的端口,默认暴露出去的地址是0.0.0.0:xxxx,可以直接访问(TODO())。

通过docker指令创建自定义的网桥,由于默认的bridge模式无法为container指定ip,所以需要通过自定义网桥的方式来实现,且自定义网桥可以限制容器之间的相互访问,跨网桥无法互相访问。

使用指定网桥的时候只要通过network指定网桥名称即可,且使用自定义的网桥可以指定容器的IP。并且由于是固定IP,就可以通过iptable来做各种的规则。

这个模式就是指定一个已有的容器,共享该容器的IP和端口。除了网络方面两个容器共享,其他的如文件系统,进程等还是隔离开的。

这个模式下,dokcer不为容器进行任何网络配置。需要我们自己为容器添加网卡,配置IP。

Docker是通过iptable的方式实现流量的控制的

通过添加iptable规则实现

该指令添加了一条nat规则,把所有来自 172.17.0.0/16 网段且即将流出本主机的数据包的源 IP 地址都修改为 10.0.0.100(建议通过添加自定义网桥的方式来做)。

直接通过-p的方式暴露一个端口出去,默认使用的是0.0.0.0,所有网卡均可访问,也可以在参数中指定特定的网卡,例如:-p 192.168.1.1:80:80来指定只能通过该网卡来访问。

查看nat表

iptables -L -n -t nat --line-numbers

查看路由规则

route -n

利用Net Namespace可以为Docker容器创建隔离的网络环境,容器具有完全独立的网络栈,与宿主机隔离。也可以使Docker容器共享主机或者其他容器的网络命名空间,基本可以满足开发者在各种场景下的需要。

Docker支持 4种网络模式 :

1)host模式,--net=host指定,不支持多主机。

2)container模式,--net = container : name_or_id指定,不支持多主机。

3)none模式,--net=none指定,不支持多主机。

4)bridge模式,--net=bridge指定,默认设置,不支持多主机。

启动容器的时候使用Host模式,那么该容器与宿主机共用一个Network Namespace,因此容器将不会虚拟自己的网卡、配置自己的IP等,而是使用宿主机的IP和端口。

采用Host模式的容器,可以直接使用宿主机的IP地址与外界进行通信,无需额外进行NAT转换。由于容器通信时,不再需要通过Linux Bridge等方式转发或者数据包的拆封,性能上有很大优势。当然, Host模式有利也有弊 ,主要包括以下缺点:

1)容器没有隔离、独立的网络栈。容器因与宿主机共用网络栈而争抢网络资源,并且容器崩溃也可能导致宿主机崩溃,这在生产环境中是不允许发生的。

2)容器不再拥有所有的端口资源,因为一些端口已经被宿主机服务、Bridge模式的容器端口绑定等其他服务占用了。

需要补充说明的是,Host模式下的容器仅仅是网络命名空间与主机相同,但容器的文件系统、进程列表等还是和与宿主机隔离的。

Container模式是一种特殊的网络模式。该模式下的容器使用其他容器的网络命名空间,网络隔离性会处于Bridge模式与Host模式之间。当容器与其他容器共享网络命名空间时,这两个容器间不存在网络隔离,但它们与宿主机及其他容器又存在网络隔离。

在Kubernetes体系架构下引入Pod概念,Kubernetes为Pod创建一个基础设施容器, 同一Pod下的其他容器都以Container模式 共享这个基础设施容器的网络命名空间,相互之间以localhost访问,构成一个统一的整体。

与前两种不同,None模式的Docker容器拥有自己的Network Namespace,但并不为Docker容器进行网络配置。该Docker容器没有网卡、IP、路由等信息。需要用户为Docker容器添加网卡、配置IP等。

Bridge模式是Docker默认的网络模式,也是开发者最常使用的网络模式。在这种模式下,Docker为容器创建独立的网络栈,保证容器内的进程使用独立的网络环境,实现容器之间、容器与宿主机之间的网络栈隔离。同时,通过宿主机上的Docker0网桥,容器可以与宿主机乃至外界进行网络通信。

同一宿主机上,容器之间都是连接在Docker0这个网桥上,Docker0作为虚拟交换机使容器间相互通信 。但是, 由于宿主机的IP地址与容器veth pair的IP地址均不在同一个网段 ,故仅仅依靠 veth pair和NameSpace的技术 并不足以使宿主机以外的网络主动发现容器的存在。Docker采用了 端口绑定的方式(通过iptables的NAT) ,将宿主机上的端口流量转发到容器内的端口上,这样一来,外界就可以与容器中的进程进行通信。 iptables的介绍,请点我点我 。

创建容器,并将宿主机的3306端口绑定到容器的3306端口:docker run -tid --name db -p 3306:3306 mysql

在宿主机上,可以通过“iptables -t nat -L -n”,查到一条DNAT规则:DNAT tcp --0.0.0.0/0 0.0.0.0/0 tcp dpt:3306 to:172.17.0.5:3306

Bridge模式的容器与外界通信时,必定会占用宿主机上的端口,从而与宿主机竞争端口资源,这会造成对宿主机端口管理很复杂。同时,由于容器与外界通信是基于三层上iptables NAT,性能和效率损耗是显而易见的。

NAT将地址空间分段的做法引入了额外的复杂度。比如容器中应用所见的IP并不是对外暴露的IP, 因为网络隔离,容器中的应用实际上只能检测到容器的IP,但是需要对外宣称的则是宿主机的IP,这种信息的不对称将带来诸如破坏自注册机制等问题 。

摘抄自陆平的《基于Kubernetes的容器云平台实战》一书的第10章Kubernetes网络


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/bake/7904505.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-11
下一篇2023-04-11

发表评论

登录后才能评论

评论列表(0条)

    保存