Skip to content

Latest commit

 

History

History
191 lines (105 loc) · 15.6 KB

KVM虚拟机网络管理实战.md

File metadata and controls

191 lines (105 loc) · 15.6 KB

上一篇文章我们介绍完KVM的存储管理实战后,接下来我们本篇文章就开始主要介绍KVM的网络管理实战。KVM的网络管理模型与OpenStack Neutron中的网络管理非常类似,而在学些OpenStack时,网络服务Neutron往往是很多人初学OpenStack的一个难点。因此,掌握了本篇内容的知识点,对于后续学习OpenStack Neutron部分的内容有事半功倍的效果。

virsh中的网络管理基础

在介绍KVM中常见的网络模型之前,我们先来看看virsh有哪些网络管理的命令。与存储管理实战和全生命周期管理实战类似,virsh主要提供对节点上的物理网络接口和分配给虚拟机的虚拟网络进行管理的命令。包括:创建节点上的物理接口、编辑节点上物理接口的XML配置文件,查询节点上物理接口、创建虚拟机的虚拟网络、编辑虚拟机的虚拟网络和删除虚拟机的虚拟网络等。常用的命令和作用如下:

virsh网络管理常用命令
命令 功能描述
iface-list 显示出物理主机的网络接口列表
iface-list 根据网络接口名称查询其对应的MAC地址
iface-name 根据MAC地址查询其对应的网络接口名称
iface-edit 编辑一个物理主机的网络接口XML配置文件
iface-dumpxml 以XML配置文件转存出一个网络接口的状态信息
iface-destroy 关闭宿主机上的一个物理网络接口
net-list 列出libvirt管理的虚拟网络
net-info 根据名称查询一个虚拟网络的基本信息
net-uuid 根据名称查询一个虚拟网络的uuid
net-name 根据uuid查询一个虚拟网络的名称
net-create<net.xml> 根据一个网络的xml配置文件创建一个虚拟网络
net-edit 编译一个虚拟网络的XML配置文件
net-dumpxml 转存出一个虚拟网络的XML配置文件
net-destroy 销毁一个虚拟网络

有了上面的命令基础,我们就可以几个简单验证。比如,我们现在想看下当前节点有哪几个物理接口,可以使用如下命令:

img

现在,我们想把br0这个网桥的XML文件导出转存,可以使用下面的命令的实现。

img

以后就可以按照上面的xml配置文件,写一个网桥,然后通过iface-define定义,然后再通过iface-start命令启动即可(需要注意MAC不能重复,可以使用random工具随机生成MAC)。

我们完成物理接口的简单验证后,接下来看看虚拟网络的信息。比如,我们现在需要看下当前节点有哪些虚拟网络,可以通过net-list命令实现。如下:

img

上图表示当前节点只有一个虚拟网络default,我们通过net-info命令可以看下default网络的详细信息。如下:

img

同理,我们也可以将default网络的xml配置转存,便于后续自己编写网络xml文件。如下:

img

KVM中常见的网络模型

有了上面基础认知,下面我们就来看下KVM中常见的4种简单网络模型,分别如下:

  • **隔离模型:**虚拟机之间组建网络,该模式无法与宿主机通信,无法与其他网络通信,相当于虚拟机只是连接到一台交换机上。其对应OpenStack Neutron中local网络模型。

  • **路由模型:**相当于虚拟机连接到一台路由器上,由路由器(物理网卡),统一转发,但是不会改变源地址。

  • **NAT模型:**在路由模式中,会出现虚拟机可以访问其他主机,但是其他主机的报文无法到达虚拟机,而NAT模式则将源地址转换为路由器(物理网卡)地址,这样其他主机也知道报文来自那个主机,在docker环境中经常被使用。

  • **桥接模型:**在宿主机中创建一张虚拟网卡作为宿主机的网卡,而物理网卡则作为交换机。

为了加深大家的理解,我们后面就对上述4种网络模型逐一进行验证。

隔离网络模型

img

如上图所示,VM0和VM1都是在宿主机上创建的虚拟机,虚拟机的网卡分为前半段和后半段,前半段位于虚拟机上,后半段在宿主机上,按照图中所示,前半段就是eth0,它是在虚拟机内部看到的网卡名字,而后半段就是vnet0和vnet1,它们是在宿主机上看到的网卡名字。实际上,在VM1上所有发往eth0的数据就是直接发往vnet0,是由vnet0进行数据的传送处理。

在隔离模式下,宿主机创建一个虚拟交换机vSwitch,然后把vnet0和vnet1接入到该虚拟交换机,交换机也可以叫做bridge,因为vnet0和vnet1在一个网桥内,所以可以互相通信,而虚拟机的eth0是通过后半段进行数据传输,所以只要虚拟机的前半段ip在一个网段内,就可以互相通信,这就是隔离模式。下面,我们就通过实例进行验证。

**Step1:**创建一个网桥br1,且不连接宿主机的任何物理网卡。

img

**Step2:**我们用centos7.5模板虚拟机镜像直接迅速拉起两个测试虚拟机VM0和VM1。

img

由于我们没有给网桥配置IP和DHCP分配范围,所以虚拟机没有IP地址。我们可以手动给虚拟机添加IP,VM0的虚拟机地址设置为10.10.101.251。如下

img

同理,给虚拟机VM1设置IP为192.168.101.252。如下:

img

此时,我们对VM0与VM1进行ping测试,是可以ping通的。但是,即使两个虚拟机与宿主机(10.10.101.11)在同一个网段,仍然无法ping通。所以,这是一个隔离网络模型。

img

**Step3:**此时,我们在宿主机上查询网桥br1的挂接信息和虚拟机的虚拟网卡vnet信息。如下:

img

路由网络模型

img

