Vagrant是什么
Vagrant 是一个快速建立开发环境的工具。通过一个文件来定义虚拟机的CPU数量、内存大小、主机名、网络等,可以批量生成多个虚拟机,快速构建环境。
安装
以macOS环境为例:
$ brew install vagrant
$ vagrant version
Installed Version: 2.3.4
Latest Version: 2.3.4
You're running an up-to-date version of Vagrant!
初始化环境
Vagrant通过vagrant init
命令初始化Vagrant,声明默认的Vagrantfile,此步骤非必须。
$ make vagrant_demo
$ cd vagrant_demo
$ vagrant init centos/7
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.
$ ls -al
total 8
drwxr-xr-x 3 lili staff 96 Apr 13 10:14 .
drwxr-xr-x+ 105 lili staff 3360 Apr 13 10:14 ..
-rw-r--r-- 1 lili staff 3014 Apr 13 10:14 Vagrantfile
$ # -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
# The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at
# https://docs.vagrantup.com.
# Every Vagrant development environment requires a box. You can search for
# boxes at https://vagrantcloud.com/search.
config.vm.box = "centos/7"
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# NOTE: This will enable public access to the opened port
# config.vm.network "forwarded_port", guest: 80, host: 8080
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine and only allow access
# via 127.0.0.1 to disable public access
# config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
# Create a private network, which allows host-only access to the machine
# using a specific IP.
# config.vm.network "private_network", ip: "192.168.33.10"
# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
# config.vm.network "public_network"
# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
# config.vm.synced_folder "../data", "/vagrant_data"
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
#
# config.vm.provider "virtualbox" do |vb|
# # Display the VirtualBox GUI when booting the machine
# vb.gui = true
#
# # Customize the amount of memory on the VM:
# vb.memory = "1024"
# end
#
# View the documentation for the provider you are using for more
# information on available options.
# Enable provisioning with a shell script. Additional provisioners such as
# Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
# documentation for more information about their specific syntax and use.
# config.vm.provision "shell", inline: <<-SHELL
# apt-get update
# apt-get install -y apache2
# SHELL
end
Vagrantfile定义
Vagrant.configure(2) do |config|
config.vm.box = "centos/7"
config.vm.box_url = "https://mirrors.ustc.edu.cn/centos-cloud/centos/7/vagrant/x86_64/images/CentOS-7.box"
config.vm.box_check_update = false
config.vm.hostname = "vagrant-demo"
config.vm.provider "virtualbox" do |vbox|
vbox.name = "vagrantdemo"
vbox.cpus = 2
vbox.memory = 2048
end
config.vm.network :public_network, ip: "192.168.1.2", gateway: "192.168.1.1", netmask: "255.255.255.0"
end
-
第一行Vagrant.configure(2)中的2代表配置文件的版本
-
config.vm.box和config.vm.box_url是对虚拟机镜像的定义,参考下文
-
config.vm.box_check_update:不检查box的更新
-
config.vm.hostname:定义虚拟机系统的名称
-
config.vm.provider:定义provide
-
vbox.name:定义虚拟机在virtualbox显示的名称
-
vbox.cpus:定义虚拟机使用的CPU数量
-
vbox.memory:定义虚拟机使用的内存大小
-
config.vm.network:为虚拟机定义公网网络配置,可只写IP,若不配置gateway,默认网卡的网关将是eth0的网关,默认网卡是NAT网络模型
在配置虚拟机的virtualbox信息时,也可以使用如下格式:
vbox.customize ["modifyvm", :id, "--memory", "2048"]
vbox.customize ["modifyvm", :id, "--cpus", 2]
vbox.customize ["modifyvm", :id, "--name", "vagrantdemo"]
常用使用
1、启动虚拟机
$ vagrant up
2、查看虚拟机状态
# 查看当前项目的虚拟机状态
$ vagrant status
# 查看所有虚拟机状态,包括非当前项目下,此命令可在任意位置执行
$ vagrant global-status
3、关闭虚拟机
$ vagrant halt
4、重启虚拟机
$ vagrant reload
5、启动关闭的虚拟机
$ vagrant resume
6、虚拟机快照
# 创建快照
$ vagrant snapshot save snap1
# 列出创建的快照
$ vagrant snapshot list
# 恢复快照
$ vagrant snapshot restore snap1
# 删除快照
$ vagrant snapshot delete snap1
7、暂停虚拟机
$ vagrant supsend
8、登录虚拟机
$ vagrant ssh default
9、虚拟机与主机互传文件
默认情况下,虚拟机的/vagrant
目录与Vagrantfile文件所在目录共享,如果通过scp协议复制非共享目录的文件,可通过插件vagrant-scp
实现,插件安装方式见下节。
10、插件
默认情况下,插件从官网下载
$ vagrant plugin install vagrant-scp
从国内镜像站安装
$ vagrant plugin install --plugin-clean-sources --plugin-source https://mirrors.aliyun.com/rubygems/ vagrant-scp
为了后续方便,可将从国内镜像站安装的命令进行别名
$ echo 'vagrant-plugin-install="vagrant plugin install --plugin-clean-sources --plugin-source https://mirrors.aliyun.com/rubygems/"' > ~/.zshrc
$ source ~/.zshrc
$ vagrant-plugin-install vagrant-scp
查看安装的插件
$ vagrant plugin list
vagrant-scp (0.5.9, global)
vagrant-share (2.0.0, global)
删除插件
$ vagrant plugin delete vagrant-scp
box
box是构建虚拟机环境时使用的镜像,类似ISO,如果box在本地不存在的话,则默认从HashiCorp官方下载,为了加速,可从国内镜像站下载。
从官方下载镜像:
$ vagrant box add centos/7
从国内镜像站下载:
$ vagrant box add --name centos/7 https://mirrors.ustc.edu.cn/centos-cloud/centos/7/vagrant/x86_64/images/CentOS-7.box
如果本地已经存在同名的box,可添加--force
参数进行覆盖
在Vagrantfile中定义国内镜像地址:
config.vm.box = "centos/7"
config.vm.box_url = "https://mirrors.ustc.edu.cn/centos-cloud/centos/7/vagrant/x86_64/images/CentOS-7.box"
其中config.vm.box
定义镜像的名称,config.vm.box_url
定义镜像的下载地址。如果包含版本信息,可通过config.vm.box_version
进行配置,例如:config.vm.box_version = "1.0.282"
查看本地镜像:
$ vagrant box list
centos/7 (virtualbox, 0)
删除本地镜像:
$ vagrant box remove centos/7
Are you sure you want to remove this box? [y/N] y
Removing box 'centos/7' (v0) with provider 'virtualbox'...
定义多台虚拟机
逐一定义
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "centos/7"
config.vm.define "node1" do |node1|
node1.vm.hostname = "node1"
node1.vm.provider "virtualbox" do |vbox|
vbox.name = "node1"
vbox.cpus = 2
vbox.memory = 2048
end
config.vm.define "node2" do |node2|
node2.vm.hostname = "node2"
node2.vm.provider "virtualbox" do |vbox|
vbox.name = "node2"
vbox.cpus = 2
vbox.memory = 2048
end
end
使用循环
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
(1..3).each do |i|
config.vm.define "node-#{i}" do |node|
node.vm.hostname = "node-#{i}"
node.vm.box_check_update = false
node.vm.provider "virtualbox" do |vbox|
vbox.name = "node-#{i}"
vbox.cpus = 2
vbox.memory =2048
end
end
end
end
使用预定义变量批量创建
# -*- mode: ruby -*-
# vi: set ft=ruby :
vms = [
{
:name => "node1",
:eth1 => "192.168.1.11",
:cpus => 2,
:memory => 2048
},
{
:name => "node2",
:eth1 => "192.168.1.12",
:cpus => 2,
:memory => 2048
},
{
:name => "node3",
:eth1 => "192.168.1.13",
:cpus => 2,
:memory => 2048
}
]
Vagrant.configure("2") do |config|
config.vm.box = "centos/7"
config.vm.box_url = "https://mirrors.ustc.edu.cn/centos-cloud/centos/7/vagrant/x86_64/images/CentOS-7.box"
vms.each do |i|
config.vm.define i[:name] do |node|
node.vm.hostname = i[:name]
node.vm.box_check_update = false
node.vm.provider "virtualbox" do |vbox|
vbox.name = i[:name]
vbox.cpus = i[:cpus]
vbox.memory = i[:memory]
end
node.vm.network :public_network, ip: i[:eth1], gateway: "192.168.1.1"
end
end
end
执行脚本或命令
执行外部脚本
Vagrantfile文件:
Vagrant.configure("2") do |config|
(1..3).each do |i|
config.vm.define "master-00#{i}" do |node|
node.vm.box = "centos7-standard"
node.vm.box_check_update = false
node.vm.hostname = "master-00#{i}"
node.vm.network "public_network", ip: "192.168.1.10#{i}"
node.vm.provision "shell", path: "post-deploy.sh" ,run: "always"
end
end
(1..3).each do |i|
config.vm.define "node-00#{i}" do |node|
node.vm.box = "centos/7"
node.vm.box_check_update = false
node.vm.hostname = "node-00#{i}"
node.vm.network "public_network", ip: "192.168.1.10#{i}"
node.vm.provision "shell", path: "post-deploy.sh" ,run: "always"
end
end
end
#!/bin/bash
value=$( grep -ic "entry" /etc/hosts )
if [ $value -eq 0 ]
then
echo "
192.168.11.101 master-001
192.168.11.102 master-002
192.168.11.103 master-003
" >> /etc/hosts
fi
其中node.vm.provision配置为shell,作用是在虚拟机启动后执行的shell命令,此外provision还有file、ansible等,可参考官方。
此处将在系统启动后要执行的脚本和Vagrantfile放在同一级目录下,文件讲传到虚拟机内并执行,run
指明脚本执行的频次,有once
(默认值,仅在第一次执行vagrant up
或vagrant destroy
后再执行vagrant up
后执行脚本)、always(每次执行vagrant up
或vagrant reload
后执行)、never(永远不执行)。
执行inline脚本
$script = <<-'SCRIPT'
echo "These are my \"quotes\"! I am provisioning my guest."
date > /etc/vagrant_provisioned_at
SCRIPT
Vagrant.configure("2") do |config|
config.vm.provision "shell", inline: $script
end
或
Vagrant.configure("2") do |config|
config.vm.provision "shell",
inline: "echo Hello, World"
end
脚本参数
Vagrant.configure("2") do |config|
config.vm.provision "shell" do |s|
s.inline = "echo $1"
s.args = "'hello, world!'"
end
end
或
Vagrant.configure("2") do |config|
config.vm.provision "shell" do |s|
s.inline = "echo $1"
s.args = ["hello, world!"]
end
end