iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 3
1

【應試目標能力】

703.1 虛擬機器部署 Virtual Machine Deployment (4)

  • 瞭解 Vagrant 架構及概念,包括儲存及網路
  • 從 Atlas 取得並使用 box
  • 建立及執行 Vagrantfile
  • 存取 Vagrant 虛擬機器
  • 在 Vagrant 虛擬機和 host 系統間共享並同步目錄
  • 瞭解 Vagrant provisioning,包括檔案、Shell、Ansible 和 Docker
  • 瞭解多台機器建置

第一個工具要介紹的是 Vagrant。為什麼是 Vagrant 呢?當研究一個新主題的時候,很多時候我的第一步是建個虛擬機,然後在那台虛擬機中去建立所需要的環境、安裝所需要的軟體,這時 Vagrant 就派上用場了。

Vagrant 是 HashiCorp 開發的虛擬機器 (virtual machine) 管理工具,應該算是覆蓋在底層虛擬機軟體上的一個介面,讓我們可以用設定檔和命令列指令很快地安裝好一台虛擬機器。我不太清楚在 production 場景 Vagrant 有沒有用武之地,因為我猜企業用的虛擬化平台應該會有它自己的編配管理,但如果像我的使用情境,是在本機上透過安裝虛擬機器來學習新技術,而且是 Linux 系統的話,我想 Vagrant 應該會是一個很方便的工具(會這樣說是因為我還沒有用 Vagrant 安裝過 Windows 作業系統)。

以我自己的經驗來說,新安裝一台虛擬機器有一些麻煩之處:

  1. 從原始作業系統的映像檔 (iso) 開始下載、安裝,要花很多時間。
  2. 對虛擬機器一開始建立的設置有些內容不太熟悉,不知道要選什麼。
  3. 網路的設定有點麻煩,尤其是對網路不熟的人,什麼 bridge、NAT 的,我只是希望這台虛擬機有一個 IP 可以讓我從本機連,然後這台虛擬機可以連外。
  4. 虛擬機和本機共享目錄的設定。

以上的問題,透過 Vagrant 都可以輕鬆地解決。Vagrant 的工作流程大概是這樣的:

  1. 編寫設定檔 (Vagrantfile)
  2. 根據設定檔下載引入 Vagrant box 檔案。
  3. Vagarnt 根據設定檔配置,開通並執行虛擬機器,讓它成為運行狀態。

要使用 Vagrant 前,當然要先安裝 Vagrant,然後因為 Vagrant 是基於虛擬機器軟體的管理工具,所以在安裝 Vagrant 前要先安裝虛擬機器軟體,在 Vagrant 的術語中,底層的虛擬機器軟體叫作 provider。如果是個人使用的話,可以選擇 VirtualBox 或 VMWare Workstation Player 這兩套軟體,在個人非商業行為的情境下它們是免費的。Vagrant 預設的 provider 是 VirtualBox,這也是官方推薦剛開始接觸 Vagrant 使用的 provider。官網上有列出目前支援的 provider,除了 VirtualBox 和 VMWare 外,還有 Docker 和 Hyper-V,詳細設定方法請參考 https://www.vagrantup.com/docs/providers/ 的說明。因為 VirtualBox 是官方推薦的,不需要額外設定,因此之後我都會用 VirtualBox 作為 provider。另外有一點要提醒的,VirtualBox 目前是由 Oracle 所維護,雖然是免費的,但是如果在商業環境下使用,有可能會被 Oracle 要求費用(想想 Oracle Java 的例子),所以如果要在公司的機器上安裝,可能還是先問一下網管人員比較好。

VirtualBox 下載安裝請參考 https://www.virtualbox.org/wiki/Downloads,目前有 Windows、OS X、Linux、Solaris 等不同版本,因為都是圖形化介面,安裝應該不會有太大的難度。安裝好 VirtualBox 後接著是 Vagrant,請參考 https://www.vagrantup.com/downloads.html, 也是圖形化介面,請依照本機作業系統選擇適當的安裝檔。

因為我是很久以前就安裝了,所以不太記得安裝好這兩個軟體後還需不需要其他的步驟或設定(之前有遇過在 Windows 7 上安裝遇到必須升級 Windows PowerShell 版本的問題),如果在之後的操作有遇到其他的問題,請自行依訊息上網搜尋相關解法。

接下來,我自己的習慣是會先開一個目錄,進到這個目錄裡操作。這個目錄用來放置 Vagrant 虛擬機器的設定檔 Vagrantfile,此外也可以用來作本機與虛擬機的共享目錄。這裡的本機就是自己的實體主機,Vagrant 中稱作 host,有宿主的意思,而 Vagrant 虛擬機或環境則稱作 guest。

