1. 程式人生 > >Vagrant入門 Vagrant入門

Vagrant入門 Vagrant入門

Vagrant入門

簡單地說,Vagrant讓我們可以通過程式碼的方式快速地、可重複地建立針對不同虛擬環境的虛擬機器,包括Virtualbox、AWS、Docker等。它使得我們可以一次性地、自動建立多個環境相同的虛擬機器,對於軟體開發和測試尤其有用。本文我們將以Virtualbox為例,看看Vagrant的基本使用。

 

 

 

這是一個關於Vagrant的學習系列,包含如下文章:

  1. Vagrant入門
  2. 建立自己的Vagrant box 
  3. 用Vagrant搭建Jenkins構建環境
  4. 用Vagrant和Ansible搭建持續交付平臺

 

(一)快速入門

首先需要建立一個目錄用於存放Vagrantfile檔案以及Vagrant在工作中的資料:

mkdir my-vagrant-project
cd my-vagrant-project

 

然後初始化Vagrant工程:

vagrant init ubuntu/trusty64

 

該命令會在當前目錄下建立Vagrantfile,並且指定所使用的box為ubuntu/trusty64,該box由

Hashicorp官網提供。此時,Vagrant發現box的名字的格式為“使用者名稱/box名”,則會使用“https://atlas.hashicorp.com/使用者名稱/box名”來下載該box。對於非官網提供的box,可以通過以下命令建立:

vagrant init my-box https://boxes.company.com/my.box

 

其中,my-box為該box的名字,後面的URL為該box的下載地址。接下來就可以啟動虛擬機器了:

vagrant up

 

此時Vagrant會先從Hashicorp下載ubuntu/trusty64這個box(如果先前下載過了則跳過),然後啟動虛擬機器。在預設情況下,Virtualbox將作為provider,當然你也可以使用其他provider,比如以下命令將啟動一個hyperv虛擬機器:

vagrant up --provider hyperv

 

登入到虛擬機器:

vagrant ssh

 

此時vagrant將使用預設的使用者vagrant以及預設的SSH公鑰金鑰鍵值對直接登入虛擬機器。

 

關閉虛擬機器:

vagrant halt

 

刪除虛擬機器:

vagrant destroy

 

請注意,vagrant destroy只會刪除虛擬機器本身,也即你在Virtualbox將看不到該虛擬機器,但是不會刪除該虛擬機器所使用的box。

 

Vagrant還會在Vagrantfile所在同級目錄下建立一個.vagrant隱藏資料夾,該資料夾包含了在本地執行虛擬機器的一些資訊。如果使用了程式碼庫管理(比如Git),這個.vagrant資料夾應該被ignore掉。

 

(二)新增和檢視所下載的box

 Vagrant會將所下載的box儲存到~/.vagrant.d/boxes目錄下,除了在執行“vagrant up”時Vagrant會下載box外,你也可以單獨下載box到本地:

vagrant box add ubuntu/trusty64

 

這將從Hashicorp官網上下載ubuntu/trusty64這個box,你也可以指定一個另外的URL:

vagrant box add --name mybox http://someurl.com/ubuntu.box

 

這裡的mybox是一個邏輯名字,你可以用該名字來設定Vangrantfile的“config.vm.box”。

你可以在任何時候向Vagrant中新增新的box以備後用,在執行vagrant up時,Vagrant首先檢查本地是有存在所需要的box,如果有則直接使用,如果沒有則下載。

 

列出本地所有的box:

vagrant box list

 

刪除某個box:

vagrant box remove box-name

 

(三)埠轉發(Port Forwarding)

在預設情況下,Vagrant所建立的Virtualbox虛擬機器使用的是NAT網路型別,即外界是不能直接訪問你的虛擬機器的,就連Host機器也訪問不了。此時,如果你在虛擬機器中啟動的一個Tomcat來部署網站的測試環境,而又想外界能夠訪問的話,你需要使用埠轉發:

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

 

以上程式碼將Host機的8888埠轉發到了虛擬機器的8080埠,這樣你便可以通過在Host機上訪問http://localhost:8888來訪問虛擬機器的Tomcat了。對於Virtualbox來說,只有NAT型別的網路型別支援埠轉發,這也是為什麼Vagrant建立的Virtualbox虛擬機器預設都有一個支援NAT的虛擬網絡卡,原因就是要能夠支援Vagrant級別的埠轉發。另外,Vagrant在第一次嘗試連線虛擬機器時使用的也是NAT。

 

(四)共享資料夾

在預設情況下,Vagrant所建立的虛擬機器已經為我們建立了一個共享資料夾,在虛擬機器上是/home/vagrant目錄,在Host機上則為Vagrantfile所在目錄,當然你也可以額外新增另外的共享資料夾:

Vagrant.configure("2") do |config|
  config.vm.synced_folder "src/", "/srv/website"
end

 

第一個引數為Host機器上的目錄,第二個引數為虛擬機器上的目錄。

 

 (五)Provision

簡單地說,Provision即通過使用某些工具自動地、批量地為機器安裝軟體以及配置系統,它省去了人工安裝和配置系統時的重複性和易錯性,當然還享受了計算機與生俱來的速度。Vagrant提供多種方式對虛擬機器進行Provision,包括Shell、Chef、Puppet和Ansible等。以Shell為例,既可以通過直接在Vagrantfile中編寫Shell指令碼的方式,也可以通過引用外部Shell檔案的方式。

 

直接在Vagrantfile中編寫Shell指令碼,可以通過“inline”指定指令碼內容:

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

  config.vm.provision "shell", inline: "echo hello"
end

 

 通過引用外部指令碼檔案的方式:

Vagrant.configure("2") do |config|
  config.vm.provision "shell", path: "script.sh"
end

 

在使用Ansible時,有兩種方式:(1)在Host機器上安裝Ansible,(2)採用Ansible Local的方式,即在虛擬機器自身上安裝Ansible。對於第(1)種方法,我們需要保證Host機器上已經安裝了Ansible,然後進行配置:

複製程式碼
Vagrant.configure("2") do |config|

  #
  # Run Ansible from the Vagrant Host
  #
  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "playbook.yml"
  end

end
複製程式碼

 

在使用第(2)種方法時,Vagrant會首先檢查box中是否已經安裝了Ansible,如果沒有,則會自動安裝到虛擬機器上,然後再執行provision:

複製程式碼
Vagrant.configure("2") do |config|
  # Run Ansible from the Vagrant VM
  config.vm.provision "ansible_local" do |ansible|
    ansible.playbook = "playbook.yml"
  end
end
複製程式碼

 

當我們多次執行“vagrant up”啟動虛擬機器時,provison並不會每次都執行,只有在這三種情況下provision才會執行:

  1. 首次執行vagrant up
  2. 執行vagrant provision
  3. 執行vagrant reload --provision

 

當然,你也可以在Vagrantfile中配置成每次執行vagrant up時都執行provision:

Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: "echo hello",
    run: "always"
end

 

(六)網路配置

在預設情況下,對於Virtualbox而言,Vagrant將使用Virtualbox的NAT網路方式,這種方式允許虛擬機器訪問外部網路,但是不允許外界訪問虛擬機器,就連Host機器也訪問不了。另外,我們可以為虛擬機器配置private network和public network。在配置private network時,相當於虛擬機器和Host機共同組成了一個單獨的區域網,外界無法訪問該區域網,但是虛擬機器可以訪問外界,Host機和虛擬機器之間也可以互訪。請注意,這裡說的外界是指原本和Host處於同一區域網的其他機器。

 

使用private network時,我們可以給虛擬機器指定固定的私有IP:

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

 

當然也可以使用DHCP的方式動態分配IP:

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

 

對於Virtualbox而言,此時虛擬機器其實有兩張網絡卡在工作,一種是Vagrant預設建立的NAT網絡卡,另一種是Host only型別的網絡卡提供private network。

 

在使用public network時,虛擬機器和Host在網路中具有同等的地位(共同使用Host機的物理網絡卡與外界通訊),就相當於在Host所在網路中又多了一臺計算機一樣,此時虛擬機器可以使用網路中的DHCP伺服器獲得與Host處於同一個網段的IP地址,以下配置預設採用DHCP方式配置public network:

Vagrant.configure("2") do |config|
  config.vm.network "public_network"
end

 

如果Host機器有多張網絡卡,此時執行vagrant up, Vagrant會詢問需要使用那張網絡卡連線到網路,如果不想要這種互動,則可以在Vagrantfile中進行配置:

config.vm.network "public_network", bridge: [
  "en1: Wi-Fi (AirPort)",
]

這裡的 Wi-Fi(AirPort)表示使用了Mac筆記本的Airport連線到Wi-Fi。

 

除了DHCP,也可以使用靜態IP:

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

 

(七)Provider特定配置

不同的Provider有不同的特性,也存在不同的配置方式。以Virtualbox為例,Vagrant預設會給虛擬機器指定一個不具備可讀性的名字,比如my-vagrant-project_default_1471685053487_94837,我們可以對此進行配置予以更改:

config.vm.provider "virtualbox" do |v|
  v.name = "my_vm"
end

 

Provider的特定配置也可以覆蓋Vagrant原來的配置:

複製程式碼
Vagrant.configure("2") do |config|
  config.vm.box = "precise64"

  config.vm.provider "vmware_fusion" do |v, override|
    override.vm.box = "precise64_fusion"
  end
