Virtual Ethenet技术

这篇博客详细介绍了Virtual Ethernet技术在网络隔离中的应用,特别是如何利用network namespace为每个容器创建独立的网络空间。通过虚拟网卡和iptables规则,实现了外界访问容器内部以及容器对外界的数据通信。此外,还探讨了容器的创建过程,端口映射和路由表配置,确保网络流量正确路由。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://blog.youkuaiyun.com/coolboylai2/article/details/25410401

 

2.7.1 综述

网络隔离主要是利用namespace技术中的networknamespace。当创建一个instance时,首先容器会在DEA这台主机上创建一对虚拟网卡。将其中一个网卡留在宿主机的default network namespace,另一张网卡留在container networknamespace。然后对两张网卡的IP,掩码进行配置。

 外界需要访问容器的时候,首先通过访问宿主机上的某一个端口,然后通过DNAT进行转换,把宿主机的某一个端口映射到容器里面的某一端口。容器里面需要访问外界的时候,通过容器内的虚拟网卡(这对虚拟网卡很有意思,任何一端接受到的消息都会发送给另外一个端),然后访问到容器外界对应的虚拟网卡。IPtables会把所有的容器的源地址转换为宿主机的IP(SNAT),然后根据Kernel Route Table表,根据不同的目的地址发往到对应的网卡。

在容器内部的KernelRoute Table会添加一个缺省的网关,这个网关就是容器外对应的张虚拟网卡。容器内对外界的所有访问都会通过这对虚拟网卡。

 

2.7.2 网络拓扑结构


 输入流:

访问主机上的某一个端口,iptables对数据包的目的地址进行DNAT转换。然后根据KernelRoute Table将数据包分发给相应的虚拟网卡,容器外虚拟网卡接收到这些信息之后发完容器内对应的虚拟网卡,再把数据交由Application。

 

输出流:

容器内的数据包会通过首先发送到容器内对应的虚拟网卡,然后发送给容器外对应的虚拟网卡,经过Iptables的源地址转换,把数据包的源地址换成物理网卡IP地址,然后再发送出去。

2.7.3 Network Namespace

     Network Namespace网络资源隔离的一种技术,是为了给每一个容器创建一个独立的网络空间。在clone或者fork一个子进程的时候,指定相应的flag便可创建一个独立的namespace。使用network namespace的意义在于,在每一个容器内部看来,它们都认为自己有一张独立的网卡,内核路由表以及iptables规则等。并且一个容器无法感知到其它容器的存在。

2.7.4 容器的创建

      容器创建网络空间隔离,主要是用内核提供的Virtual Ethenet技术,内核提供了iplink add指令,为我们创建一对虚拟网卡(interface-0,interface-1)。这对虚拟网卡的任何一端收到消息将会发送给了另外一端。刚开始这些虚拟网卡都是存在于宿主机的default网络空间中,在启动whd子进程的时候通过ip link set指令将interface-1移入wshd这个子进程的的网络空间中,而interface-0则继续留在宿主机的default网络空间中。

create一个容器,warden会为我们创建一对虚拟网卡,如下:

w-17k4bbqqh7o-0   Link encap:以太网  硬件地址5a:87:b0:2f:aa:e5 

   inet 地址:10.254.0.1  广播:10.254.0.3  掩码:255.255.255.252

容器内的一个网卡

w-17k4bbqqh7o-1   Link encap:Ethernet  HWaddr 1e:43:92:cd:bd:55 

         inet addr:10.254.0.2 Bcast:10.254.0.3 Mask:255.255.255.252

每一个容器会占用4个IP地址,相当于一个很小的子网,Ip地址使用范围参见4.5.1.

在DEA启动容器的时候会执行两次net_in  操作,但是端口没有指定,从默认的61001端口开始,容器的端口也是一样。端口使用范围4.5.2

DEA在启动一个实例的时候会进行两次NETIN操作,把主机上的两个端口映射到容器里面相应的端口。端口映射即在宿主机的nat表中添加两条转换规则把宿主机的。

    iptables -t nat-A ${nat_instance_chain}

      --protocoltcp

      --destination"${external_ip}"

      --destination-port"${HOST_PORT}"

      --jump DNAT

     --to-destination "${network_container_ip}:${CONTAINER_PORT}

执行两次上面的命令。查看iptablesnat表结果如下:

Chainwarden-instance-17mgcetupda (1 references)

target     prot opt source               destination        

