1.bridged(桥接模式)

在bridged模式下,虚拟出来的操作系统就像是局域网中的一台独立的主机,它可以访问网内任何一台机器。同时,由于这个虚拟系统是局域网中的一个独立的主机系统,那么就可以手工配置它的TCP/IP配置信息,以实现通过局域网的网关或路由器访问互联网。

使用bridged模式的虚拟系统和宿主机器的关系,就像连接在同一个Hub上的两台电脑。想让它们相互通讯,你就需要为虚拟系统配置IP地址和子网掩码,否则就无法通信

​(参考dhcp服务器是否开启,如果开启,则可以选择dhcp方式自动获取网络地址)。

这种方式最简单,直接将虚拟网卡桥接到一个物理网卡上面,和linux下一个网卡绑定两个不同地址类似,实际上是将网卡设置为混杂模式,从而达到侦听多个IP的能力。

在此种模式下,虚拟机内部的网卡(例如linux下的eth0)直接连到了物理网卡所在的网络上,可以想象为虚拟机和host机处于对等的地位,在网络关系上是平等的,没有谁在谁后面的问题。使用这种方式很简单,前提是你可以得到1个以上的地址。

用KVM配置Bridge方式:

首先需要确定你的host主机上用的网络连接方式为桥接方式,我的机器上的用的是一个叫br0的网桥。创建网桥的方式也很简单,以我的系统为例,网卡一个eno16777736,在目

录/etc/sysconfig/network-scripts/下创建文件ifcfg-br0,然后修改文件ifcfg-eno16777736为:

BOOTPROTO=none 
DEVICE=eno16777736 
HWADDR=00:0c:29:09:0d:3d 
NM_CONTROLLED=no 
ONBOOT=yes 
BRIDGE=br0

修改文件ifcfg-br0的内容为:

BOOTPROTO=static 
DEVICE=br0 
TYPE=Bridge 
NM_CONTROLLED=no 
IPADDR=192.168.7.183 
NETMASK=255.255.255.0 
GATEWAY=192.168.7.254

在虚拟机的XML配置文件中device下添加interface标签即可,标签如下:

<interface type='bridge'> 
<mac address='52:54:00:84:e9:e1'/> 
<source bridge='br0'/> 
<model type='rtl8139'/> 
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> 
</interface>

当然也可以先定义一下这个网络,然后在添加到虚拟机的XML文件中,给它起名为br0.xml,这个文件中可以写一些网络的详细配置参数,大致的形式如下:

<network> 
<name>br0</name> 
<uuid>fb48b969-b9f4-e859-d957-50aedd850fb4</uuid> 
<forward mode='bridge'> 
<bridge name ='br0'/> 
</forward> 
</network>

然后用libvirt来定义并开启这个网络,配置文件中的interface标签当然还是不能少,用上面的就好,名字正好一致了:

virsh net-define br0.xml

virsh net-start br0

然后就可已启动客户机,检查网络连接了。

2.NAT(网络地址转换模式)

使用NAT模式,就是让虚拟系统借助NAT(网络地址转换)功能,通过宿主机器所在的网络来访问公网。也就是说,使用NAT模式可以实现在虚拟系统里访问互联网。很显然,如果你只有一个外网地址,此种方式很合适。

KVM虚拟机Nat方式上网:

virsh net-list

查看当前活跃的网络,可以看到一个default网络,这个就是一个默认的Nat网络了。

virsh net-dumpxml default

可以查看该网络的详细配置如下:

<network> 
<name>default</name> 
<uuid>75dbebde-fc15-4350-8a06-f1432f9e6d30</uuid> 
<forward mode='nat'> 
<nat> 
<port start='1024' end='65535'/> 
</nat> 
</forward> 
<bridge name='virbr0' stp='on' delay='0' /> 
<mac address='52:54:00:bc:f2:65'/> 
<ip address='192.168.122.1' netmask='255.255.255.0'> 
<dhcp> 
<range start='192.168.122.2' end='192.168.122.254' /> 
</dhcp> 
</ip> 
</network>

