使用vagrant搭建测试环境

使用 vagrant 管理虚拟机,能实现搭建可重复的开发或者测试环境。在需要验证某些集群软件,比如 Ceph,Kubernetes,MySQL Cluster 时,会比较有用。vagrant 是基于 Ruby 开发的,在 Windows 10 上运行会比较慢,但是似乎也没有什么替代品。如果能使用容器代替虚拟机,或许可以试试 Docker Compose。

安装

以 Windows 10 为例,下载并安装 vagrant 和 VirtualBox,另外建议安装 msys2。安装完成之后,在 msys2 中将 vagrant 和 VirtualBox 加入 PATH

export PATH=$PATH:/c/Program\ Files/Oracle/VirtualBox:/c/HashiCorp/Vagrant/bin

使用

box管理

box 是虚拟机镜像,vagrant 基于 box 创建并启动虚拟机。由于网络原因,一般需要手动下载需要的 box,然后导入,vagrant up 时能看到 box 直链。通过以下命令管理 box。

vagrant box list
vagrant box add package.box --name=mysql-mgr/8.0.20
vagrant box remove mysql-mgr/8.0.20
vagrant package   # 将当前虚拟机导出为 box

虚拟机管理

包括启停,重建等。

vagrant up
vagrant suspend
vagrant destroy -f
vagrant reload
vagrant ssh

由于 vagrant 在 Windows 10 上非常慢,vagrant ssh 可以用 Xshell 之类的工具代替。

Vagrantfile

一个示例 Vagrantfile。

Vagrant.require_version ">= 1.4.3"
VAGRANTFILE_API_VERSION = "2"

BOX='itop-mgr/2.7'

(1..3).each do |i|
  Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
    config.vm.define :"itop-mgr-#{i}" do |node|
      node.vm.box = BOX
      node.vm.network :private_network, ip: "192.168.10.#{i+100}"
      node.vm.hostname = "itop-mgr-#{i}"
      node.vm.synced_folder "files/", "/vagrant", create: true, type: "rsync"
      if Vagrant.has_plugin?("vagrant-vbguest")
        node.vbguest.auto_update = false
      end      
      
      node.vm.provider "virtualbox" do |v|
        v.customize ["modifyvm", :id, "--memory", "1536"]
        v.name = "itop-mgr-#{i}"
        v.gui = false
      end
	  
	  node.ssh.shell = "bash -c 'BASH_ENV=/etc/profile exec bash'"
	  node.vm.provision "shell", path: "post-deploy.sh" ,run: "always"
    end
  end
end

一般不需要启动图形界面,通过 v.gui = false 设置。

共享文件夹

使用 type: "rsync" 指定用 rsync 方式将文件同步到虚拟机中。

node.vm.synced_folder "files/", "/vagrant", create: true, type: "rsync"

指定 rsync 方式是因为 Windows 10 上共享目录方式可能会报以下错误,并且安装 vagrant-vbguest 插件后依然不能解决。

mount: unknown filesystem type 'vboxsf'

自定义操作

启动虚拟机后,一般需要执行一些脚本来安装软件或者修改设置。vagrant 支持 shell 或者 ansible,puppet 之类的工具。

node.vm.provision "shell", path: "post-deploy.sh" ,run: "always"

如果是每次都需要运行的 shell 脚本(run: "always"),需要注意非首次执行时检查一下是否需要再次执行命令。比如,只在首次启动时初始化 MySQL,可以这么写:

LOCK="/etc/mysql_init.lock"
# 只在第一次执行时初始化
if [ ! -f $LOCK ];then
	rm -fr /var/lib/mysql
	mysqld --initialize-insecure --user=mysql
	systemctl start mysqld
	# (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2),重启生成 sock 文件
	systemctl restart mysqld
	systemctl status mysqld
	cat > /tmp/init.sql <<EOF
ALTER USER 'root'@'localhost' IDENTIFIED BY '$MYSQL_ROOT' PASSWORD EXPIRE NEVER;
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '$MYSQL_ROOT';
create user root@'%' identified WITH mysql_native_password BY '$MYSQL_ROOT';
grant all privileges on *.* to root@'%' with grant option;
flush privileges;
EOF
	mysql -uroot < /tmp/init.sql
	touch $LOCK
fi

SATA驱动器

centos/7 box 默认是 IDE 驱动器,如果想添加 SATA 驱动器,可以参考如下代码。

(1..3).each do |k|
  node_disk = "./itop-mgr-#{i}/node_disk#{k}.vdi"
  unless File.exists?(node_disk)
	v.customize ['createhd', '--filename', node_disk, '--size', 1 * 5120]
  end
  v.customize ["storagectl", :id, "--name", "SATA", "--add", "sata"]
  v.customize ['storageattach', :id,  '--storagectl', 'SATA', '--port', "#{k}", '--device', 0, '--type', 'hdd', '--medium', node_disk]
end

不安装 VirtualBox Guest Additions

速度太慢。

# 不使用共享文件夹
node.vm.synced_folder ".", "/vagrant", disabled: true
if Vagrant.has_plugin?("vagrant-vbguest")
  node.vbguest.auto_update = false
end

管理硬盘

直接删除硬盘文件,如果报错:VERR_ALREADY_EXISTS,需通过 VBOXmanage 删除。

VBoxManage.exe list hdds
VBoxManage.exe closemedium disk /e/dev/ceph-learn/node-2/node_disk1.vdi --delete

参考资料

1. https://www.vagrantup.com/docs
2. https://stackoverflow.com/questions/21574260/change-default-disk-controller-in-vagrant

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注