上一節中,咱們介紹了怎樣安裝 Vagrant,安裝自己並不困難。本章節中咱們首先要快速上手,以便得到一個直觀的概念:html
打開命令行工具,終端工具,或者iTerm2等,創建一個咱們將要新建虛機的項目目錄,例如 first-vm:node
cd $HOME mkdir -p vms/first-vm cd vms/first-vm
Windows的命令可能像這樣:nginx
cd %HOME% mkdir -p vms\first-vm cd vms\first-vm
咱們須要一個徹底空白的工做目錄做爲開始。如上咱們新建一個目錄當作項目目錄的基準位置。git
以 Ubuntu 操做系統爲虛擬機的例子,咱們能夠這樣初始化:shell
vagrant init ubuntu/xenial64
這個命令將會去下載 ubuntu 的 box 鏡像回來,而後以該鏡像爲核心,在工做目錄下創建一份虛擬機規範描述文件 Vagrantfile。有關的描述咱們稍後會加以介紹。apache
在這裏,你須要知道的是,你能夠修改或查看這個文本格式的文件。本質上說,Vagrantfile採用ruby等價的語法,因此你能夠選擇文本編輯器按照ruby進行語法加亮。在啓動這個vagrant虛機以前,能夠修改Vagrantfile中的配置,例如添加更多網卡。ubuntu
那麼,咱們能夠啓動這個虛機或者關閉它:後端
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。