对于普通的网络设备,就像一个管道,只有两端,数据从一端进,从另一端出,如物理网卡从外面网络中收到数据转发给内核网络协议栈,从网络协议栈过来的数据转发到外部网络。而 Bridge 有多个端口,数据可以从多个端口进,从多个端口出,原理和交换机类似。
Bridge 的这个特性让它可以接入其他的网络设备,比如物理设备、虚拟设备。Bridge 通常充当主设备,其他设备为从设备,这样的效果就等同于物理交换机的端口连接了一根网线。Bridge是和主机的网络协议栈相连的,也就是说通过bridge的网络数据,是要经过host主机的内核协议栈的进行处理的(我的理解就是net_filter通过iptables设置的rules进行处理)
veth-pair 就是一对的虚拟设备接口,它都是成对出现的。一端连着协议栈,一端彼此相连着
正因为有这个特性,它常常充当着一个桥梁,连接着各种虚拟网络设备。例如在docker中,他们连接容器所处网络namespace和bridge。
此图中veth-pair一个是连接在bridge上的veth,另一个是连接在容器网络namespace上的eth0。veth和eth0彼此相连,veth通过bridge与host的网络协议栈相连,eth0通过容器namespace和容器的网络协议栈相连。这里的容器是在host内部的容器,不考虑跨节点的容器。
安装docker成功后,我们可以看到docker在host机器上默认的创建一个docker0的bridge,这个bridge也是容器的默认的连接方式。在这里我们将用将创建网络namespace来模拟容器,让namespace和我们创建好的bridge连接起来,容器之间可以相互访问,容器可以和host所在网络访问。
首先我们要打开host机器上的ip_forwarding功能,这样host的物理网卡和bridge之间才能forward数据包。IP_FORWARD可以使连接在同一个网络协议栈上的网络接口间进行数据包的转发,适合host上有多块物理网卡,虚拟设备接口,结合iptables的 forward链一起使用。例如主机网络协议栈上连接了30.0/24这个物理网卡和88.0/24这个bridge虚拟设备,一个数据包从30.0/24这块网卡进入网络协议栈,数据包的destination是88.0/24这个网段上的某一个IP地址,内核协议栈发现这个包是去bridge子网的,于是就会把这个数据包forward给bridge连在网络协议栈上的端口并进行处理。如果forward功能没有打开,数据包无法转发到bridge,只能在drop掉。
这个重启后就失效了,要想永久有效请修改文件/etc/sysctl.conf
创建一个bridge br0,激活这个device,并给他分配一个IP地址及掩码192.168.88.1/24。
创建一个网络的namespace ns0,然后在这个网络namespace中执行bash命令(另外起一个terminal做这个事情),如果你还不清楚什么是linux内核namespace,请google相关资料。
执行命令后,我这个terminal已经进入到ns0这个namespace了,这和docker容器的网络namespace是一致的。通过ip命令查询,现在这个命令空间里面只有一个loopback的网络设备,没有其他网络设备相连。然后通过命令使loopback设备active
接下来我们就要创建veth pair,一边和这个ns0连接,一边和br0连接,并给他们分配IP地址。(这些 *** 作不要在ns0里执行bash命令的terminal里面做)
这里创建一个veth pair,veth0和veth0p,并且把veth0和ns0相连,并分配和br0同一个网段的IP地址192.168.88.2,启动veth0p这个设备。返回到ns0下bash的terminal,可以看到多出一个网卡信息并分配到IP地址,但是这个dev是处于LOWERLAYDOWN的状态,这是由于pair另一端还没有接入到br0.
接下来就是把veth0连接到br0上,并启动这个设备。
我们可以看到br0上有一个veth设备连接上来,返回去看ns0下的bash,我们可以看到veth0p的状态已经变成UP。
现在br0的IP是192.168.88.1,ns0的IP地址为192.168.88.2,我们可以在ns0下去ping 192.168.88.1是可以通的,我们可以通过同样的步骤在创建另外一个namespace ns1并分配IP192.168.88.3。ns0,ns1, br0都是可以相互连接的,这里就不重复创建了。
目前为止连接在bridge上的namespace都是可以相互访问,这个体现了bridge虚拟交换机的功能。如果我们还需要容器能访问host所在的网络,我们需要继续配置下面步骤。
在ns0下的bash命令行下设置默认路由,不属于192.168.88.0/24这个网段的数据包全部路由到默认网关br0 192.168.88.1.
由于192.168.88.0/24这个网段和host所在的网路不是一个网络,一切从88.0/24这个网络的数据包要访问外部网络都是要通过host的主机IP去访问的,对于远端服务连接它是不知道88.0/24这个网络的,他接收的数据包的src地址都是host的IP地址,在这里我们需要对88.0/24这个网段的数据包做SNAT。在host的terminal下通过iptables的命令设置。
iptables必须是enable的,并对NAT table的POSTROUTING chain添加一条规则,所有src地址为88.0/24这个网段的数据包,全部走host机器上的物理网卡,通过MASQUERADE选项修改src地址为网卡eno16777736的IP地址。你也可以用SNAT这个参数代替指定一个特殊IP地址。
请自行参考iptables的用法和原理,如果你的host主机上实现设置了其他iptables rules从而阻止了88.0/24这个网络的forward或者routing,需要自行检查一下,每一个机器的网络状态是不一样的没办法全部覆盖。这里推荐一个系列博客很详细的讲解了 iptables 。
这里可以看到我们在ns0下的bash命令行,可以ping通host所在网络的机器30.134和internet上的baidu。现在就完成了整个模拟实验。
ocker安装时会创建一个名为docker0的虚拟网桥。除非我们进行另外的配置,新创建的容器都会自动连接到这个虚拟网桥提供的风格,bridge网络用于同一主机上的docker容器相互通信,连接到同一个网桥的docker容器可以相互通信。
bridge 对宿主机来讲相当于一个单独的网卡设备 对于运行在宿主机上的每个容器来说相当于一个交换机,所有容器的虚拟网线的一端都连接到docker0上。
容器通过本地主机进行上网,容器会创建名为veth的虚拟网卡,网卡一端连接到docker0网桥,另一端连接容器,容器就可以通过网桥通过分配的IP地址进行上网。
我们也可以自定义自己的bridge网络,docker文档建议使用自定义bridge网络
导入容器并启动
验证
创建自定义网络
建一个自定义网络, 可以指定子网、IP地址范围、网关等网络配置
查看docker网络,是否创建成功
查看自定义网络的细节
创建容器bb1,连接到自定义网络,并进入容器验证,可以看到该容器的ip地址为172.22.16.2
验证后按Ctrl+P后,再按Ctrl+Q,从bb1容器退回到主机环境而不关闭容器bb1
再创建一个容器bb2,也连接到网络mynet2中
进入容器,访问bb1容器的ip地址,进行验证
会得到如下 类似回复
Docker网络bridge桥接模式,是创建和运行容器时默认模式。这种模式会为每个容器分配一个独立的网卡,桥接到默认或指定的bridge上,同一个Bridge下的容器下可以互相通信的。我们也可以创建自定义bridge以满足个性化的网络需~~~
【点击右上角加'关注',全国产经信息不错过】
就网络而言,网桥网络是在网段之间转发流量的链路层设备。网桥可以是在主机内核中运行的硬件设备或软件设备。
就Docker而言,网桥网络使用软件网桥,该软件网桥允许连接到同一网桥网络的容器进行通信,同时提供与未连接到该网桥网络的容器的隔离。Docker网桥驱动程序会自动在主机中安装规则,以使不同网桥网络上的容器无法直接相互通信。
桥接网络适用于在同一Docker守护程序主机上运行的容器。为了在不同Docker守护程序主机上运行的容器之间进行通信,您可以在OS级别管理路由,也可以使用 覆盖网络。
启动Docker时,会自动创建一个默认的桥接网络(也称为bridge),并且除非另有说明,否则新启动的容器将连接到它。您还可以创建用户定义的自定义网桥网络。用户定义的网桥网络优于默认bridge 网络。
用户定义的网桥和默认网桥之间的
用户定义的网桥可在容器之间提供自动DNS解析。
缺省桥接网络上的容器只能通过IP地址相互访问,除非您使用被认为是传统的--link选项。在用户定义的网桥网络上,容器可以通过名称或别名相互解析。
想象一个具有Web前端和数据库后端的应用程序。如果调用容器web和db,则db无论应用程序堆栈在哪个Docker主机上运行,Web容器都可以在处连接到db容器。
如果在默认网桥网络上运行相同的应用程序堆栈,则需要在容器之间手动创建链接(使用旧式--link 标志)。这些链接需要双向创建,因此您可以看到,要进行通信的容器要多于两个,这会变得很复杂。或者,您可以 *** 作/etc/hosts容器中的文件,但这会导致难以调试的问题。
用户定义的网桥提供了更好的隔离性。
所有未--network指定的容器都将连接到默认网桥网络。这可能是一种风险,因为不相关的堆栈/服务/容器随后能够进行通信。
使用用户定义的网络可提供作用域网络,其中只有连接到该网络的容器才能通信。
容器可以随时随地从用户定义的网络连接和分离。
在容器的生命周期内,您可以即时将其与用户定义的网络连接或断开连接。要从默认桥接网络中删除容器,您需要停止容器并使用其他网络选项重新创建它。
每个用户定义的网络都会创建一个可配置的网桥。
如果您的容器使用默认的桥接网络,则可以对其进行配置,但是所有容器都使用相同的设置,例如MTU和iptables规则。另外,配置默认桥接网络发生在Docker本身之外,并且需要重新启动Docker。
用户定义的桥接网络是使用创建和配置的 docker network create。如果不同的应用程序组具有不同的网络要求,则可以在创建时分别配置每个用户定义的网桥。
默认网桥网络上的链接容器共享环境变量。
最初,在两个容器之间共享环境变量的唯一方法是使用--linkflag链接它们。用户定义的网络无法进行这种类型的变量共享。但是,存在共享环境变量的高级方法。一些想法:
多个容器可以使用Docker卷挂载包含共享信息的文件或目录。
使用可以一起启动多个容器docker-compose,并且compose文件可以定义共享变量。
您可以使用群体服务来代替独立容器,并利用共享机密和 配置。
连接到同一用户定义网桥网络的容器可以有效地将所有端口彼此公开。为了使容器或不同网络上的非Docker主机可以访问该端口,必须使用或 标志发布该端口。-p--publish
全国产经平台联系电话:010-65367702,邮箱:hz@people-energy.com.cn,地址:北京市朝阳区金台西路2号人民日报社
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)