end
複製程式碼

 

 在下一篇中,我們將講到如何建立自己的Vagrant box 

簡單地說,Vagrant讓我們可以通過程式碼的方式快速地、可重複地建立針對不同虛擬環境的虛擬機器,包括Virtualbox、AWS、Docker等。它使得我們可以一次性地、自動建立多個環境相同的虛擬機器,對於軟體開發和測試尤其有用。本文我們將以Virtualbox為例,看看Vagrant的基本使用。

 

 

 

這是一個關於Vagrant的學習系列,包含如下文章:

  1. Vagrant入門
  2. 建立自己的Vagrant box 
  3. 用Vagrant搭建Jenkins構建環境
  4. 用Vagrant和Ansible搭建持續交付平臺

 

(一)快速入門

首先需要建立一個目錄用於存放Vagrantfile檔案以及Vagrant在工作中的資料:

mkdir my-vagrant-project
cd my-vagrant-project

 

然後初始化Vagrant工程:

vagrant init ubuntu/trusty64

 

該命令會在當前目錄下建立Vagrantfile,並且指定所使用的box為ubuntu/trusty64,該box由Hashicorp官網提供。此時,Vagrant發現box的名字的格式為“使用者名稱/box名”,則會使用“https://atlas.hashicorp.com/使用者名稱/box名”來下載該box。對於非官網提供的box,可以通過以下命令建立:

vagrant init my-box https://boxes.company.com/my.box

 

其中,my-box為該box的名字,後面的URL為該box的下載地址。接下來就可以啟動虛擬機器了:

vagrant up

 

此時Vagrant會先從Hashicorp下載ubuntu/trusty64這個box(如果先前下載過了則跳過),然後啟動虛擬機器。在預設情況下,Virtualbox將作為provider,當然你也可以使用其他provider,比如以下命令將啟動一個hyperv虛擬機器:

vagrant up --provider hyperv

 

登入到虛擬機器:

vagrant ssh

 

此時vagrant將使用預設的使用者vagrant以及預設的SSH公鑰金鑰鍵值對直接登入虛擬機器。

 

關閉虛擬機器:

vagrant halt

 

刪除虛擬機器:

vagrant destroy

 

請注意,vagrant destroy只會刪除虛擬機器本身,也即你在Virtualbox將看不到該虛擬機器,但是不會刪除該虛擬機器所使用的box。

 

Vagrant還會在Vagrantfile所在同級目錄下建立一個.vagrant隱藏資料夾,該資料夾包含了在本地執行虛擬機器的一些資訊。如果使用了程式碼庫管理(比如Git),這個.vagrant資料夾應該被ignore掉。

 

(二)新增和檢視所下載的box

 Vagrant會將所下載的box儲存到~/.vagrant.d/boxes目錄下,除了在執行“vagrant up”時Vagrant會下載box外,你也可以單獨下載box到本地:

vagrant box add ubuntu/trusty64

 

這將從Hashicorp官網上下載ubuntu/trusty64這個box,你也可以指定一個另外的URL:

vagrant box add --name mybox http://someurl.com/ubuntu.box

 

這裡的mybox是一個邏輯名字,你可以用該名字來設定Vangrantfile的“config.vm.box”。

你可以在任何時候向Vagrant中新增新的box以備後用,在執行vagrant up時,Vagrant首先檢查本地是有存在所需要的box,如果有則直接使用,如果沒有則下載。

 

列出本地所有的box:

vagrant box list

 

刪除某個box:

vagrant box remove box-name

 

(三)埠轉發(Port Forwarding)

在預設情況下,Vagrant所建立的Virtualbox虛擬機器使用的是NAT網路型別,即外界是不能直接訪問你的虛擬機器的,就連Host機器也訪問不了。此時,如果你在虛擬機器中啟動的一個Tomcat來部署網站的測試環境,而又想外界能夠訪問的話,你需要使用埠轉發:

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

 

以上程式碼將Host機的8888埠轉發到了虛擬機器的8080埠,這樣你便可以通過在Host機上訪問http://localhost:8888來訪問虛擬機器的Tomcat了。對於Virtualbox來說,只有NAT型別的網路型別支援埠轉發,這也是為什麼Vagrant建立的Virtualbox虛擬機器預設都有一個支援NAT的虛擬網絡卡,原因就是要能夠支援Vagrant級別的埠轉發。另外,Vagrant在第一次嘗試連線虛擬機器時使用的也是NAT。

 

(四)共享資料夾

在預設情況下,Vagrant所建立的虛擬機器已經為我們建立了一個共享資料夾,在虛擬機器上是/home/vagrant目錄,在Host機上則為Vagrantfile所在目錄,當然你也可以額外新增另外的共享資料夾:

Vagrant.configure("2") do |config|
  config.vm.synced_folder "src/", "/srv/website"
