在大型的系统开发时,通常需要准备多套环境用于开发和测试的目的,如:开发环境,UAT测试环境,集成测试环境和模拟环境等。这样通常会需要大量的机器节点,尤其是进行大数据类的系统开发的时候,通常一个大数据集群都要几台到几十台机器,这个时候的机器数量的需求将更是惊人。如果这些节点机器都通过物理机的方式实现,那成本就更是让人无法接受了。面对这种情况,选用虚拟化环境的方案,是一个非常好的选择。因为测试和开发环境通常对节点机器的配置要求不高,运行时甚至可以不必同时运行,可以根据工作安排灵活调度。但是确对环境之间的隔离性,以及与生产环境的一致性上要求很高。这种时候通过虚拟化资源池的方式将能应对这种困局。
本人目前正在实施的一个项目就是这种情况。当前项目需要部署CDH集群,为了尽可能和生产环境保持一致,以及保证各套环境之间的隔离,就需要搭建五套测试和开发环境,同时要求每套环境的节点数不能少于10台,整个下来就是4,5十台机器。这样庞大的主机资源公司没法提供,那就只能自己想办法解决。目前项目有六台性能比较好的测试物理机器,于是就想到用这六台机器搭建一套虚拟化开发测试资源池,并在该资源池的基础上,配置多套的开发测试环境。
考察了多种虚拟化的实现方案,鉴于只是用于开发和测试用途,对性能和稳定性要求并不高。所以考虑开源的技术方案,最终选择采用vagrant+virtualBox的方案实现虚拟机管理,在虚拟网络方面选择简单的tap+vxlan虚拟网络方案。
vagrant:2.2.3
virtualBox:5.2.5
虚拟机/宿主机操作系统:centos 7.2
在WMM方面有许多商业和开源的方案,最终选择Vagrant+VirtualBox的方案,主要出于以下考虑:
基于上述考虑,在开发和测试用途上,Vagrant+VirtualBox的方案已经完全足够满足需要了。
虚拟集群规划为:每套环境配置12个节点的虚拟机集群,每台宿主机上均匀分配两台虚拟的客户机,每台客户机简单地挂载1T的虚拟硬盘,没有使用复杂的存储卷管理,12个节点的集群通过虚拟网络连接,虚拟网络可跨物理机组网。
宿主机(6)
host1~6: 10.58.9.106-10.58.9.111
客户机(12)
guest1-12:10.20.0.11-10.20.0.22
vagrant镜像的话,一般使用vagrant的官方的centos镜像就行,如有特殊的版本需求,或者需要提前统一配置软件包或者系统环境的,可以自行制作vagrant的vbox镜像。在这个项目中为了要和系统生产环境保证一致,所以使用公司生产环境的centos镜像iso自己制作了vagrant的镜像,vagrant镜像的制作过程还是比较多坑的,这篇文章主要讲虚拟环境的搭建,就不详细说明vagrant的制作过程,后续再把这块的趟坑过程拿出来和大家分享。
现在开始在每台宿主机上分别执行创建和配置虚拟机:
介质:
yum localinstall -y ./VirtualBox-5.2-5.2.22_126460_el7-1.x86_64.rpm
yum localinstall -y ./vagrant_2.2.3_x86_64.rpm
由于虚拟机需要安装完整的操作系统,所以需要的磁盘空间一般比较大,所以需要选择一个较大的文件系统目录作为Vbox虚拟机的存放目录,所以在宿主机上选一个可用空间较大的文件系统作为vbox的虚拟机目录。
vboxmanage setproperty machinefolder /opt/vagrant-vms
往vagrant仓库导入已经做好的centos7.2的vagrant镜像源
vagrant box remove centos7.2-base-1.0.0
vagrant box add centos7.2-base-1.0.0 ./centos7.2-base-1.0.1.box
vagrant box list ##查看vagrant的镜像仓库,如add成功,则仓库中会有一个“centos7.2-base-1.0.0 ”的镜像
新建两个vagrant虚拟机目录(vagrant是通过目录和Vagrantfile区分和管理虚拟机的)。
mkdir /vagrant/vm-test0-0
mkdir /vagrant/vm-test0-0/data
mkdir /vagrant/vm-test0-1
mkdir /vagrant/vm-test0-1/data
分别拷贝宿主机的ssh登录私钥到vagrant虚拟机目录下,并命名为private_key(如果未配置正确的private_key,则只能通过密码的方式登录虚拟的客户机)。
分别将vm-test0-0和vm-test0-1的配置文件cp到对应虚拟机目录下,并命名为Vagrantfile。
vm-test0-0:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "centos7.2-base-1.0.0"##配置镜像源
config.vm.network "forwarded_port", guest: 1521, host: 1521 ##客户机到宿主机的端口映射
config.vm.network "forwarded_port", guest: 13075, host: 13075 ##客户机到宿主机的端口映射
config.vm.network "forwarded_port", guest: 22858, host: 22858 ##客户机到宿主机的端口映射
config.vm.network "public_network", bridge: "vbox-test0-tap0", ip: "10.20.0.13" ##配置虚拟机网络和ip地址,网络类型为:"public_network",网卡选择:"vbox-test0-tap1" ,ip地址:"10.20.0.13",至于tap网卡怎么建,后续网络部分会详细说明。
config.vm.synced_folder "./data", "/vagrant_data" ##设置宿主机和客户机的文件同步目录
config.ssh.private_key_path = "./private_key" ## 配置ssh私钥
config.vm.provider "virtualbox" do |vb|
vb.memory = "32768" ##设置虚拟机内存
vb.name = "vm-test0-0" ##设置虚拟机名,virtualbox你上的虚拟机名字,与客户机的hostname无关
vb.cpus = 8 ##设置使用的cpu核数
end
##以下为客户机的启动后的配置工作
config.vm.provision "shell",
run: "always",
inline: "ip li set enp0s8 mtu 1450" ##设置接入虚拟网络的接口的MTU为1450,与虚拟网络部分的tap的mtu设置一致
end
vm-test0-1:Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "centos7.2-base-1.0.0" ##配置镜像源
config.vm.network "forwarded_port", guest: 7001, host: 7001 ##客户机到宿主机的端口映射
config.vm.network "forwarded_port", guest: 7011, host: 7011 ##客户机到宿主机的端口映射
config.vm.network "public_network", bridge: "vbox-test0-tap1", ip: "10.20.0.14" ##配置虚拟机网络和ip地址,网络类型为:"public_network",网卡选择:"vbox-test0-tap1" ,ip地址:"10.20.0.14",至于tap网卡怎么建,后续网络部分会详细说明。
config.vm.synced_folder "./data", "/vagrant_data" ##设置宿主机和客户机的文件同步目录
config.ssh.private_key_path = "./private_key" ## 配置ssh私钥
config.vm.provider "virtualbox" do |vb|
vb.memory = "32768" ##设置虚拟机内存
vb.name = "vm-test0-1" ##设置虚拟机名,virtualbox你上的虚拟机名字,与客户机的hostname无关
vb.cpus = 8 ##设置使用的cpu核数
end
##以下为客户机的启动后的配置工作
config.vm.provision "shell",
run: "always",
inline: "ip li set enp0s8 mtu 1450" ##设置接入虚拟网络的接口的MTU为1450,与虚拟网络部分的tap的mtu设置一致
end
初始化虚拟主机
cd /vagrant/vm-test0-0
vagrant halt ##原有虚拟机关机,如之前未初始化过虚拟机无需该步
vagrant destroy ##删除原有虚拟机,如之前未初始化过虚拟机无需该步
rm -rf ./.vagrant ##删除虚拟机目录,如之前未初始化过虚拟机无需该步
vagrant up ##创建并初始化虚拟机
cd /vagrant/vm-test0-1
vagrant halt ##原有虚拟机关机,如之前未初始化过虚拟机无需该步
vagrant destroy ##删除原有虚拟机,如之前未初始化过虚拟机无需该步
rm -rf ./.vagrant ##删除虚拟机目录,如之前未初始化过虚拟机无需该步
vagrant up ##创建并初始化虚拟机
由于为了限制vagrant镜像的大小,所以一般vagrant建立的虚拟机默认挂载的磁盘都比较小。对于磁盘空间需求较大的环境,一般会额外挂载外部存储。由于是测试开发环境所以没有使用专门的虚拟化存储方案,而是采用最简单的虚拟磁盘的方式扩展虚拟机的存储容量。
虚拟磁盘IO速度提升
在虚拟机上挂载虚拟磁盘,如果使用同步方式读写磁盘,IO速度会很低。所以在开发和测试环境建议使用异步读写方式挂载磁盘,从而大幅度提升系统IO读写速度。
vagrant halt ##关闭虚拟机
vboxmanage createvdi -filename vm-test0-0-01.vdi -szie 1048576 ##创建虚拟磁盘文件
vboxmanage storageattach vm-test0-0 --storagectl "SATA" --port 1 --device 0 --type hdd --medium ../vm-test0-0-01.vdi ##挂载虚拟磁盘文件到客户机
vboxmanage storagectl vm-test0-0 --name 'SATA' --hostiocache on ##开启客户机和宿主机的SATA通道的iocache模式,否则同步写入物理磁盘,IO速度会很慢。
vagrant up ##启动虚拟机
cd /vagrant/vm-test0-1
vagrant halt ##关闭虚拟机
vboxmanage createvdi -filename vm-test0-1-01.vdi -szie 1048576 ##创建虚拟磁盘文件
vboxmanage storageattach vm-test0-1 --storagectl "SATA" --port 1 --device 0 --type hdd --medium ../vm-test0-1-01.vdi ##挂载虚拟磁盘文件到客户机
vboxmanage storagectl vm-test0-1 --name 'SATA' --hostiocache on ##开启客户机和宿主机的SATA通道的iocache模式
vagrant up ##启动虚拟机
vboxmanage showvminfo vm-test0-0
vboxmanage showvminfo vm-test0-1
如新建虚拟机成功则返回相关虚拟机的信息。
可以使用virtualBox的vboxmange snapshot
对虚拟进行快照备份
vboxmange snapshot vm-test0-0 take vm-test0-0-snapshot
在这个方案中使用vxlan作为虚拟网络的解决方案,之所以选择vxlan出于一下几个方案的考虑:
通过xvlan的方式在现有的物理网络上虚拟出供不同测试和开发环境使用的虚拟网络,每个虚拟网络支持夸物理主机实现虚拟机的组网,从而能够将虚拟机的负载均衡到不同的物理机上,保证虚拟环境的可扩展性。虚拟网络之间相互隔离,不能相互访问。
主要使用到三个虚拟网络的概念。
网桥(br):
网桥的作用主要可以理解为在linux的内存中虚拟一个二层的switch,它的作用是将宿主机的网络协议栈,客户机的tap接口和vxlan接口连在一个switch上实现网络交换。
tap:
使用种linux 上的虚拟网络接口,通过该接口可以完成内核空间的网络包与用户空间的程序之间的直接传输
vxlan:
使用vxlan可以通俗的可以理解为在现有网络环境的情况下,通过使用现有网络硬件,虚拟出相互隔离新的网络。如:可以在原有192.168.0.0的物理环境上虚拟出10.20.0.0,10.20.0.1等相互隔离的网络。类似于vlan,但与vlan不同的是vxlan是在udp包的基础上封装以太包,而vlan则直接就是以太包。所以在灵活性和扩展性上,vxlan要比vlan好很多,而且能够通过纯软件的方式实现,从而完全消除了硬件层面的改造。
整体的虚拟网络规划图如下:
ip li add br-test0 type bridge
linux下有tap和veth两种虚拟设备实现虚拟网络接口,一般veth主要针对夸网络命名空间,在容器场景使用。而tap则用于虚拟机的场景。经过实际验证,在虚拟机场景上使用vetch无效,具体原有没有去详细研究过,感觉是linux内核网络协议栈的问题,虚拟机方案需要完整的linux网络协议栈,而命名空间似乎是有一部分是共享使用的。
vxlan的MTU设置
由于vxlan协议不支持vxlan包的自动的拆包和组包,所以使用的vxlan的虚拟网络的mtu需要比实际物理物理网络的mtu小一点,留一点空间给协议封装。不然会出现数据包长度截断问题,导致一些用到大数据包的应用无法使用。本人在实际配置的时候就出现vxlan的mtu太小,导致ssh的秘钥交换阶段异常错误的情况。
VBoxTunctl -b -t vbox-test0-tap0 -u root
VBoxTunctl -b -t vbox-test0-tap1 -u root
ip li set vbox-test0-tap0 mtu 1450 ##由于物理网络的mtu是1500,所以这里设置vxlan的虚拟网络的mtu是1450
ip li set vbox-test0-tap1 mtu 1450 ##由于物理网络的mtu是1500,所以这里设置vxlan的虚拟网络的mtu是1450
ip li set vbox-test0-tap0 master br-test0 ##将tap接口连接上网桥
ip li set vbox-test0-tap1 master br-test0 ##将tap接口连接上网桥
ip li set vbox-test0-tap0 up ##启动tap接口
ip li set vbox-test0-tap1 up ##启动tap接口
ip li add vxlan-test0 type vxlan \
id 113 \ ##vlan id
dstport 4789 \ ##xvlan服务的端口
group 239.1.1.113 \ ##group id 广播组id
dev enp129s0f1 ## enp129s0f1为物理网络接口
ip li set vxlan-test0 master br-test0 ##将vxlan接口连接上网桥
ip li set vxlan-test0 up ##启动vxlan接口
ip addr add 10.20.0.2/24 brd 10.20.0.255 dev br-test0 ##设置网桥ip地址,使得宿主机可以通过虚拟网络地址访问宿主机
ip link set br-test0 up ##启动网桥
brctl show ##显示网桥信息
ip addr ##显示ip和网络接口信息
#!/bin/bash
#yum localinstall -y ./VirtualBox-5.2-5.2.22_126460_el7-1.x86_64.rpm
#yum localinstall -y ./vagrant_2.2.3_x86_64.rpm
mkdir /opt/vagrant-vms
vboxmanage setproperty machinefolder /opt/vagrant-vms
vagrant box remove edip-centos7.2-base-1.0.0
vagrant box add edip-centos7.2-base-1.0.0 ./edip-centos7.2-base-1.0.1.box
vagrant box list
cd ./vm-test0-0
vagrant halt
vagrant destroy
#vboxmanage unregistervm vm-test0-0 --delete
rm -rf ./.vagrant
vagrant up
vagrant halt
vboxmanage storageattach vm-test0-0 --storagectl "SATA" --port 1 --device 0 --type hdd --medium ../vm-test0-0-01.vdi
vboxmanage storagectl vm-test0-0 --name 'SATA' --hostiocache on
vagrant up
cd ../vm-test0-1
vagrant halt
vagrant destroy
#vboxmanage unregistervm vm-test0-1 --delete
rm -rf ./.vagrant
vagrant up
vagrant halt
vboxmanage storageattach vm-test0-1 --storagectl "SATA" --port 1 --device 0 --type hdd --medium ../vm-test0-1-01.vdi
vboxmanage storagectl vm-test0-1 --name 'SATA' --hostiocache on
vagrant up
cd ..
#vboxmanage storageattach vm-test0-0 --storagectl "SATA Controller" --port 1 --device 0 --type hdd --medium vm-test0-0-01.vdi
#vboxmanage storageattach vm-test0-1 --storagectl "SATA Controller" --port 1 --device 0 --type hdd --medium vm-test0-1-01.vdi
vboxmanage showvminfo vm-test0-0
vboxmanage showvminfo vm-test0-1
#!/bin/bash
yum install -y bridge-utils
yum localinstall -y ./VirtualBox-5.2-5.2.22_126460_el7-1.x86_64.rpm
yum localinstall -y ./vagrant_2.2.3_x86_64.rpm
ip li add br-test0 type bridge
VBoxTunctl -b -t vbox-test0-tap0 -u root
VBoxTunctl -b -t vbox-test0-tap1 -u root
#ip li set vbox-test0-tap0 up
#ip li set vbox-test0-tap1 up
ip li set vbox-test0-tap0 mtu 1450
ip li set vbox-test0-tap1 mtu 1450
ip li set vbox-test0-tap0 master br-test0
ip li set vbox-test0-tap1 master br-test0
ip li set vbox-test0-tap0 up
ip li set vbox-test0-tap1 up
#ip link set br-test0 up
ip li add vxlan-test0 type vxlan \
id 113 \
dstport 4789 \
group 239.1.1.113 \
dev enp129s0f1
ip li set vxlan-test0 master br-test0
ip li set vxlan-test0 up
ip addr add 10.20.0.2/24 brd 10.20.0.255 dev br-test0
ip link set br-test0 up
brctl show
ip addr
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。