如何为2个KVM-Guests分配多个公共IP地址

对于这个话题,我是新手,现在我想了解如何通过KVM主机为多个公共IP地址分配多个公共IP地址。 我发现了很多例子,如何使用1个公共IP运行获得这样的设置。

这里是我的设置:服务器只有一个网卡/ MAC,并运行2个KVM客人与Apache(和其他的东西)。 这两个访客环境是Ubuntu的服务器11.10和必须运行在单独的虚拟机。 5个公共IP地址用于处理SSL证书和其他东西。 第一个VM应该使用5个地址/证书中的3个。 第二个虚拟机得到其余的。 Apache的东西configuration正确。

我已经通过iptables尝试了许多不同的方式来将stream量从主机网卡路由到客户网卡。 尽pipe有一个方法是正确的,但只是错误的实现,我把这些细节留给了你,让你无法接受。 问题是:什么是理想的方式呢?

应满足以下条件:

  • Apache必须得到访问者的原始IP地址
  • Apache必须知道,使用正确的ssl-vhost会使用哪个公共IP地址
  • 该stream量不能通过主机上的(反向)代理进行路由,因为在其他VM客户机上还有2个非公开的http服务。 而且:只有sshd应该直接监听主机 – 没有别的
  • 每个虚拟机应该能够直接访问互联网。
  • 数据中心中的networking是基于MAC的交换机。 正如我所知道的,与互联网交stream的唯一途径是通过eth0及其MAC地址。

如果我放弃所有的虚拟化东西,这将是非常容易的,因为Apache直接从特定的IP地址获取请求。

我开放任何工作解决scheme。

图

在您的dom0(例如KVM主机)WAN接口上使用桥接器。 这需要安装bridge-utils软件包。 由于这是基于Debian的发行版,您可以在/etc/network/interfacesconfiguration它:

 iface eth0 inet manual auto br_wan iface br_wan inet dhcp # Assuming DHCP to get address, otherwise migrate all WAN connection options here #address 192.168.122.0 bridge_ports eth0 tap_guest1 bridge_stp off bridge_maxwait 0 bridge_fd 0 pre-up ip tuntap add dev tap_guest1 user guest1 mode tap # This command is required if your ISP allocates static IPs depending on MAC address # You shouldn't use this but might be handy some time #pre-up sysctl -q -w net/ipv4/conf/tap_guest1/proxy_arp=1 post-down ip tuntap del tap_guest1 mode tap 

Pre-up命令设置了TAP界面,将您的KVM访客连接到网桥。 请注意,此设置允许从非特权用户guest1运行kvm。 请注意,使用sysctl设置net.ipv4.ip_forward = 1也可能是有用的。

我使用iproute2软件包的ip tuntap命令。 目前还没有在Debian软件包中logging,但很快将会在上游的手册页面中提供。 由于该软件包安装在每个基于Debian的服务器上,因此您不需要安装uml-utilitiesopenvpn软件包即可创build这些界面。

这种方法确实缺乏一些优雅来pipe理大量的tap界面,因为您需要创build与tap_guest1界面类似的上tap_guest1 。 这可以通过在/etc/network/pre-up.d/etc/network/post-down.d写入其他脚本来解决。 如果要在使用ifdown / ifup脚本的情况下重新configurationbr_wan接口,而KVM guest br_wan仍在运行,则也会出现问题 – 您需要从桥configuration中除去除eth0之外的所有接口,并手动将它们从网桥中拆除(不要忘记然后在网桥重新configuration之后将它们重新连接),或closures网桥上运行的所有KVM实例。

另一种方式,也许更干净,是为KVM自己编写定制的ifup脚本,并在你的网卡的script选项中使用它。 你可以在/etc/qemu-ifup得到一个例子。 有关详细信息,请参阅kvm手册页 。

然后你可以像这样运行你的KVM盒子:

 kvm -net nic,model=virtio,macaddr=12:34:56:78:9a:bc \ -net tap,ifname=tap_guest1,script=no,downscript=no \ -boot c -nographic -display none -daemonize \ guest1-drive.qcow2 

在您的KVM guest虚拟机的一个接口上设置多个IP地址可以通过命令手动完成

 ip address add aaa.bbb.ccc.101/24 dev eth0 

