三、NAT模型
NAT模型其实就是SNAT的实现,路由中虚拟机能将报文发送给外部主机,但是外部主机因找不到通往虚拟机的路由因而无法回应请求。但是外部主机能同宿主机通信,所以在宿主机上添加一个NAT转发,从而在外部主机请求虚拟机时,将虚拟机的IP地址转换为宿主机上的某个地址,从而实现外部网络与虚拟机的通信,其实际上只是通过iptables的nat表的POSTROUTING链实现地址转换罢了。
实现方法:
1、编写虚拟机启动脚本
[root@kvm-node1 ~]# cat /opt/tools/qemu-natup
#!/bin/bash bridge=br0 net="192.168.122.1/24" checkbr(){ if brctl show |grep -i $1;then return 0 else return 1 fi } initbr(){ brctl addbr $bridge ip link set $bridge up ip addr add $net dev $bridge } enable_ip_forward(){ sysctl -w net.ipv4.ip_forward=1 sysctl -p } setup_nat(){ checkbr $bridge if [ $? -eq 1 ];then initbr enable_ip_forward iptables -t nat -A POSTROUTING -s $net ! -d $net -j MASQUERADE fi } if [ -n $1 ];then setup_nat ip link set $1 up brctl addif $bridge $1 exit 0 else echo "Error: no interface specified." exit 1 fi
2、编写虚拟机停止脚本
[root@kvm-node1 ~]# cat /opt/tools/qemu-natdown
#!/bin/bash bridge=br0 net="192.168.122.0/24" remove_rule() { iptables -t nat -F } isalone_bridge() { if ! brctl show | awk "/^$bridge/{print \$4}" | grep "[^[:space:]]" &> /dev/null; then ip link set $bridge down brctl delbr $bridge remove_rule fi } if [ -n $1 ];then ip link set $1 down brctl delif $bridge $1 isalone_bridge exit 0 else echo "Error: no interface specified." exit 1 fi
3、启动虚拟机
qemu-kvm --name "centos5-nat" -smp 1 -m 512 -cpu host --drive file=/images/kvm/centos5.img,if=virtio,media=disk,cache=writeback -net nic,model=virtio,macaddr=00:0c:29:86:4e:1a -net tap,ifname=vnet0.0,script=/opt/tools/qemu-natup,downscript=/opt/tools/qemu-natdown -daemonize
4、进入虚拟机,配置网络
5、给虚拟机添加默认网关,将br0的IP地址设置为虚拟机的默认网关
可以看到,添加了默认网关之后,虚拟机已经可以ping通宿主机了。另外,因为宿主机上添加了iptables规则,所以此时也可以ping通外部网络(192.168.49.1)了,NAT模型的实现完成。
四、桥接模型
在宿主机中创建一个桥设备,把宿主机的eth0放在桥上,这样Guest1上的eth0将报文发给vnet0,再直接发给宿主机上的eth0,将源地址改为宿主机上的eth0的地址。
当响应报文到达物理机上的eth0时如何判断此响应报文是发给虚拟机的还是物理机自己的?
物理机会先创建一个虚拟网卡,在物理机上打开混杂模式(无论mac地址是不是自己的都将接收响应报文),如果mac地址是自己的则转发给虚拟网卡,如果不是自己的则转发给vnet0,这就是桥接模型,因为物理机的网卡具有桥的功能所以叫做桥接模型。
实现方式:
1、创建虚拟机启动脚本
[root@kvm-node1 tools]# cat qemu-brup
#!/bin/bash bridge=br0 device=eth1 device_ip=`ifconfig eth1|awk ‘/inet addr/ {print $2}‘ |cut -d: -f2` checkbr(){ if brctl show |grep -i $1;then return 0 else return 1 fi } initbr(){ brctl addbr $bridge ip link set $bridge up brctl addif $bridge $device ifconfig $device 0.0.0.0 ifconfig $bridge ${device_ip} netmask 255.255.255.0 up } setup_nat(){ checkbr $bridge if [ $? -eq 1 ];then initbr fi } if [ -n $1 ];then setup_nat ip link set $1 up brctl addif $bridge $1 exit 0 else echo "Error: no interface specified." exit 1 fi
2、创建虚拟机停止脚本
[root@kvm-node1 tools]# cat qemu-brdown
#!/bin/bash bridge=br0 device=eth1 isalone_bridge() { if ! brctl show | awk "/^$bridge/{print \$4}" | grep "[^[:space:]]" &> /dev/null; then ip link set $bridge down brctl delbr $bridge remove_rule fi } if [ -n $1 ];then ip link set $1 down brctl delif $bridge $1 ifconfig $bridge 0.0.0.0 brctl delif $bridge $device isalone_bridge exit 0 else echo "Error: no interface specified." exit 1 fi
3、使用qemu-kvm创建虚拟机
qemu-kvm --name "centos5-bridge" -smp 1 -m 512 --drive file=/images/kvm/centos5.img,if=virtio,media=disk,cache=writeback -net nic,model=virtio,macaddr=00:0c:29:86:4e:6a -net tap,ifname=vnet0.0,script=/opt/tools/qemu-brup,downscript=/opt/tools/qemu-brdown --daemonize
4、登录虚拟机,检查虚拟机网络
虚拟机的ip段和宿主机上的eth1在一个网段(因为使用宿主机的eth0的IP地址进行ssh,所以这里使用eth1进行桥接)
5、在虚拟机上ping宿主机测试
虚拟机可以ping通宿主机的IP地址(eth1的IP地址),也可以ping通外部网络(eth1的网关地址)
至此,桥接模型实现完成。
原文:http://blog.51cto.com/jerry12356/2132246