问题描述
我刚刚根据本指南在我的 Ubuntu 服务器上安装了 KVM:https://help.ubuntu.com/community/KVM/Installation
然后准备一个桥接网络,如下所示:https://help.ubuntu.com/community/KVM/Networking
然后,我用 virt-manager 创建了一个虚拟机。我试了几次,但是客人无法连接到网络!有什么帮助吗?
如果配置:
br0 Link encap:Ethernet HWaddr d0:27:88:b0:e4:38
inet addr:192.168.20.100 Bcast:192.168.20.255 Mask:255.255.255.0
inet6 addr: fe80::d227:88ff:feb0:e438/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:62 errors:0 dropped:0 overruns:0 frame:0
TX packets:62 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:10493 (10.4 KB) TX bytes:8433 (8.4 KB)
eth0 Link encap:Ethernet HWaddr d0:27:88:b0:e4:38
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:62 errors:0 dropped:0 overruns:0 frame:0
TX packets:63 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:11361 (11.3 KB) TX bytes:8479 (8.4 KB)
Interrupt:41
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:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
virbr0 Link encap:Ethernet HWaddr 5a:8c:57:95:af:3b
inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0
UP 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:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
brctl 显示:
bridge name bridge id STP enabled interfaces
br0 8000.d02788b0e438 no eth0
virbr0 8000.000000000000 yes
brctl showmacs br0:
port no mac addr is local? ageing timer
1 5c:d9:98:67:b6:28 no 48.33
1 d0:27:88:b0:e4:38 yes 0.00
1 e0:2a:82:f9:6c:09 no 0.00
ip路由:
default via 192.168.20.1 dev br0 metric 100
192.168.20.0/24 dev br0 proto kernel scope link src 192.168.20.100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1
*在客人中 *我无法从客人那里复制粘贴信息,因为无法通过 ssh 访问它。它没有从 DHCP 获得任何 ip。即使手动设置后也无法正常工作。
最佳思路
预赛
以下内容适用于 Ubuntu 12.04。您应该在测试时禁用计算机的防火墙,以免干扰。
/etc/default/qemu-kvm 文件应该与最初安装的一样。
您需要安装 bridge-utils qemu-kvm 和 libvirt-bin。任何使用虚拟机的用户都应该添加到 libvirtd 组中。
似乎不再需要添加 CAP_NET_ADMIN 功能。
网络设置
默认网络模式是用户模式,也称为 SLIRP。它使用预定义的 virbr0 桥接器,该桥接器通过 NAT 路由到来宾计算机。 NAT 路由使用内核的 ip_forwarding 功能和 iptables。桥接模式在客户机中使用虚拟网桥,(未编号的)以太网接口连接到该虚拟网桥,并且主机和客户机都有自己的网络接口。
下图可能会使差异更加清晰:
您可以看到默认用户网络是如何定义的:
virsh net-dumpxml default
我可以使用以下方法设置桥接模式:
在 /etc/network/interfaces 中(来自您在问题中提到的帖子的桥接部分):
auto lo
iface lo inet loopback
#auto eth0
#iface eth0 inet dhcp
auto eth0
iface eth0 inet manual
auto br0
iface br0 inet dhcp
bridge_ports eth0
bridge_stp off
bridge_fd 0
bridge_maxwait 0
重启;并确保无线网络未激活。使用 ip route
检查默认 IP 路由。它必须使用 br0 接口。
注:如果进行此更改时您的以太网未连接,则需要插入以太网电缆并获得操作符,否则引导将挂起两分钟,您将无法使用网络功能那是因为 eth0 接口,通过在这个文件中,必须先出现,然后才能正常进行引导。
注:通常,您不能使用无线网络代替 eth0,因为它们无法使用多个 MAC 地址(我推断他们需要第二个用于网桥)。
作为替代方案,您可以禁用以太网并确保它没有 IP 地址,并且没有使用 ip route
设置的默认路由。然后:
sudo ifconfig eth0 0.0.0.0 up
sudo brctl addbr br0
sudo brctl addif br0 eth0
sudo ifconfig br0 up
sudo dhclient br0 &
您还可以在此处提供静态 IP 地址,以及定义默认路由和 DNS 地址。对于此示例,dhclient
执行此操作。
这是我的路由表:
$ip route list
default via 192.168.1.1 dev br0 metric 100
169.254.0.0/16 dev br0 scope link metric 1000
192.168.1.0/24 dev br0 proto kernel scope link src 192.168.1.45
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1
使用 kvm
然后我可以使用以下命令启动桥接的 kvm 机器:
$ sudo kvm -name Quantal -m 1024 -hda foo.qcow2 --soundhw ac97 -device virtio-net,netdev=tunnel -netdev tap,id=tunnel,ifname=vnet0
-netdev tap
参数使 sudo 成为一项要求。当 VM 启动时,qemu-kvm 运行以下命令:
ifconfig vnet0 0.0.0.0 up
brctl addif brctl addif br0 vnet0
这是由 /etc/qemu-ifup 完成的
VM 的 vnet0 接口被添加到 br0 网桥,因为上面的默认路由使用该网桥接口。如果它不存在,则 Tap 接口将被添加到 virbr0 接口。由于它没有连接到 Internet,因此在我的实验中,NAT 将用于将访客连接到主机和 Internet。您可以将 vnet0 定向到 /etc/default/qemu-kvm 中的特定网桥。使用下面的 virt-manager,您可以明确指示要连接到哪个网桥。
由于上面qemu-kvm下发的命令,加上-netdev tap,id=tunnel,ifname=vnet0
参数,vm虚拟机连接到vnet0隧道,隧道连接到br0网桥。
我现在可以从我网络上的另一台计算机直接 ssh 进入这个来宾虚拟机。
我的主机 ifconfig
(注意当 VM 运行时出现在我的网络上的 vnet0 接口):
$ifconfig
br0 Link encap:Ethernet HWaddr 00:1e:33:88:07:e5
inet addr:192.168.1.45 Bcast:255.255.255.255 Mask:255.255.255.0
inet6 addr: fe80::21e:33ff:fe88:7e5/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:6526 errors:0 dropped:0 overruns:0 frame:0
TX packets:7543 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:2712940 (2.7 MB) TX bytes:1071835 (1.0 MB)
eth0 Link encap:Ethernet HWaddr 00:1e:33:88:07:e5
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:7181 errors:0 dropped:0 overruns:0 frame:0
TX packets:7740 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2974585 (2.9 MB) TX bytes:1096580 (1.0 MB)
Interrupt:43 Base address:0x6000
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:10 errors:0 dropped:0 overruns:0 frame:0
TX packets:10 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:664 (664.0 B) TX bytes:664 (664.0 B)
vnet0 Link encap:Ethernet HWaddr ca:0c:73:c3:bc:45
inet6 addr: fe80::c80c:73ff:fec3:bc45/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:226 errors:0 dropped:0 overruns:0 frame:0
TX packets:429 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:26919 (26.9 KB) TX bytes:58929 (58.9 KB)
virbr0 Link encap:Ethernet HWaddr d6:18:22:db:ff:93
inet addr:192.168.122.1 Bcast:192.168.122.255 Mask:255.255.255.0
UP 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:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
我在运行 VM 时的网桥配置:
$brctl show
bridge name bridge id STP enabled interfaces
br0 8000.001e338807e5 no eth0
vnet0
virbr0 8000.000000000000 yes
请注意,虚拟机的 vnet0 接口和 eth0 接口都连接到 br0 网桥。
MAC在br0接口上:
$brctl showmacs br0
port no mac addr is local? ageing timer
1 00:05:5d:cf:64:61 no 2.54
1 00:19:d2:42:5d:3f no 36.76
1 00:19:df:da:af:7c no 2.86
1 00:1e:33:88:07:e5 yes 0.00
1 00:60:0f:e4:17:d6 no 0.79
2 52:54:00:12:34:56 no 0.80
1 58:6d:8f:17:5b:c0 no 5.91
1 c8:aa:21:be:8d:16 no 167.69
2 ca:0c:73:c3:bc:45 yes 0.00
请注意,br0 接口将我的主机连接到来宾使用的同一网桥。
您可以使用 traceroute 8.8.8.8
检查您是否被桥接而不是 NAT 路由到您自己的网络。如果第一个节点是您网络的路由器而不是访客的 IP 地址,则您的网络应该可以正常工作。
virt-manager
确保您已安装 virt-manager
和 hal
。 hal
包是 virt-manager
的建议依赖项,用于在创建或编辑来宾时确定系统的网络配置。
在如上所述定义 br0 网桥的同时,我使用 virt-manager 创建了一个虚拟机,如下所示:
\n\n\n\n
我能够直接访问我的家庭网络的其余部分,并从该访客访问 Internet。我还能够从我家庭网络上的另一台(非主机、非访客)Ubuntu 计算机 ssh 进入它。
这是由 virt-manager 运行的非常长的 kvm
命令(用于与 EApubs 或其他有此问题的人进行比较):
/usr/bin/kvm -S -M pc-1.0 -enable-kvm -m 1024 -smp 1,sockets=1,cores=1,threads=1 -name precise -uuid f057a729-eda6-4b85-84dc-f100c9ae3789 -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/var/lib/libvirt/qemu/precise.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown -drive file=/media/natty/home/gruber/ubuntu-kvm/tmpW8gSGB.qcow2,if=none,id=drive-ide0-0-0,format=qcow2 -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 -netdev tap,fd=18,id=hostnet0 -device rtl8139,netdev=hostnet0,id=net0,mac=52:54:00:0e:da:9b,bus=pci.0,addr=0x3 -chardev pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -usb -vnc 127.0.0.1:0 -vga cirrus -device intel-hda,id=sound0,bus=pci.0,addr=0x4 -device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
这是 /etc/libvirt/qemu/quantal.xml 中虚拟机描述的网络部分
<interface type='bridge'>
<mac address='52:54:00:b0:8e:aa'/>
<source bridge='br0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
根据 this 链接,为了性能和可靠性,最好将网络设备型号设置为 virtio
,您可以通过按 i 按钮在 virt-viewer 中执行此操作,进入 NIC 设置,并将 “Device model” 设置为 virtio
。您还可以通过添加以下行将其添加到上面的 XML 中:
<model type='virtio'/>
总之
这一切发生在 12.04 是:
-
安装 virt-manager、bridge-utils、qemu-kvm 及相关包
-
确保希望使用 kvm 的每个用户都在 libvirtd 组中。
-
如上所述定义 /etc/network/interfaces (与引用的文章匹配)
-
重新启动,确保以太网已插入并且无线(如果有)已关闭。
-
直接对图像运行 kvm,例如
-device e1000,netdev=tunnel -netdev tap,id=tunnel,ifname=vnet0
,或者使用 virt-manager 创建一个虚拟机,在 Step 4->Advanced Options 面板下指定网桥 br0。
无需对网络、功能、模板或配置进行进一步更改。
要将新访客中的服务公开到 Internet,您应该:
-
准备和配置您需要的任何防火墙服务。
-
在访客配置或 DHCP 服务中分配静态地址。
-
如果您使用的是 NAT 路由器,请为您正在实施的服务打开一个端口,将其定向到访客的 IP 地址。
请记住为您的主机测试和 re-enable 防火墙服务。它可能需要任何条目才能将流量转发给访客。
请参阅 https://help.ubuntu.com/community/KVM/Installation 、 https://help.ubuntu.com/community/KVM/Networking 和 https://help.ubuntu.com/12.04/serverguide/libvirt.html 。
次佳思路
如果您看到的行为是主机可以访问客人,客人可以访问主机,但客人无法访问网络上的其他机器,反之亦然……可能是主机的防火墙阻止了访问。
见:https://bugs.launchpad.net/ubuntu/+source/ufw/+bug/573461
具体来说,这部分:\n“最后一步是禁用网桥上的netfilter:
# cat >> /etc/sysctl.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0
EOF
第三种思路
这是我用来为 qemu-kvm
创建网桥的两个脚本。
首先,让主机成为IP路由器。
脚本 ip-router.sh
:
#!/bin/bash
internetinterface="eth0"
username=`whoami`
if [ "x$username" != "xroot" ] ; then
echo
echo "You must be root in order to run this script..."
echo
exit
fi
if [ "x$1" != "x" ] ; then
internetinterface="$1"
fi
if [ "x$1" == "xdel" ] || [ "x$2" == "xdel" ] ; then
disable="1"
else
disable="0"
fi
if [ "$disable" == "0" ] ; then
echo "Enabling IP forward and setting up masquerade NAT on interface $internetinterface"
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o $internetinterface -j MASQUERADE
else
echo "Disable IP forward and setting down masquerade NAT on interface $internetinterface"
echo 0 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -D POSTROUTING -o $internetinterface -j MASQUERADE
fi
然后,创建 tun-tap
接口并使用默认接口(通常是具有 Internet 连接的接口)创建 bridge
。
脚本 create-qemu-bridged-tuntap.sh
:
#!/bin/bash
bridgename=br0
tapinterface=tap0
outinterface=eth1
if [ "x$1" != "x" ] ; then
outinterface="$1"
fi
ifaces=`awk -F: '{print $1}' /proc/net/dev | tail -n +3`
iffound="0"
for i in $ifaces
do
if [ "$outinterface" == "$i" ] ; then
iffound="1"
fi
done
if [ "$iffound" == "0" ] ; then
echo
echo "Can't find the output interface."
echo
exit 1
fi
outifaceip=`ifconfig | grep -A1 $outinterface | tail -1 | awk -F: '{print $2}' | awk '{print $1}'`
outifaceiptokens=`echo $outifaceip | awk -F \. '{print NF}'`
if [ "$outifaceiptokens" != "4" ] ; then
echo
echo "The selected output interface $outinterface doesn't seem to have a valid IP address."
echo
exit 1
fi
hostaddress="192.168.1.1"
guestaddress="192.168.1.95"
sudo tunctl -t $tapinterface
sudo brctl addbr $bridgename
sudo brctl addif $bridgename $tapinterface
sudo ip link set $bridgename up
sudo ip addr add $hostaddress/24 dev $bridgename
sudo route add -host $guestaddress dev $bridgename
sudo parprouted eth1 $bridgename
sudo ~/scripts/ip-router.sh $outinterface
我每天都使用这些脚本,所以它们应该也适合你。您必须安装一些软件包才能使所有这些工作。使用:
dlocate `which COMMAND`
您可以查看需要哪个软件包才能拥有 COMMAND
。例如,要查看哪个包需要有 brctl
,只需运行:
dlocate `which brctl`
你将拥有:
bridge-utils: /sbin/brctl
对这些脚本中的所有命令使用相同的方法,您应该(至少)运行这个 aptitude
命令行:
sudo aptitude install dlocate iproute parprouted iptables uml-utilities bridge-utils net-tools
最后,您可以启动主脚本(作为普通用户):
#> create-qemu-bridged-tuntap.sh eth0
Set 'tap0' persistent and owned by uid 0
Enabling IP forward and setting up masquerade NAT on interface eth0
运行 ip addr
你应该看到一个 IP 地址为 192.168.1.1
的 br0
接口,如 create-qemu-bridged-tuntap.sh
脚本中指定的那样:
#> ip addr
8: br0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
link/ether 36:76:ee:d6:63:b2 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.1/24 scope global br0
这是 guest
看到的 host address
。相反,来宾的 IP 地址为 192.168.1.95
(同样,这可以在主脚本中轻松更改)。
现在,使用 virt-manager
,您只需设置您的访客网卡以使用 br0
作为物理接口。
在 guest
内部,您只需为 eth0
提供 192.168.1.95
的 IP 地址,一切都会正常运行。
Slackware13:~> ifconfig
eth0 Link encap:Ethernet HWaddr 52:54:00:F7:6A:78
inet addr:192.168.1.95 Bcast:192.168.1.255 Mask:255.255.255.0