可以看到该网络搭建在一个网桥virbr0上,这个网桥在安装并启动libvirt的时候自动生成。然后在客户机的XML配置文件中添加标签interface内容如下:

<interface type='network'> 
<mac address='52:54:00:c7:18:b5'/> 
<source network='default'/> 
<model type='virtio'/> 
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> 
</interface>

则可以让客户机用nat方式来上网了,经验证,客户机可以获取到122网段,2到254之间的一个ip地址。

我们可以直接编辑修改default网络的配置:

virsh net-edit default

也可以直接将default网络干掉,然后再重新定义:

virsh net-undefine default

重新创建一个default.xml文件,自定义其中的内容,可以指定某个mac地址对应某个ip,指定某个ip段。例如下面的内容,name对应的是客户机的名字。

<network> 
<name>default</name> 
<uuid>dc69ff61-6445-4376-b940-8714a3922bf7</uuid> 
<forward mode='nat'/> 
<bridge name='virbr0' stp='on' delay='0' /> 
<mac address='52:54:00:81:14:18'/> 
<ip address='192.168.122.1' netmask='255.255.255.0'> 
<dhcp> 
<range start='192.168.122.2' end='192.168.122.254' /> 
<host mac='00:25:90:eb:4b:bb' name='guest1' ip='192.168.5.13' /> 
<host mac='00:25:90:eb:34:2c' name='guest2' ip='192.168.7.206' /> 
<host mac='00:25:90:eb:e5:de' name='guest3' ip='192.168.7.207' /> 
<host mac='00:25:90:eb:7e:11' name='guest4' ip='192.168.7.208' /> 
<host mac='00:25:90:eb:b2:11' name='guest5' ip='192.168.7.209' /> 
</dhcp> 
</ip> 
</network>

然后用命令:

virsh net-define default.xml

virsh net-start default

启用一个客户机,检查网络时候可用。

KVM 客户机网络连接有两种方式:

用户网络(User Networking):让虚拟机访问主机、互联网或本地网络上的资源的简单方法,但是不能从网络或其他的客户机访问客户机,性能上也需要大的调整。NAT方式。

虚拟网桥(Virtual Bridge):这种方式要比用户网络复杂一些,但是设置好后客户机与互联网,客户机与主机之间的通信都很容易。Bridge方式。

本文主要解释NAT方式的配置。

NAT方式原理

NAT方式是kvm安装后的默认方式。它支持主机与虚拟机的互访,同时也支持虚拟机访问互联网,但不支持外界访问虚拟机。

检查当前的网络设置:

#virsh net-list --all

Name State Autostart

default active yes

default是宿主机安装虚拟机支持模块的时候自动安装的。

检查当前的网络接口:

#ifconfig
eth0 Link encap:Ethernet HWaddr 44:37:E6:4A:62:AD 
inet6 addr: fe80::4637:e6ff:fe4a:62ad/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:987782 errors:0 dropped:0 overruns:0 frame:0
TX packets:84155 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000 
RX bytes:109919111 (104.8 MiB) TX bytes:12695454 (12.1 MiB)
Interrupt:17

lo Link encap:Local Loopback 
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:4 errors:0 dropped:0 overruns:0 frame:0
TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0 
RX bytes:240 (240.0 b) TX bytes:240 (240.0 b)

virbr0 Link encap:Ethernet HWaddr 52:54:00:B9:B0:96 
inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:2126 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0 
RX bytes:0 (0.0 b) TX bytes:100387 (98.0 KiB)

virbr0-nic Link encap:Ethernet HWaddr 52:54:00:B9:B0:96 
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500 
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

其中virbr0是由宿主机虚拟机支持模块安装时产生的虚拟网络接口,也是一个switch和bridge,负责把内容分发到各虚拟机。

virbr0是一个桥接器,接收所有到网络192.168.122.*的内容。从下面命令可以验证:

