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