Vagrant初体验
介绍
Vagrant
Vagrant 就是为了方便的实现虚拟化环境而设计的,使用Ruby开发,基于VirtualBox等虚拟机管理软件的接口,提供了一个可配置、轻量级的便携式虚拟开发环境。使用Vagrant可以很方便的就建立起来一个虚拟环境,而且可以模拟多台虚拟机,这样我们平时还可以在开发机模拟分布式系统。
Vagrant还会创建一些共享文件夹,用来给你在主机和虚拟机之间共享代码用。这样就使得我们可以在主机上写程序,然后在虚拟机中运行。如此一来团队之间就可以共享相同的开发环境,就不会再出现类似“只有你的环境才会出现的bug”这样的事情。
团队新员工加入,常常会遇到花一天甚至更多时间来从头搭建完整的开发环境,而有了Vagrant,只需要直接将已经打包好的package(里面包括开发工具,代码库,配置好的服务器等)拿过来就可以工作了,这对于提升工作效率非常有帮助。
Vagrant不仅可以用来作为个人的虚拟开发环境工具,而且特别适合团队使用,它使得我们虚拟化环境变得如此的简单,只要一个简单的命令就可以开启虚拟之路。
VirtualBox
VirtualBox 是一款开源虚拟机软件。VirtualBox 是由德国 Innotek 公司开发,由Sun Microsystems公司出品的软件,使用Qt编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。Innotek 以 GNU General Public License (GPL) 释出 VirtualBox,并提供二进制版本及 OSE 版本的代码。使用者可以在VirtualBox上安装并且执行Solaris、Windows、DOS、Linux、OS/2 Warp、BSD等系统作为客户端操作系统。已由甲骨文公司进行开发,是甲骨文公司xVM虚拟化平台技术的一部份。
VirtualBox号称是最强的免费虚拟机软件,它不仅具有丰富的特色,而且性能也很优异!它简单易用,可虚拟的系统包括Windows(从Windows 3.1到Windows10、Windows Server 2012,所有的Windows系统都支持)、Mac OS X、Linux、OpenBSD、Solaris、IBM OS2甚至Android等操作系统!使用者可以在VirtualBox上安装并且运行上述的这些操作系统! 与同性质的VMware及Virtual PC比较下,VirtualBox独到之处包括远端桌面协定(RDP)、iSCSI及USB的支持,VirtualBox在客户端操作系统上已可以支持USB 3.0的硬件装置,不过要安装 VirtualBox Extension Pack。
虚拟开发环境
平常我们经常会遇到这样的问题:在开发机上面开发完毕程序,放到正式环境之后会出现各种奇怪的问题:描述符少了、nginx配置不正确、MySQL编码不对、php缺少模块、glibc版本太低等。
所以我们就需要虚拟开发环境,我们虚拟和正式环境一样的虚拟开发环境,而随着个人开发机硬件的升级,我们可以很容易的在本机跑虚拟机,例如VMware、VirtualBox等。因此使用虚拟化开发环境,在本机可以运行自己喜欢的OS(Windows、Ubuntu、Mac等),开发的程序运行在虚拟机中,这样迁移到生产环境可以避免环境不一致导致的莫名错误。
虚拟开发环境特别适合团队中开发环境、测试环境、正式环境不同的场合,这样就可以使得整个团队保持一致的环境,我写这一章的初衷就是为了让大家和我的开发环境保持一致,让读者和我们整个大团队保持一致的开发环境。
安装
安装Vagrant
目前唯一安装的办法就是到官方网站下载打包好的 安装包 他的安装过程和VirtualBox的安装一样都是傻瓜化安装,一步一步执行就可以完成安装。
尽量下载最新的程序,因为VirtualBox经常升级,升级后有些接口会变化,老的Vagrant可能无法使用。
要想检测安装是否成功,可以打开终端命令行工具,输入vagrant,看看程序是不是已经可以运行了。如果不行,请检查一下环境变量里面是否包含vagrant所在的路径。
安装VirtualBox
VirtualBox是Oracle开源的虚拟化系统,它支持多个平台,所以你可以到官网网站 下载适合你平台的VirtualBox最新版本并安装,它的安装过程都很傻瓜化,一步一步执行就可以完成安装了。
本文使用VirtualBox版本6.1.4
Vagrant入门
vagrant的命令详解
命令 | 作用 |
---|---|
vagrant box add | 添加box的操作 |
vagrant init | 初始化box的操作,会生成vagrant的配置文件Vagrantfile |
vagrant up | 启动本地环境 |
vagrant ssh | 通过 ssh 登录本地环境所在虚拟机 |
vagrant halt | 关闭本地环境 |
vagrant suspend | 暂停本地环境 |
vagrant resume | 恢复本地环境 |
vagrant reload | 修改了 Vagrantfile 后,使之生效(相当于先 halt,再 up) |
vagrant destroy | 彻底移除本地环境 |
vagrant box list | 显示当前已经添加的box列表 |
vagrant box remove | 删除相应的box |
vagrant package | 打包命令,可以把当前的运行的虚拟机环境进行打包 |
vagrant plugin | 用于安装卸载插件 |
vagrant status | 获取当前虚拟机的状态 |
vagrant global-status | 显示当前用户Vagrant的所有环境状态 |
Vagrant常用命令
前面讲了Vagrant的几个命令:
- vagrant box add 添加box的操作
- vagrant init 初始化box的操作
- vagrant up 启动虚拟机的操作
- vagrant ssh 登录虚拟机的操作
Vagrant还包括如下一些操作:
vagrant box list
显示当前已经添加的box列表1
2vagrant box list
base (virtualbox)vagrant box remove
删除相应的box1
2vagrant box remove base virtualbox
Removing box 'base' with provider 'virtualbox'...vagrant destroy
停止当前正在运行的虚拟机并销毁所有创建的资源1
2
3vagrant destroy
Are you sure you want to destroy the 'default' VM? [y/N] y
[default] Destroying VM and associated drives...vagrant halt
关机1
2vagrant halt
[default] Attempting graceful shutdown of VM...vagrant package
打包命令,可以把当前的运行的虚拟机环境进行打包1
2
3
4
5
6vagrant package
[default] Attempting graceful shutdown of VM...
[default] Clearing any previously set forwarded ports...
[default] Creating temporary directory for export...
[default] Exporting VM...
[default] Compressing package to: C:\Users\DOBO\vagrant\package.boxvagrant plugin
用于安装卸载插件vagrant provision
通常情况下Box只做最基本的设置,而不是设置好所有的环境,因此Vagrant通常使用Chef或者Puppet来做进一步的环境搭建。那么Chef或者Puppet称为provisioning,而该命令就是指定开启相应的provisioning。按照Vagrant作者的说法,所谓的provisioning就是”The problem of installing software on a booted system”的意思。除了Chef和Puppet这些主流的配置管理工具之外,我们还可以使用Shell来编写安装脚本。
例如: vagrant provision –provision-with chefvagrant reload
重新启动虚拟机,主要用于重新载入配置文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15vagrant reload
[default] Attempting graceful shutdown of VM...
[default] Setting the name of the VM...
[default] Clearing any previously set forwarded ports...
[default] Creating shared folders metadata...
[default] Clearing any previously set network interfaces...
[default] Preparing network interfaces based on configuration...
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] Booting VM...
[default] Waiting for VM to boot. This can take a few minutes.
[default] VM booted and ready for use!
[default] Setting hostname...
[default] Mounting shared folders...
[default] -- /vagrantvagrant resume
恢复前面被挂起的状态
1
2
3
4
5vagrant resume
[default] Resuming suspended VM...
[default] Booting VM...
[default] Waiting for VM to boot. This can take a few minutes.
[default] VM booted and ready for use!vagrant ssh-config
输出用于ssh连接的一些信息
1
2
3
4
5
6
7
8
9
10
11vagrant ssh-config
Host default
HostName 127.0.0.1
User vagrant
Port 2222
UserKnownHostsFile /dev/null
StrictHostKeyChecking no
PasswordAuthentication no
IdentityFile "C:\Users/DOBO\.vagrant.d\insecure_private_key"
IdentitiesOnly yes
LogLevel FATALvagrant status
获取当前虚拟机的状态
1
2
3
4
5
6
7
8
9vagrant status
Current machine states:
default running (virtualbox)
The VM is running. To stop this VM, you can run `vagrant halt` to
shut it down forcefully, or you can run `vagrant suspend` to simply
suspend the virtual machine. In either case, to restart it again,
simply run `vagrant up`.vagrant suspend
挂起当前的虚拟机
1
2vagrant suspend
[default] Saving VM state and suspending execution...
Vagrant配置
当我们安装好VirtualBox和Vagrant后,我们要开始考虑在VM上使用什么操作系统了,一个打包好的操作系统在Vagrant中称为Box,即Box是一个打包好的操作系统环境,目前网络上什么都有,所以你不用自己去制作操作系统或者制作Box:vagrantbox.es上面有大家熟知的大多数操作系统,你只需要下载就可以了,下载主要是为了安装的时候快速,当然Vagrant也支持在线安装。
建立开发环境目录
我的开发机是Windows,所以我建立了如下的开发环境目录,读者可以根据自己的系统不同建立一个目录就可以:
C:\Users\DOBO\vagrant
下载Box
添加box的命令如下:
1 | vagrant box add base 远端的box地址或者本地的box文件名 |
vagrant box add 是添加box的命令
base是box的名称,可以是任意的字符串,base是默认名称,主要用来标识一下你添加的box,后面的命令都是基于这个标识来操作的。
例子:
1 | vagrant box add base http://files.vagrantup.com/lucid64.box |
我在开发机上面是这样操作的,首先进入我们的开发环境目录C:\Users\DOBO\vagrant,执行如下的命令
1 | vagrant box add base lucid64.box |
安装过程的信息:
1 | Downloading or copying the box... |
box中的镜像文件被放到了:C:\Users\当前用户名.vagrant.d\boxes\目录下。
通过vagrant box add这样的方式安装远程的box,可能很慢,所以建议大家先下载box到本地再执行这样的操作。
初始化
初始化的命令如下:
1 | vagrant init |
如果你添加的box名称不是base,那么需要在初始化的时候指定名称,例如
1 | vagrant init "CentOS 6.3 x86_64 minimal" |
初始化过程的信息:
1 | A `Vagrantfile` has been placed in this directory. |
这样就会在当前目录生成一个 Vagrantfile的文件,里面有很多配置信息,后面我们会详细讲解每一项的含义,但是默认的配置就可以开箱即用。
启动虚拟机
启动虚拟机的命令如下:
1 | vagrant up |
启动过程的信息:
1 | Bringing machine 'default' up with 'virtualbox' provider... |
连接到虚拟机
上面已经启动了虚拟机,之后我们就可以通过ssh来连接到虚拟机了。比如在我的开发机中可以像这样来连接:
1 | vagrant ssh |
连接到虚拟机后的信息如下:
1 | Linux lucid64 2.6.32-38-server #83-Ubuntu SMP Wed Jan 4 11:26:59 UTC 2012 x86_64 GNU/Linux |
这样我们就可以像连接到一台服务器一样进行操作了。
window机器不支持这样的命令,必须使用第三方客户端来进行连接,例如putty、Xshell4等.
putty为例:
主机地址: 127.0.0.1
端口: 2222
用户名: vagrant
密码: vagrant
系统信息
进入系统之后我们可以看一下系统的基础信息:
1 | vagrant@lucid64:/vagrant$ df -h |
/vagrant这个目录是自动映射的,被映射到C:\Users\DOBO\vagrant,这样就方便我们以后在开发机中进行开发,在虚拟机中进行运行效果测试了。
Vagrantfile配置文件详解
在我们的开发目录下有一个文件Vagrantfile,里面包含有大量的配置信息,主要包括三个方面的配置,虚拟机的配置、SSH配置、Vagrant的一些基础配置。Vagrant是使用Ruby开发的,所以它的配置语法也是Ruby的,但是我们没有学过Ruby的人还是可以跟着它的注释知道怎么配置一些基本项的配置。
box设置
1
config.vm.box = "base"
上面这配置展示了Vagrant要去启用那个box作为系统,也就是上面我们输入vagrant init Box名称时所指定的box,如果沒有输入box名称的話,那么默认就是base,VirtualBox提供了VBoxManage这个命令行工具,可以让我们设定VM,用modifyvm这个命令让我们可以设定VM的名称和内存大小等等,这里说的名称指的是在VirtualBox中显示的名称,我们也可以在Vagrantfile中进行设定,在Vagrantfile中加入如下这行就可以设定了:
1
2
3config.vm.provider "virtualbox" do |v|
v.customize ["modifyvm", :id, "--name", "dobo", "--memory", "512"]
end这行设置的意思是调用VBoxManage的modifyvm的命令,设置VM的名称为dobo,内存为512MB。你可以类似的通过定制其它VM属性来定制你自己的VM。
2. 网络设置
Vagrant有两种方式来进行网络连接,一种是host-only(主机模式),意思是主机和虚拟机之间的网络互访,而不是虚拟机访问internet的技术,也就是只有你一個人自High,其他人访问不到你的虚拟机。另一种是Bridge(桥接模式),该模式下的VM就像是局域网中的一台独立的主机,也就是说需要VM到你的路由器要IP,这样的话局域网里面其他机器就可以访问它了,一般我们设置虚拟机都是自high为主,所以我们的设置一般如下:
1
config.vm.network :private_network, ip: "11.11.11.11"
这里我们虚拟机设置为hostonly,并且指定了一个IP,IP的话建议最好不要用192.168..这个网段,因为很有可能和你局域网里面的其它机器IP冲突,所以最好使用类似11.11..这样的IP地址。
3. hostname设置
hostname的设置非常简单,Vagrantfile中加入下面这行就可以了:
1
config.vm.hostname = "go-app"
设置hostname非常重要,因为当我们有很多台虚拟服务器的时候,都是依靠hostname來做识别的,例如Puppet或是Chef,都是通过hostname來做识别的,既然设置那么简单,所以我们就別偷懒,设置一个。
4. 同步目录
我们上面介绍过/vagrant目录默认就是当前的开发目录,这是在虚拟机开启的时候默认挂载同步的。我们还可以通过配置来设置额外的同步目录:
1
config.vm.synced_folder "C:\Users\DOBO\data", "/vagrant_data"
上面这个设定,第一个参数是主机的目录,第二个参数是虚拟机挂载的目录
5. 端口转发
1
config.vm.network :forwarded_port, guest: 80, host: 8080
上面这句配置可厉害了,这一行的意思是把对host机器上8080端口的访问请求forward到虚拟机的80端口的服务上,例如你在你的虚拟机上使用nginx跑了一个Go应用,那么你在host机器上的浏览器中打开 `http://localhost:8080`时,Vagrant就会把这个请求转发到VM里面跑在80端口的nginx服务上,因此我们可以通过这个设置来帮助我们去设定host和VM之间,或是VM和VM之间的信息交互。
> `修改完Vagrantfile的配置后,记得要用vagrant reload命令来重启VM之后才能使用VM更新后的配置`
模拟打造多机器的分布式系统
前面这些单主机单虚拟机主要是用来自己做开发机,从这部分开始的内容主要将向大家介绍如何在单机上通过虚拟机来打造分布式造集群系统。这种多机器模式特别适合以下几种人:
- 快速建立产品网络的多机器环境,例如web服务器、db服务器
- 建立一个分布式系统,学习他们是如何交互的
- 测试API和其他组件的通信
- 容灾模拟,网络断网、机器死机、连接超时等情况
Vagrant支持单机模拟多台机器,而且支持一个配置文件Vagrntfile就可以跑分布式系统。
现在我们来建立多台VM跑起來,並且让他们之间能够相通信,假设一台是应用服务器、一台是DB服务器,那么这个结构在Vagrant中非常简单,其实和单台的配置差不多,你只需要通过config.vm.define来定义不同的角色就可以了,现在我们打开配置文件进行如下设置:
1 | Vagrant.configure("2") do |config| |
这里的设置和前面我们单机设置配置类似,只是我们使用了:web以及:db分別做了两个VM的设置,并且给每个VM设置了不同的hostname和IP,设置好之后再使用vagrant up
将虚拟机跑起来:
1 | vagrant up |
看到上面的信息输出后,我们就可以通过vagrant ssh登录虚拟机了,但是这次和上次使用的不一样了,这次我们需要指定相应的角色,用来告诉ssh你期望连接的是哪一台:
1 | vagrant ssh web |
1 | vagrant ssh db |
是不是很酷!现在接下来我们再来验证一下虚拟机之间的通信,让我们先使用ssh登录web虚拟机,然后在web虚拟机上使用ssh登录db虚拟机(默认密码是vagrant):
1 | vagrant ssh web |
通过上面的信息我们可以看到虚拟机之间通信是畅通的,所以现在开始你伟大的架构设计吧,你想设计怎么样的架构都可以,唯一限制你的就是你主机的硬件配置了。