## 介紹
[Vagrant](https://developer.hashicorp.com/vagrant) 可以迅速建立虛擬主機配置環境,不需要再像 Vitrual Box 將整個 OS 安裝一遍,只需要使用 [Vagrant boxes](https://developer.hashicorp.com/vagrant/docs/boxes) 就可以馬上獲得一個作業系統。在 [Vagrant Cloud](https://app.vagrantup.com/boxes/search) 上就能搜尋需要的 box 來使用,尤其官方特邊推薦 [Bento Boxes](https://app.vagrantup.com/bento) 中的 boxes,除了大部分為知名創作者外,大部分品質穩定且也都在 Github 上開源。
## 安裝
直接到 [Vagrant 官網](https://developer.hashicorp.com/vagrant/downloads)下載相對應的版本即可。
本人使用 Windows 做示範,請使用 Windows 可執行的 Bash CMD 即可。
## 示範
### 1. 版本顯示
輸入:
```
$ vagrant version
```
輸出:
```
Installed Version: 2.3.7
Latest Version: 2.3.7
You're running an up-to-date version of Vagrant!
```
### 2. 初始化 box
輸入:
```
$ mkdir ~/Desktop/workspace
$ cd ~/Desktop/workspace
$ vagrant init bento/centos-7.9
```
輸出:
```
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.
```
注意:若資料夾內已有 Vagrantfile 時則不能重複初始化新的 box。
### 3. 啟動 box
輸入:
```
$ vagrant up
```
輸出:
```
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'bento/centos-7.9' could not be found. Attempting to find and install...
default: Box Provider: virtualbox
default: Box Version: >= 0
==> default: Loading metadata for box 'bento/centos-7.9'
default: URL: https://vagrantcloud.com/bento/centos-7.9
==> default: Adding box 'bento/centos-7.9' (v202303.13.0) for provider: virtualbox
default: Downloading: https://vagrantcloud.com/bento/boxes/centos-7.9/versions/202303.13.0/providers/virtualbox.box
default:
==> default: Successfully added box 'bento/centos-7.9' (v202303.13.0) for 'virtualbox'!
==> default: Importing base box 'bento/centos-7.9'...
==> default: Matching MAC address for NAT networking...
==> default: Checking if box 'bento/centos-7.9' version '202303.13.0' is up to date...
==> default: Setting the name of the VM: workspace_default_1689059864043_23910
==> default: Fixed port collision for 22 => 2222. Now on port 2200.
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
default: Adapter 1: nat
==> default: Forwarding ports...
default: 22 (guest) => 2200 (host) (adapter 1)
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 127.0.0.1:2200
default: SSH username: vagrant
default: SSH auth method: private key
default:
default: Vagrant insecure key detected. Vagrant will automatically replace
default: this with a newly generated keypair for better security.
default:
default: Inserting generated public key within guest...
default: Removing insecure key from the guest if it's present...
default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
default: The guest additions on this VM do not match the installed version of
default: VirtualBox! In most cases this is fine, but in rare cases it can
default: prevent things such as shared folders from working properly. If you see
default: shared folder errors, please make sure the guest additions within the
default: virtual machine match the version of VirtualBox you have installed on
default: your host and reload your VM.
default:
default: Guest Additions Version: 7.0.6
default: VirtualBox Version: 6.1
==> default: Mounting shared folders...
default: /vagrant => C:/Users/Kurt/Desktop/workspace
```
注意:因首次啟動需要下載整份 box,所以耗時會較久
### 4. ssh box
輸入:
```
$ vagrant ssh
```
輸出:
```
This system is built by the Bento project by Chef Software
More information can be found at https://github.com/chef/bento
[vagrant@localhost ~]$
```
#### 此時我們已進入這個 box 之中,而我們這次使用的系統是 CentOS 7.9。
輸入:
```
$ cat /etc/*release*
```
輸出:
```
CentOS Linux release 7.9.2009 (Core)
Derived from Red Hat Enterprise Linux 7.9 (Source)
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
CentOS Linux release 7.9.2009 (Core)
CentOS Linux release 7.9.2009 (Core)
cpe:/o:centos:centos:7
```
注意:通常默認的密碼為 `vagrant`,若無法登入上網查應該也有答案。
### 5. 關閉 box
輸入:
```
$ vagrant halt
```
輸出:
```
==> default: Attempting graceful shutdown of VM...
```
### 6. 命名此 box
因預設初始化 box 時通常命名為 default,當太多 box 在執行時會產生錯亂。
輸入:
```
$ vagrant status
```
輸出:
```
Current machine states:
default poweroff (virtualbox)
The VM is powered off. To restart the VM, simply run `vagrant up`
```
我們只需要在 Vagrantfile 中增加 define 的設定即可。
Vagrantfile:
```
Vagrant.configure("2") do |config|
config.vm.box = "bento/centos-7.9"
config.vm.define "Training_for_TS"
end
```
此時再將 box up 之後就能看到 box 已更名為 Training_for_TS。
輸入:
```
$ vagrant.exe up
```
輸出:
```
Bringing machine 'Training_for_TS' up with 'virtualbox' provider...
==> Training_for_TS: Importing base box 'bento/centos-7.9'...
==> Training_for_TS: Matching MAC address for NAT networking...
==> Training_for_TS: Checking if box 'bento/centos-7.9' version '202303.13.0' is up to date...
==> Training_for_TS: Setting the name of the VM: workspace_Training_for_TS_1689061454221_81981
==> Training_for_TS: Fixed port collision for 22 => 2222. Now on port 2200.
==> Training_for_TS: Clearing any previously set network interfaces...
==> Training_for_TS: Preparing network interfaces based on configuration...
Training_for_TS: Adapter 1: nat
==> Training_for_TS: Forwarding ports...
Training_for_TS: 22 (guest) => 2200 (host) (adapter 1)
==> Training_for_TS: Booting VM...
==> Training_for_TS: Waiting for machine to boot. This may take a few minutes...
Training_for_TS: SSH address: 127.0.0.1:2200
Training_for_TS: SSH username: vagrant
Training_for_TS: SSH auth method: private key
Training_for_TS:
Training_for_TS: Vagrant insecure key detected. Vagrant will automatically replace
Training_for_TS: this with a newly generated keypair for better security.
Training_for_TS:
Training_for_TS: Inserting generated public key within guest...
Training_for_TS: Removing insecure key from the guest if it's present...
Training_for_TS: Key inserted! Disconnecting and reconnecting using new SSH key...
==> Training_for_TS: Machine booted and ready!
==> Training_for_TS: Checking for guest additions in VM...
Training_for_TS: The guest additions on this VM do not match the installed version of
Training_for_TS: VirtualBox! In most cases this is fine, but in rare cases it can
Training_for_TS: prevent things such as shared folders from working properly. If you see
Training_for_TS: shared folder errors, please make sure the guest additions within the
Training_for_TS: virtual machine match the version of VirtualBox you have installed on
Training_for_TS: your host and reload your VM.
Training_for_TS:
Training_for_TS: Guest Additions Version: 7.0.6
Training_for_TS: VirtualBox Version: 6.1
==> Training_for_TS: Mounting shared folders...
Training_for_TS: /vagrant => C:/Users/Kurt/Desktop/workspace
```
輸入:
```
$ vagrant status
```
輸出:
```
Current machine states:
Training_for_TS 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`.
```
### 7. 打包 box
打包 box 的目的是為了讓其他人能用完全相同的開發環境,這樣才能確保所有人都是在相同的基礎上開發。
打包需要在 box 為關機狀態下才能進行。
輸入:
```
$ vagrant package
```
輸出:
```
==> Training_for_TS: Clearing any previously set forwarded ports...
==> Training_for_TS: Exporting VM...
==> Training_for_TS: Compressing package to: C:/Users/Kurt/Desktop/workspace/package.box
```
打包完成後會出現一個新檔案 package.box,此時只需要將此 package.box 傳給其他組員,其他組員就能使用相同的環境開發。
### 8. 新增 box
當拿到 box 或 box 的 url,我們可以使用指令加入到我們的環境中。
首先我們先確認我們環境中有那些 box。
輸入:
```
$ vagrant box list
```
輸出:
```
bento/centos-7.9 (virtualbox, 202303.13.0)
```
使用指令將 package.box 加到我們的 list 中。
輸入:
```
$ vagrant box add TS_team package.box
```
輸出:
```
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'TS_team' (v0) for provider:
box: Unpacking necessary files from: file://C:/Users/Kurt/Desktop/workspace/package.box
box:
==> box: Successfully added box 'TS_team' (v0) for 'virtualbox'!
```
#### 注意:package.box 的位置可以是一個檔案或 url。
此時我們確認 box list 中已增加了 TS_team 這個 box。
輸入:
```
$ vagrant box list
```
輸出:
```
TS_team (virtualbox, 0)
bento/centos-7.9 (virtualbox, 202303.13.0)
```
最後我們只需要在新的資料夾內初始化這個 box,就能得到一模一樣的開發環境了。
輸入:
```
$ mkdir ~/Desktop/TS_team
$ cd ~/Desktop/TS_team
$ vagrant init TS_team
$ vagrant status
$ vagrant ssh
```
## 結語
有時團隊在開發時可能會共用開發環境,但這其實可能並不是太好的做法,如果大家各自能拿到一模一樣的開發環境,並分別開發,最後再用各自的版本控制合在 Staging 上並測試,或許也是一個不錯的方案。
主要會想使用這個方法的契機為 TS Team 在 training 時發現各個工程師的環境不盡相同,有人使用 CentOS7,有人用 docker,也有人用 RHEL9,而此次剛好又是 DB 相關的 training,還需要各自再倒資料進 DB,耗費許多時間。若一開始準備好已倒好資料的環境給每個人使用,就可以減少前期在建置的這些時間。
原有使用 Virtual Box 的人也可以試著使用 Vagrant 看看,雖然 Vagrant 是建立在 Virtual Box 之上,但省下下載 iSO 和安裝的時間,可以利用這些時間做更多的事,也是更好的方案。