使用 Vagrant 构建开发环境

使用 Vagrant 构建开发环境

摘要:本文描述了如使用 Vagrant 构建统一的开发环境。

问题

作为开发人员,我们通常面临的问题有:

  1. 开发环境需要手工安装配置,这包括操作系统(CentOS、Ubuntu)、PHP/HHVM、Python、Node.js、MySQL、Apache/Nginx等的版本和配置。
  2. 无法重现问题。
    甲:你说的问题,怎么在我的机器上没事儿啊?
    乙:可问题的确存在,不信你到我的机器上来看。
    甲:那我的机器和你的环境哪里不同呢?
    因为环境不同,比如开发环境和生产环境不同,和测试环境也不完全相同。
  3. 团队中没有统一的方法配置开发环境,保持相同的环境,好的可能会有一个文档,告诉大家要下载、安装的东西,缺乏文档的可能就要到处问了。
  4. 在同一台机器上,要为参与的不同项目配置不同的环境,因为要求的软件、版本不同,有时候这根本就不可能。
  5. 团队中不同的成员使用的机器、操作系统就不同,就很难保证完全相同的环境。比如很多开源项目,团队成员来自五湖四海,有人用Windows,有人用Mac,系统不一样,配置就可能不同,导致不同的结果。

解决方法 - Vagrant之道

用虚拟机构建一致的环境,并且把安装和配置的过程自动化,这就是Vagrant所做的事情。按照Vagrant的流程:

  • 系统工程师只需要准备Vagrant配置以及相应的脚本,来配置虚拟机。
  • 团队成员只需要从源码控制中签出代码,运行vagrant up,就可以有一个完整的开发环境了。开发人员还是可以继续在自己的机器上使用自己熟悉的编辑器、浏览器和其它工具,而代码及数据库、web服务器则是运行在Vagrant的虚拟机中。
  • 如果把虚拟机搞乱了,只需要用vagrant destroy把虚拟机删除,再运行vagrant up就又可以得到事先配置好的虚拟机了。
  • 用完之后,只需要使用vagrant halt或者vagrant suspend把虚拟机关机或者休眠,第二天用vagrant up就把虚拟机重新启动,恢复到昨天的状态了。
  • 这种对虚拟机的管理方式,不单在一个项目的团队中可以使用,而且可以跨多个项目使用。使用相同的流程和环境,提高了生产力,再也不会有“在我的机器上明明没有这个问题”的问题了。

这就是Vagrant之道(参看[5]第4页)。

Vagrant可以做下面这些事情:

  • 通过SSH登录虚拟机
  • 关掉虚拟机
  • 删除虚拟机,完全删除虚拟硬盘和配置信息
  • 暂停和恢复虚拟机
  • 把虚拟机打包,从而可以分发给其他开发人员

Vagrant涉及的概念:

  • Vagrant本身并不是虚拟机,它通过其供应商(provider)来使用虚拟机,支持的虚拟机有Oracle的VirtualBoxVMWareVMWare FusionVMWare Workstation和微软的Hyper-V,以及象Docker这样的容器,还有Amazone的AWSRackspaceDigitalOcean等公有云。缺省的是使用VirtualBox,因为这是免费的,也是最容易配置的。
  • 虚拟机只是提供了一个虚拟的机器,其中的各种软件的安装和配置还是要靠provision,支持的配置工具有最基本的shell脚本、以及PuppetChefAnsible等等。
  • 为了便于虚拟机的分发和共享,虚拟机本身的虚拟硬盘和配置加上Vagrant的设置文件可以打包在一起,这在Vagrant中叫box,这是可被Vagrant直接使用的虚拟机镜像文件。众多厂商和用户在Atlas(以 前叫Vagrant Cloud)上提供了各种box,对应你所使用的provider。你也可以在其它box的基础上,进一步配置、发布自己的box,共享给自己的团队或者公众。
  • 如果上述的功能还不能满足你对环境的要求,Vagrant还提供插件,对基本的功能进行扩展,甚至你也可以按照其规范开发自己的插件,满足特定的要求。

下面我们就用几个例子来说明Vagrant的使用。

请先下载、安装VirtualBoxVagrant。因为Vagrant是用ruby开发的,你还要下载、安装Ruby。不论你的机器是Windows、Mac或者各种Linux发行版本,这几个软件都有相应的版本。

实例一 最简单的Vagrant环境

创建一个新目录,比如叫example。然后运行:

vagrant init hashicorp/precise64

在上述命令中指定了hashicorp/precise64为使用的box,这是Ubuntu 12.04 LTS,更多的信息可见https://atlas.hashicorp.com/hashicorp/boxes/precise64。第一次需要一个box时(即在运行vagrant up时),Vagrant会自动下载该box到你的机器上,这通常位于<homedir>\.vagrant.d\boxes(例如,在Windows 7上,这就是C:\Users\myusername\.vagrant.d\boxes),以后就不必再次下载了。