接下來就是要決定要安裝那一個映像檔。和 Docker 類似,Vagrant 也提供了各種 provider、distruibution、版本,以及依各種需求預先安裝好各式軟體的映像檔,這個映像檔在 Vagrant 中稱作 box。文件中是這麼說明的:Box 是 Vagrant 環境的套件格式 (package format),Vagrant 使用基礎映像檔以快速地克隆 (clone) 出一台虛擬機器,這些基礎映像檔就是 Vagrant 中的 box,而指定你的 Vagrant 環境所要使用的 box,這是在創建新的 Vagrantfile 後的第一步。

那要到那裡去尋找 box 呢?應試目標能力中提到的 Atlas 好像停止維護了,現在可到 Vagrant Cloud https://app.vagrantup.com 去找到適合的 box。Vagrant Cloud 除了讓我們下載其他人提供的 box 之外,也可以將自己的 box 上傳供他人使用。

一個 box 的完整名稱由兩部分組成,username(也可以當作是 namespace)及 boxname,中間以 "/ " 連接,例如 ubuntu/trusty64,這是 Ubuntu 官方所提供的 14.04 的 box。此外一個 box 還會有不同的版本號,但一般狀況下不需特別指定。決定好要使用的 box 之後,我們就可以來編寫設定檔 Vagrantfile 了。前面提到,指定要使用的 box 是建立新的 Vagrantfile 後的第一步,這個意思是說 Vagrantfile 中有一個參數用來指定 box 的名稱。也可以在創建 Vagrantfile 時直接指定 box 名稱。假設我們要安裝 Ubuntu 16.04,那麼可以使用 Ubuntu 官方提供的 ubuntu/xenial64 這個 box,指令如下:

$ vagrant init ubuntu/xenial64

若不加 box 名稱,可直接下 $ vagrant init,再修改 Vagrantfile 中的相關參數。這個指令會在當下目錄產生一個叫 Vagrantfile 的檔案。Vagrantfile 比較特別的地方是,它並不像其他工具的設定檔可能是 XML、YAML、JSON 或 INI 的資料格式。它看起來像是一支腳本程式,使用 Ruby 這個語言的語法。新建立的 Vagrantfile 有很多設定都被註解掉了,此外還有各種設置的說明,在文件中都以 # 井字號開頭。將設置說明的部分拿掉後的 Vagrantfile 如下:

Vagrant.configure("2") do |config|
    config.vm.box = "base"
    # config.vm.box_check_update = false
    # config.vm.network "forwarded_port", guest: 80, host: 8080
    # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
    # config.vm.network "private_network", ip: "192.168.33.10"
    # config.vm.network "public_network"
    # config.vm.synced_folder "../data", "/vagrant_data"
    # config.vm.provider "virtualbox" do |vb|
    #   vb.gui = true
    #   vb.memory = "1024"
    # end
    # config.vm.provision "shell", inline: <<-SHELL
    #   apt-get update
    #   apt-get install -y apache2
    # SHELL
end

第一行的 "2" 指的是 Vagrant 版本,有些 Vagrantfile 會在開頭以常數指定此值,然後在這裡使用該常數。中間 config 部分是主要的設定,格式是 config.xxx.yyy,這裡的 xxx 也可以當成是 namespace,範例中的設定都在 vm 這個 namespace 下,這也是最常用的設定,其他還有 config.sshconfig.vagrant 等等,有興趣請參考官方文件 Vagrantfile 一章的相關說明。

首先是 config.vm.box = "base",它指定了要使用的 box 名稱。若 $ vagrant init 有給予 box 名稱參數,這裡就會是該 box 的名稱。我們手動把它修改為 ubuntu/xenial64

config.vm.box = "ubuntu/xenial64"

接下來的部分全部都被註解掉了,所以其實修改 box 名稱後就可以使用此設定檔了,不過我們還是看一下其他的配置。

config.vm.box_check_update 是指在執行 vagrant up 時,要不要檢查 box 有無更新版本,預設是 true。若有更新版本 Vagrant 會給予提示,但不會主動下載更新的版本。

config.vm.network 這一段是網路的配置。如果這台虛擬機只會用 ssh 連進去玩一玩,那麼什麼都不用改也是可以的。forwarded_port 是把這台虛擬機的 port(這裡的例子是 80)和本機的 port (這裡的例子是 8080) 綁在一起,這樣在沒有虛擬機 IP 的狀況下,可透過 host 的 8080 port 來訪問虛擬機的 80 port。設定中的 guest 是指虛擬機,host 是指本機,前面已經提過了。這裡我比較想要直接給虛擬機一個 IP,而且因為只需要讓 host 連,所以使用內部網路 (private network),不另外再分配一個對外實體 IP 。我們把底下這一行的註解拿掉:

config.vm.network "private_network", ip: "192.168.33.10" 

給這台虛擬機 192.168.33.10 的 IP。注意一下這裡內部 IP 區段是 192.168.0.0 ~ 192.168.255.255。

config.vm.synced_folder,是虛擬機和本機的共用目錄設置,它後面有兩個參數,第一個參數是本機上的目錄位置,第二個參數是虛擬機上的目錄位置。本機的目錄必須存在,否則啟動時會報錯。預設會將虛擬機的 /vagrant 目錄和本機 Vagrantfile 所在的目錄共享,所以這裡不一定要設定。如果 provider 是 VirtualBox,會以 VirtualBox shared folder 作為 synced folder 的機制,也可以使用 rsync。另外有可能會用到的功能是目錄的權限設定,連同 synced foler 的其他設定請參考官文文件說明 https://www.vagrantup.com/docs/synced-folders/

config.vm.provider 用來指定虛擬機的 provider 及其他資源的配置。如果更改設定的話,記得把這一整段的註解都拿掉,從 config.vm.provider 到同一個縮排的 end 為止。比較常用的是記憶體的大小 vb.memory,這邊給定 1024 MB。如果 host 的記憶體沒有很大的話,這裡可以稍微調小一點,另外可用 vb.cpus 來修改 CPU 的核數,例如 vb.cpus = "2"

最後是 config.vm.provision,可以用來指定環境建立時的「開通」動作,例如這裡使用 apt-get install apache2 來安裝 Apache 伺服。這部分明天會有更多的說明。

另外有一個我自己會用到的,是 hostname 的設定,例如要指定主機名稱為 ubuntu-test,參數如下:

config.vm.hostname = "ubuntu-test"

最後找個 Vagrantfile 範例來看一下,來自 Linux Academy 的教學文 (https://linuxacademy.com/blog/linux/vagrant-cheat-sheet-get-started-with-vagrant/)。

$samplescript = <<SCRIPT
yum install -y httpd
systemctl enable httpd
systemctl start httpd
SCRIPT

Vagrant.configure(2) do |config|
  config.vm.box = "centos/7"
  config.vm.hostname = "myhost"
  config.vm.network "private_network", ip: "192.168.50.10"
  config.vm.synced_folder "src/", "/var/www/html"

  config.vm.provision "shell", inline: $samplescript

  config.vm.provider "virtualbox" do |vb|
    vb.memory = "1024"
    vb.cpus = "2"
  end
end

這個 Vagrantfile 使用了 centos/7 box,hostname 為 myhost,內部網路 IP 為 192.168.50.10,host 的 src 目錄和 guest 的 /var/www/html 共享(要先在 Vagrantfile 所在的目錄底下先建立一個 src 目錄)。開通後會安裝 httpd (Apache) 並啟動它。guest 的資源設置為記憶體 1024 MB 及 2 個 CPU。不過實際上網路上的 Vagrantfile 範例大部分都會比這個複雜啦,如果有看不懂的地方,再去查一下文件吧。

設定好了之後,我們要來建立並啟動這個虛擬環境了!下面這個指令用來讓 Vagrant 依 Vagrantfile 中的設定去下載 box 檔案,然後把機器建起來。

$ vagrant up

Vagrant 會從目前所在的目錄開始,逐漸往上層去找 Vagrantfile,所以建議像之前提到的,建立一個專門的目錄並在該目錄下操作相關指令,才能確保 Vagrant 找到的 Vagrantfile 是我們想要的那一個。

第一次下載 box 要比較長的時間,如果之前已經有下載過,Vagrant 會直接使用,下載好的 box 在我的 mac OS 中會放在使用者家目錄 ~/.vagrant.d/boxes 此目錄底下,Vagrant 也有專門用來管理 box 檔案的指令。接著 Vagrant 會幫我們完成剩下的事情,並把過程輸出在 console。如果一切順利,看到下面輸出並返回命令列提示字元後,就表示機器準備好了。

==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
==> default: Mounting shared folders...

這個時候如果把 VirtualBox 打開,應該可以看到這台執行中的虛擬機,它的名稱前綴會是 Vagrantfile 所在的目錄名稱,可以在設定檔中作修改。今天就先到這邊,明天接著看看要如何與新建的 Vagrant 虛擬環境進行互動。


上一篇
[Day 02] LPI DevOps Tools Engineer 證照介紹 (2)
下一篇
[Day 04] Vagrant (2)
系列文
30 天準備 LPI DevOps Tools Engineer 證照30

尚未有邦友留言

立即登入留言