Vagrant 在本地快速建立機器并初始化

一、Vagrant 介紹

Vagrant 是一個軟件,可以自動化虛擬機的安裝和配置流程,用來管理虛擬機,如 VirtualBox、VMware、AWS 等目前市面上個人 PC 的主流操作系統不是Windows 就是 MacOS。對于這些用戶,如果需要用 Linux 環境進行開發或學習,使用虛擬機無疑是最方便的選擇。主要好處是可以提供一個可配置、可移植和復用的軟件環境,可以使用 shell、chef、puppet 等工具部署。所以 vagrant 不能單獨使用,如果你用它來管理自己的開發環境的話,必須在自己的電腦里安裝了虛擬機軟件,如 virtualbox。

更進一步,Vagrant 提供一個命令行工具 vagrant,通過這個命令行工具可以直接啟動一個虛擬機,當然你需要提前定義一個 Vagrantfile 文件,這有點類似Dockerfile 之于 docker了。可以通過編寫一個 Vagrantfile 來控制虛擬機的啟動、虛擬機網絡環境的配置、虛擬機與主機間的文件共享,以及啟動后自動執行一些配置腳本,比如自動執行一個 shell script 來安裝一些必備的開發工具,如Mysql。這意味著,當你需要在多臺機器間同步開發進度時,只需要同步Vagrantfile,就可以保證各臺機器擁有一致的開發環境。另外,即便對于計算機小白用戶,Vagrant也是一個利器。以前我們為了學習一門語言,必須先手動安裝這門語言的編譯環境。有了 Vagrant后,我們可以下載別人寫好的 Vagrantfile,然后運行 vagrant up,vagrant 就會自動下載虛擬機鏡像,自動加載鏡像并配置虛擬機,然后交給我們一個即開即用的學習環境。

二、 安裝與使用

Vagrant 既然是配置虛擬機,那么自然需要虛擬機程序和被虛擬的操作系統鏡像(Image)。前者常用的選擇有 VirtualBox 和 VMWare,后者則包括 Ubuntu、FreeBSD 等等。Vagrant 稱前者為 provider,稱后者為 box。原則上,我們可以自由搭配 provider 和 box,但由于 VirtualBox 開源且免費,Vagrant將其作為默認的 provider。所以,一般會先安裝 VirtualBox,再安裝Vagrant。

我這里在 mac 上做測試,直接使用官方的安裝包來安裝 Vagrant
https://www.vagrantup.com/downloads.html

使用 VirtualBox

本文將使用 VirtualBox 作為虛擬機管理器(providers),因為它是免費的、適用于各大平臺,且在 Vagrant 已集成。
可以通過下面的命令啟動運行一個虛擬機

$ vagrant init hashicorp/precise32
$ vagrant up

在執行以上兩條命令后, 將擁有一臺運行在 VirtualBox 下的 Ubuntu 12.04 LTS 32位 虛擬機。 我們可以通過 vagrant ssh 命令來 SSH 登錄到這臺虛擬機上,當用完以后,可以通過 vagrant destroy 命令來銷毀所有的使用痕跡。

項目建立

在創建使用 Vagrant 的第一步,就是對 Vagrantfile 配置文件進行配置。Vagrantfile 配置文件的作用有兩個方面:

  1. 設置項目的根目錄,很多 Vagrant 的配置都是與根目錄有緊密關系。

  2. 指定在項目中所需的虛擬機類型及資源,例如需要安裝哪些軟件以及在哪里可以訪問到這些資源。

Vagrant 有一個內置的命令來初始化一個目錄作為 Vagrant 項目的根目錄: vagrant init

$ mkdir vagrant
$ cd vagrant
$ vagrant init

上面這些命令會創建一個 Vagrantfile 文件在當前的目錄,可以打開 Vagrantfile 配置文件查看一下,內容包含了注釋說明及實例。


image.png

也可以在已存在的項目目錄中執行 vagrant init 命令,來設置一個已存在的項目

Boxes

Vagrant 是通過基礎鏡像包來實現快速克隆創建虛擬機的。這些基礎鏡像包在 Vagrant 中被稱為 boxes , 而在創建 Vagrantfile 文件后的第一件事情就是指定 Vagrant 環境使用哪一個 Box。

$ vagrant box add hashicorp/precise32

