KVM虚拟机的网卡有两种方式:桥接和NAT转发。在桥接方式下,虚拟机的虚拟网卡和主机网卡组成虚拟交换机(bridging),桥接网卡配置外部IP地址;外部网络可直接访问到虚拟机。在NAT转发方式下,主机创建一个虚拟桥接网卡专供采用NAT方式的虚拟机使用,该桥接网卡配置内部网地址,通过主机netfilter网络地址翻译(NAT),跟外部网络连通,就像一般家庭和公司内部网通过NAT路由器上网一样。
一、桥接方式
桥接方式的KVM网络配置主要是将主机的物理网卡纳入一个虚拟桥接网卡,并将主机的IP地址配置在桥接网卡上。我们以CentOS 6/7系统为例。
# cd /etc/sysconfig/network-scripts # ifdown p4p2 # echo 'DEVICE=p4p2 HWADDR=A4:1F:72:xx:xx:xx TYPE=Ethernet UUID=059ace33-78ea-4c01-91c4-213f6eb9e4b5 ONBOOT=yes NM_CONTROLLED=no #BOOTPROTO=dhcp BRIDGE=br0' > ifcfg-p4p2 # echo 'DEVICE=br0 TYPE=Bridge ONBOOT=yes NM_CONTROLLED=no BOOTPROTO=static IPADDR=xx.xx.xx.xx PREFIX=25 GATEWAY=xx.xx.xx.xx' > ifcfg-br0 # ifup br0
二、NAT方式
NAT方式下,主机的网络配置的实质就是netfilter防火墙规则和绑定到虚拟桥接网卡的dnsmasq DHCP服务器的配置,其余的工作,如配置虚拟桥接网卡,都由KVM系统完成。
除了端口转发须手动设置外,其余的防火墙规则也都会由KVM自动创建。为了让KVM自动地置端口转发,我写了一个KVM在启动/关闭虚拟机或重连虚拟网卡时会调用的脚本/etc/libvirt/hooks/qemu:
[root@master ~]# cat /etc/libvirt/hooks/qemu #!/bin/sh # Forwarding multiple ports on Host_ipaddr to Host_ipaddr. # The numbers of Proto, Guest and Host port arrays must match. # Adapted from the example script http://wiki.libvirt.org/page/Networking#Forwarding_Incoming_Connections Host_ipaddr='<Host IP Addr>' case "$1" in 'ubuntu1404') Proto=('tcp' 'tcp' 'tcp' 'udp' 'tcp') Host_port=( '2202' '80' '1723' '1194' '443') Guest_port=( '22' '80' '1723' '1194' '443') Guest_ipaddr='192.168.122.2' ;; 'centos6wh') Proto=('tcp' ) Host_port=( '2203' ) Guest_port=( '22' ) Guest_ipaddr='192.168.122.3' ;; *) exit ;; esac length=$(( ${#Host_port[@]} - 1 )) if [ "${2}" = "stopped" -o "${2}" = "reconnect" ]; then for i in `seq 0 $length`; do iptables -t nat -D PREROUTING -d ${Host_ipaddr} -p ${Proto[$i]} --dport ${Host_port[$i]} -j DNAT \ --to ${Guest_ipaddr}:${Guest_port[$i]} iptables -D FORWARD -d ${Guest_ipaddr}/32 -p ${Proto[$i]} -m state --state NEW \ -m ${Proto[$i]} --dport ${Guest_port[$i]} -j ACCEPT done fi if [ "${2}" = "start" -o "${2}" = "reconnect" ]; then for i in `seq 0 $length`; do iptables -t nat -I PREROUTING -d ${Host_ipaddr} -p ${Proto[$i]} --dport ${Host_port[$i]} -j DNAT \ --to ${Guest_ipaddr}:${Guest_port[$i]} iptables -I FORWARD -d ${Guest_ipaddr}/32 -p ${Proto[$i]} -m state --state NEW \ -m ${Proto[$i]} --dport ${Guest_port[$i]} -j ACCEPT done fi
当需要增加端口映射时,只须修改一下脚本开头部分就可以了。
DHCP服务器(dnsmasq)的配置,须由KVM系统的指令net-edit和net-update完成。net-edit直接修改定义虚拟网络的xml文件,而且修改好后不会立即生效,必须重启虚拟网络,这会导致虚拟机网卡断开。好在大部分配置的修改可以由可以立即生效的net-update命令来完成,例如:
virsh # net-update default add ip-dhcp-host "<host mac='52:54:00:00:00:01' name='vm1' ip='192.168.122.4' />" --live --config
这条命令设置一个静态的IP地址租约。根据KVM文档,以下配置修改可由net-update完成,立即生效。
ip-dhcp-host ip-dhcp-range (add/delete only, no modify) forward-interface (add/delete only) portgroup dns-host dns-txt dns-srv