end

 

第一個引數為Host機器上的目錄,第二個引數為虛擬機器上的目錄。

 

 (五)Provision

簡單地說,Provision即通過使用某些工具自動地、批量地為機器安裝軟體以及配置系統,它省去了人工安裝和配置系統時的重複性和易錯性,當然還享受了計算機與生俱來的速度。Vagrant提供多種方式對虛擬機器進行Provision,包括Shell、Chef、Puppet和Ansible等。以Shell為例,既可以通過直接在Vagrantfile中編寫Shell指令碼的方式,也可以通過引用外部Shell檔案的方式。

 

直接在Vagrantfile中編寫Shell指令碼,可以通過“inline”指定指令碼內容:

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

  config.vm.provision "shell", inline: "echo hello"
end

 

 通過引用外部指令碼檔案的方式:

Vagrant.configure("2") do |config|
  config.vm.provision "shell", path: "script.sh"
end

 

在使用Ansible時,有兩種方式:(1)在Host機器上安裝Ansible,(2)採用Ansible Local的方式,即在虛擬機器自身上安裝Ansible。對於第(1)種方法,我們需要保證Host機器上已經安裝了Ansible,然後進行配置:

複製程式碼
Vagrant.configure("2") do |config|

  #
  # Run Ansible from the Vagrant Host
  #
  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "playbook.yml"
  end

end
複製程式碼

 

在使用第(2)種方法時,Vagrant會首先檢查box中是否已經安裝了Ansible,如果沒有,則會自動安裝到虛擬機器上,然後再執行provision:

複製程式碼
Vagrant.configure("2") do |config|
  # Run Ansible from the Vagrant VM
  config.vm.provision "ansible_local" do |ansible|
    ansible.playbook = "playbook.yml"
  end
end
複製程式碼

 

當我們多次執行“vagrant up”啟動虛擬機器時,provison並不會每次都執行,只有在這三種情況下provision才會執行:

  1. 首次執行vagrant up
  2. 執行vagrant provision
  3. 執行vagrant reload --provision

 

當然,你也可以在Vagrantfile中配置成每次執行vagrant up時都執行provision:

Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: "echo hello",
    run: "always"
end

 

(六)網路配置

在預設情況下,對於Virtualbox而言,Vagrant將使用Virtualbox的NAT網路方式,這種方式允許虛擬機器訪問外部網路,但是不允許外界訪問虛擬機器,就連Host機器也訪問不了。另外,我們可以為虛擬機器配置private network和public network。在配置private network時,相當於虛擬機器和Host機共同組成了一個單獨的區域網,外界無法訪問該區域網,但是虛擬機器可以訪問外界,Host機和虛擬機器之間也可以互訪。請注意,這裡說的外界是指原本和Host處於同一區域網的其他機器。

 

使用private network時,我們可以給虛擬機器指定固定的私有IP:

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

 

當然也可以使用DHCP的方式動態分配IP:

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

 

對於Virtualbox而言,此時虛擬機器其實有兩張網絡卡在工作,一種是Vagrant預設建立的NAT網絡卡,另一種是Host only型別的網絡卡提供private network。

 

在使用public network時,虛擬機器和Host在網路中具有同等的地位(共同使用Host機的物理網絡卡與外界通訊),就相當於在Host所在網路中又多了一臺計算機一樣,此時虛擬機器可以使用網路中的DHCP伺服器獲得與Host處於同一個網段的IP地址,以下配置預設採用DHCP方式配置public network:

Vagrant.configure("2") do |config|
  config.vm.network "public_network"
end

 

如果Host機器有多張網絡卡,此時執行vagrant up, Vagrant會詢問需要使用那張網絡卡連線到網路,如果不想要這種互動,則可以在Vagrantfile中進行配置:

config.vm.network "public_network", bridge: [
  "en1: Wi-Fi (AirPort)",
]

這裡的 Wi-Fi(AirPort)表示使用了Mac筆記本的Airport連線到Wi-Fi。

 

除了DHCP,也可以使用靜態IP:

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

 

(七)Provider特定配置

不同的Provider有不同的特性,也存在不同的配置方式。以Virtualbox為例,Vagrant預設會給虛擬機器指定一個不具備可讀性的名字,比如my-vagrant-project_default_1471685053487_94837,我們可以對此進行配置予以更改:

config.vm.provider "virtualbox" do |v|
  v.name = "my_vm"
end

 

Provider的特定配置也可以覆蓋Vagrant原來的配置:

複製程式碼
Vagrant.configure("2") do |config|
  config.vm.box = "precise64"

  config.vm.provider "vmware_fusion" do |v, override|
    override.vm.box = "precise64_fusion"
  end
end
複製程式碼

 

 在下一篇中,我們將講到如何建立自己的Vagrant box