Boxes 是通過 vagrant box add 命令來添加到 Vagrant 中的。這將從 HashiCorp's Atlas box catalog 這個專門用來存放 boxes 的地方下載一個名叫 "hashicorp/precise32" 的 box。不但可以從 HashiCorp's Atlas 下載 boxes,其外還可以從本地文件、自定義 URL 等方式添加 boxes。

已經添加了的 boxes 可以被多個項目重復使用。每個項目其實是從 box 克隆并初始化出一個鏡像,不會對原有的 box 基礎鏡像進行任何修改。所以,當兩個項目都使用了 hashicorp/precise32 這個 box,在其中一個項目虛擬機中添加了文件,不會對另外一個項目中的虛擬機造成任何影響。

image.png

上面可以看到已經將 box 添加到了 Vagrant 中,我們需要對我們的項目進行配置,才能將這個項目作為我們今后的基礎環境。打開 Vagrantfile 文件,對其內容依照以下進行編輯:

Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/precise32"
end

"hashicorp/precise32" 這個名字必須和你前面添加進去的 box 名稱相同。 Vagrant 是根據這個名字去判斷進行哪種操作的。如果你之前沒有添加過 box,當你運行 Vagrant 時它會根據這個名字自動下載并添加該 box 進來。

啟動和登錄

啟動使用如下命令:

$ vagrant up

一分鐘之內,這個命令會執行完畢,我們將擁有一個運行 Ubuntu 的虛擬機。但是我們無法真實地看到任何變化,因為 Vagrant 在運行時沒有提供 UI 界面。為了證實 Vagrant 已經正確地運行,你可以通過 SSH 登錄到虛擬機中查看:
剛開始啟動我的一直有報錯如下:


image.png

后面查閱資料貌似是一個bug,我將本地的virtualbox 升級到 5.2.18 之后,重啟reload 解決

$ vagrant ssh

這個命令會進入一個完整的 SSH 會話,可以繼續與虛擬機進行交互,也可以進行任何你想做的操作。雖然這個環境可能是臨時的,但輕易不要執行 rm -rf / 命令,因為 Vagrant 共享了一個 /vagrant 目錄,這個目錄是存放在宿主機上的(具體在宿主機在哪個路徑是由 Vagrantfile 文件中設置的),如果執行了這個命令,也將刪除了宿主機上的這個目錄。當這臺虛擬機不想再使用的時候, 在宿主機器上執行 vagrant destroy 命令,Vagrant 就會刪除所有數據及痕跡。
vagrant ssh $name ,如果主機上就一個vagrant可以不指定名字。默認進入的用戶是vagrant。


image.png
與宿主機同步目錄

默認情況下,Vagrant 共享項目根路徑(注意,這個可在 Vagrantfile 中配置)到你宿主機的 /vagrant 目錄中。 再次執行 vagrant up 命令,SSH 登錄到虛擬機中查看,發現與宿主機的 vagrant 根目錄相同:


image.png

再次 touch 文件 驗證:


image.png

因此,Vagrant 是保持了虛擬機與宿主機間這個目錄的同步的。
有了 /Vagrant 這個同步目錄,我們可以繼續在宿主機上使用慣用的編輯器進行開發,文件則會自動同步至虛擬機中。
Provision 軟件安裝

這一步相當于自動執行“安裝各類軟件”、“調整系統設置”等步驟。其實,這一步的操作結果可以被打包到 box 中,從而完全避免 Provision。比如,我們既可以在Provision 中安裝Python,也可以直接將一個已經安裝好 Python 的系統打包為box,然后使用該 box 創建虛擬機。兩種方式各有優劣,顯然前者更靈活、更輕量。畢竟,不是所有打包到box中的功能都為用戶所需。使用 Provision 可以最大限度的“按需定制”。

在這一步,Vagrant會可能需要調用第三方的 Provision System,比如Chef、Puppet。而最基本的Provision可以通過shell script來指定,反映在Vagrantfile中,便是如下的代碼:

Vagrant.configure("2") do |config|
...
config.vm.provision "shell", inline: "echo Hello, World"
config.vm.provision "shell", path: "script.sh"
...
end
其中,inline表示script直接寫在Vagrantfile中,而path則表示script被寫在指定的文件中。

Provision可以說是自動裝機的核心步驟,Vagrant則提供了一個方便的接口。
可以在 Vagrantfile 中定義要安裝的軟件和操作,例如我們安裝 Apache。
在與Vagrantfile同級的目錄下創建一個bootstrap.sh文件。

#!/usr/bin/env bash

apt-get update
apt-get install -y apache2
if ! [ -L /var/www ]; then
  rm -rf /var/www
  ln -fs /vagrant /var/www
fi

然后在 Vagrantfile 中使用它。

Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/precise64"
  config.vm.provision :shell, path: "bootstrap.sh"
end

"provision" 這一行告訴 Vagrant 使用 shell provisioner 去啟動機器并使用bootstrap.sh。
加入

config.vm.network :forwarded_port, guest: 80, host: 4567

可以做網絡端口轉發,然后執行 vagrant reload 或者 vagrant up 可以生效。如果之前已經在 running了,則使用 vagrant reload --provision 可以快速 restart 而跳過 initial。


image.png

image.png

訪問本地的 4567 端口,可以看到之前寫進腳本的均已成功顯示:


image.png
Share

我們做的 vagrant 是可以分享給別人的用的,只要有一個 hashicorp 賬號,vagrant login 后就可以執行 vagrant share 分享,會生成一個 URL,其它人也可以訪問到你的 vagrant 里的服務。
如果有了賬號,我們就可以通過 vagrant login 進行登錄

$ vagrant login
Username or Email: mitchellh
Password (will be hidden):
You're now logged in!

可以通過 vagrant share 來分享

$ vagrant share
...
==> default: Your Vagrant Share is running!
==> default: URL: http://frosty-weasel-0857.vagrantshare.com
...

可以通過 Ctrl+C 來中止。

中止

vagrant suspend
Vagrant halt
Vagrant destroy

三、網絡

vagrant 提供了三種網絡配置方式:端口轉發(默認)、私有網絡、公有網絡,可以在配置文件 Vagrantfile 進行網絡配置,推薦使用私有網絡。

端口轉發(forwarded ports)

1 .定義
端口轉發指把宿主機的端口映射到虛擬機的某一個端口上,訪問宿主機端口時,請求實際是被轉發到虛擬機上指定端口的。
:宿主機指運行虛擬機的物理機。

2 .優點

  • 容易實現外網訪問虛擬機

3 .缺點

  • 如果端口較少需要映射很容易,但是端口比較多時,就比較麻煩,例如:MySQL,redis,nginx等服務。
  • 不支持在宿主機使用小于1024的端口來轉發,例如:不能使用SSL的443端口來進行https連接。

4 .配置
在配置文件Vagrantfile下做如下編輯

Vagrant.configure("2") do |config|
  config.vm.network  
       "forwarded_port"(必須) //端口轉發標識
       , guest(必須): //虛擬機端口
       , host(必須): //宿主機端口,值必須大于1024
       ,guest_ip(可選): //虛擬機端口綁定虛擬機ip地址
       ,host_ip(可選): //虛擬機端口綁定宿主機ip
       ,protocol(可選)://指定通信協議,可以使用tcp/udp,默認tcp
       ,auto_correct(可選)://true/false,若配置為true,則每次開啟虛擬機的時候自動檢查是否存在端口沖突
end

:若guest_ip和host_ip兩項配置為空,則局域網下的所有設備都可以訪問該虛擬機。

示例配置,如下:

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

訪問宿主計算機8080端口的請求都轉發到虛擬機的80端口上進行處理。

私有網絡(private networks)

1 .定義
私有網絡是指只有宿主機可以訪問虛擬機,如果多個虛擬機設定在同一個網段也可以互相訪問。
2 .優點

  • 安全,只有自己可以訪問

3 .缺點

  • 團隊成員不能訪問你的虛擬機

4 .配置
使用私有網絡的最簡單方法是允許通過DHCP分配IP。

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

這將自動從保留的地址空間分配IP地址。 可以通過使用 vagrant ssh 將 SSH 連接到計算機并使用適當的命令行工具查找 IP(例如ifconfig)來確定 IP 地址。

還可以為計算機指定靜態IP地址。 可以使用已知的靜態 IP 訪問 Vagrant 受管計算機。 配置如下:

config.vm.network 
                 "private_network"http://必須 ,私有網絡標識
                 , ip: "192.168.33.10"

:私有ip可以自行指定
如果您想自己手動配置網絡接口,可以通過指定auto_config來禁用Vagrant的自動配置功能:
Vagrant.configure("2") do |config|
config.vm.network "private_network", ip: "192.168.50.4",
auto_config: false
end

公有網絡(public networks)

1 .定義
公有網絡是指設置虛擬機和宿主機有相同的網絡配置。

2 .優點

  • 方便團隊協作,別人可以訪問你的虛擬機

3 .缺點

  • 只有在有網絡的情況下才能訪問虛擬機

4 .配置

Vagrant.configure("2") do |config|
  config.vm.network 
   "public_network" //必須 公有網絡標識
  ,ip(string):  //可選,配置靜態ip
  ,bridge(string/array): "en1: Wi-Fi (AirPort)"http://可選,設置橋接的網卡
end

四、分布式環境

我們可以在 Vagrantfile 里使用 config.vm.define 方法定義多個主機:

Vagrant.configure("2") do |config|
  config.vm.provision "shell", inline: "echo Hello"

  config.vm.define "web" do |web|
    web.vm.box = "apache"
  end

  config.vm.define "db" do |db|
    db.vm.box = "mysql"
  end
end

如上,config.vm.define 采用定義一個變量的塊。 此變量(如上面的web)與config 變量完全相同,只是內部變量的任何配置僅適用于正在定義的計算機。 因此,web 上的任何配置都只會影響 web 計算機。也可以繼續使用 config 對象。 config 對象在特定于機器的配置之前加載和合并。使用這些范圍時,配置程序等事務的執行順序變得很重要。 Vagrant 按照 Vagrantfile 中列出的順序強制執行從外到內的排序。 例如,使用下面的 Vagrantfile,輸出順序為 "A", "C", "B"

Vagrant.configure("2") do |config|
    config.vm.provision :shell, inline: 'echo A'
    config.vm.define :testing do |test|
        test.vm.provision :shell, inline: 'echo B'
    end
    config.vm.provision :shell, inline: 'echo C'
end

當在 Vagrantfile 中定義了多臺計算機時,各種 vagrant 命令的使用會略有變化。
僅針對單個機器有意義的命令(例如 vagrant ssh)現在需要控制機器的名稱。例如上面的例子,需要使用 vagrant ssh web 或 vagrant ssh db。

默認情況下,其他命令(例如 vagrant up)在每臺機器上運行。因此,如果vagrant up ,Vagrant 會啟動 web 和 db 機器。也可以選擇具體啟動 vagrant up web 或 vagrant up db。此外,也可以指定正則表達式以僅匹配某些計算機。

另外,可以使用自動啟動設置允許告知 Vagrant 不啟動特定計算機。 例:

config.vm.define "web"
config.vm.define "db"
config.vm.define "db_follower", autostart: false

當使用上述設置運行 vagrant 時,Vagrant 將自動啟動 "web" 和 "db" 機器,但不會啟動 "db_follower" 機器。 可以通過運行 vagrant up db_follower 來手動強制 "db_follower" 計算機啟動。

可以指定主計算機。 主計算機將是未指定分布式環境中的特定計算機時使用的默認計算機。要指定默認計算機,只需在定義時將其標記為主計算機。 只能指定一臺主機。

config.vm.define "web", primary: true do |web|
  # ...
end

Push

從版本1.7開始,Vagrant 能夠將與 Vagrantfile 相同的目錄中的應用程序代碼部署或“推送”到遠程數據庫(如FTP服務器或HashiCorp的Atlas)。
推送的定義在應用程序的 Vagrantfile 中定義,并使用 vagrant push 子命令調用。 與 Vagrant 的其他組件非常相似,每個 Vagrant Push 插件都有自己的配置選項。 有關更多信息,請參閱Vagrant Push插件的文檔。 以下是Vagrantfile中的Vagrant Push配置部分示例:

config.push.define "ftp" do |push|
  push.host = "ftp.company.com"
  push.username = "..."
  # ...
end

當應用程序準備好部署到FTP服務器時,只需運行一個命令:

vagrant push

與 Vagrant Providers 非常相似,Vagrant Push也支持多個后端聲明。 考慮staging 和 QA 環境的常見情況:

config.push.define "staging", strategy: "ftp" do |push|
  # ...
end

config.push.define "qa", strategy: "ftp" do |push|
  # ...
end

在這種情況下,用戶必須將 Vagrant Push 的名稱傳遞給子命令:

vagrant push staging

參考:
https://www.vagrantup.com/docs/
https://jimmysong.io/posts/vagrant-intro/
http://www.lxweimin.com/p/050b0a4468c4

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評論 6 541
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,471評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,436評論 2 378

推薦閱讀更多精彩內容