定位 发表于 2019-12-7 21:45:34

linux虚拟化网络之OpenvSwitch,经典实战,全网最全,最完善

网络架构图:



环境(centos6.7):(图中从左至右,在下面依次列出主机)

[*]主机1:192.168.66.6(eth0)、172.31.225.247(eth1)
[*]主机2:192.168.66.7(eth0)、192.168.77.1(eth1)
[*]主机3:192.168.66.8(eth0)、192.168.77.2(eth1)
[*]主机4:192.168.66.9(eth0)、192.168.77.254(eth1)、172.31.225.244(eth2)


[*]虚拟交换机:通过openvswitch创建出来
[*]虚拟路由:通过网络namespace创建出来,主机2中的虚拟路由用来当作虚拟机的dhcp服务器,动态分配ip地址;主机4中的虚拟路由用来连接虚拟交换机和物理桥
[*]物理桥:通过brctl命令创建(也可以用openvswitch统一管理),但为了更好的区分openvswitch,就用brctl
[*](vm1、vm2、vm3、vm4):通过qemu-kvm底层工具创建
[*]系统镜像:简单且用来作测试的cirros


实现目的:

[*]主机2、主机3可以通过主机1上外网,本地安装相关的软件包,诸如:openvswitch等
[*]vm1和vm3可以互相通信,vm2和vm4可以互相通信;vm1和vm2不能通信,vm3和vm4不能通信
[*]主机2中的vm1、vm3可以通过主机4和外网互相通信


目的1实现操作:
1、让主机2和主机3中的eth0网卡的网关指向主机1的eth0地址




2、主机1打开转发功能,并添加一条源地址转换规则


在主机2和主机3上测试外网:





目的2实现操作:
主机2上的操作:
1、下载openvswitch源码,生成rpm包,安装openvswitch包,我这里的版本为2.3.1
注:不同版本的openvswitch要求内核也不一样,具体参照链接:https://bbs.cnblackhat.com/thread-2820-1-1.html
yum install gcc make python-devel openssl-devel kernel-devel graphviz kernel-debug-devel autoconf automake rpm-build redhat-rpm-config libtool
mkdir -p /root/rpmbuild/SOURCES
wget https://www.openvswitch.org/releases/openvswitch-2.3.1.tar.gz
tar xf openvswitch-2.3.1.tar.gz
cp openvswitch-2.3.1.tar.gz /root/rpmbuild/SOURCES/
cd openvswitch-2.3.1

由于安装openvswitch,其依赖kmod-openvswitch-2.3.1-1.el6.x86_64.rpm,但是在编译kmod-openvswitch时,总是报错,网络上也没找到对应的解决方法(这里就忽略掉此依赖包,执行下面的命令),网上提供的解决方法(到github下载对应的源码进行编译),参考链接:https://bbs.cnblackhat.com/thread-2821-1-1.html
sed 's/openvswitch-kmod, //g' rhel/openvswitch.spec > rhel/openvswitch_no_kmod.spec
rpmbuild -bb rhel/openvswitch_no_kmod.spec

编译完成后rpm包位于/root/rpmbuild/RPMS/x86_64/
rpm -ivh /root/rpmbuild/RPMS/x86_64/openvswitch-2.3.1-1.x86_64.rpm

启动openvswitch服务
service openvswitch start

创建一个桥接br-in
ovs-vsctl add-br br-in

创建名称空间r0,创建一对网卡,把名称空间r0和虚拟交换机连接起来,并提供dhcp服务;配置yum源,更新iproute,默认6没有netns
vim /etc/yum.repos.d/rdo-release.repo

name=OpenStack Kilo Repository
baseurl=https://repos.fedorapeople.org/repos/openstack/EOL/openstack-icehouse/epel-6/
skip_if_unavailable=0
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-RDO-kilo


yum install iproute
ip link add sif0 type veth peer name rif0
ip netns add r0
ip netns exec r0 dnsmasq -F 10.0.4.200,10.0.4.220,86400 -i rif0

激活sif0网卡,并添加至br-in桥上
ip link set sif0 up
ovs-vsctl add-port br-in sif0

把rif0添加至名称空间r0内,并激活rif0和本地回环接口lo,配置rif0地址
ip link set rif0 netns r0
ip netns exec r0 ip link set rif0 up
ip netns exec r0 ip link set lo up
ip netns exec r0 ip addr add 10.0.4.254/24 dev rif0

