Vagrant

Table of Contents

1. Vagrant 简介

Vagrant 是一个虚拟机运行环境管理工具。通过 Vagrant 可以方便地创建和删除虚拟机、配置虚拟机运行参数、自动化配置和安装开发环境必须的各类软件等等。Vagrant 最初仅支持 VirtualBox,现在支持 VMWare、HyperV 等等。

参考:
https://www.vagrantup.com/
Getting Started - Vagrant by HashiCorp

2. Vagrant 基本使用

下面介绍一下 Vagrant 的基本使用。

第一步,创建工程目录:

$ mkdir my-vagrant-prj
$ cd my-vagrant-prj

第二步,使用 vagrant init 初始化 Vagrant 工程,如:

$ vagrant init ubuntu/trusty64  # 初始化Vagrant工程,会在当前目录下创建文件Vagrantfile

说明:上面命令会在当前创建一个 Vagrantfile 文件,其内容如下(去掉了注释):

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/trusty64"
end

第三步,使用 vagrant up 可以启动虚拟机:

$ vagrant up       # 启动虚拟机(默认为VirtualBox虚拟机,本地不存在时会先下载它)

说明 1:如果本地没有 ubuntu/trusty64 这个 box,会先下载它(Vagrant 发现 box 的名字的格式为“用户名/box 名”,则认为 box 由 Hashicorp 官网提供,会使用“https://atlas.hashicorp.com/ubuntu/trusty64” 来下载该 box)。
说明 2:Vagrant 下载的 box 保存在目录~/.vagrant.d/boxes 中,ubuntu/trusty64 大概有 400 多 MB:

$ du -sh .vagrant.d/boxes/
425M	.vagrant.d/boxes/

说明 3:当启动完虚拟机后,打开 VirtualBox Manager,可以看到刚启动的虚拟机。如图 1 所示。

vagrant_virtualbox.jpg

Figure 1: 通过 Vagrant 启动的虚拟机

最后,使用 vagrant ssh 可登录上个步骤启动的虚拟机:

$ vagrant ssh      # 使用默认用户vagrant以及内置的SSH私钥登录虚拟机
Welcome to Ubuntu 14.04.5 LTS (GNU/Linux 3.13.0-139-generic x86_64)
......
vagrant@vagrant-ubuntu-trusty-64:~$

使用 vagrant suspend 可以挂起虚拟机,如:

$ vagrant suspend   # 挂起虚拟机,使用vagrant up可以再次启动已经挂起的虚拟机(较快)
==> default: Saving VM state and suspending execution...

使用 vagrant halt 可以关闭虚拟机,如:

$ vagrant halt      # 关闭虚拟机,使用vagrant up可以再次启动已经关闭的虚拟机(较慢)

使用 vagrant destroy 可以删除 VirtualBox 虚拟机,如:

$ vagrant destroy   # 删除虚拟机,使用vagrant up会导入box到VirtualBox虚拟机,并启动它(很慢)

说明:上面命令不会删除 box 本身,使用 vagrant box remove 命令可以删除 box。

使用 vagrant status 可以检测虚拟机状态,如:

$ vagrant status
Current machine states:

default                   poweroff (virtualbox)

The VM is powered off. To restart the VM, simply run `vagrant up`

3. Provision

所谓 Provision 就是自动安装软件,使用 vagrant up 启动虚拟机后就可以使用它们了,这非常方便。

参考:
Vagrant Virtual Development Environment Cookbook, 2015, Chapter 3 Provisioning a Vagrant Environment
https://www.vagrantup.com/docs/provisioning/

3.1. 实例:通过简单 shell 命令 provision nginx

下面通过安装 nginx 服务器的例子来介绍通过简单 shell 命令进行 Provision 的过程。

首先,在 Vagrantfile 所在目录中创建子文件夹 html,并新建一个 index.html 文件。如:

$ cat html/index.html
<html>
    <body>
       It works.
    </body>
</html>

然后,修改 Vagrantfile 为:

$nginx_install = <<SCRIPT
    if [ ! -x /usr/sbin/nginx ]; then
        apt-get install -y nginx;
    fi
    # Default NGINX directory: /usr/share/nginx/html
    # Replace this with symbolic link to vagrant directory.
    if [ ! -L /usr/share/nginx/html ]; then
        rm -rf /usr/share/nginx/html
        ln -s /vagrant/html /usr/share/nginx/html
    fi
SCRIPT

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.provision "shell", inline: $nginx_install        # inline方式的Provision
  config.vm.network "forwarded_port", guest: 80, host: 8080  # 配置端口映射
end

使用 vagrant up --provision 启动虚拟机(如果是第一次运行 vagrant up 可以省略参数 --provision ),即会自动进行 Provision。如果当前虚拟机在启动状态,使用 vagrant reload --provision 也可以让其进行 Provision。

启动完成后,在 host 中访问 localhost:8080,可以测试 nginx 是否正常提供了服务:

$ curl http://localhost:8080/
<html>
    <body>
       It works.
    </body>
</html>

3.2. 实例:通过外部 shell 脚本 provision nginx

如果 Provision 的程序比较复杂,把它们放在外部 shell 脚本中会使 Vagrantfile 更加简洁。

这里把前面介绍的例子改造为对应的“外部 shell”方式。

在 Vagrantfile 所在目录中创建脚本"nginx-install.sh",内容如下:

#!/usr/bin/env bash

if [ ! -x /usr/sbin/nginx ]; then
    apt-get install -y nginx;
fi
# Default NGINX directory: /usr/share/nginx/html
# Replace this with symbolic link to vagrant directory.
if [ ! -L /usr/share/nginx/html ]; then
    rm -rf /usr/share/nginx/html
    ln -s /vagrant/html /usr/share/nginx/html
fi

修改 Vagrantfile 为:

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/trusty64"
  config.vm.provision "shell", path: "nginx-install.sh"      # 通过path指定外部shell
  config.vm.network "forwarded_port", guest: 80, host: 8080  # 配置端口映射
end

3.3. 使用 Ansible 进行 Provision

4. Vagrant 常用设置

4.1. 设置共享目录

默认地,Vagrant 会把 Host 机中 Vagrantfile 所在目录共享为虚拟机中的/vagrant 目录。

你可以通过下面方式增加共享目录:

Vagrant.configure("2") do |config|
  # other config here

  config.vm.synced_folder "src/", "/srv/website"
end

第一个参数为 Host 机器中的目录,第二个参数为虚拟机中的目录。

参考:https://www.vagrantup.com/docs/synced-folders/

4.2. 配置网络

4.2.1. 配置 NAT 网络的端口转发

默认地,Vagrant 采用 NAT 网络方式 ,Host 不能直接访问你的虚拟机,你需要使用下面方式配置端口转发:

Vagrant.configure("2") do |config|
  # other config here

  config.vm.network "forwarded_port", guest: 80, host: 8080
end

参考:https://www.vagrantup.com/docs/networking/forwarded_ports.html

4.2.2. Private Networks 下使用 DHCP 或者静态 IP

通过下面方式可以从 dhcp 服务器获取 ip:

Vagrant.configure("2") do |config|
  # other config here

  config.vm.network "private_network", type: "dhcp"
end

通过下面方式可以配置静态 ip:

Vagrant.configure("2") do |config|
  # other config here

  config.vm.network "private_network", ip: "192.168.50.4"
end

Author: cig01

Created: <2017-04-16 Sun>

Last updated: <2018-01-26 Fri>

Creator: Emacs 27.1 (Org mode 9.4)