最近打算研究下分布式和微服务,说到分布式,要研究的话,肯定要先解决虚拟机问题。而Vagrant让我们可以通过代码的方式快速地、可重复地创建针对不同虚拟环境的虚拟机,包括Virtualbox、AWS、Docker等。它使得我们可以一次性地、自动创建多个环境相同的虚拟机,对于软件开发和测试尤其有用。本文我们将以Virtualbox为例,看看Vagrant的基本使用,主要包括建立和删除虚拟机,配置虚拟机运行参数,管理虚拟机运行状态。
Vagrant的下载与安装
下载官网:https://www.vagrantup.com/downloads.html
我这里使用的是Windows系统,根据自己的环境下载好之后,自行安装Vagrant。
Virtualbox的下载与安装
下载官网:https://www.virtualbox.org/wiki/Downloads
快速入门
首先找到一个合适的目录,创建一个用于存放Vagrantfile文件以及Vagrant在工作中的数据:
mkdir vagrant-project
cd vagrant-project
然后初始化Vagrant工程
vagrant init centos/7
该命令会在当前目录下创建Vagrantfile,并且指定所使用的box为centos/7,该box由官网https://app.vagrantup.com/boxes/search提供。此时,Vagrant根据centos来下载对应的版本的box。box中的镜像文件被放到了:~/.vagrant.d/boxes/,如果在windows或mac系统中应该是放到了: C:\Users\当前用户名.vagrant.d\boxes\目录下。
对于非官网提供的box,可以通过以下命令来初始化,其中my-box为该box以后要使用的名字,后面的URL为该box的下载地址。
vagrant init my-box https://boxes.company.com/my.box
如果是本地已经有box了的,可以通过以下命令来创建,其中boxname为该box以后要使用的名字,后面的url为是本地box路径。
vagrant box add [boxname] [url]
接下来就可以通过vagrant up命令启动虚拟机了。
vagrant up
这里说明一下,如果是在线下载box的话,所以这里要想把虚拟up起来的话,可能会很慢,建议通过其它路径,例如迅雷等,先下载好box然后再通过vagrant box add命令添加。
此时Vagrant会先从Hashicorp下载ubuntu/trusty64这个box(如果先前下载过了则跳过),然后启动虚拟机。在默认情况下,Virtualbox将作为provider,当然你也可以使用其他provider,比如以下命令将启动一个hyperv虚拟机:
vagrant up --provider hyperv
启动虚拟机后,通过vagrant提供的ssh命令就可以登录虚拟机,在这里vagrant将使用默认的用户vagrant以及预设的SSH公钥密钥键值对直接登录虚拟机,ssh的秘钥存放的地址一般是项目所在的目录的.vagrant/machines/default/virtualbox目录下,例如我这里应该就是vagrant-project/.vagrant/machines/default/virtualbox,通过这里的秘钥,可以使用xshell直接登录到虚拟机中,有的人不想用秘钥,想通过密令登录的话,可以参考我的另一篇文章https://blog.csdn.net/gleaming_shen/article/details/80860493
vagrant up
关闭虚拟机:
vagrant halt
删除虚拟机,请注意,vagrant destroy只会删除虚拟机本身,相当于从Virtualbox删除虚拟机,不会删除该虚拟机所使用的box。
列出本地所有的box:
vagrant box list
删除某个box:
vagrant box remove boxname
挂起虚拟机:
vagrant suspend
重启虚拟机:
vagrant reload
查看虚拟机状态:
vagrant status
Vagrant.configure("2") do |config|
config.vm.network "forwarded_port", guest: 8080, host: 8888
end
以上代码将Host机的8888端口转发到了虚拟机的8080端口,这样你便可以通过在Host机上访问http://localhost:8888来访问虚拟机的服务了。对于Virtualbox来说,只有NAT类型的网络类型支持端口转发,这也是为什么Vagrant创建的Virtualbox虚拟机默认都有一个支持NAT的虚拟网卡,原因就是要能够支持Vagrant级别的端口转发。另外,Vagrant在第一次尝试连接虚拟机时使用的也是NAT。在up虚拟机的时候,默认会帮将Host的2222端口转发到虚拟机的22端口,作为ssh登录的端口。
直接在Vagrantfile中编写Shell脚本,可以通过“inline”指定脚本内容:
Vagrant.configure("2") do |config|
# ... other configuration
config.vm.provision "shell", inline: "echo hello"
end
多行shell脚本的话可以通过两种办法指定脚本内容,第一种是通过“inline”指定脚本内容:
Vagrant.configure("2") do |config|
# ... other configuration
config.vm.provision "shell", inline: <<-SHELL
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-selinux docker-engine-selinux docker-engine
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce
sudo systemctl start docker
SHELL
end
第二种是通过引用外部脚本文件的方式:
Vagrant.configure("2") do |config|
config.vm.provision "shell", path: "script.sh"
end
当我们多次执行“vagrant up”启动虚拟机时,provison并不会每次都执行,只有在这三种情况下provision才会运行:
当然,你也可以在Vagrantfile中配置成每次执行vagrant up时都运行provision:
Vagrant.configure("2") do |config|
config.vm.provision "shell", inline: "echo hello",
run: "always"
end
使用private network时,我们可以给虚拟机指定固定的私有IP:
Vagrant.configure("2") do |config|
config.vm.network "private_network", ip: "192.168.50.4"
end
当然也可以使用DHCP的方式动态分配IP:
Vagrant.configure("2") do |config|
config.vm.network "private_network", type: "dhcp"
end
对于Virtualbox而言,此时虚拟机其实有两张网卡在工作,一种是Vagrant默认创建的NAT网卡,另一种是Host only类型的网卡提供private network。
在使用public network时,虚拟机和Host在网络中具有同等的地位(共同使用Host机的物理网卡与外界通信),就相当于在Host所在网络中又多了一台计算机一样,此时虚拟机可以使用网络中的DHCP服务器获得与Host处于同一个网段的IP地址,以下配置默认采用DHCP方式配置public network:
Vagrant.configure("2") do |config|
config.vm.network "public_network"
end
如果Host机器有多张网卡,此时运行vagrant up, Vagrant会询问需要使用那张网卡连接到网络,如果不想要这种交互,则可以在Vagrantfile中进行配置:
config.vm.network "public_network", bridge: [
"en1: Wi-Fi (AirPort)",
]
这里的 Wi-Fi(AirPort)表示使用了Mac笔记本的Airport连接到Wi-Fi。
除了DHCP,也可以使用静态IP:
Vagrant.configure("2") do |config|
config.vm.network "public_network", ip: "192.168.0.5"
end
config.vm.provider "virtualbox" do |v|
v.name = "my_vm"
end
Provider的特定配置也可以覆盖Vagrant原来的配置:
Vagrant.configure("2") do |config|
config.vm.box = "centos"
config.vm.provider "vmware_fusion" do |v, override|
# 配置虚拟机名字
override.vm.box = "centos_dev"
# 配置虚拟机内存和cpu个数
vb.memory = "1024"
vb.cpus = 2
end
end