由于桥br-in设备是openvswitch创建的,并且不能被brctl管理,所以需要单独写if-up和if-down脚本
if-up内容如下:
#!/bin/bash
#
bridge="br-in"

if [ -n "$1" ]; then
        ip link set $1 up
        sleep 1
        ovs-vsctl add-port $bridge $1
        [ $? -eq 0 ] && exit 0 || exit 1
else
        echo "Error: no port specified."
        exit 2
fi


if-down内容如下:
#!/bin/bash
#
bridge=br-in

if [ -n "$1" ]; then
        ip link set $1 down
        sleep 1
        ovs-vsctl del-port $bridge $1
        [ $? -eq 0 ] && exit 0 }} exit 1
else
        echo "Error: no port specified."
        exit 2
fi


添加执行权限:
chmod +x /etc/if-up
chmod +x /etc/if-down

拷贝这两个脚本文件到主机2上
scp /etc/if-* root@192.168.66.8:/etc/

创建镜像保存目录
mkdir /vm/images/ -pv

下载cirros镜像至/vm/images下,这里大家可以直接下载我给的,优化过的,下载链接:




添加虚拟机vm1和vm2
qemu-kvm -name vm1 -m 128 -smp 1 --drive file=/vm/images/cirros-0.3.6-x86_64-disk.img,media=disk,if=virtio -net nic,model=virtio,macaddr=52:54:00:00:00:01 -net tap,ifname=vif0.0,script=/etc/if-up,downscript=/etc/if-down --daemonize

qemu-kvm -name vm2 -m 128 -smp 1 --drive file=/vm/images/cirros-0.3.6-x86_64-disk2.img,media=disk,if=virtio -net nic,model=virtio,macaddr=52:54:00:00:00:05 -net tap,ifname=vif1.0,script=/etc/if-up,downscript=/etc/if-down --daemonize


通过vncviewer登录进入系统,查看ip地址:
vm1:10.0.4.200
vm2:10.0.4.201


主机3上的操作:
从主机2上拷贝openvswitch软件包
scp 192.168.66.7:/root/rpmbuild/RPMS/x86_64/openvswitch-2.3.1-1.x86_64.rpm /root
rpm -ivm /root/openvswitch-2.3.1-1.x86_64.rpm

启动openvswitch服务
service openvswitch start

接着添加一个桥设备
ovs-vsctl add-br br-in


主机3上就不创建网络名称空间了,直接从主机2上的网络名称空间上获取ip地址,由于两边的虚拟机处于在不同的机器上,还不能通信,所以我们这里在eth1上通过gre隧道来实现其互相通信,首先在桥br-in上添加一个端口gre0
ovs-vsctl add-port br-in gre0

执行上面这条命令如果报错:ovs-vsctl: Error detected while setting up 'gre0'.  See ovs-vswitchd log for details.,就忽略它,实际上已经添加成功了

接着在激活gre0,并设置隧道相关配置
ip link set gre0 up
ovs-vsctl set interface gre0 type=gre options:remote_ip=192.168.77.1

主机2上也执行相同的操作,remote_ip设置为主机3上eth1的地址,即192.168.77.2
ovs-vsctl add-port br-in gre0
ip link set gre0 up
ovs-vsctl set interface gre0 type=gre options:remote_ip=192.168.77.2

此时我们就可以在主机3上创建虚拟机了
qemu-kvm -name vm3 -m 128 -smp 1 --drive file=/vm/images/cirros-0.3.6-x86_64-disk.img,media=disk,if=virtio -net nic,model=virtio,macaddr=52:54:00:00:a0:03 -net tap,ifname=vif0.0,script=/etc/if-up,downscript=/etc/if-down --daemonize

qemu-kvm -name vm4 -m 128 -smp 1 --drive file=/vm/images/cirros-0.3.6-x86_64-disk2.img,media=disk,if=virtio -net nic,model=virtio,macaddr=52:54:00:00:a0:02 -net tap,ifname=vif1.0,script=/etc/if-up,downscript=/etc/if-down --daemonize

通过vncviewer远程连接进入,查得虚拟机ip地址如下:
vm3:10.0.4.202
vm4:10.0.4.208


两台主机通信测试:
在vm1内部ping其它三台主机,经测试,他们都是可以互相通信的