上述会生成一个基本的Vagrant配置文件Vagrantfile,最简单的情况可以只有这一个文件。基本内容如下:

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # Every Vagrant virtual environment requires a box to build off of.
  config.vm.box = "hashicorp/precise64"

  # 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.
  config.vm.network "forwarded_port", guest: 80, host: 8080
end

 这个文件指定了下面这些基本的配置:

  • 在上述生成的配置文件中,指定了如下box:
    config.vm.box = "hashicorp/precise64"
  • 其次,指定虚拟机和主机之间的映射目录,通常共享的是源文件目录。这样,你就可以在主机上继续使用自己熟悉的编辑器写代码,而使用虚拟机环境来运行、调试。
    上述配置文件没有指定任何映射目录,但是Vagrant缺省会把主机Vagrantfile配置文件所在的目录映射为虚拟机上的/vagrant目录。
  • 还有,就是配置虚拟机的网络,否则,你从主机上无法访问虚拟机。这有三种模式:forwarded ports、host-only networking和bridged networking。
    • Forwarded Ports,缺省值,在主机上选择一个端口,转发给虚拟机的一个端口,这样就不必给虚拟机一个IP,就可以从主机访问虚拟机了。
      上述配置文件中,使用的是Forwarded Ports:
      config.vm.network "forwarded_port", guest: 80, host: 8080

      这会把虚拟机的80端口映射到主机的8080端口,在主机上通过localhost:8080就可以访问虚拟机了。同时,缺省会有另外一个映射,把虚拟机的22端口映射到主机的2222端口,这是为了允许从主机上通过SSH登录到虚拟机。

    • Host-Only Networking,这会在主机上创建一个仅对主机和虚拟机可见的私有网络,这样虚拟机得到一个指定的静态IP地址,就可以从主机通过该静态IP地址来访问虚拟机了,而虚拟机也可以通过*.*.*.1的IP地址来访问主机。这种情况下,主机所在的网络上的其他机器是无法“看到”这个私有网络的,也就无法访问虚拟机。
    • Bridged Networking,桥接虚拟机到主机上的一个设备(应该指网卡),这样虚拟机就如同主机所在网络上的另外一台物理机器一样,这意味着虚拟机可以访问网络资源,网络上的其他机器也可以访问虚拟机。

有了这个Vagrantfile配置文件,就可以启动虚拟机了。在命令行中,在Vagrantfile所在的目录中,运行如下命令:

vagrant up

小窍门:在Windows 7(及以上版本?)的Windows Explorer中,可以按住Shift键,再用鼠标右击某个目录,直接在跳出的上下文菜单中点击"Open command window here",就直接进入命令行并进入该目录了。

输出如下:

 从上面的输出中,我们可以看到指定使用的box、端口的映射和共享目录的映射。

前面提到虚拟机22端口对主机2222端口的映射是用于SSH的,我们现在就可以用SSH登录虚拟机了。运行如下命令:

vagrant ssh

小窍门:如果你的命令行没有对ssh的支持,就无法登录。在Windows上,可以在安装git的时候,有一个选项,选择添加相应的目录到系统路径中,就支持在命令行使用SSH了。

上述命令相应的输出为:

这就登录进入了虚拟机,在$提示符下可以使用Linux命令操纵虚拟机了。

实例二 Python Sphinx文档环境

第二个例子中,我们用VirtualBox和shell脚本来构建一个最基本的虚拟环境,用于使用Sphinx来生成文档。先创建一个新目录,比如叫docs,在其中创建一个新文件Vagrantfile,完整的配置为:

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # Every Vagrant virtual environment requires a box to build off of.
  config.vm.box = "puphpet/ubuntu1404-x64"

  # 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"
  config.vm.synced_folder ".", "/docs"

  config.vm.provider "virtualbox" do |v|
    v.name = "cakephp_docs"
    v.memory = 384
  end

  config.vm.provision :shell, path: "provision.sh"
end

 最常用的Linux版本之一是Ubuntu 14.04,我们就以此为基础,在配置中指定使用puppet/ubuntu1404-x64 box:

  config.vm.box = "puphpet/ubuntu1404-x64"

映射主机的当前目录(即Vagrantfile配置文件所在的目录)为虚拟机的/docs目录,这里会放置源代码控制下的文档源码*.rst文件:

  config.vm.synced_folder "./", "/docs"

另外,因为不需要从主机访问虚拟机的web服务器,所以没有配置网络,即使用的是缺省的Forwarded Ports模式。

再指定使用一个shell脚本,安装、配置sphinx:

  config.vm.provision :shell, path: "provision.sh"

在同一目录下,再创建shell脚本文件povision.sh,其内容为:

#!/usr/bin/env bash

echo "update apt repository..."
apt-get update >/dev/null 2>&1
echo "Installing python-setuptools..."
sudo apt-get install -y python-setuptools >/dev/null 2>&1
echo "Installing easy_install..."
sudo apt-get install -y easy_install >/dev/null 2>&1
echo "Installing sphinx..."
sudo easy_install sphinx==1.2 >/dev/null 2>&1
echo "Installing sphinxcontrib-phpdomain..."
sudo easy_install sphinxcontrib-phpdomain >/dev/null 2>&1