brctl show


bridge name bridge id STP enabled interfaces
virbr0 8000.525400b9b096 yes virbr0-nic

route

Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.122.0 * 255.255.255.0 U 0 0 0 virbr0

同时,虚拟机支持模块会修改iptables规则,通过命令可以查看:

iptables -t nat -L -nv

Chain PREROUTING (policy ACCEPT 16924 packets, 2759K bytes)
pkts bytes target prot opt in out source destination
Chain POSTROUTING (policy ACCEPT 2009 packets, 125K bytes)
pkts bytes target prot opt in out source destination 
421 31847 MASQUERADE all -- 192.168.122.0/24 !192.168.122.0/24 ----------->这条是关键,它配置了NAT功能。

Chain OUTPUT (policy ACCEPT 2011 packets, 125K bytes)
pkts bytes target prot opt in out source destination

iptables -t filter -L -nv


Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination 
1 74 ACCEPT udp -- virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:53 ---->由libvirt脚本自动写入
0 0 ACCEPT tcp -- virbr0 
0.0.0.0/0 0.0.0.0/0 tcp dpt:53 ---->由libvirt脚本自动写入
3 984 ACCEPT udp -- virbr0 0.0.0.0/0 0.0.0.0/0 udp dpt:67 ---->由libvirt脚本自动写入
0 0 ACCEPT tcp -- virbr0 
0.0.0.0/0 0.0.0.0/0 tcp dpt:67 ---->由libvirt脚本自动写入
178K 195M ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED ---->iptables的系统预设
2 168 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 ---->iptables的系统预设
1148 216K ACCEPT all -- lo 0.0.0.0/0 0.0.0.0/0 ---->iptables的系统预设
1 60 ACCEPT tcp -- 
0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 ---->iptables的系统预设
16564 2721K REJECT all -- 
0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited ---->iptables的系统预设
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination 
3726 3485K ACCEPT all -- 
virbr0 0.0.0.0/0 192.168.122.0/24 state RELATED,ESTABLISHED ---->由libvirt脚本自动写入
3491 399K ACCEPT all -- virbr0 192.168.122.0/24 0.0.0.0/0 ---->由libvirt脚本自动写入
0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0 ---->由libvirt脚本自动写入
0 0 REJECT all -- 
virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable ---->由libvirt脚本自动写入
0 0 REJECT all -- virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable ---->由libvirt脚本自动写入
0 0 REJECT all -- 
* 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited ---->iptables的系统预设
Chain OUTPUT (policy ACCEPT 181K packets, 138M bytes)
pkts bytes target prot opt in out source destination

如果没有default的话,或者需要扩展自己的虚拟网络,可以使用命令重新安装NAT。

NAT方式的适用范围
桌面主机虚拟化。
创建步骤

#virsh net-define /usr/share/libvirt/networks/default.xml

此命令定义一个虚拟网络,default.xml的内容:

<network>
<name>default</name>
<bridge name="virbr0" />
<forward/>
<ip address="192.168.122.1" netmask="255.255.255.0">
<dhcp>
<range start="192.168.122.2" end="192.168.122.254" />
</dhcp>
</ip>
</network>

也可以修改xml,创建自己的虚拟网络。

标记为自动启动:

#virsh net-autostart default
Network default marked as autostarted

启动网络:

#virsh net-start default
Network default started

网络启动后可以用命令brctl show 查看和验证。

修改/etc/sysctl.conf中参数,允许ip转发:

net.ipv4.ip_forward=1

客户机安装

客户机安装时注意,网络要选择用NAT方式。

编辑修改虚拟机配置文件 /etc/libvirt/qemu/v1.xml,增加如下内容

<interface type='network'>
  <mac address='52:54:00:4f:1b:07'/>
  <source network='default'/>
  <model type='virtio'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>

虚拟机启动后,验证网络接口是否正常:

brctl show