DNAT       tcp --  anywhere            cfv2b-a2b77e16-916d-4233-80a7-7102a0dc88b7.novalocal  tcp dpt:61001 to:10.254.0.9:61001

DNAT       tcp --  anywhere            cfv2b-a2b77e16-916d-4233-80a7-7102a0dc88b7.novalocal  tcp dpt:61002 to:10.254.0.10:61002

Route表的修改: Route表根据数据包的目的地址确定相应的发送给相应的网卡,路由分为几种,一种是网络路由,对应的目的地址是一端网络。一种是主机路由,对应的目的地址是一个主机地址,还有一个就是缺省路由,所有无法匹配的的地址都将会通过默认的接口进行发送。

 

容器内部的路由器表主要有两条,一条是网络路由,一条是缺省路由,如下:

Kernel IP routing table

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface

default         10.254.0.9      0.0.0.0         UG   0      0        0 w-17m6fqlrpd9-1

10.254.0.8      *               255.255.255.252 U     0     0        0 w-17m6fqlrpd9-1

上面的路由表表示,目的网络是10.254.0.8的数据包交由w-17m6fqlrp-1这张网卡发送,这个数据包再发送到宿主机上面。缺省的发送到容器外对应的虚拟网卡10.254.0.9处理。

 

2.7.5 外界访问容器内部  

    在Cloud Foundry中,DEA负责运行应用程序,而真正负责运行的是warden创建的container。当你的一个instance在container中启动之后,外部如何访问呢?

我们知道route转发请求到某一个应用上面是通过DEAIP:PORT来进行转发的。由此可知外界是通过IP+PORT的方式来访问到应用。那么这是怎么实现的呢?主要是通过源地址转换,这个在容器创建的时候已经为我们创建了规则。以Container1为例,见下图:

DNAT       tcp --  anywhere            cfv2b-a2b77e16-916d-4233-80a7-7102a0dc88b7.novalocal  tcp dpt:61001  to:10.254.0.10:61001

DNAT       tcp --  anywhere            cfv2b-a2b77e16-916d-4233-80a7-7102a0dc88b7.novalocal  tcp dpt:61002  to:10.254.0.10:61002

主机上的61001端口映射到容器内的61001端口,通过这个端口我们就可以访问到应用程序。以下是端口访问示意图:


以Container1为例,在访问主机的61001端口之后,首先通过DNAT转换之后,即10.10.18.38:61001转换为10.254.0.10:61001。经过KernelRoute Table交由w-17m6fqlrpd9-0网卡。容器外部分路由表如下所示:

Kernel IP routing table

Destination     Gateway        Genmask         Flags MetricRef    Use Iface

0.0.0.0         10.10.18.254    0.0.0.0         UG   0      0        0 eth0

10.10.18.0      0.0.0.0         255.255.255.0   U    1      0        0 eth0

10.254.0.8      0.0.0.0         255.255.255.252 U     0     0        0 w-17m6fqlrpd7-0

从第三条路由可以看到,所有发往10.254.0.8这个子网的所有数据包都是通过w-17m6fqlrpd9-0网卡发送。因为10.254.0.10/30属于子网10.254.0.8,所以发往w-17m6fqlrpd7-0网卡。虚拟网卡任何一端收到消息都会发送给另外一个端口。然后数据包发往w-17m6fqlrpd7-1网卡,然后发送到10.254.0.10:61001端口,最后被App接收。

 

2.7.6容器向外发送数据

