接上篇,介绍NAT网络模型和桥接模型。
三、NAT模型
NAT模型其实就是SNAT的实现,路由中虚拟机能将报文发送给外部主机,但是外部主机因找不到通往虚拟机的路由因而无法回应请求。但是外部主机能同宿主机通信,所以在宿主机上添加一个NAT转发,从而在外部主机请求虚拟机时,将虚拟机的IP地址转换为宿主机上的某个地址,从而实现外部网络与虚拟机的通信,其实际上只是通过iptables的nat表的POSTROUTING链实现地址转换罢了。
实现方法:
1、编写虚拟机启动脚本
[[email protected] ~]# 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、编写虚拟机停止脚本
[[email protected] ~]# 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、创建虚拟机启动脚本
[[email protected] 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、创建虚拟机停止脚本
[[email protected] 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