虚拟化开发环境
2011-03-03ShopQi 中应用到的技术越来越多,开发环境的搭建变得越来越繁琐,这对开源项目的团队协作是相当不利的
试想,每个程序员的偏好都不同,所使用的操作系统,编辑器都是五花八门的,在开发过程中由于开发环境不一致出现问题的不在少数,调试难度也大
所以,很多公司要求所有的开发机器不能随意安装软件,要保持开发环境高度一致
这种强制限制虽然让人感到不自由,但在公司做软件,也算情有可原
而做开源项目就不同了,我们要尽可能提供便利,减少安装过程对原有环境的影响
要实现这一目标是非常困难的,还好,现在有了Vagrant
Vagrant
Vargant是构建虚拟化开发环境的工具,它是用ruby开发的,并以gem方面发布,它会帮我们
- 创建一个Ubuntu10.04版本的32位VirtualBox虚拟机,并应用chef安装项目所需的ruby、数据库、应用服务器程序等
- 将宿主机项目所在的目录与虚拟机共享,我们在宿主机用喜欢的编辑器修改程序,虚拟机中的开发环境可以立即读取到
这样就可以保证项目组成员的开发环境是一致的,不一定是rails项目才适用,java php或其他的都是可以使用vagrant
有时候,我们需要跟进开发多个项目,有的用java,有的用ruby,有的使用mysql,有的使用mongodb
把这些都装起来也没问题,但是有点浪费性能了,同一时间我们只会开发一个项目
用vagrant我们可以很好的解决这类问题,每个项目一个虚拟机,需要时才启动
下载
虚拟机的操作系统镜像文件是经过定制的,在vargant中引入的镜像文件称为"Box"
我们先下载这个镜像文件,地址如下
http://files.vagrantup.com/lucid32.box
假设下载后放至~/lucid32.box
同时需要下载VirtualBox程序,并安装
安装
安装前请确保宿主机已经安装了ruby和rubygem
gem install bundler vagrant --no-ri --no-rdoc
创建虚拟机
先引入刚才下载的镜像文件,作为vagant管理下的一个box,以后每次要生成一个用于开发的虚拟机,都会从这个box中复制出来
vagrant box add lucid32 ~/lucid32.box #进入项目目录 cd ~/Documents/shopqi #初始化,生成配置文件Vagrantfile vagrant init lucid32 #生成项目虚拟机 vagrant up
等一会儿,一个ubuntu的虚拟机就建好了
在虚拟机上安装开发环境
vagrant可以根据chef指定的cookbook recipe进行安装,关于chef的介绍可以参考 应用chef构建服务器集群自动化部署与管理
这里采用的是不依赖chef服务器的chef-solo方式,recipe采用 ShopQi 服务器部署的cookbook
指定recipe,需要修改Vagrantfile,增加以下内容
config.vm.provision :chef_solo do |chef|
chef.recipe_url = “https://dl.dropbox.com/u/19519145/shopqi/chef-solo.tar.gz”
chef.add_recipe “develop”
end
chef-solo.tar.gz文件是包含cookbooks集合的压缩包
#进入cookbooks所在目录后运行命令 tar zcvf chef-solo.tar.gz ./cookbooks
develop cookbook会引入开发机所需要的依赖recipe, 查看内容
启动虚拟机
vagrant up #如果已经启动,只想更新或者调试recipe,运行vagrant provision
如果你和我一样,喜欢rvm来管理ruby版本,并安装了除system自带的ruby,则需要修改/etc/profile,否则gems会被安装在自带ruby之下
参考 http://rvm.beginrescueend.com/integration/vagrant/
ssh登录虚拟机
之后,我们可以登录虚拟机,像以前一样执行rake等命令
vagrant ssh #查看项目目录,会发现与宿主机的当前目录内容一致 ls /vagrant
刚才引入的cookbook包含了nginx recipe,所以我们可以看看虚拟机上nginx是否能正常访问了
wget -qO- 127.0.0.1:3000
結果返回:
<html> <head> <title>Welcome to nginx!</title> </head> <body bgcolor="white" text="black"> <center><h1>Welcome to nginx!</h1></center> </body> </html>
说明能正常访问,为了能在宿主机上用浏览器访问它,我们需要进行端口映射
修改VagrantFile,加入以下内容:
Vagrant::Config.run do |config|
# Forward guest port 3000 to host port 8088 and name the mapping “web”
config.vm.forward_port(“web”, 3000, 8088)
end
用浏览器打开 http://127.0.0.1:8088 就可以访问了
打包发布
现在开发环境已经安装好了,整个过程非常高效。更进一步,我们可以把已经做好的环境打包成镜像文件,分发给其他人,他们就可以瞬间建好开发环境了。
准备pkg文件,此文件只用于定义映射端口,会被合并至Vagrantfile文件中,内容一般为
Vagrant::Config.run do |config|
#Forward nginx
config.vm.forward_port(“web”, 3000, 8088)
end
#执行打包 vagrant package --vagrantfile Vagrantfile.pkg
执行后当前目录会生成package.box文件
关闭虚拟机
vagrant halt
测试
单元测试
还是跟以前一样
验收测试
由于cucumber使用的@javascript,需要打开浏览器测试ajax。而虚拟机并未安装桌面,此测试进行不了。
开源社区中有不少技术可以进行headless后台测试,但都不成熟.
所以,我们只能在宿主机上进行这样的测试了,这样的话,宿主机又要安装项目的相关插件,这可不少.
有什么办法能让插件跟着项目跑,而不把插件安装到系统上呢?
答案是可以的,我们在虚拟机上使用bundle install安装插件的时候,指定参数—path vendor/bundle,将插件安装在项目的vendor/bundle目录,这样在宿主机就不用再安装这些插件了。
还有,我们的测试数据库还在虚拟机上,还得修改 Vagrantfile
,把mongodb,redis-server,nodejs等服务的端口映射至宿主机
直接在宿主机上运行以下命令就可以测试了
bundle exec cucumber features
注意:将gems打包后,会导致在虚拟机运行rails各种命令时,速度巨慢,原因是virtaulbox共享目录的bug:随着目录内文件数的增长,对共享目录的访问会很慢
解决方案是应用nfs共享目录,具体查看这里 http://vagrantup.com/docs/nfs.html 和 http://vagrantup.com/docs/host_only_networking.html
#宿主机需要安装nfs服务 sudo apt-get install nfs-kernel-server
进入rails控制器
经过上面的处理,插件已经安装好了,但是由于rails并未安装进系统,使用以下命令是进不了控制台的
rails c
得在项目目录下,运行
script/rails c
报错
找不到client.pem
[default] I cannot read /etc/chef/client.pem, which you told me to use to sign requests!: stderr
[default] (: stderr
[default] Chef::Exceptions::PrivateKeyMissing: stderr
这也太奇怪了,用的是chef-solo方式,而非chef-server,怎么也需要client.pem?
原来是部分cookbook使用了search方法,此方法用于从chef-server中查找相应的信息
解决方法是在cookbook中加入判断条件,开发环境部署时不调用search,生产环境才调用
node[:instance_role]
‘unknown’: unknown terminal type.
很不幸,这是vagrant的一个bug,详情参考 commit#77a1b9a6efe4f5cdc993
解决方法,更新vagrant至0.7.3,不过,这个版本还没有发布,只能先手动修改本地gem的代码了
FATAL: No cookbook found in [“/tmp/vagrant-chef/cookbooks-0”, “/tmp/vagrant-chef/cookbooks”], make sure cookbook_path is set correctly.
这是vagrant的一个bug,详情请看
https://github.com/mitchellh/vagrant/issues#issue/308
https://github.com/mitchellh/vagrant/issues/closed#issue/297
不影响使用,作者正在修复…
运行chef-solo过程的其他错误?
#登录虚拟机 vagrant ssh #在虚拟机运行chef-solo,显示更显示的debug信息 cd /tmp/vagrant-chef sudo chef-solo -c solo.rb -j dna.json -l debug
如果希望vagrant命令运行时都显示详细信息,可以配置Vagrantfile
config.vm.provision :chef_solo do |chef|
chef.log_level = :debug
end
参考资源
Vagrant官网
chef_solo配置
client.pem error
Creating An Ubuntu 10.10 x32 Vagrant Box
Setting up a Vagrant VM for TriSano
opscode vagrant