容器里面的应用需要访问外界,首先会通过容器内的虚拟网卡发往在主机网络空间容器外的虚拟网卡。然后通过SNAT((SNAT:源地址转换,将数据包的源地址进行替换,把容器里面发出来的数据转发到主机的这张网卡上)转换,把数据包的源地址转换成物理网卡的IP地址,然后发送出去。


当Application要访问外部的时候,数据包首先发送到Virtual Interface-1,再发送到容器外对应的虚拟网卡Virtual Interface-0,然后通过源地址转换。

Chainwarden-postrouting (1 references)

target     prot opt source               destination        

SNAT       all --  10.254.0.0/22        anywhere             to:10.10.18.38

把所有10.254.0.0/22(容器的虚拟网卡对应IP地址段)转换到10.10.18.38(物理网卡IP)。最后通过物理网卡发送出去。

2.7.7 端口使用

      DEA在start一个instance的时候会进行两次Netin操作,也就是进行两次端口映射,把宿主机上的两个端口映射到容器内部,DEA使用的是默认端口(端口使用).一个端口用于应用容器的访问,一个端口用于容器console链接。

   一个端口用于应用程序访问,比如访问hello.cf.local,访问到的就是相应的应用程序端口。

  在2.7.4中提到在instance启动时候会把主机上的两个端口映射给对应的容器。

DNAT       tcp --  anywhere            cfv2b-a2b77e16-916d-4233-80a7-7102a0dc88b7.novalocal  tcp dpt:61001 to:10.254.0.46:61001

DNAT       tcp --  anywhere             cfv2b-a2b77e16-916d-4233-80a7-7102a0dc88b7.novalocal  tcp dpt:61002 to:10.254.0.46:61002

假设hello这个应用程序就是存放在部署在10.254.0.46这个容器里面,访问hello,cf.local就会访问到DeaHostIp:61001,然后访问到10.254.0.46:61001,最后被应用程序接收。

另外一个端口用于console链接,console链接是用来对应用程序在运行过程中出现的一些问题或者删除一些数据,都需要通过console端口来进行使用。cf console这个命令的资料较少。主要是CloudFoundry官博上的两篇文章来理解cf  console的使用。

在hello这个程序中就是61001这个端口,通过cfconsole hello(cf console appname)就可以访问到应用的console,不过这需要应用程序的支持,也就是说应用程序必须监听这个端口,并且提供相应的操作。

2.7.8 Virtual  Ethernet

Virtual Ehernet技术是由内核提供用于网络空间的隔离,对应的指令是iplink add name $network_host_iface type veth peer name $network_container_iface

添加两个网卡,一个是network_host_iface,一个$network_container_iface。

Ip link add用的就是veth技术,veth就是专门为linux container所创建的,他会创建一个成对的设备,一个在container之内,一个在container之外。两个设备除了名字不一样,其他都是一样的,一个设备接收到数据包会发送给另外一个设备。所以两者是相通的,veth全称就是 Virtual Ethernet。

 

虚拟以太网是指在真实的互联网中,通过软件方法在数据链路层实现一个 按以太网原理工作的虚拟网络。在虚拟网络中可以透明地运行所有应用程 序,支持各种第三层网络协议,如IP,IPv6,IPX等,可以进行普通的文件 共享以及ERP、VoIP等待应用。 特点: . 配置极其简单。 . 树形结构,可以从任一个节点接入,可谓一点接入,全网通行。 . 配合握手服务器(可由任一节点充当),可以实现两个节点间 直接 点对点 通讯,无需中转 !! . 3DES 数据加密 用途: . 创建企业虚拟网 . 创建专题虚拟网,你可以作为虚拟网的树根,然后把所有志同道合的人连接在一起,形成一个独具特色的 “虚拟以太网社区”。 简单地说,任何人都可以用VE建立自己的虚拟Internet世界。 使用说明: 1.双击virtualether.exe运行,程序会自动安装驱动程序va.sys,成功后会弹出设置界面。 2.设置方法。virtual ethernet的设置包括本地(local),远端(remote)和代理(proxy)。   local设置,本端作为虚拟HUB接受连接:  . 设置本端的连接监听端口,即虚拟HUB的连接端口。  . 设置本端的连接密码,当远端连接过来时,需要进行密码验证。 . 设置点对点通讯的握手服务器域名/IP,及其端口。 . 如果本端想做握手服务器,可以设置一个本地的UDP端口。 注:只有本端想做虚拟HUB时才需要正确设置。    remote设置,本端作为虚拟网卡向虚拟HUB发起连接:  . 远端虚拟HUB的IP或域名(当然可以是动态域名)  . 远端虚拟HUB的密码,即远端在 local 设置中的密码 . 远端虚拟HUB的连接端口,即远端在 local 设置中监听端口 注:1.只有本端想与虚拟HUB连接时才需要正确设置。 2.如果想连接到自己的虚拟HUB,则选择“connect to my local virtual HUB”。 Proxy设置,如果你机器通过代理上网,如HTTP代理,Socket代理,就需要根据你的 代理情况进行设置。(这个功能可以穿透firewall,网管要小心啦) 两个VA之间发生通讯时,如果已经配置握手服务器,软件会自动尝试建立点对点通道。 VE不会自动为虚拟网卡分配IP,如果有这个需要,只需要在虚拟网络中找一台机器运行DHCP服务即可。如选择其中一台提供HUB的机器运行DHCP服务。 如果你的上网方式是通过 http 代理,则可能需要把将要连接的虚拟HUM的监听端口设置成443才可以
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值