vagreant tutorial

vagreant tutorial

this tutorial base on vagrant-tutorial and suit for ~> 1.2 vagrant, thanks author @gogojimmy

what is vagreant

Vagrant is a tool for building and distributing virtualized development environments.

install vagreant

Vagrant 背後用的是 Virtual Box 作為虛擬機器, Vagrant 只是一個讓你可以方面做設定來開你想要的虛擬機器的方便工具, 所以你必須先安裝 Vagrant 和 Virtual Box, Virtual Box 你可以在Virtual Box 官網下載適合你平台的版本,而 Vagrant 你可以在 Vagrant 官網下載打包好的版本,或是如果你跟我一樣是個玉樹臨風的 Rubist, 你可以打開我們最愛的小黑視窗輸入

$ gem install vagrant # not recomment

Vagrant 1.1後已經不支援使用Gem來安裝了 http://mitchellh.com/abandoning-rubygems

$# wget http://files.vagrantup.com/packages/7e400d00a3c5a0fdf2809c8b5001a035415a607b/vagrant_1.2.2_i686.deb -O ~/Downloads/vagrant_1.2.2_i686.deb && sudo dpkg -i ~/Downloads/vagrant_1.2.2_i686.deb
$ wget http://files.vagrantup.com/packages/7e400d00a3c5a0fdf2809c8b5001a035415a607b/vagrant_1.2.2_i686.deb -P ~/Downloads/ && sudo dpkg -i ~/Downloads/vagrant_1.2.2_i686.deb

開始使用Vagrant 新增作業系統

當你已經安裝好 Virtual Box 以及 Vagrant 後,你要開始思考你想要在你的VM上使用什麼作業系統,一個打包好的作業系統環境在 Vagrant 稱之為 Box,也就是說每個 Box 都是一個打包好的作業系統環境,當然網路上什麼都有,你不用自己去找作業系統,vagrantbox.es 上面就有許多大家熟知且已經打包好的作業系統,你只需要下載就可以了,為你的Vagrant增加一個 Box 很簡單

# Vagrant version 1.2.2 should use bellow
$ vagrant box add {你想要的Box名稱} {下載網址}
# vagrant box add ubuntu-13-04 ~/raring-server-cloudimg-amd64-vagrant-disk.box
# vagrant box add ubuntu-13-04 raring-server-cloudimg-amd64-vagrant-disk.box
$ vagrant box add ubuntu-13-04  http://cloud-images.ubuntu.com/raring/current/raring-server-cloudimg-vagrant-amd64-disk1.box

# not work for francis
$ vagrant box add ubuntu-13-04 http://cloud-images.ubuntu.com/raring/current/raring-server-cloudimg-vagrant-amd64-disk1.box
vagrant box list
#vagrant box remove ubuntu-12-10 virtualbox

# box add centos-6_4-x86_64 CentOS-6.4-x86_64.box
# box add centos-6_4-x86_64 CentOS-6.4-x86_64.box

Vagrant 就會開始下載這個 Box,你可以用vagrant box list這個指令看到你所擁有的所有 Box,想像就是你的書架上多了一片 Ubuntu 12.10 的安裝光碟,以後要安裝機器就是用這的安裝就可以了,有了Box以後,我們要產生一個設定檔來設定我們的虛擬機器,這個檔案可以透過指令 vagrant init Box名稱來產生,你可以在你的專案中或是另外開個練習用的資料夾輸入,這時候你的資料夾終究會有一個名稱為vagrantfile的檔案,這個檔案就是所有魔法的開始

$ mkdir vagrant-boxes && cd vagrant-boxes
vagrant init ubuntu-13-04
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

讓VM動起來

我們晚一點再提設定檔的部份,讓我們先把VM跑起來,要讓VM跑起來的指令是vagrant up

