整個Vagrant系列,已經有四篇文章了:html
上一節中,咱們介紹了怎樣安裝 Vagrant,安裝自己並不困難。本章節中咱們首先要快速上手,以便得到一個直觀的概念:node
打開命令行工具,終端工具,或者iTerm2等,創建一個咱們將要新建虛機的項目目錄,例如 first-vm
:nginx
cd $HOME
mkdir -p vms/first-vm
cd vms/first-vm
複製代碼
Windows的命令可能像這樣:git
cd %HOME%
mkdir -p vms\first-vm
cd vms\first-vm
複製代碼
咱們須要一個徹底空白的工做目錄做爲開始。如上咱們新建一個目錄當作項目目錄的基準位置。shell
以 Ubuntu 操做系統爲虛擬機的例子,咱們能夠這樣初始化:apache
vagrant init ubuntu/xenial64
複製代碼
這個命令將會去下載 ubuntu 的 box 鏡像回來,而後以該鏡像爲核心,在工做目錄下創建一份虛擬機規範描述文件 Vagrantfile
。有關的描述咱們稍後會加以介紹。ubuntu
在這裏,你須要知道的是,你能夠修改或查看這個文本格式的文件。本質上說,Vagrantfile採用ruby等價的語法,因此你能夠選擇文本編輯器按照ruby進行語法加亮。在啓動這個vagrant虛機以前,能夠修改Vagrantfile中的配置,例如添加更多網卡。後端
那麼,咱們能夠啓動這個虛機或者關閉它:緩存
vagrant up #啓動虛機
vagrant halt #中止虛機
vagrant destroy [-f] #刪除虛機
複製代碼
刪除虛機的指令將會所有刪除虛機的後端vmm中的所有相關文件、快照等等,但並不會刪除項目目錄中的 Vagrantfile
。安全
當虛機啓動以後,在項目目錄執行命令 vagrant ssh
能夠登陸到虛擬機中。
虛機目錄 /vagrant 和項目目錄是自動同步的,在虛機中寫入/vagrant中將會在宿主機中的項目目錄中找到相應的內容。
虛機是完整的 Ubuntu 操做系統,當使用 vagrant ssh
登陸到虛擬機中以後,你獲得了一個虛擬機的終端控制檯,如今你可使用 Ubuntu 自身的shell指令了,而且能夠隨時經過 exit
結束控制檯返回到宿主機的控制檯環境。
$ vagrant up
...
$ vagrant ssh
vagrant@vm1> ll /vagrant
...
vagrant@vm1> exit
$ ...
$ vagrant shutdown
複製代碼
vagrant init [name [url]] # 初始化當前目錄到 vagrant 環境
vagrant up # 啓動虛擬機
vagrant halt # 關閉虛擬機
vagrant reload # 重啓虛擬機
vagrant status # 查看虛擬機運行狀態
vagrant destroy [-f] # 銷燬當前虛擬機(但不刪除Vagrantfile)
vagrant suspend # 掛起當前虛擬機
vagrant resume # 恢復被掛起的vm
vagrant ssh # SSH 登陸至虛擬機
vagrant box add ADDRESS # 安裝box文件/url到本地
vagrant box list # 列出全部本地已安裝的box列表
vagrant box outdated # 檢查已安裝的box是否有更新的版本
vagrant box remove NAME # 刪除某個已安裝的box
vagrant package # 打包當前虛擬機環境爲box文件以用於分發
vagrant plugin # 安裝卸載vagrant插件
vagrant provision # 執行專門的環境初始化腳本
vagrant ssh-config # 輸出ssh鏈接的一些信息
vagrant version # 獲取vagrant的版本
複製代碼
更多命令能夠查看 vagrant 官方的文檔。
對於剛創建的第一個虛擬機鏡像first-vm,它的項目目錄名稱爲「first-vm」,而且已經至少使用 vagrant up 啓動過一次了,那麼咱們如今能夠將這個虛擬機導出爲box包:
vagrant package --base=first-vm --output=first-vm-v1.box
複製代碼
這個box一樣能夠被添加到本機的vagrant boxes緩存中:
vagrant box add first-vm-v1.box --name=first-vm-v1
複製代碼
box文件其實是一個 OVF 包。
開源虛擬化格式OVF文件是一種開源的文件規範,它描述了一個開源、安全、有效、可拓展的便攜式虛擬打包以及軟件分佈格式,它通常有幾個部分組成,分別是ovf文件、mf文件、cert文件、vmdk文件和iso文件。
若是網絡模式中使用 private_network 的話,在打包以前須要清除一下private_network的設置,避免沒必要要的錯誤:
vm$ sudo rm -f /etc/udev/rule.d/70-persistent-net.rules
複製代碼
這條bash指令應該在虛機中被執行,對於不一樣的操做系統來講,文件的位置多是有變化的。
將這個box文件分發給同事,則他們也能夠建立一個徹底等價的虛擬機。
vagrant box add first-vm-v1.box --name=myteam/first-vm-v1
vagrant init my-team/first-vm-v1
vagrant up
複製代碼
此前,咱們經過 vagrant init
的指令建立了新的虛擬機環境,在工做目錄中一個 Vagrantfile將被自動建立,若是它還沒有存在的話。 這個文件一般應該是這樣子的:
# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
# The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at
# https://docs.vagrantup.com.
# Every Vagrant development environment requires a box. You can search for
# boxes at https://vagrantcloud.com/search.
config.vm.box = "ubuntu/xenial64"
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# NOTE: This will enable public access to the opened port
# config.vm.network "forwarded_port", guest: 80, host: 8080
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine and only allow access
# via 127.0.0.1 to disable public access
# config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
# Create a private network, which allows host-only access to the machine
# using a specific IP.
# config.vm.network "private_network", ip: "192.168.33.10"
# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
# config.vm.network "public_network"
# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
# config.vm.synced_folder "../data", "/vagrant_data"
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
#
# config.vm.provider "virtualbox" do |vb|
# # Display the VirtualBox GUI when booting the machine
# vb.gui = true
#
# # Customize the amount of memory on the VM:
# vb.memory = "1024"
# end
#
# View the documentation for the provider you are using for more
# information on available options.
# Enable provisioning with a shell script. Additional provisioners such as
# Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
# documentation for more information about their specific syntax and use.
# config.vm.provision "shell", inline: <<-SHELL
# apt-get update
# apt-get install -y apache2
# SHELL
end
複製代碼
這個文件的內容很容易讀懂。
box
config.vm.box = "ubuntu/xenial64"
複製代碼
這句話是指定操做系統用的。換句話說,你用文本編輯器修改它也就會隨心替換系統了。
只不過若是你真的要這麼作的話,須要執行
vagrant destroy; vagrant up
這樣的序列,以便清理舊的虛擬機設施和以新的虛機配置建立相應的設施。
對於 VirtualBox來講,它提供了 VBoxManage 命令行工具能夠針對某個 VM 作不少事,modifyvm
就是一條能夠修訂 VM 配置參數的子命令。而Vagrant也能夠在配置文件 Vagrantfile
中操做 virtualbox 以達到相似的目的。例如:
config.vm.provider "virtualbox" do |v|
v.customize ["modifyvm", :id, "--name", "bastion", "--memory", "2048"]
end
複製代碼
這個示例能夠修改 VM 的內存爲 2GB。
網絡設置 默認狀況下,vagrant通知provider建立 NAT 類型的網卡,這樣虛擬機將可以和主機之間相互通信,同時VM可以藉助宿主機的外網環境直接訪問公網。 在這種狀況下,咱們能夠指定VM的端口轉發來暴露VM中的應用程序的端口,從而在宿主機上能夠直接與該端口進行通訊。
config.vm.network "forwarded_port", guest: 80, host: 8080
複製代碼
例如,咱們在VM中安裝了nginx的話,上面的端口轉發設定能夠將其暴露爲宿主機的 :8080 ,這樣咱們從宿主機或者內網的其餘主機均可以訪問VM中的nginx服務了。 網絡配置是個大話題,咱們稍後會專列一章更多地講述幾種最佳實踐。
同步文件夾 咱們曾經提到過當 SSH 到 VM 中時,/vagrant
實際上和主機的VM工做目錄是等價的,也就是 Vagrantfile
所在的那個目錄。這種特性實際上就是 vagrant 創建的一個同步目錄的機制。通常來講,它是經過 provider 的所謂 共享文件夾(Shared Folder)的特性來實現的。 咱們固然並不須要關心 provider 的特性,也沒必要關心 vagrant 是怎麼作的。咱們只須要知道,這個鏈接點是能夠被自定義的:
config.vm.synced_folder "../data", "/vagrant_data"
複製代碼
上面這一配置,會將宿主機的 VM工做目錄/../data
映射爲 VM中的 /vagrant_data
。 你還能夠作到更多:
使用ruby循環語句創建多個 VMs 在一個Vagrantfile配置中,創建一組VMs是很容易的事情:
(1..3).each do |i|
config.vm.define "node-#{i}" do |node|
node.vm.provision "shell",
inline: "echo hello from node #{i}"
end
end
複製代碼
值得注意的是,使用ruby的 for i in 1..3 do
循環,你沒法獲得想要的結果。緣由是 for i in
語句在每次循環迭代時爲 i
賦新的值,並重用循環體的語句塊,這就致使 |node|
也並不獲得新的副本,而是上一次循環時的 node
,結果是你只能獲得一個不斷修改後的單一的 VM。以下所示:
# THIS DOES NOT WORK!
for i in 1..3 do
config.vm.define "node-#{i}" do |node|
node.vm.provision "shell",
inline: "echo hello from node #{i}"
end
end
複製代碼
替換 VM 的 Locale 通常狀況下,SSH會話沿用宿主機控制檯的Locale,但你能夠經過預約義覆蓋它,在會話中老是使用特定的語言:
ENV["LC_ALL"] = "en_US.UTF-8"
Vagrant.configure("2") do |config|
# ...
end
複製代碼
Provisioning Provisioning 也是一個大話題。我會考慮單列一章。 不過在這裏,咱們主要是說起這個機制能幹些什麼。 簡單地說,Provisioning是一個首次啓動時的後初始化點,它發生在 VM 操做系統被安裝就緒,並首次啓動完成時。你能夠編寫 Shell 腳本在這個點自動完成你的專屬環境初始化動做,例如安裝標準服務、安裝bash擴展組件(例如git-prompt)、創建必要的工做文件夾和拉取特定的分發包之類。 若是有必要,在從此,即便VM已經完成了首次初始化了,你也能夠經過 vagrant up --provision
這樣的指令來強制 VM 開機和再次執行 Provisioning 腳本。 在 Vagrantfile 中,典型地能夠這樣指定 Provioning:
$script = <<-SCRIPT echo I am provisioning... date > /etc/vagrant_provisioned_at SCRIPT
Vagrant.configure("2") do |config|
config.vm.provision "shell", inline: $script
end
複製代碼
也能夠指定一個腳本文件,注意咱們經過 /vagrant
傳遞 provision.sh 到 VM 中,而典型的 box 系統中,/vagrant
是在 $PATH
搜索路徑中的:
Vagrant.configure("2") do |config|
config.vm.provision "shell", path: "provision.sh"
end
複製代碼
你也能夠指定腳本的全路徑名,甚至能夠在 path 中指定一個 url。