Vagrant Tutorial(3)細說虛擬機生滅狀態
Vagrant Tutorial(2)跟著流浪漢把玩虛擬機 << 前情 上回我們示範,只用兩行 Vagrant 指令,就能生出一個 Ubuntu 虛擬機。這一回,讓我們分解動作,慢慢分析這背後到底發生了什麼事。你將會瞭解 Vagrant 管理虛擬機(Vagrant 術語為 box)的邏輯,以及從 VirtualBox 角度來看,虛擬機實際上的生滅狀態。畢竟,最初 Vagrant 是站在 VirtualBox 的基礎,加工出一套可程式化介面。多瞭解「上層 Vagrant」是怎麼與「底層 VirtualBox」互動,會讓你更好駕馭 Vagrant 的威力。 行前準備:回復成乾淨狀態如果你上回有乖乖地照著「生出一個虛擬機,只要兩道指令」來做,那麼這一回,我們要先將你的 host OS 恢復到尚未下載啟動 guest OS 虛擬機的乾淨狀態(簡單的說,就是 undo 那兩道指令啦)。且讓我們先進入同樣的工作目錄,大掃除一番。 如果你的 host OS 是 Linux 或 Mac,請輸入以下指令: $ cd demo-1 $ vagrant halt ; vagrant destroy --force $ rm -rf .vagrant Vagrantfile $ vagrant box remove ubuntu/trusty64 $ rm -rf $HOME/.vagrant.d/boxes/ubuntu-VAGRANTSLASH-trusty64 如果你的 host OS 是 Windows,請改成: $ cd demo-1 $ vagrant halt $ vagrant destroy --force $ del /F /Q Vagrantfile $ rmdir /S /Q .vagrant $ vagrant box remove ubuntu/trusty64 $ rmdir /S /Q %USERPROFILE%\.vagrant.d\boxes\ubuntu-VAGRANTSLASH-trusty64 看到這些 undo 手續,加上一點點倒推的想像力,不難一瞥之前 Vagrant 做了哪些事。 行前準備:雙視窗觀察畫面接下來,建議你開兩個視窗,一邊是終端機命令列,讓你輸入 Vagrant 指令;一邊是 VirtualBox 視窗,讓你即時觀察輸入的上層 Vagrant 指令會對底層的 VirtualBox 產生什麼樣的變化,有助於領會進階操作的原理。 譬如說,做完前面的大掃除步驟後,我的雙視窗觀察畫面會變成這樣: 看著這畫面,由左至右,可依序觀察到幾件事:
嗯,的確已經回到乾淨的狀態。 我也故意將這兩個視窗的 z-order 安排成:Vagrant 所在的【終端機視窗】,疊在 VirtualBox 所在的視窗上面,以凸顯「上層 Vagrant」與「底層 VirtualBox」之間的上位、下位階層關係。 行前準備一切就緒,且讓我們放慢動作,一步一步來⋯⋯ 定義你要用的虛擬機照 Vagrant 的遊戲規則,在啟動任何一個 Vagrant box 之前,必須先定義好,在這個工作目錄中,我們要啟動的是哪一種 box,以及這個 box 該有哪些相關屬性。最常見的定義內容計有:
因此,我們必需先在選定的工作目錄裡(或是上層目錄,或是上上層目錄⋯⋯),把這些屬性寫進一個名叫 Vagrant 是用 Ruby 寫的,而 Ruby 陣營又對於直接以 Ruby 語言當成 DSL (domain-specific language) 覺得天經地義理所當然,更無比自豪(請見本文附錄),因此, 每次都要先寫一份 Vagrant 定義檔,才能開始玩 Vagrant,也挺麻煩的 $ vagrant init ubuntu/trusty64 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. $ 畫面上告訴我們 “A `Vagrantfile` has been placed in this directory.”。沒錯吧! 畫面上也叫我們 “Please read the comments in the Vagrantfile”。好吧,乖乖的照著提示,看一看 Vagrant 自動幫我們生出的 # -*- mode: ruby -*- # vi: set ft=ruby : # Vagrantfile API/syntax version. Don't touch unless you know what you're doing! VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| # All Vagrant configuration is done here. The most common configuration # options are documented and commented below. For a complete reference, # please see the online documentation at vagrantup.com. # Every Vagrant virtual environment requires a box to build off of. config.vm.box = "ubuntu/trusty64" [略] 註解很多,即使不懂 Ruby,也不難做些初步的修改。有了這份
下載虛擬機檔案本體
且慢!把手移開鍵盤,先不要急著輸入上回示範過的 還記得嗎?上回文章提過:
且讓我們拿著放大鏡,分析這所謂的「查詢並下載 box 檔案」動作。 請先用瀏覽器打開上回的 http://asciinema.org/a/11428 錄影,重看第 0 分 28 秒~4 分 25 秒。你會看到這樣的畫面: 其中:
那麼,下載回來的 box 檔案本體,會存在哪裡呢?我們稍後會再回頭探討這件事。 啟動(開機)你定義好的虛擬機好,現在你可以輸入 $ vagrant up 緊接著前述的「向 Vagrant Cloud 查詢並下載這個 box 檔案」中間過程之後,你會先看到如下的畫面: 這表示,上層的 Vagrant 正在把 緊接著,你會看到 Vagrant 旋即把這台虛擬機切換至「已開機,執行中」狀態: 此時,也可以在終端機視窗用 $ vagrant status Current machine states: default running (virtualbox) The VM is running. To stop this VM, you can run `vagrant halt` to shut it down forcefully, or you can run `vagrant suspend` to simply suspend the virtual machine. In either case, to restart it again, simply run `vagrant up`. $ 順便也看看,Vagrant 在我們的工作目錄做了什麼事? $ # 看看現在工作目錄有什麼變化... $ ls -al total 16 drwxr-xr-x 4 william wheel 136 8 31 21:45 . drwxrwxrwt 13 root wheel 442 8 31 20:55 .. drwxr-xr-x 3 william wheel 102 8 31 21:45 .vagrant -rw-r--r-- 1 william wheel 4822 8 30 21:43 Vagrantfile $ 可以看到,工作目錄除了原本就有的定義檔 Vagrant box 檔案本體剛剛是針對工作目錄看的 local 資訊,現在也讓我們看看 global 資訊。 先來回顧一下,系統裡面已經下載過哪些 Vagrant box 了: $ vagrant box list ubuntu/trusty64 (virtualbox, 14.04) $ 順便找找 box 檔案本體被 Vagrant 藏在哪裡吧。如果你沒有改變
且讓我們從這裡出發,一層一層鑽進去探險: $ ls -al $HOME/.vagrant.d total 16 drwxr-xr-x 9 william staff 306 8 31 21:55 . drwxr-xr-x+ 70 william staff 2380 8 31 21:57 .. drwx------ 3 william staff 102 8 31 21:56 boxes drwxr-xr-x 13 william staff 442 8 31 21:51 data drwxr-xr-x 3 william staff 102 3 31 14:56 gems -rw------- 1 william staff 1675 3 5 17:00 insecure_private_key drwxr-xr-x 3 william staff 102 3 5 17:00 rgloader -rw-r--r-- 1 william staff 3 3 31 14:56 setup_version drwxr-xr-x 4 william staff 136 8 31 21:50 tmp $ $ # 嗯,其中 'boxes' 這個目錄很可疑,進去看看... $ ls -al $HOME/.vagrant.d/boxes total 0 drwx------ 3 william staff 102 8 31 21:56 . drwxr-xr-x 9 william staff 306 8 31 21:55 .. drwxr-xr-x 4 william staff 136 7 3 22:47 ubuntu-VAGRANTSLASH-trusty64 $ $ # 嗯,出現了 'ubuntu' 及 'trusty64' 關鍵字,進去看看... $ ls -al $HOME/.vagrant.d/boxes/ubuntu-VAGRANTSLASH-trusty64 total 8 drwxr-xr-x 4 william staff 136 7 3 22:47 . drwx------ 3 william staff 102 8 31 21:56 .. drwxr-xr-x 3 william staff 102 8 31 21:50 14.04 -rw-r--r-- 1 william staff 40 8 31 21:50 metadata_url $ $ # 嗯,有一個疑似版本號的目錄 '14.04',進去看看... $ ls -al $HOME/.vagrant.d/boxes/ubuntu-VAGRANTSLASH-trusty64/14.04 total 0 drwxr-xr-x 3 william staff 102 8 31 21:50 . drwxr-xr-x 4 william staff 136 7 3 22:47 .. drwxr-xr-x 6 william staff 204 8 31 21:50 virtualbox $ $ # 嗯,二話不說,鑽進去 'virtualbox' 目錄看看... $ ls -al $HOME/.vagrant.d/boxes/ubuntu-VAGRANTSLASH-trusty64/14.04/virtualbox total 737512 drwxr-xr-x 6 william staff 204 8 31 21:50 . drwxr-xr-x 3 william staff 102 8 31 21:50 .. -rw-r--r-- 1 william staff 505 8 31 21:50 Vagrantfile -rw------- 1 william staff 377585664 8 31 21:50 box-disk1.vmdk -rw------- 1 william staff 10506 8 31 21:50 box.ovf -rw-r--r-- 1 william staff 25 8 31 21:50 metadata.json $ $ # 就是這個!!! 'box-disk1.vmdk' 從最後所到目錄可看出,Vagrant 將下載回來的 box 檔案本體,儲存成互通性較高的 VMDK 格式,而不是 VirtualBox 原生的 VDI 格式。 有興趣的,可以再打開這目錄裡面的其他檔案瀏覽一番。 關機、移除現在,試著將這台虛擬機關機: $ vagrant halt ==> default: Attempting graceful shutdown of VM... $ 的確,從 VirtualBox 角度來看,這台虛擬機狀態,從「執行中」變成「電源關閉」: 注意喔,這台虛擬機只是「關機」而已,並沒有被「移除」。因此,不管是從底層的 VirtualBox 還是上層的 Vagrant 兩種角度來看,這個 Ubuntu 虛擬機執行個體都還存在(只不過是暫時關機): $ # 先看一看在此工作目錄下,Vagrant 目前的狀態... $ vagrant status Current machine states: default poweroff (virtualbox) The VM is powered off. To restart the VM, simply run `vagrant up` $ $ # 很明顯地告訴我們,這台 VM 還可以再被 restart... $ # 那麼,這個 Vagrant box 檔案本體還存在嗎? $ vagrant box list ubuntu/trusty64 (virtualbox, 14.04) $ $ # 還在! 如果想進一步把它移除呢?可以用 $ vagrant destroy default: Are you sure you want to destroy the 'default' VM? [y/N] Y ==> default: Destroying VM and associated drives... $ 從畫面上可看到,這台虛擬機,徹底從 VirtualBox 的虛擬機清單上除名: 不過,有趣的地方在於,這只是從「VirtualBox 虛擬機清單」上除名,但並沒有從「Vagrant 所管理維護的『已下載 box 清單』」上除名: $ # 照例,先看一看在此工作目錄下,Vagrant 目前的狀態... $ vagrant status Current machine states: default not created (virtualbox) The environment has not yet been created. Run `vagrant up` to create the environment. If a machine is not created, only the default provider will be shown. So if a provider is not listed, then the machine is not created for that environment. $ $ # 現在的「Vagrant 所管理維護的『已下載 box 清單』」呢? $ vagrant box list ubuntu/trusty64 (virtualbox, 14.04) $ $ # 還在! $ # 那麼,box 檔案本體呢? $ ls -al $HOME/.vagrant.d/boxes/ubuntu-VAGRANTSLASH-trusty64/14.04/virtualbox total 737512 drwxr-xr-x 6 william staff 204 8 31 21:50 . drwxr-xr-x 3 william staff 102 8 31 21:50 .. -rw-r--r-- 1 william staff 505 8 31 21:50 Vagrantfile -rw------- 1 william staff 377585664 8 31 21:50 box-disk1.vmdk -rw------- 1 william staff 10506 8 31 21:50 box.ovf -rw-r--r-- 1 william staff 25 8 31 21:50 metadata.json $ $ # 也還在! 所以,Vagrant 不會輕易把下載回來的「Vagrant box 檔案本體」(即畫面中的 vmdk 檔)清除掉,只是把藉著它而增生出來的「VirtualBox 虛擬機執行個體 (instance)」清除掉而已。也因此,你反覆執行 up、halt、destroy 指令不管多少次,系統不會每次都跑去 Vagrant Cloud 下載那動輒數百 MB 的 box 檔案本體;除非你像本文一開始的大掃除動作那樣,強制驅離 小結這一回,我們學會利用 以上都是很基本的觀念,必須非常熟練。 我把最核心的操作動線錄影起來: http://www.screencast.com/t/U0iOeaDjJXMb ,建議你,不妨照著影片多試幾次,並留意影片中提醒的觀察重點。等到熟練了,再回到文章,將文章提到的所有細節都親自檢驗過一遍,才能擁有足夠的問題排除能力。 下一回,來碰碰大家愛用的 Redis,以及最近很夯的 Docker 吧。我會以「在 Ubuntu 中安裝 Docker engine」為例,示範如何設定虛擬機組態。 附錄Ruby 達人 ihower 在他的《Ruby on Rails 實戰聖經》FAQ 中如是說:
|
ben l
12/01
寫得非常詳細又清楚 謝謝!