#vagrant destroy &&VAGRANT_LOG=DEBUG vagrant up
VAGRANT_LOG=DEBUG vagrant up
vagrant 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`.

known issue https://github.com/mitchellh/vagrant/issues/455

sudo rm /etc/udev/rules.d/70-persistent-net.rules
sudo touch /etc/udev/rules.d/70-persistent-net.rules
sudo ufw allow 2222
sudo ufw disable

#Vagrantfile
Vagrant::Config.run do |config|
  config.vm.network :bridged, :bridge => "en0: Wi-Fi (AirPort)"
end

#http://docs-v1.vagrantup.com/v1/docs/config/ssh/port.html

將習慣的環境打包成Box

我的環境大概要裝15分鐘左右, 有人說一個程式設計師的人生花最多時間的一件事情就是等, 這個說法真是一點也不為過, 每次裝機都從環境重新開始 Build 也不是辦法,我們要讓人生有更多的時間去處理更多的事情, 所以我們可以把一個已經Build好的環境打包成一個我們自己的 Box, 以後我們只要直接使用這個打包好的版本就可以了, 因此讓我們幫自己的人生省點時間, 速速登出VM來打包這個 Box

$ vagrant 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: /home/jhjguxin/vagrant-boxes/ubuntu-server-12042/package.box

vagrant package 這個指令會在你目前的資料夾下建立一個 package.box 的 Box 檔案, 這時候我們跟剛剛一樣把它加入到我們的Box List中, 以後我們就可以快速使用這個 Box 就好了! 除此之外, 可以自定 Box 的意義還有讓你的團隊都能用VM來擁有自己的 Staging 環境,例如在 Rails 專案中我們也可以建立一個 Vagrant 的設定檔來做一個給開發人員測試用的 Staging 環境, 這時候你就可以指定好你自定的機器設定, 確保每個開發人員都能擁有一樣的環境來進行開發.

$ vagrant box add francis-ubuntu-server-12042 package.box
$ vagrant box list

Vagrant 基本設定

設定VM的名稱及記憶體

config.vm.box = "francis-ubuntu-server-12042"

這告訴了 Vagrant 要去套用哪個 Box 作為環境, 也就是你一開始輸入 varant init Box名稱時所指定的Box, 如果沒有輸入Box名稱的話就會是預設的base, Virtual Box本身提供了VBoxManage這個command line tool讓你可以設定你的VM, 用 modifyvm 這個指令讓你可以設定VM的名稱及記憶體大小等等,這裡說的名稱指的是在Virtual Box中顯示的名稱,我們也可以在 VagrantFile 中進行設定,在你的 vagrantfile 中加入這行

config.vm.customize ["modifyvm", :id, "--name", "francis-ubuntu-server-12042", "--memory", "512"]

行設定檔意思就是呼叫 VBoxManage 的 modifyvm 的指令, 設定VM的名稱為 `francis-ubuntu-server-12042′ 而設定VM的記憶體大小為 512MB,你可以照這這種作法為你的 VM 設定好不同的設定.

設定 Hostname 以及 Port forward

# 設定 hostname 非常重要,有很多服務都仰賴著 hostname 來做為辨識,例如Puppet或是Chef,一般一些監控服務像是New Relic之類的也都是以 hostname 來做為辨識
config.vm.host_name = "gogojimmy-app"
# 把Host機器上8080 port傳來的東西forward到VM跑的 80 port的服務
config.vm.forward_port 80, 8080

設定網路橋接方式

Vagrant有兩種橋接方式是, 一種是host only, 意思是說在你電腦同個區網中的其他電腦是看不到你的VM的, 只有你一個人自 High, 另一種是Bridge, 當然就是說VM會跟你區網的router去要一組 IP, 區網中的其他電腦也都能看到他, 般來說因為開 VM 的情況都是自 High居多, 因此我們在設定上都是設定host only:

config.vm.network :hostonly, "33.33.13.10"

這邊將網路設定成 hostonly, 並且指定一組 IP 位址, IP 位址的設定會建議不要使用 192.168.. 的設定, 因為很有可能會跟你區網的IP衝突, 你可以改使用像是 33.33.. 的設定.

更改vagrantfile的設定後,記得要用vagrant reload的指令重開VM讓VM可以用新的設定檔跑起來

讓我們開始打造多機器環境

重頭戲來了, 前面的一切都是為了今天鋪陳, 現在我們要建立多個 VM 跑起來,並且讓他們互相溝通, 有人跑 Application, 有人跑DB, 有人跑Memcached, 這一切在 Vagrant 中非常簡單, 跟剛剛的設定都一樣, 你只需要指定好機器的角色就可以了, 讓我們再次打開我們的設定檔來設定一台APP Server加上一台DB Server:

# for v1 ~> 1.1
config.vm.define :app do |app_config|
    app_config.vm.customize ["modifyvm", :id, "--name", "app", "--memory", "512"]
    app_config.vm.box = "ubuntu-server-12042"
    app_config.vm.host_name = "app"
    app_config.vm.network :hostonly, "33.33.13.10"
end
config.vm.define :db do |db_config|
  db_config.vm.customize ["modifyvm", :id, "--name", "db", "--memory", "512"]
  db_config.vm.box = "ubuntu-server-12042"
  db_config.vm.host_name = "db"
  db_config.vm.network :hostonly, "33.33.13.11"
end

# for v2 ~> 1.2
config.vm.provision :shell, :inline => "echo Hello"
config.vm.define :app do |app_config|
  app_config.vm.provider "virtualbox" do |v|
    v.customize ["modifyvm", :id, "--name", "app", "--memory", "512"]
  end
  app_config.vm.box = "ubuntu-server-12042"
  app_config.vm.hostname = "app"
  app_config.vm.network :private_network, ip: "33.33.13.10"
end
config.vm.define :db do |db_config|
  db_config.vm.provider "virtualbox" do |v|
    v.customize ["modifyvm", :id, "--name", "db", "--memory", "512"]
  end
  db_config.vm.box = "ubuntu-server-12042"
  db_config.vm.hostname = "db"
  db_config.vm.network :private_network, ip: "33.33.13.11"
end

這邊的設定就像是剛剛在設定的部份教的一樣, 只是我們使用了 :app 以及:db 分別做了兩個 VM 的設定, 並且給予不同的 hostname 和IP, 設定好了以後再使用 vagrant up 將機器跑起來:

$ vagrant up
Bringing machine 'app' up with 'virtualbox' provider...
Bringing machine 'db' up with 'virtualbox' provider...
[app] Importing base box 'ubuntu-server-12042'...
[app] Matching MAC address for NAT networking...
[app] Setting the name of the VM...
[app] Clearing any previously set forwarded ports...
[app] Creating shared folders metadata...
[app] Clearing any previously set network interfaces...
[app] Preparing network interfaces based on configuration...
[app] Forwarding ports...
[app] -- 22 => 2222 (adapter 1)
[app] Running any VM customizations...
[app] Booting VM...
[app] Waiting for VM to boot. This can take a few minutes.
[app] VM booted and ready for use!
[app] Setting hostname...
[app] Configuring and enabling network interfaces...
[app] Mounting shared folders...
[app] -- /vagrant
[db] Importing base box 'ubuntu-server-12042'...
[db] Matching MAC address for NAT networking...
[db] Setting the name of the VM...
[db] Clearing any previously set forwarded ports...
[db] Fixed port collision for 22 => 2222. Now on port 2200.
[db] Creating shared folders metadata...
[db] Clearing any previously set network interfaces...
[db] Preparing network interfaces based on configuration...
[db] Forwarding ports...
[db] -- 22 => 2200 (adapter 1)
[db] Running any VM customizations...
[db] Booting VM...
[db] Waiting for VM to boot. This can take a few minutes.
[db] VM booted and ready for use!
[db] Setting hostname...
[db] Configuring and enabling network interfaces...
[db] Mounting shared folders...
[db] -- /vagrant

看到上面的訊息跑完後,你就可以跟剛剛一樣使用 ssh 連到VM裡,但這次不同的是你要加上你所指定的角色告訴你要連線的機器是哪一台:

$vagrant ssh app vagrant ssh app
Welcome to Ubuntu 12.04.2 LTS (GNU/Linux 3.5.0-23-generic x86_64)

 * Documentation:  https://help.ubuntu.com/
Last login: Wed Apr 10 14:03:49 2013 from 10.0.2.2
vagrant@app:~$

是不是很酷!!再來我們來驗證一下 VM 之間的連線,讓我們使用 ssh 登入 db 的機器,然後在 db 的機器上使用 ssh 來連線到 app 的機器(預設密碼就是vagrant):

看到了嗎, VM之間的溝通也是沒有問題的! 你現在可以開始好好思考你偉大的Infrastructure, 讓你的程式跑在多機器的環境中, 如果你對於 Infrastructure 不熟悉, Amazon有提供了不少範例可以參考, 想像力就是你的超能力, 現在唯一侷限你的只會是你的電腦記憶體了, 不要開到跑不動都不會有事的, 今天就開始用Vagrant練習你的機器佈署吧!