或者像/etc/network/interfaces

 auto eth0 eth0:1 iface eth0 inet static address aaa.bbb.ccc.100 network aaa.bbb.ccc.0 netmask 255.255.255.0 broadcast aaa.bbb.ccc.255 gateway aaa.bbb.ccc.1 iface eth0:1 inet static address aaa.bbb.ccc.101 network aaa.bbb.ccc.0 netmask 255.255.255.0 broadcast aaa.bbb.ccc.255 gateway aaa.bbb.ccc.1 

请注意,如果您的数据中心/提供商不希望您在同一个networking上显示其他框,则可能不会configuration它们,并且它们将不可用。 在这种情况下,您可能需要创build内部网桥并使用iptables在您的WAN接口和此网桥之间使用DNAT和SNAT转发数据包。 假设你的本地虚拟桥接networking是10.0.0.0/8,你的guest1是10.0.0.2,你需要这个:

 iptables -t nat -A PREROUTING --dst aaa.bbb.ccc.100 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2 iptables -t nat -A PREROUTING --dst aaa.bbb.ccc.101 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.2 ... iptables -t nat -A POSTROUTING -p tcp --dst 10.0.0.2 -j SNAT --to-source aaa.bbb.ccc.100 

请注意,您需要的每个KVM访客都需要与外部IP一样多的DNAT命令,但只需要一个SNAT规则即可访问互联网。 您也可以只允许所需的端口,只允许HTTP / HTTPS / SSHstream量。 如果你省略了--dport语句,那么所有的端口都将被转发。 除非您愿意托pipeDHCP服务器,否则您的KVM来宾应该将KVM主机的静态networking设置设为默认网关。

你使用一个桥而不是使用iptables转发数据包。 启动guest虚拟机之后,您可以将IPconfiguration到guest虚拟机上的NIC(如果您有多个虚拟NIC)。

请参阅此文档 。

@ jollyroger:非常感谢您的全面指导。 可悲的是,在我的情况下,它没有奏效。 但是,您的指南帮助我更好地了解与KVM一起使用的linuxnetworking/桥接function。

所以我恢复了一切,直接从我的托pipe公司得到了一些帮助。 该scheme与使用virt-managervirsh添加自定义networkingconfiguration一样简单。 这是解决scheme,终于为我工作:

我有一个/ 29-子网(+主机上的另一个不同的ssh IP)。 数据中心的networking是基于MAC的交换机,所以所有的stream量都必须通过本地网关(据我了解)。 我的提供者是德国的Hetzner。 我使用http://www.subnet-calculator.com/subnet.php?net_class=A来计算network-configuration-xml的所有必要设置:

 <network> <name>{some systemwide unique name. eg: subnet1}</name> <uuid>{> call uuidgen from shell to generate a uuid}</uuid> <forward dev="{interface eg: eth0}" mode="route" /> <bridge name="{name of a _new_ virtual interface eg: virbr2}" stp="off" forwardDelay="0" /> <ip address="{subnet-calc: Host Address Range Start Address}" netmask="subnet-calc: Subnet Mask"> <dhcp> <range start="{subnet-calc: Host Address Range Start Address+1}" end="{subnet-calc: Host Address Range End Address}" /> </dhcp> </ip> </network> 

我将这个XML数据保存到/tmp/subnet1.xml文件中,并通过使用以下命令来应用这个新的虚拟networking:

 sudo virsh net-define /tmp/subnet1.xml 

我使用virt-manager 0.9.0(通过在我的Windows机器上通过putty进行x11转发)来创build和编辑所有的虚拟机。 所以我的两个公共虚拟机都得到了这个新的虚拟networking。 在每个VM中,我已经为每个公共IP创build了一个新的虚拟networking接口。 我注意到哪个MAC地址用于哪个公共IP。 因此,如果我想将一个公有IP地址移动到另一个虚拟机上,那么只不过是删除虚拟机A中的虚拟网卡,并使用相同的MAC地址在虚拟机B中创build虚拟网卡。

另一件事,如果您尝试重现这种情况:在启动虚拟机之前,请确保虚拟networking“subnet1”(sa)处于活动状态。 在virt-manager的主窗口中,select编辑>连接详情,然后跳转到Tab Virtual Networks 。 如果networking“subnet1”是灰色的,只需将其标记并点击播放button即可。

现在启动虚拟机并键入ifconfig 。 在我的情况下,一切工作直接。

如果我错过了这份报告中的任何内容,请问。 如果有人有更好的解决scheme,请随时在这里添加它。