因为Python是Linux自带的,不需要再安装了。该脚本使用apt-get安装两个软件包python-setuptools和easy_install,然后再用easy_install安装sphinx 1.2和sphinxcontrib-phpdomain。

这样就配置好了,在命令行中,在Vagrantfile所在的目录中运行

vagrant up
vagrant ssh

之后,就通过SSH登录到虚拟机,可以在其中用sphinx从源代码构建html文档了。

实例三 LAMP开发环境

在第三个例子中,我们使用PuPHPet为PHP配置一个LAMP开发环境。PuPHPet是一个网页的向导式界面,让你更容易地生成使用Puppet的Vagrant配置文件。

用浏览器打开https://puphpet.com

第一步,选择部署目标,缺省为本地,使用VirtualBox。我们选择操作系统为Ubuntu 14.04 64位,如下图所示:

Provider和VM操作系统

然后,设置虚拟机IP地址、内存、端口,以及目录映射,注意这里的目录是用来作为网站应用根目录的,如下图所示:

IP地址、内存、端口,以及目录映射

第二步,选择要在虚拟机上安装的软件包。我们选择Ubuntu的htop和vim,如下图所示:

Server Packages

第三步,防火墙规则,不需要做任何设置,略过:

Firewall Rules

第四步,选择web服务器,我们选择使用Apache,要安装rewrite模块,如下图所示:

Webservers

再设置域名、网站根目录,允许设置多个VHOST,如下图所示:

Webservers - Apache Virtual Host

注意上面的Document Root路径和在第一步中设置的目录映射有关。

第五步,选择语言PHP,以及相关的设置和需要的模块,如下图所示:

Languages

还可以选择需要的PHP库,如下图所示:

PHP Modules/Libraries

第六步,选择数据库MySQL,并且设置管理员密码,如下图所示:

Databases

然后创建数据库,允许创建多个数据库,如下图所示:

MySQL Create User  & Database

其中,/var/www/database/backup/2014-10-19_cakephp_blog.sql是在虚拟机中要恢复的数据库备份,这个路径也和你在第一步中设置的目录映射有关。

第七步,选择其它工具,包括邮件工具Mailcatcher、队列工具Beanstalkd及RabbitMQ、搜索工具Elastic Search及Solr,如下图所示:

Additional Tools

我们不使用任何额外工具,所以略过这一步。

第八步,也就是最后一步,完成,如下图所示:

Create Your Manifest

点击那个大大的蓝色按钮“GO AHEAD THEN, MAKE IT!”,就可以下载一个将近3MB的puphpet.zip。打开这个.zip文件,可以看到按照我们前面第一至八步设置的Vagrantfile配置以及相应的Puppet模块,如下图所示:

puphpet.zip

把它解压到一个目录中,这些文件可以和PHP项目的源代码一起放入源码控制中,供项目团队的其他成员使用。

在命令行中,在Vagrantfile所在的目录中运行vagrant up,就可以得到一个运行的LAMP虚拟机了。

在主机的hosts文件中,按照第四步的设置加入下面这行:

192.168.56.102    www.cakephp3.dev                # CakePHP 3

就可以在主机的浏览器上通过www.cakephp3.dev访问虚拟机上的网站了。

Vagrant的常用命令

vagrant up  # 启动、配置虚拟机
vagrant suspend  # 休眠虚拟机
vagrant halt  # 关闭虚拟机
vagrant destroy  # 删除虚拟机
vagrant status  # 当前目录下Vagrantfile配置对应的Vagrant虚拟机的状态,以及在此状态下可以使用的命令
vagrant global-status  # 本机上所有Vagrant虚拟机的状态

更多的命令可以参考[3]中的Command-Line Interface

进一步的思考

  • 打包、分发box,这是Vagrant通过box以及Atlas提供的功能。
  • 使用Docker的provider,可以节省资源,极大地缩短虚拟机的启动时间,也利于生产环境的部署。
  • 是否可以使用Vagrant来配置Windows虚拟机?应该使用什么provision?是否可以使用PowerShell?
  • 是否可以使用Vagrant来配置Mac虚拟机?可能不行,至少在Atlas上没有找到Mac的box。而且,恐怕也没必要。

参考资料

  1. Vagrant官网
    https://www.vagrantup.com/
  2. Vagrant Getting Started
    https://docs.vagrantup.com/v2/getting-started/
  3. Vagrant Documentation
    https://docs.vagrantup.com/v2/
  4. Atlas (之前叫Vagrant Cloud)
    https://atlas.hashicorp.com
  5. Vagrant: up and running, ISBN 978-1-449-33583-0
    http://shop.oreilly.com/product/0636920026358.do
  6. Hello Vagrant - 黄博文
    http://www.cnblogs.com/huang0925/p/3349841.html
  7. Docker与Vagrant之间的特点比较
    http://www.cnblogs.com/vikings-blog/p/3973265.html
 
 
posted @ 2014-12-29 19:48  Black Puppy  阅读(3618)  评论(4编辑  收藏  举报