一个关于Linux内部netns相关的实验,架构图如下:
实验环境准备
vmware workstation 12.0
Linux CentOS 7
ip:192.168.1.104
yum install qemu-kvm
wget http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-disk.img
ln -sv /usr/libexec/qemu-kvm /usr/bin/
echo 1 > /proc/sys/net/ipv4/ip_forward(一定要开启,netns内部的ip_forward不可控,需要根据宿主机的状态而定)
创建桥设备
br-in作为 V switch
ifconfig ens33 0;brctl addbr br-ex;brctl addif br-ex ens33;
ifconfig br-ex 192.168.1.104 up
brctl addbr br-in
ifconfig br-in up
创建V route,命名为route1
ip netns add route1
实验目的
创建两个kvm虚拟机之后,通过两对虚拟网卡,以及NAT规则,
实现kvm虚拟机与物理机之间相互通信,
并且虚拟机的ip的值可由部署在名称空间内的dhcp服务器自动获取。
创建kvm虚拟机
为了规范,我们创建镜像文件目录,并且让虚拟机使用单独的映像文件
mkdir /images/kvm/ -p
cp cirros-0.3.4-x86_64-disk.img /images/kvm/cirros1.qcow2
cp cirros-0.3.4-x86_64-disk.img /images/kvm/cirros2.qcow2
创建虚拟机
qemu-kvm -m 256 -smp 1 -name cirros1 \
-drive file=/images/cirros/cirros1.qcow2,if=virtio,cache=writeback,media=disk \
-net nic,macaddr=52:54:00:11:22:33 \
-net tap,ifname=virtintr1,script=/etc/qemu-ifup,downscript=no \
-nographic
qemu-kvm -m 256 -smp 1 -name cirros2 \
-drive file=/images/cirros/cirros2.qcow2,if=virtio,cache=writeback,media=disk \
-net nic,macaddr=52:54:00:11:44:33 \
-net tap,ifname=virtintr2,script=/etc/qemu-ifup,downscript=no \
-nographic
虚拟机的两个 tap(由-net tap生成) 会自动通过指定的脚本绑定至V switch
脚本创建在/etc/目录下,脚本为qemu-ifup
#!/bin/bash
#
bridge=br-in
if [ -n "$1" ]; then
ip link set $1 up
brctl addif $bridge $1
[ $? -eq 0 ] && exit 0|| exit 1
else
echo "Error: No Interface Specified."
exit 1
fi
接下来,创建一对虚拟veth
ip link add veth0 type veth peer name veth1
将veth0关联至br-in, veth1放入route1
brctl addif br-in veth0
ip link set veth1 netns route1
启动veth1和veth0
ifconfig veth0 up
ip netns exec route1 ifconfig veth1 up
给route1内的veth1添加ip地址,并将kvm虚拟机的网关指向veth1
ip netns exec route1 ifconfig veth1 192.168.2.254/24
将kvm的虚拟机ip地址设为与veth1同网段
cirros1
ifconfig eth0 192.168.2.1/24
route add default gw 192.168.100.254
cirros2
ifconfig eth0 192.168.2.2/24
route add default gw 192.168.100.254
这时kvm虚拟机可以ping通192.168.2.254,并且二者相互ping通
添加第二对虚拟veth,并将其关联至route1和br-ex
ip link add virt0 type veth peer name virt1
brctl addif br-ex virt1
ifconfig virt1 up
ip link set virt0 netns route1
ip netns exec route1 ifconfig virt0 up
将virt0的地址添加至与宿主机同网段
ip netns exec route1 ifconfig virt0 192.168.1.188/24 up
此时,kvm虚拟机可以ping通192.168.1.188,但是并不可以ping通192.168.1.104,因为回应报文无法到达kvm虚拟机内部,这是我们需要在route1上添加iptables的NAT规则,使其做原地址转换,这样kvm就可以ping通外部主机
ip netns exec route1 iptables -t nat -A POSTROUTING -s 192.168.2.0/24 ! -d 192.168.2.0/24 -j SNAT --to-source 192.168.1.188
我们还可以在route1内部部署一个dhcp服务器,让其为kvm自动添加地址
ip netns exec route1 dnsmasq -F 192.168.2.100,192.168.2.150 --dhcp-option=option:router,192.168.2.254
在我们的kvm内部使用udhcpc -R即可获取到ip地址.