bridge name bridge id STP enabled interfaces
virbr0 8000.525400b9b096 yes virbr0-nic
vnet0

Bridge方式的影响

Bridge方式配置出来的接口对NAT方式没有影响,因为NAT方式并没有使用物理网卡。但作为客户机,只能选择其中的一种。

Bridge方式即虚拟网桥的网络连接方式,是客户机和子网里面的机器能够互相通信。可以使虚拟机成为网络中具有独立IP的主机。

场景说明:KVM虚拟机之前没有设置为Bridge模式,然后就直接创建虚拟机了(当时网卡模式选择的为default),后来调整KVM网卡模式为Bridge后,虚拟机没法正常联网。

[root@node160 ~]# virsh shudown CentOS-7.3-X86_64

[root@node160 ~]# virsh edit CentOS-7.3-X86_64

将xml配置文件中的:
<interface type=‘network‘>
<mac address=‘52:54:00:e4:7c:77‘/>
<source network=‘default‘/>
<model type=‘virtio‘/>
<address type=‘pci‘ domain=‘0x0000‘ bus=‘0x00‘ slot=‘0x03‘ function=‘0x0‘/>
</interface>

修改为:
<interface type=‘bridge‘>
<mac address=‘52:54:00:e4:7c:77‘/>
<source bridge=‘br0‘/>
<model type=‘virtio‘/>
<address type=‘pci‘ domain=‘0x0000‘ bus=‘0x00‘ slot=‘0x03‘ function=‘0x0‘/>
</interface>

由于kvm虚拟机使用的是bridge模式,可以把virbr0接口(即NAT方式里面的default虚拟网络)删除

[root@node160 ~]# ip add list

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
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 master br0 state UP qlen 1000
link/ether 00:0c:29:14:2b:9a brd ff:ff:ff:ff:ff:ff
4: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN qlen 1000
link/ether 52:54:00:9f:ad:48 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 qlen 1000
link/ether 52:54:00:9f:ad:48 brd ff:ff:ff:ff:ff:ff
7: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
link/ether 00:0c:29:14:2b:9a brd ff:ff:ff:ff:ff:ff
inet 10.10.10.160/24 brd 10.10.10.255 scope global br0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe14:2b9a/64 scope link 
valid_lft forever preferred_lft forever
8: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN qlen 1000
link/ether fe:54:00:71:7b:aa brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fe71:7baa/64 scope link 
valid_lft forever preferred_lft forever
10: vnet1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN qlen 1000
link/ether fe:54:00:e4:7c:77 brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fee4:7c77/64 scope link 
valid_lft forever preferred_lft forever

[root@node160 ~]# virsh net-list --all
Name State Autostart Persistent

default active yes yes

[root@node160 ~]# brctl show

bridge namebridge idSTP enabledinterfaces
br08000.000c29142b9anoeth0
vnet0
vnet1
virbr08000.5254009fad48yesvirbr0-nic

[root@node160 ~]# virsh net-destroy default

Network default destroyed

[root@node160 ~]# virsh net-undefine default

Network default has been undefined

配置完成后,再次查看网卡信息

[root@node160 ~]# ip add list

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
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 master br0 state UP qlen 1000
link/ether 00:0c:29:14:2b:9a brd ff:ff:ff:ff:ff:ff
7: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP qlen 1000
link/ether 00:0c:29:14:2b:9a brd ff:ff:ff:ff:ff:ff
inet 10.10.10.160/24 brd 10.10.10.255 scope global br0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe14:2b9a/64 scope link 
valid_lft forever preferred_lft forever
8: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN qlen 1000
link/ether fe:54:00:71:7b:aa brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fe71:7baa/64 scope link 
valid_lft forever preferred_lft forever
10: vnet1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN qlen 1000
link/ether fe:54:00:e4:7c:77 brd ff:ff:ff:ff:ff:ff
inet6 fe80::fc54:ff:fee4:7c77/64 scope link 
valid_lft forever preferred_lft forever