vagrant 做測試環(huán)境的一點總結(jié)(下)
生活不會因為某個節(jié)點而變得與眾不同,未來的幸運,都是過往努力的積攢。
vagrant 是我在本地 osx 系統(tǒng)下做測試環(huán)境時候開始研究的,以前只是單一的用 vbox 裝個本地虛機時并沒有發(fā)覺用或者不用有什么差別,但隨著本地開始有一些特殊需求的時候,才發(fā)覺 vagrant 提供的功能還是很值得稱贊的。
provisioning
類似于開機啟動,可以開機執(zhí)行某個命令,可以執(zhí)行某個腳本都可以
比如我想在開機后自動安裝某個包,同步下時間,那么如果是 vbox 的虛機可能你得連到虛機里,然后在/etc/rc.local下寫上命令等等,但在 Vagrantfile 里,可以直接以配置的形式體現(xiàn),下面這段是配置里自帶的一段,開機自動更新包,安裝 Apache
- config.vm.provision "shell", inline: <<-SHELL
- apt-get update
- apt-get install -y apache2
- SHELL
所以只要把中間那部分換成自己的命令就好,但是如果命令太長,還有邏輯判斷,***是開機執(zhí)行個腳本,那在配置文件里應(yīng)該這樣寫
- config.vm.provision :shell, path: "<scriptname.sh>"
注意這里的路徑是以Vagrantfile所在的目錄為根目錄的,上述的寫法,腳本就必須存放在和 Vagrantfile同級就可以
vagrant 創(chuàng)建集群
如果是 vbox 或者是 VMware 的話,模擬一個集群方法就是多建幾個虛機環(huán)境,然后打通內(nèi)網(wǎng),無論是 clone 還是新建都還挺麻煩的,但是 vagrant 靠一個配置文件就可以完成,這里直接引用 go-best-practice 里的這段話
Vagrant支持單機模擬多臺機器,而且支持一個配置文件Vagrntfile就可以跑分布式系統(tǒng)。這種多機器模式特別適合以下幾種人:
快速建立產(chǎn)品網(wǎng)絡(luò)的多機器環(huán)境,例如web服務(wù)器、db服務(wù)器
建立一個分布式系統(tǒng),學習他們是如何交互的
測試API和其他組件的通信
容災(zāi)模擬,網(wǎng)絡(luò)斷網(wǎng)、機器死機、連接超時等情況
現(xiàn)在我們來建立多臺VM跑起來,並且讓他們之間能夠相通信,假設(shè)一臺是應(yīng)用服務(wù)器、一臺是DB服務(wù)器,那么這個結(jié)構(gòu)在Vagrant中非常簡單,其實和單臺的配置差不多,你只需要通過config.vm.define來定義不同的角色就可以了,現(xiàn)在我們打開配置文件進行如下設(shè)置:
- Vagrant.configure("2") do |config|
- config.vm.define :web do |web|
- web.vm.provider "virtualbox" do |v|
- v.customize ["modifyvm", :id, "--name", "web", "--memory", "512"]
- end
- web.vm.box = "base"
- web.vm.hostname = "web"
- web.vm.network :private_network, ip: "11.11.1.1"
- end
- config.vm.define :db do |db|
- db.vm.provider "virtualbox" do |v|
- v.customize ["modifyvm", :id, "--name", "db", "--memory", "512"]
- end
- db.vm.box = "base"
- db.vm.hostname = "db"
- db.vm.network :private_network, ip: "11.11.1.2"
- end
- end
這里的設(shè)置和前面我們單機設(shè)置配置類似,只是我們使用了:web以及:db分別做了兩個VM的設(shè)置,并且給每個VM設(shè)置了不同的hostname和IP,設(shè)置好之后再使用vagrant up將虛擬機跑起來:
再次啟動并連接,連接并需要指定角色即可
- $ vagrant up
- $ vagrant ssh web
- vagrant@web:~$
- $ vagrant ssh db
- vagrant@db:~$
批量生成機器
上面的情況適合于想建立個小集群,用于特定的環(huán)境,而現(xiàn)在有個需求想一次性生成10臺機器,用上面的方法就略顯復(fù)雜了,得寫一大串配置文件,顯得臃腫,不過 vagrant 也提供了特定的方式
以下這個配置來源于 https://jacobustczhi.gitbooks.io/-vagrant/content/chapter.html
- Vagrant.configure("2") do |config|
- # The most common configuration options are documented and commented below.
- # For a complete reference, please see the online documentation at
- # https://docs.vagrantup.com.
- # Every Vagrant development environment requires a box. You can search for
- # boxes at https://atlas.hashicorp.com/search.
- (0..10).each do |i|
- config.vm.define "node#{i}" do |node|
- # 設(shè)置虛擬機的Box
- node.vm.box = "ubuntu/trusty64"
- # 設(shè)置虛擬機的主機名
- node.vm.hostname="node#{i}"
- # 設(shè)置虛擬機的IP
- node.vm.network "public_network", bridge: "eno1", ip: "192.168.17.20#{i}"
- # VirtaulBox相關(guān)配置
- node.vm.provider "virtualbox" do |v|
- v.name = "node#{i}"
- v.memory = 1024
- v.cpus = 1
- end
- end
- if ARGV[0] == "up" && ! File.exist?("./disk1.vdi")
- # 運行腳本增加swap空間
- config.vm.provision "shell", path: "increase_swap.sh"
- end
- end
- end
可以看到,與創(chuàng)建單個虛擬機相比,這里多了層循環(huán),而變量 i 可以用于設(shè)置節(jié)點的名稱與IP,使用#{i}取值:
- (0..10).each do |i|
- end
plugin
根據(jù)網(wǎng)友KiwenLau的文章里提到了一個錯誤
VirtualBox 設(shè)置共享目錄時需要在虛擬機中安裝VirtualBox Guest Additions,這個 Vagrant會自動安裝。但是,VirtualBox Guest Additions是內(nèi)核模塊,當虛擬機的內(nèi)核升級之后,VirtualBox Guest Additions會失效,導致共享目錄掛載失敗,出錯信息如下:
- Failed to mount folders in Linux guest. This is usually because
- the “vboxsf” file system is not available. Please verify that
- the guest additions are properly installed in the guest and
- can work properly. The command attempted was:
- mount -t vboxsf -o uid=id -u vagrant,gid=getent group vagrant | cut -d: -f3 vagrant /vagrant
- mount -t vboxsf -o uid=id -u vagrant,gid=id -g vagrant vagrant /vagrant
- The error output from the last command was:
- stdin: is not a tty
- /sbin/mount.vboxsf: mounting failed with the error: No such device
安裝 Vagrant 插件vagrant-vbguest可以解決這個問題,因為該插件會在虛擬機內(nèi)核升級之后重新安裝VirtualBox Guest Additions。
- $ vagrant plugin install vagrant-vbguest