JT's Blog

Do the right things and do the things right.

使用Vagrant 操作Virtaul Boxes

| Comments

vagrant_virtulaBox

Why Vagrant + Virtual Box

學習Rails 的過程,會使用Mac 的Parallels Desktop 建立Ubuntu 當作Production,使用幾次之後覺得有點麻煩,如果要再擴大系統架構,就玩不下去了,於是google 搜尋找到了Vagrant + Virtual Box 的組合,覺得這是不錯的組合,寫篇文章紀錄一下

Installtion

安裝Vagrant, Virtual 這兩套軟體

概念

Box 可以從Vagrant網站下載,Box 是Virtual Box 專用的,表示一個Virtual Machine (VM),而官方提供的Box 又稱為Base,也就是最基本的VM

新增 Box

可以到官網 查詢要用什麼box_name (vm)

這次介紹使用 ubuntu/trusty64

1
2
3
$ vagrant box add [box_name]
# e.g.
$ vagrant box add ubuntu/trusty64

初始化

這邊有點抽象不太好理解,可能多操作幾次,就可以理解接下來說明的內容

每初始一個VM 都會建立一個對應的Vagrantfile,而這VM 已與原本的Base 衍生出來(或解讀為Base 的Instance)

1
2
3
4
$ mkdir vagrant-test && cd vagrant-test
$ vagrant init [box_name]
# e.g.
$ vagrant init ubuntu/trusty64

Configuration of Vagrantfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  # 預設是true
  # 不檢查更新版本
  # config.vm.box_check_update = false

  # 設定使用的 Box
  config.vm.box = "ubuntu/trusty64"

  # 設定虛擬主機的所使用的記憶體,可以避免在虛擬主機 bundle install 時,記憶體不足的錯誤
  config.vm.provider :virtualbox do |vb|
    vb.customize ["modifyvm", :id, "--memory", "1024"]
  end

  # 設定虛擬主機僅供自己使用的 ip (注意設跟自己的虛擬ip 同一個網域)
  config.vm.network :private_network, ip: "10.10.10.10"

  # 設定主機名稱
  config.vm.hostname = "ubuntu-rails"

  # Forward the Rails server default port to the host
  config.vm.network "forwarded_port", guest: 80, host: 8080

  # Forward the Redis default port to the host
  # config.vm.network "forwarded_port", guest: 6379, host: 6379

end

操作指令

開機

1
$ vagrant up

使用ssh 連線到VM

1
$ vagrant ssh

重開 (修改 vagrantfile 後需要重開)

1
$ vagrant reload

暫停 <-> 恢復

1
2
$ vagrant suspend
$ vagrant resume

關機

1
$ vagrant halt

Others

VM 狀態

1
$ vagrant status

列出box 清單

1
$ vagrant box list

查看所有指令清單

1
$ vagrant list-commands

Provisioners

Vagrant 允許使用Provisioner 自動安裝或調整設定內容,就是在啟動VM 之後,執行已設定的腳本或軟體

Vagrant 提供三種自動化 provisioning 機制:

  • inline script(內嵌腳本)
  • external script file(外部腳本檔)
  • configuration management software(組態管理軟體)

在Vagrantfile 中設定要使用哪種provision

1
2
3
4
5
6
7
8
9
10
# inline script
config.vm.provision "shell", inline: "nginx -v"

# external script file
config.vm.provision "shell", path: "check_env.sh"

# configuration management software
config.vm.provision "chef_solo" do |chef|
    # ...
  end

打包自己專用的BOX

如果每個VM 都要因應不同需求安裝對應的軟體,實在非常費時費工

可以透過package 把已經設定好的VM 打包變成Box,如果日後有需求,可以根據此Box 初始一個新的VM

1
2
3
4
5
6
7
8
9
10
# 指令會在你目前的資料夾下建立一個myFirstVM.box
$ vagrant package --output myFirstVM.box

# 將box 加入清單
$ vagrant box add [box_name] myFirstVM.box
# e.g.
$ vagrant box add ubuntu-nginx-rails-redis myFirstVM.box

# 初始化
$ vagrant init ubuntu-nginx-rails-redis

多機環境

只有一個VM 是還不夠的,Vagrant 是很強大的,可以在Vagrantfile 設定多主機的環境

以下示範建立 app * 1 + db * 1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  # as rails-app
  config.vm.define :app do |app_config|
    app_config.vm.provider :virtualbox do |vb|
      vb.customize ["modifyvm", :id, "--memory", "512"]
    end

    app_config.vm.box = "ubuntu/trusty64"
    app_config.vm.host_name = "app"
    app_config.vm.network :private_network, ip: "10.10.10.10"
  end

  # as mysql database
  config.vm.define :db do |db_config|
    db_config.vm.provider :virtualbox do |vb|
        vb.customize ["modifyvm", :id, "--memory", "512"]
      end
    db_config.vm.box = "ubuntu/trusty64"
    db_config.vm.host_name = "db"
    db_config.vm.network :private_network, ip: "10.10.10.11"
  end
end

後記

  • 指令不熟悉可以透過 vagrant -h 找到答案
  • vagrant 是非常強大的工具,也可以串接AWS 或 Docker,有空再來寫篇文章吧

Reference

Comments