使用 vagrant 管理虚拟机,能实现搭建可重复的开发或者测试环境。在需要验证某些集群软件,比如 Ceph,Kubernetes,MySQL Cluster 时,会比较有用。vagrant 是基于 Ruby 开发的,在 Windows 10 上运行会比较慢,但是似乎也没有什么替代品。如果能使用容器代替虚拟机,或许可以试试 Docker Compose。
Contents
安装
以 Windows 10 为例,下载并安装 vagrant 和 VirtualBox,另外建议安装 msys2。安装完成之后,在 msys2 中将 vagrant 和 VirtualBox 加入 PATH
。
1 |
export PATH=$PATH:/c/Program\ Files/Oracle/VirtualBox:/c/HashiCorp/Vagrant/bin |
使用
box管理
box 是虚拟机镜像,vagrant 基于 box 创建并启动虚拟机。由于网络原因,一般需要手动下载需要的 box,然后导入,vagrant up
时能看到 box 直链。通过以下命令管理 box。
1 2 3 4 |
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 |
虚拟机管理
包括启停,重建等。
1 2 3 4 5 |
vagrant up vagrant suspend vagrant destroy -f vagrant reload vagrant ssh |
由于 vagrant 在 Windows 10 上非常慢,vagrant ssh
可以用 Xshell 之类的工具代替。
Vagrantfile
一个示例 Vagrantfile。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
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 方式将文件同步到虚拟机中。
1 |
node.vm.synced_folder "files/", "/vagrant", create: true, type: "rsync" |
指定 rsync 方式是因为 Windows 10 上共享目录方式可能会报以下错误,并且安装 vagrant-vbguest
插件后依然不能解决。
mount: unknown filesystem type 'vboxsf'
自定义操作
启动虚拟机后,一般需要执行一些脚本来安装软件或者修改设置。vagrant 支持 shell 或者 ansible,puppet 之类的工具。
1 |
node.vm.provision "shell", path: "post-deploy.sh" ,run: "always" |
如果是每次都需要运行的 shell 脚本(run: "always"
),需要注意非首次执行时检查一下是否需要再次执行命令。比如,只在首次启动时初始化 MySQL,可以这么写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
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 2 3 4 5 6 7 8 |
(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
速度太慢。
1 2 3 4 5 |
# 不使用共享文件夹 node.vm.synced_folder ".", "/vagrant", disabled: true if Vagrant.has_plugin?("vagrant-vbguest") node.vbguest.auto_update = false end |
管理硬盘
直接删除硬盘文件,如果报错:VERR_ALREADY_EXISTS
,需通过 VBOXmanage 删除。
1 2 |
VBoxManage.exe list hdds VBoxManage.exe closemedium disk /e/dev/ceph-learn/node-2/node_disk1.vdi --delete |
参考资料
1 2 |
1. https://www.vagrantup.com/docs 2. https://stackoverflow.com/questions/21574260/change-default-disk-controller-in-vagrant |
发表回复