kvm总结(6) : 桥接网络和nat网络

先来看看kvm的nat网络模型是什么样的

nat网络

在安装kvm后,会自动创建一个默认的nat网络,虚拟机可以使用这个nat网络访问外部网络,这个nat网络由一个虚拟交换机和若干iptables规则组成,这样说可能不太容易理解,我们来看一张示意图。

从上述示意图中可以看出,在kvm的nat网络中,虚拟机连接到虚拟交换机,经过iptables规则的nat处理,通过宿主机的物理网卡与物理交换机所在的网络通讯,但是需要注意,这里的iptables规则只是对虚拟机的ip地址进行了snat(源地址转换)处理,并没有进行dnat(目标地址转换)处理,所以,虚拟机可以直接访问物理交换机所在的网络,但是物理交换机所在网络的其他主机,无法直接访问虚拟机,如果想要在物理交换机所在的网络直接访问虚拟机中的服务,则需要手动的进行dnat,为了方便描述,下文将物理交换机所在的网络称之为”外部网络”,这里说的外部网络不是公网,而是办公环境的网络,也就上图中物理交换机所在的网络,”外部网络”的”外部”是针对kvm虚拟机而言的。

为了更加具象化的理解上面的示意图,我们可以通过命令,查看一下这些设置。

在宿主机中,执行ip a命令,可以看到如下信息

 
[root@cos7 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:1c:42:65:41:f2 brd ff:ff:ff:ff:ff:ff
inet 10.211.55.10/24 brd 10.211.55.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fdb2:2c26:f4e4:0:21c:42ff:fe65:41f2/64 scope global mngtmpaddr dynamic
valid_lft 2591989sec preferred_lft 604789sec
inet6 fe80::21c:42ff:fe65:41f2/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:32:ab:9a brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:32:ab:9a brd ff:ff:ff:ff:ff:ff

上述信息中,eth0是宿主机的物理网卡,virbr0是kvm为默认nat网络创建的虚拟交换机,当使用默认nat网络时,虚拟机会连接到virbr0交换机,由于我没有启动任何虚拟机,所以不太容易观察到对应网卡的变化,如果我们启动一个虚拟机,kvm会自动创建出一个新的虚拟网卡,我们来做个实验,启动一个提前配置好的虚拟机,kvm1,如下所示:

 
[root@cos7 ~]# virsh list --all
Id Name State
----------------------------------------------------
1 kvm1 running
- kvm2 shut off
- kvm3 shut off
- kvm4 shut off
- kvm5 shut off
- kvm6 shut off

启动kvm1虚拟机后,再次使用ip a命令查看网卡信息,可以看到比没有启动虚拟机之前,多出了一个网卡,如下

 
[root@cos7 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:1c:42:65:41:f2 brd ff:ff:ff:ff:ff:ff
inet 10.211.55.10/24 brd 10.211.55.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fdb2:2c26:f4e4:0:21c:42ff:fe65:41f2/64 scope global mngtmpaddr dynamic
valid_lft 2591894sec preferred_lft 604694sec
inet6 fe80::21c:42ff:fe65:41f2/64 scope link
valid_lft forever preferred_lft forever
3: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 52:54:00:32:ab:9a brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:32:ab:9a brd ff:ff:ff:ff:ff:ff
5: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master virbr0 state UNKNOWN group default qlen 1000
link/ether fe:54:00:60:e4:6a brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fe60:e46a/64 scope link
valid_lft forever preferred_lft forever

如上所示,启动kvm1后,多出了一个vnet0网卡,vnet0网卡的作用就是为了让kvm1虚拟机能够连接到virbr0交换机,我们可以这样想象,有一根网线,网线的一头插在kvm1虚拟机上,另一头插在virbr0上,如果网线想要插在主机或者交换机上,总要有网线口吧,kvm1虚拟机的网线口在虚机内部的虚拟网卡上,交换机的网线口就是vnet0这个虚拟网卡,只不过,vnet0这个网卡(网线口)是单独为了kvm1准备的,执行brctl show命令,可以更加清楚的看到virbr0和vnet0的关系,如下:

 
注:执行brctl命令前,需要安装bridge-utils包
[root@cos7 ~]# brctl show
bridge name bridge id STP enabled interfaces
virbr0 8000.52540032ab9a yes virbr0-nic
vnet0

可以看到,当前有一个桥设备,名字叫virbr0,也就是virbr0虚拟交换机,他有两个接口(网线口),virbr0-nic和vnet0,其中,virbr0-nic接口负责和宿主机的eth网卡连,vnet0接口负责和kvm1虚拟机的eth网卡连,这样想象就应该有画面了吧。

我们还可以模拟一下拔网线和插网线,验证一下我们的想法,用ifconfig vnet0 down命令和ifconfig vnet0 down命令,模拟拔下和插上虚拟交换机这头的网线,然后观察kvm1虚拟机中的网络是否通畅。

如果再启动一个虚拟机,还能够看到宿主机又多出了一个网卡,比如,我又启动了一个kvm5,然后宿主机又多出了一个vnet1网卡,再次使用brctl命令查看,信息如下

 
[root@cos7 ~]# brctl show
bridge name bridge id STP enabled interfaces
virbr0 8000.52540032ab9a yes virbr0-nic
vnet0
vnet1

细心如你可能已经发现了,似乎有一个规律,就是虚拟机的网卡的mac地址,和其所连接的虚拟交换机的网口的mac地址,都长得特别像,比如,kvm1连得是vnet0,kvm5连的是vnet1,会发现,kvm1的mac地址和vnet0的mac地址很像,kvm5的mac地址和vnet1的mac地址很像,只有前两位不一样,可以动手查看一下,这里就不再演示了。

刚才说过,虚拟交换机和宿主机的物理网卡之间的连接,是要经过iptables规则处理的,iptables只进行了snat处理,所以无法直接通过外部网络直接访问虚拟机中的服务,除非手动添加dnat规则,我们可以通过iptables命令查看默认创建的nat规则,如果你对iptables不是特别了解,可以参考博客中的关于iptables的文章,直达连接如下:
https://www.zsythink.net/archives/tag/iptables

virbr0虚拟交换机和默认nat网络下的虚拟机所在的网段是192.168.122.0/24,virbr0的IP地址是192.168.122.1,虚拟机的网关也是指向的192.168.122.1 查看iptables规则,会发现转发的也都是这个网段的ip地址,最终实现了虚拟机访问外部网络的功能。

了解了上面的知识,我们可以把nat网络的模型图细化一下,理解成下面的样子

聊完了nat网络,现在聊聊桥接网络

桥接网络

在生产环境中,我使用的是桥接的网络模型,桥接的网络模型有一个优点,就是虚拟机和宿主机在网络上是平级的,比如,公司有几台服务器,服务器所在的网段是192.168.99.0/24,服务器A的IP地址是192.168.99.66,我们在服务器A上安装了KVM,并且创建了两台虚拟机,虚拟机A1和虚拟机A2,A1和A2使用桥接的网络模型,A1的IP地址可以设置成192.168.99.67,A2的IP地址可以设置成192.168.99.68,对于公司的物理交换机而言,宿主机A、虚机A1和虚机A2就是三台连到物理交换机的电脑,在物理交换机眼里,它们三个是相互独立的,如果A1或者A2上部署了某些服务,公司的电脑可以直接通过A1或者A2的IP地址访问到对应的服务。

桥接网络模型的示意图如下:

如上图所示,我们需要先在宿主机中创建一个虚拟交换机(桥设备),然后把宿主机的物理网卡连接到虚拟交换机上,此时,我们可以把宿主机的物理网卡想象成虚拟交换机的一个网口,虚拟交换机通过这个网口,插上网线,桥接到物理交换机上,如果虚拟机使用了桥接网络,当启动某个虚拟机时,kvm会自动创建一个虚拟网卡(相当于在虚拟交换机上创建了一个网口),以便虚拟机可以连接到虚拟交换机,从而通过虚拟交换机桥接到物理交换机上,这时,我们可以通过虚拟交换机的IP地址连接到宿主机,通过虚拟机的IP地址连接到虚拟机,就拿刚才举例的IP地址来说,上图中虚拟交换机的IP地址此时是192.168.99.66,虚拟机1的IP地址可能是192.168.99.67,虚拟机2的IP地址可能是192.168.99.68,对于物理交换机所在的网络来说,此时宿主机和虚拟机是平级的,它们的网关都是指向了物理交换机所在网络的网关。

了解完了相关概念以后,我们来动手操作一下,在实操之前,我先来描述一下我的测试环境,以便大家心里有数,前文说过,为了方便测试,我们在笔记本中通过虚拟化软件创建了一个虚拟机,用这个虚拟机模拟KVM宿主机,我们可以使用vmware或者任何常见的虚拟化软件来模拟KVM宿主机,此处使用的虚拟化软件是Parallels Desktop(下文简称pd),无论是vmware还是pd,创建虚拟机后,通常都会默认使用自带的NAT网络(虚拟化软件的NAT网络,和KVM的网络模型没有直接关系),我创建的KVM宿主机也使用了pd默认的共享网络(其实就是pd的NAT网络),但是其实,我们不应该使用虚拟化软件的NAT网络,而是应该使用虚拟化软件的桥接网络,因为我们需要模拟KVM宿主机通过网线连接到物理交换机的这个过程(不经过nat处理,KVM宿主机直接连接到物理网络获取IP的过程),所以,我们需要使用桥接的方式,那么很简单,我们只需要为KVM宿主机再创建一个网卡,使用虚拟化软件的桥接网络就行了,有了思路,我们来操作一下。

此处以pd的操作为例,其他虚拟化软件操作类似,请自行根据实际情况进行操作,如果你的KVM宿主机已经使用了虚拟化软件的桥接网络,则可以跳过相关的操作,执行pd操作前,需要提前关闭KVM宿主机。

找到KVM宿主机的硬件配置界面,如下图所示,KVM宿主机默认使用的是pd的共享网络,我们再创建一个网卡,使用pd的桥接网络,点击下图中的 “加号”,点击 “网络”

在新建的网卡中,选择通过哪个网络接口进行桥接,下图中的”USB 10/100/1000 LAN”是笔记本上的有线网口(笔记本插着扩展坞,扩展坞上连的网线,所以显示的是USB设备),这里需要根据自己的具体情况进行选择,建议把笔记本插上网线,选择有线接口进行桥接,因为我在进行实验时,如果使用无线网络桥接,会影响后面的测试,导致KVM桥接网络不可用,我对无线桥接和pd的设置不了解,没有找到问题在哪里,所以此处直接在pd中选择有线接口桥接,设置完成后,启动KVM宿主机。

进入KVM宿主机,查看网卡信息如下,可以看到已经多出了一个eth1网卡,我们就用这个网卡模拟KVM宿主机的物理网卡,这个网卡的IP地址是192.168.100.239,而我所在的办公网络中,三层交换机分配的IP段就是192.168.100.0/24,所以我们已经成功的把KVM宿主机“插上网线了”,网线的另一头连的物理交换机。

 
[root@cos7 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:1c:42:65:41:f2 brd ff:ff:ff:ff:ff:ff
inet 10.211.55.10/24 brd 10.211.55.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fdb2:2c26:f4e4:0:21c:42ff:fe65:41f2/64 scope global mngtmpaddr dynamic
valid_lft 2591981sec preferred_lft 604781sec
inet6 fe80::21c:42ff:fe65:41f2/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 00:1c:42:4c:13:4a brd ff:ff:ff:ff:ff:ff
inet 192.168.100.239/24 brd 192.168.100.255 scope global noprefixroute dynamic eth1
valid_lft 85940sec preferred_lft 85940sec
inet6 fe80::3def:65e6:8c09:1fa1/64 scope link noprefixroute
valid_lft forever preferred_lft forever
4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
link/ether 52:54:00:32:ab:9a brd ff:ff:ff:ff:ff:ff
inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
valid_lft forever preferred_lft forever
5: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
link/ether 52:54:00:32:ab:9a brd ff:ff:ff:ff:ff:ff

刚才说过,如果想要使用KVM的桥接网络,需要先在KVM宿主机中先创建一个桥设备,然后再把宿主机的物理网卡连接到桥设备中,我先描述一下大致步骤,然后再操作,步骤如下:

步骤1:创建一个桥设备(就是刚才说的虚拟交换机),将桥设备的IP地址设置成物理网络网段中的一个可用IP(刚才说过此处实验网段是192.168.100.0/24,根据实际的网络情况进行设置),网关指向物理网络所在的网关,此处网关是192.168.100.254。

步骤2:修改KVM宿主机的物理网卡(此处的eth1)的配置,将物理网卡连接到虚拟交换机,作为桥设备的网口使用,以便桥设备可以连接到物理交换机,此时的eth1不需要绑定任何IP地址,只需要作为桥设备的一个网口即可,所以,在步骤1中,我们也可以直接将桥设备的IP地址设置成192.168.100.239,因为最终eth1是不需要绑定IP的。

步骤说明白了,现在来操作,虚拟桥设备其实也是一个虚拟网卡,我们只需要创建一个虚拟网卡的配置文件就行了,KVM的默认nat网络的虚拟交换机名是virbr0,我们为桥接网络创建一个virbr1,叫别的名字也行,我就喜欢加序号,virbr1配置文件内容如下:

 
[root@cos7 ~]# cat /etc/sysconfig/network-scripts/ifcfg-virbr1
DEVICE="virbr1"
TYPE="Bridge"
ONBOOT="yes"
BOOTPROTO="static"
IPADDR="192.168.100.239"
NETMASK="255.255.255.0"
GATEWAY="192.168.100.254"
DNS1=8.8.8.8

如上所示,我们创建了一个virbr1的网卡,网卡类型是Bridge,是一个桥设备,配置了开机启用网卡和静态IP,IP地址设置的是192.168.100.239,设置子网掩码、网关和DNS,到这一步,虚拟交换机就算配置完了,现在需要把物理网卡eth1连接到这个设备上,由于我的eth1网卡也是新添加的网卡,所以再创建一个eth1的配置文件,配置内容如下:

 
[root@cos7 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1
TYPE=Ethernet
ONBOOT=yes
BRIDGE=virbr1

eth1的网卡配置也非常简单,设备类型就是Ethernet网卡,只需要指定连接的桥设备是virbr1即可。
配置完成后,重启KVM宿主机。

连入KVM宿主机以后,桥接网络就算设置完成了,我们可以先用brctl show命令查看一下桥设备,如下

 
[root@cos7 ~]# brctl show
bridge name bridge id STP enabled interfaces
virbr0 8000.52540032ab9a yes virbr0-nic
virbr1 8000.001c424c134a no eth1

可以看到,eth1已经变成virbr1的接口了。
如果你和我的测试环境一样,可以先把eth0网卡(对应pd的nat网络使用的网卡)停了,只留下eth1网卡和virbr1桥设备,应该是可以正常访问外部网络的。

现在,我们来让虚拟机连接到KVM的桥接网络,测试一下能否正常联网,为了方便测试,我就不创建新的虚拟机了,直接将原来使用nat网络的虚拟机的配置文件修改一下,让其连接到新建的桥接网络,目前已经创建的虚拟机如下:

 
[root@cos7 ~]# virsh list --all
Id Name State
----------------------------------------------------
- kvm1 shut off
- kvm2 shut off
- kvm3 shut off
- kvm4 shut off
- kvm5 shut off
- kvm6 shut off

这些虚拟机都是使用的默认的nat网络,我们把kvm6的配置修改一下,执行virsh edit kvm6命令,找到kvm6网卡配置的如下部分

 
<interface type='network'>
<mac address='52:54:00:12:0e:f7'/>
<source network='default'/>
<model type='rtl8139'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>

我们需要修改interface标签和source标签中的配置,修改后内容如下:

 
<interface type='bridge'>
<mac address='52:54:00:12:0e:f7'/>
<source bridge='virbr1'/>
<model type='rtl8139'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>

如上所示,我们将虚拟机的网络模型改为了桥接,桥接的设备指向了virbr1(注意:source后面的network改成了bridge),也就是新创建的桥设备的名字,修改完成后,启动kvm6并登录进入kvm6,查看虚拟机IP,由于我的kvm6之前设置了静态IP,所以虚拟机的IP并没有自动变成192.168.100.0/24网段的IP,如果你的虚拟机使用了DHCP获取IP,应该已经能够自动获取到物理网段的IP地址了,我修改了kvm6,让其自动获取IP地址,重启网络后,获取了如下IP地址。

 
[root@kvm6 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:12:0e:f7 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.226/24 brd 192.168.100.255 scope global noprefixroute dynamic ens3
valid_lft 86342sec preferred_lft 86342sec
inet6 fe80::5054:ff:fe12:ef7/64 scope link
valid_lft forever preferred_lft forever

可以看到kvm6的IP地址已经变为了192.168.100.226,经过测试,已经可以正常访问物理网络了,证明KVM宿主机的桥接网络模型是没有问题的,当然,我们也可以手动的把KVM6的IP设置为192.168.100.0/24网段的静态IP,就看具体需要了,此时使用brctl show命令再查看一下桥设备的接口,验证一下之前的理论,就会更加清晰的理解KVM桥接网络了。

示例中,我们修改了现有虚拟机的网络配置,如果想要通过命令在创建虚拟机时,就指定使用桥接的网络,可以使用”–network”参数,指定对应的桥接设备,比如

 
virt-install --name=kvm7 --vcpus=2 --memory=2048 --location=/data/iso/CentOS-7-x86_64-DVD-2009.iso --disk path=/var/lib/libvirt/images/kvm2.qcow2 --network bridge=virbr1 --graphics none --extra-args='console=ttyS0'

关于KVM的内容,就先总结到这里,欢迎关注微信公众号,回复 kvm常用命令脑图 即可获取博客中总结的KVM常用命令思维导图。

posted @ 2022-03-29 09:39  禾子、  阅读(1026)  评论(0编辑  收藏  举报