Vagrant 是一個管理 Virtual Machine 的 command line utility 工具。最初支援 VirtualBox,但現在也支援了 docker、Parallels、VMWare。
安裝
先安裝 VirtualBox: Download VirtualBox。
然後在 Download Vagrant,根據不同 OS 下載 binary 套件直接安裝就好了。
vagrant CLI
vagrant 本身是一個 CLI tool,目的是為了能在 script 直接操作並使用 VM,能夠讓系統安裝及測試自動化。
如果需要一個的 CentOS 7 VM 可以用以下指令處理,vagrant 有個集中分享的 Vagrant Cloud repository,我們可以直接搜尋centos7 找到適合與最多人使用的 VM。
我們使用 geerlingguy/centos7 Vagrant box VM
mkdir vagrant_centos7
cd vagrant_centos7
# 以 init 指令下載 centos 7 Vagrantfile
vagrant init geerlingguy/centos7
# 啟動 VM
vagrant up
# VM 關機
vagrant halt
# 刪除 VM
vagrant destroy
# 查詢 VM 狀態
vagrant status
# 查看 ssh 資訊
vagrant ssh-config
其他常用的指令
# 列出所有 vagrant VMs
vagrant box list
# guest OS 及 host OS 的 port 對應表
vagrant port
22 (guest) => 2222 (host)
# 以 ssh 登入 VM
vagrant ssh
Vagrantfile
剛剛使用的 CentOS 7 VM Vagranfile source code 也是透過定義 Vagrantfile 再分享到 Cloud。
而我們的 Vagrantfile 只需要這樣的設定,就能夠引用 geerlingguy 的 centos7
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "geerlingguy/centos7"
end
被引用的 Vagratfile 定義會被下載到 ~/.vagrant.d 這個目錄中,可在 boxes 目錄找到相關資訊
~/.vagrant.d/boxes/geerlingguy-VAGRANTSLASH-centos7
Vagrantfile 是採用 ruby 語法,當我們在某個目錄 (/Users/user/VirtualBoxVMs/vagrant_centos7/) 執行 vagrant 指令時,他會依照以下順序尋找 Vagrantfile
/Users/user/VirtualBoxVMs/vagrant_centos7/Vagrantfile
/Users/user/VirtualBoxVMs/Vagrantfile
/Users/user/Vagrantfile
/Users/Vagrantfile
/Vagrantfile
- Configuration Version
Vagrant.configure 後面的數字,代表不同版本的 vagrant 語法,
- "1" 表示為 1.0.x 的語法
- "2" 表示為 1.1+ 到 2.0 版的語法
Vagrant.configure("2") do |config|
# ...
end
- Networking
VM 的網路設定決定了 VM 跟 host machine 的溝通介面,網路部分分為三種,Forwarded Ports、Private Network及 Public Network。
Forwarded Ports: forwarded_port
可開放 guest machine 的某個 Port,並轉換到 host machine 的另一個 Port,TCP 或 UDP 都可以。
guest machine 啟動了一個 web server,運作在 TCP Port 80,可 forward 到 host machine 的 TCP 8080
config.vm.network "forwarded_port", guest: 80, host: 8080
跟上面一樣,將 TCP 80 forward 到 TCP 8080,同時限制只能用 127.0.0.1 存取 8080 這個 forwarded port 設定,也可以加上 TCP/UDP 的 protocol 限制,預設為 TCP。
config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1", protocol: "tcp"
Private Network
可透過 Internet 無法使用的 IP 存取 guest machine,在 VM 的網路設定通常稱為 NAT
DHCP
config.vm.network "private_network", type: "dhcp"
Static IP
config.vm.network "private_network", ip: "192.168.50.4"
IPv6
config.vm.network "private_network", ip: "fde4:8dba:82e1::c4"
# 加上 netmask
config.vm.network "private_network",
ip: "fde4:8dba:82e1::c4",
netmask: "96"
Public Network
在 VM 的網路設定通常稱為 Bridge network,就是讓 VM 直接取得可讓其他機器存取的網路設定。
DHCP
config.vm.network "public_network" # 使用 DHCP 的設定作為 default route config.vm.network "public_network", use_dhcp_assigned_default_route: true
Static IP
config.vm.network "public_network", ip: "192.168.0.17"
如果 host machine 有多個網路介面,在啟動 vagrant VM 時,會詢問要使用哪一個網路介面,可以在設定 Public Netork 時,直接決定是用哪一個網路介面。
config.vm.network "public_network", bridge: "en1: Wi-Fi (AirPort)"
# 可指定多個網路介面
config.vm.network "public_network", bridge: [
"en1: Wi-Fi (AirPort)",
"en6: Broadcom NetXtreme Gigabit Ethernet Controller",
]
可利用 shell 指令設定 ip
Vagrant.configure("2") do |config|
config.vm.network "public_network", auto_config: false
# manual ip
config.vm.provision "shell",
run: "always",
inline: "ifconfig eth1 192.168.0.17 netmask 255.255.255.0 up"
# manual ipv6
config.vm.provision "shell",
run: "always",
inline: "ifconfig eth1 inet6 add fc00::17/7"
end
設定固定 IP 以及 default route
Vagrant.configure("2") do |config|
config.vm.network "public_network", ip: "192.168.0.17"
# default router
config.vm.provision "shell",
run: "always",
inline: "route add default gw 192.168.0.1"
# default router ipv6
config.vm.provision "shell",
run: "always",
inline: "route -A inet6 add default gw fc00::1 eth1"
# delete default gw on eth0
config.vm.provision "shell",
run: "always",
inline: "eval `route -n | awk '{ if ($8 ==\"eth0\" && $2 != \"0.0.0.0\") print \"route del default gw \" $2; }'`"
end
- Synced Folders
可在 guest 及 host machine 之間共用資料夾,vagrant 預設會分享 project 目錄,也就是存放 Vagrantfile 的目錄到 /vagrant。
# 前面是 host machine folder,後面是 guest machine path
config.vm.synced_folder "src/", "/srv/website"
# disable default /vagrant shared folder
config.vm.synced_folder ".", "/vagrant", disabled: true
# 修改 folder owner, group
config.vm.synced_folder "src/", "/srv/website",
owner: "root", group: "root"
也可以使用 NFS、RSync或是 SMB 這三種 protocol
- Provisioning
這是在啟動 VM 時,自動安裝軟體、修改設定的功能。當 VM box 需要微調時,可以利用這個功能進行調整。Provisioning 可使用 shell script, ansible, chef, puppet, salt, docker 等指令,比較基本的是直接用 shell scripts。
Provisioning 會在這三個時間點發生作用
第一次以 vagrant up 啟動 VM,Provisioning 會有作用,但如果是已經啟動過的 VM,就不會執行 provisioning,但可用 --provision 強制執行。
在 VM 運作中,執行
vagrant provision
執行
vagrant reload --provision
Vagrant Shell provisioner 可在 guest machine 執行某個 script。
Inline Scripts
直接在 Vagrantfile 撰寫 scipt command
Vagrant.configure("2") do |config|
config.vm.provision "shell",
inline: "echo Hello, World"
end
在上面定義 script,然後在 config.vm.provision 中執行
$script = <<SCRIPT
echo I am provisioning...
date > /etc/vagrant_provisioned_at
SCRIPT
Vagrant.configure("2") do |config|
config.vm.provision "shell", inline: $script
end
External Script
可執行 host machine 的某一個 shell script,也可以用某個網址下載 script
Vagrant.configure("2") do |config|
config.vm.provision "shell", path: "script.sh"
end
Vagrant.configure("2") do |config|
config.vm.provision "shell", path: "https://example.com/provisioner.sh"
end
如果要執行 guest machine 的 script
Vagrant.configure("2") do |config|
config.vm.provision "shell",
inline: "/bin/sh /path/to/the/script/already/on/the/guest.sh"
end
Script Arguments
利用 args 指定 script 參數
Vagrant.configure("2") do |config|
config.vm.provision "shell" do |s|
s.inline = "echo $1"
s.args = "'hello, world!'"
end
end
Vagrant.configure("2") do |config|
config.vm.provision "shell" do |s|
s.inline = "echo $1"
s.args = ["hello, world!"]
end
end
- Multi-Machines
Multi-Machines 功能可在一個 Vagrantfile 中定義多個 guest machines。
定義兩個機器,一台是 web,一台是 db
Vagrant.configure("2") do |config|
config.vm.provision "shell", inline: "echo Hello"
config.vm.define "web" do |web|
web.vm.box = "apache"
end
config.vm.define "db" do |db|
db.vm.box = "mysql"
end
end
執行 vagrant up
會同啟動 web 及 db,也可以用 vagrant up web
只啟動 web
Reference
Vagrant Tutorial(1)雲端研發人員,你也需要虛擬機!
Vagrant Tutorial(4)虛擬機,若即若離的國中之國
Vagrant Tutorial(5)客製化虛擬機內容的幾種方法
沒有留言:
張貼留言