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,從大局着眼確是有好處的: