Vagrant让虚拟化技术走近寻常家。脚踏实地地说,网络上相似“两分钟入门”的文章有很多,但求助各类问题的帖子更多,由于vagrant官网的文档太简洁了,这里头有些道理有些坑,都没涉及到。即使是O’Reilly两天前出版的 《Vagrant: Up and Running》 也含糊着某些问题。于是在Google了各类的前人零碎经验的基础上、以本身实践证实以后,有了我这篇文章,但愿对涉及到的这些问题能汇总知识作一个澄清,并给读者一个可操做的指导。html
简单点说,三步走:linux
满共就三个命令,有些人玩到这就以为已经伟大的不得了了,至此ssh上VM各类虐。web
你还差得远 !shell
www.vagrantbox.es 介绍了vagrant的基础模板,并提供了知足各类需求的*.box文件供下载。apache
推荐选择 minimal + guest additions + puppet|chef 的box,理由:ubuntu
解释词汇:windows
辨析关系:centos
Vagrantfile是vagrant配置VM的起点, 官方文档 里零零散散的说明让我明白了“东西很简单,但找对不容易”这句话。网络
对Vagrantfile,有几个常问 HOWTO :ssh
一看便知。
Vagrant.configure("2") do |config| # ‘2’的意思是我所用的vagrant-1.2.2属于内部v2版 config.vm.define :web do |web_config| # 设置此VM名称为web web_config.vm.box = "apache-centos" # 指定使用已安装的名为“apache-centos”的vagrant box end end
config.vm.network :private_network, ip: "192.168.50.4"
config.vm.network :public_network # vagrant-1.2.2以后的版本可能改用 :bridged
config.vm.provision :shell, :inline => "ifconfig" # inline script config.vm.provision :shell, :path => "initialize.sh" # external script
尤为对不连外网的VM,咱们辛苦建了它却不能访问它的端口,那要它何用?防火墙是阻止端口访问的罪魁,索性关了它吧。
Centos/Redhat/Fedora 用iptables管理firewall,因此两个办法搞掉它
$ sudo service iptables save $ sudo service iptables stop $ sudo iptables off
$ sudo iptables -F $ sudo iptables -X $ sudo service iptables save
Ubuntu 用ufw管理firewall,关掉它就是了, 参考
$ sudo ufw disable
ssh端口默认22,那位说“为何我要改它呢”,我例举一个场景:
假如你要开发一个包含SFTP server的应用。为了给使用者提供便利,你最好保留22端口给用户,使他能使用默认方式经过SFTP传文件。同时,你要将这个应用部署到VM上作测试,那么VM的ssh login就不能同时也用22端口了,你须要为它指定新端口,如 10022。
难点在于下面的约束条件:
坑是挺多的吧?Vagrantfile的 ssh settings参考 和 forwarded ports参考 可没把这事儿说这么清楚。
解决问题需要分几步走:
Step1: 在Vagrantfile中为VM的新端口作端口映射
config.vm.network :forwarded_port, guest: 10022, host: 2255 # config.ssh.port = 2255 # port of host # commented in step1 # config.ssh.guest_port = 10022 # port of VM # commented in step1
Step2: VM上修改ssh使用的端口到新端口
:%s/#Port 22/Port 10022/g :wq
$ sudo service sshd restart
Step3: 在Vagrantfile中指定ssh login时使用VM的新端口
config.vm.network :forwarded_port, guest: 10022, host: 2255 config.ssh.port = 2255 # port of host # uncommented in step3 config.ssh.guest_port = 10022 # port of VM # uncommented in step3
Step4 [optional]: 创建新基础模板以固化上述更改
使用vagrant package命令将改过端口的VM保存为box文件。由这个新基础模板所产生的VM中,10022即为ssh访问端口,使用上述的Vagrantfile可直接经过vagrant ssh访问。
vagrant package <vm-name> --output <new-base.box>
生成新*.box文件前须清理网络设置上的障碍。详见下文。
将手动配置过的VM从新打包生成*.box文件做为新基础模板,在这件事上对linux-based的VM有个关于网络设置的障碍。
例如设置了private network(等同于virtualbox设置host-only模式的网络适配器)的VM,若不作准备而直接使用vagrant package生成新box文件,那么安装此box文件到vagrant box后在启动VM时,会发现当前Vagrantfile指定的private network配置失败。
[default] Configuring and enabling network interfaces…
The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!/sbin/ifup eth1 2> /dev/null
被启动的VM以让能够经过vagrant ssh命令去访问,但网络配置上却没有host-only模式的适配器。
还记得配置private network时设置的固定ip地址么?是的,问题就在持久网络设备udev规则(persistent network device udev rules)是被原VM设置好的,再用box生成新VM时,这些rules须要被更新。而这和Vagrantfile里对新VM设置private network的指令发生冲突。
既然之后在Vagrantfile里显示地设置private network ip是免不了的,那么只要在生成box文件前干掉udev规则就是了。
sudo rm -f /etc/udev/rule.d/70-persistent-net.rules
有趣的是这篇 参考 细述了这个问题的因果与对策,反却是O’Reilly出版的 《Vagrant: Up and Running》 一书中(第6章)对此含糊带过。
该书计划于2013年6月12日出版。试读版中尚仍有对过期命令的介绍(如“repackage”),但愿正书出来了不会当即过期。
学习的话, 官网文档 仍是应该对照的。
Virtualbox共享目录须要VM上装有Guest Additions。本身安装到VM再打包成box文件作基础模板,或者一开始就找好合适的box文件(前文提到过),随便你怎么整好。
vagrant 默认将宿主机上Vagrantfile所载目录共享至VM上的 /vagrant 目录。
咱们常须要的是指定共享某个目录,为此vagrant 支持两种方式:
vboxsf是 V irtual boxS hared F older(或 VboxS hared F older)的缩写。不少人知道能够指定vboxsf做类型来mount,殊不知这个这个词全称,甚至误解为“虚拟机文件系统”而错写成vboxfs。
vagrant默认使用这种方式共享目录。优势方便,缺点是性能很差。配置时,只要在Vagrantfile里指明:
config.vm.synced_folder "path/on/host", "/absolute/path/on/vm"
NFS是正途,不过它也挑剔。
vagrant 内置了宿主机和VM两端对NFS的支持与配置的协调。若是你用windows,那vagrant看成你的配置不存在,直接忽略(我也以为你在瞎胡闹)。Vagrantfile里很容易,标上标记就好了:
config.vm.synced_folder "path/on/host", "/absolute/path/on/vm", :nfs => true
NFS的共享目录这种方式的挑剔之处在于目录内的读写权限。
以创建宿主机与VM的共享存储这个应用场景为例,目标是:
若是你在宿主机建 /shared ,而后直接配置关联,那对上述两个目标你都会失败。按我说的步骤来吧:
$ sudo chmod o+w /shared
$ sudo chown <user>:<group> /shared
config.vm.synced_folder "/shared", "/shared", :nfs => true
这样获得的共享目录对场景设定的目标已大功告成了:
虽然vagrant支持在一个Vagrantfile中配置多个VM,但我我的喜欢为各VM写各自的Vagrantfile。
不过真正的牛人没我这么小家子气。用统一的一个Vagrantfile来管理多个VM,从大局着眼确是有好处的: