Vagrant 學習筆記

Post Directory

前言

常用的 ID 竟然有個軟體也是這個名字,所以說 不學嗎? Σ(゚д゚)

可以用工程師們都很熟悉的 Command Line 來操控 VM,並可完成自動化的安裝,學習成本也沒想像中的高,CP 值頗高的

Getting Started

$ vagrant init hashicorp/precise64
$ vagrant up

基本上就是透過 Vagarntfile 設定檔來達成自動化的動作,一開始可以通過 vagrant init 來初始化簡單的範本,或是在 vagrant init 後加上 box,等設定完後使用 vagrant up 就能啟動虛擬機了

$ vagrant init
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.

Boxes

在 Vagrant 中的 image 稱為 Boxes,下面所有講的 box 都是指 image,通常建立完 Vagrantfile 後就是產生虛擬機的 box,在起手式時已經 clone 了一個 box,所以現在使用 vagrant box list 就可以看到所有的 box 有哪些

$ vagrant box list
hashicorp/precise64 (virtualbox, 1.1.0)

也可以透過 vagrant box add 來 clone 新的 box

$ vagrant box add hashicorp/precise64

這些 box 可以透過 Vagrant Cloud 來尋找

使用 Box

開啟 Vagrantfile 你會看到

config.vm.box = "base"

可以設定使用的是哪一個 box,所以當你打開 hashicorp/precise64Vagrantfile 時你會看到

config.vm.box = "hashicorp/precise64"

這邊也可以使用 config.vm.box_version 來指定 box 版本,或是使用 config.vm.box_url 來指定 box 的 url

Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/precise64"
  config.vm.box_version = "1.1.0"
  config.vm.box_url = "http://files.vagrantup.com/precise64.box"
end

up and ssh

啟動 box

$ vagrant up

如果該虛擬機還不存在,就會根據 Vagrantfile 內的設定檔來初始化,再開機

ssh 到虛擬機

$ vagrant ssh

Synced Folders

vagrant 啟動時會預設將 Vagrantfile 位置掛載到虛擬機中的 /vagrant

Vagrant.configure("2") do |config|
  # other config here

  config.vm.synced_folder "src/", "/srv/website"
end

將本機的 src/ 目錄(相對路徑)掛載到虛擬機內的 /srv/website

Provisioning

現在你已經有最基本的虛擬機了,但所需要的環境每次都要 ssh 進去裝太慢了,Vagrant 可以利用先寫好的自動安裝環境腳本來達到自動化配置

安裝 Apache

將寫好的 bootstrap.sh 放到 Vagrantfile 跟目錄

#!/usr/bin/env bash

apt-get update
apt-get install -y apache2
if ! [ -L /var/www ]; then
  rm -rf /var/www
  ln -fs /vagrant /var/www
fi

並設定 Vagrantfile

Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/precise64"
  config.vm.provision :shell, path: "bootstrap.sh"
end

之後 vagrant up 就會看到腳本自動安裝了。如果虛擬機是開啟的狀態,可以使用 vagrant reload --provision 來重開並安裝。

Networking

Port Forwarding

將虛擬機(guest)內的 port 映射到本機(host)的 port 上,使的可以透過本機的 IP+Port 來連線到虛擬機中的 Service

Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/precise64"
  config.vm.provision :shell, path: "bootstrap.sh"
  config.vm.network :forwarded_port, guest: 80, host: 4567
end

相關參數

Port Collisions and Correction

有時候 service 一多時,可能會出現 port 相同,這時可以透過上面的 auto_correct 的參數來略過這問題

Vagrant.configure("2") do |config|
  config.vm.network "forwarded_port", guest: 80, host: 8080,
    auto_correct: true
end

Private Networks

虛擬機的私有網路,無法從外部網路連進來(需要是同一個 Provider)

DHCP

Vagrant.configure("2") do |config|
  config.vm.network "private_network", type: "dhcp"
end

這樣就會自動分配一個 IP 給虛擬機

Static IP

Vagrant.configure("2") do |config|
  config.vm.network "private_network", ip: "192.168.50.4"
end

自己指定個靜態 IP 給虛擬機,不過不能跟 系統保留IP 重複

IPv6

IPv6 並不支援 DHCP

Vagrant.configure("2") do |config|
  config.vm.network "private_network",
    ip: "fde4:8dba:82e1::c4",
    netmask: "96"
end

Disable Auto-Configuration

Vagrant.configure("2") do |config|
  config.vm.network "private_network", ip: "192.168.50.4",
    auto_config: false
end

如果你想要手動設定網卡,可以將 auto_config 參數設定成 false

Share

HTTP Sharing

Vagrant 可以透過 share 參數拿到一個 URL,這樣其他人就可以瀏覽到你的 service 了

如果你遇到找不到指令這問題,你可以使用下面指令來安裝。

vagrant plugin install vagrant-share

另外,因為是使用 ngrok 來實作,所以也必須安裝他

並且做好 Port Forwarding,否則會出現下面錯誤

Vagrant was unable to detect an HTTP port for your machine.

Because your machine appears to have no static IP associated with it, Vagrant scans through your forwarded ports, looking for one that responds to an HTTP request. Vagrant couldn’t find any functioning HTTP port!

There are a few options to fix this error:

  1. Create a forwarded port pointing to your HTTP server inside your Vagrant machine.

  2. Specify an HTTP port manually with --http to this command.

  3. Assign a non-local address to your machine. This may or may not be possible depending on what provider you’re using.

  4. Make sure that the HTTP server is up and running within your machine. Vagrant share won’t start until it is reachable.

SSH Sharing

可以使用下面參數來開啟遠端 ssh

$ vagrant share --ssh

遠端的使用者則須使用

$ vagrant connect --ssh bazaar_wolf:sultan_oasis

bazaar_wolf:sultan_oasis 為使用 vagrant share --ssh 時出現的 NAME

Teardown

vagrant supend

暫停虛擬機,並停在目前的適用環境跟狀態,要繼續使用時使用 vagrant up 就能恢復到暫停前的狀態

優點:

缺點:

vagrant halt

暫停並關閉虛擬機

優點:

缺點:

vagrant destroy

銷毀虛擬機

優點:

缺點:

Rebuild

砍掉後重新啟動就好

$ vagrant up

Providers

基本上 Vagrant 都是使用 VirtualBox 來開虛擬機的,這邊提供一個參數可以改變虛擬機的 Provider,Vagrant 支援了很多 Providers,EX: VirtualBox, Hyper-V, Docker

$ vagrant up --provider=vmware_fusion
$ vagrant up --provider=aws

在 Vagrantfile 設定檔中

Vagrant.configure("2") do |config|
  # ...

  config.vm.provider "virtualbox" do |vb|
    # 設定 virtualbox 參數,CPU 使用率最多只能是本機的 50%
    vb.customize ["modifyvm", :id, "--cpuexecutioncap", "50"]
    v.memory = 1024
    v.cpus = 2
    # 虛擬機名稱
    v.name = "my_vm"
    # GUI
    v.gui = true
    # 設定網路
    config.vm.network "private_network", ip: "192.168.50.4",
      virtualbox__intnet: true
  end
end

Multi-Machine

Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: "echo A, Hello"

  config.vm.define :testing do |test|
    test.vm.provision :shell, inline: "echo B"
  end

  config.vm.provision :shell, inline: "echo C"

  config.vm.define "web" do |web|
    web.vm.box = "apache"
  end

  config.vm.define "db" do |db|
    db.vm.box = "mysql"
  end

end

Vagant 會按照 Vagrantfile 內的順序去初始化虛擬機,每台虛擬機間可以使用 Networking 來溝通,特別是 Private Networks

指定主要主機

再多台主機的情況下,如果未指定主機時就會採用 default machine,這邊可以添加 primary 參數來做設定

config.vm.define "web", primary: true do |web|
  # ...
end

自動開機

vagrant up 時會啟動所有虛擬機,如果不需要讓他自動啟動,可以添加 autostart 參數

config.vm.define "web"
config.vm.define "db"
config.vm.define "db_follower", autostart: false

後記

基本上真的很簡單(?,可以很快速的上手 直接用指令就能操作 VM 真的很方便,clone 一個 box 速度也很快 就讓我們邊流浪邊玩VM吧 ლ(╹◡╹ლ)

Source: https://www.vagrantup.com/docs/index.html

Tweet