但这里我们要求vm1不能和vm2通信,vm3不能和vm4通信,所以我们还需要设置vif0.0和vif1.0端口上tag标签,给他们家标签,vm1和vm3设置同一个标签,vm2和vm4设置成同一个标签(分别在两台机器上操作)
ovs-vsctl set port vif0.0 tag=10
ovs-vsctl set port vif1.0 tag=10

这样的话,10.0.4.200(vm1)和10.0.4.202(vm3)可以互相通信;10.0.4.201(vm2)和10.0.4.208(vm4)可以互相通信;其它主机之间也不能互相通信,即使在同一个局域网





目的3实现操作:
这里我们是让主机2和主机4通过隧道实现通信的,我们把主机2和主机3相关的隧道功能配置删除,重新配置,这里直接删除桥br-in上面的端口gre0,并移除tag所赋的值,分别在两台主机上(主机2和主机3)操作
ovs-vsctl del-port br-in gre0
ovs-vsctl remove port vif0.0 tag 10
ovs-vsctl remove port vif1.0 tag 20

这块我们就不通过gre隧道和vlan来实现了,我们用vxlan来实现,vxlan其也支持gre隧道,同时也比vlan支持的端口数量还要多
主机2上操作:ovs-vsctl add-port br-in vx0 -- set interface vx0 type=vxlan options:remote_ip=192.168.77.254
主机4上操作:ovs-vsctl add-port br-in vx0 -- set interface vx0 type=vxlan options:remote_ip=192.168.77.1

紧接着在主机4上创建虚拟机交换机,安装和启动服务这块我就省略了,上面都已经说过
ovs-vsctl add-br br-in

在创建虚拟路由,通过网络名称空间,这台主机是centos7,默认带netns功能,升级操作就省略了,如果你是6版本,按照上面的操作进行升级
ip netns add r0

创建一对网卡,用来连接虚拟交换机和虚拟路由
ip link add sin0 type veth peer name rin0

在桥br-in设备上添加端口sin0,在网络名称空间r0添加rin0
ovs-vsctl add-port br-in sin0
ip link set sin0 up
ip link set rin0 netns r0
ip netns exec r0 ip link set rin0 up
ip netns exec r0 ip addr add 10.0.4.100/24 dev rin0


主机4上网络名称空间和vm1内ping测试:(已经可以通信了)




添加物理桥设备br-ex,并把eth2关联到br-ex桥设备上,这里我是直接添加ifcfg-br-ex,并修改ifcfg-br-ex和ifcfg-eth2配置
ifcfg-br-ex配置如下:
TYPE="Ethernet"
BOOTPROTO="none"
IPADDR="172.31.225.244"
NETMASK="255.255.255.0"
GATEWAY=172.31.225.1
NAME="br-ex"
DEVICE="br-ex"
ONBOOT="yes"
TYPE=Bridge


ifcfg-eth2配置如下:
TYPE="Ethernet"
BOOTPROTO="none"
NAME="eth2"
DEVICE="eth2"
ONBOOT="yes"
BRIDGE=br-ex


重启网络服务
systemctl restart network

然后再添加一对网卡,用来连接虚拟路由器和物理桥设备br-ex,并激活这对网卡,配置rex0的ip地址
ip link add rex0 type veth peer name sex0
ip link set sex0 up
brctl addif br-ex sex0
ip link set rex0 netns r0
ip netns exec r0 ip link set rex0 up
ip netns exec r0 ip addr add 172.31.225.248/24 dev rex0

紧接着在网络名称空间r0内打开转达功能,并配置源地址转换


最后在vm1和vm2上添加默认网关10.0.4.100(rin0)




在vm1和vm2内部ping测试,如果ping不通,把之前的网关10.0.4.254给删掉,即route del default gw 10.0.4.254




到这里,虚拟机已经可以和外网通信了,但是别人访问不了虚拟机,所以还得在网络名称空间内部做个目标地址转换,并在其内部添加一块网卡专门用来给vm1用
ip netns exec r0 ifconfig rex0:0 172.31.225.249/24 up
ip netns exec r0 iptables -t nat -A POSTROUTING -s 10.0.4.200/32 -j SNAT --to-source 172.31.225.249
ip netns exec r0 iptables -t nat -A PREROUTING -d 172.31.225.249 -j DNAT --to-destination 10.0.4.200


在物理机器172.31.225.76上测试ping


在主机2上抓包验证



到这里就结束了,原创不易,转载请注明来源
页: [1]
查看完整版本: linux虚拟化网络之OpenvSwitch,经典实战,全网最全,最完善