在隔离模型的基础上,将宿主机的一块虚拟网卡virnet0加入到虚拟网桥中,这样virnet0就可以和虚拟机通信,通过将虚拟机的默认网关设置为virnet0的IP地址,然后在宿主机中打开IP地址转发,使得虚拟机可以访问宿主机。不过此时虚拟机仅仅可以将报文发送到外部网络,因为外部网络没有路由到虚拟机中,所以外部网络无法将报文回传给虚拟机。

**step1:**在宿主机上用tunctl创建一个虚拟网卡,也就是创建一个tap设备virnet0。忘了tunctl是什么的,请回顾本站Linux原生网络虚拟化内容。

img

**step2:**将virnet0加入到网桥br1中,并设置网桥br1为网关,地址为10.10.101.100

img

**step3:**进入虚拟机设置网关为10.10.101.100,也就是配置一条默认路由即可。

img

**step4:**在宿主机中打开ip包转发功能,也就是将宿主机变成一个路由器(详见本站Linux原生网络虚拟化文章内容)。

img

**step5:**此时,我们在虚拟机中尝试ping宿主机,发现可以ping通。如下:

img

但是,我们无法ping通宿主机的网关,如下:

img

这是因为报文发到网关后,网关找不到回包的路由,所以报文无法回复,这时候,我们通过在宿主机上添加一条iptables规则,使得网关可以回包。至于,iptables如何配置,请参见本站Linux常用运维工具分类中的iptable文章。

复制

iptables -t nat -A POSTROUTING -s 10.10.101.0/24 -j MASQUERADE

img

添加包转发规则后,就可以在虚拟机中ping通宿主机网关了。如下:

img

**step6:**但是,我们在宿主机外的机器上仍无法ping通虚拟机。比如,我们在真实的物理机(win10)上还是无法ping通虚拟机10.10.101.251。如下:

img

为了解决外部主机ping通虚拟机的问题,我们需要win10上也添加一条路由,将访问虚拟机的数据包发往VMware的虚拟网卡地址192.168.101.11上。完成后,再次进行尝试,发现网络已通,且可以通过win10直接ssh虚拟机vm0。如下:(这里注意必须指定VMware NAT网卡的地址段,因为在VMware内部只有NAT虚拟网卡有三层转发功能)

img

通过上述实践,也可以发现路由模型的缺陷,虽然虚拟机能同宿主机通信,也能将数据包发到外部网络,但是外部网络无法回传数据包,要想外部网络能与虚拟机通信,就要添加对应的路由规则。这对于大规模的虚拟环境,这显然是不科学的。

NAT网络模型

img

NAT模型其实就是SNAT的实现,路由中虚拟机能将报文发送给外部主机,但是外部主机因找不到通往虚拟机的路由因而无法回应请求。外部主机能同宿主机通信,所以在宿主机上添加一个NAT转发,从而在外部主机响应能够到达虚拟机,但是不能直接访问虚拟机。这种方式是将虚拟机的IP地址转换为宿主机上的某个地址,从而实现虚拟机与外部网络通信,其实际上只是通过iptables的nat表的POSTROUTING链实现地址转换罢了。如果要实现外部网络直接访问虚拟机,还需要在宿主机上配置DNAT转发,一般不采用这种方式。

在我们创建KVM虚拟机时,如果使用default网络类型,它就是一个NAT网络。我们可以看下它的XML配置文件内容:

img

有了上面的了解,那我们创建一个NAT网络就很轻松了。怎么办?重新写一份?no…no…这不符合互联网时代的要求!拷贝一份,直接修改。。。。同时,我们可以在自定义的nat网络配置文件中,指定两个虚拟机的IP地址。如下:

img

完成上面的配置后,现在定义一个网络natnet,并设置开启自动启动。如下:

img

完成上面配置后,libvirt会自动帮我们创建一个XML文件描述的网桥natbr0,并且将网关IP和MAC按照XML文件的配置自动生成。如下:

img

同时,libvirt会在宿主机的iptables的nat转发表中,自动帮我增加nat网络的数据包转发策略。如下:

img

完成上面的配置,此时我们需要修改两个虚拟机XML文件的网络配置信息,然后重新定义启动。虚拟机XML配置文件网络信息修改,只需要修改接口类型为network类型,network的上行接口修改为我们自定义的网络名称即可,其它不变。如下:

img

然后,我们重新定义虚拟机并启动。如下:

img

现在,我们进入虚拟机查询的虚拟机的IP确实为我们制定的IP地址188.64.100.2,且自动增加了默认路由指向natbr0网桥上联接口地址188.64.100.1,而且虚拟机和宿主机可以互相ping通。如下

img

而且,我们在虚拟机下可以ping通外部真实物理机win10,但是从真实物理机win10下ping测虚拟机vm0却发现还是ping不通,这就是典型的SNAT原理,也就是虚拟机可以访问外部网络,但是外部网络看不见内网的虚拟机,这样对内网的虚拟机中应用起到保护作用。如下:

img

img

如果,需要虚拟机访问互联网internet,需要给虚拟机中增加DNS解析,nameserver就配置成虚拟网关188.64.100.1即可。如下:

img

至此,nat网络模型验证完毕。四个基本模型中还有一个桥接网络模型,这也是网上常见的配置模型,这种模型就是将虚拟机与宿主机放在一个局域网内,可以互访,且同一局域网的其他外部主机也能访问虚拟机。而且,如果宿主机能上互联网,那么互联网的服务器也能访问虚拟机。除非有特殊应用场景,否则一般在实际运维不采用这种方式,因为不安全。这种方式我就懒得举例了,网上的教程很多。最后,祝大家在KVM的世界里愉快的玩耍。。。。。。嘿嘿嘿嘿。。。。。