# vm-02. Vagrant
________________________________________
## 1. Overview & Install
________________________________________
Overview & terms
- VirtualBoxなどの補助ツール
- VM作成をコマンド1行で実現する
- VMの作成先は、Virtual Boxの設定で決まる
- VMの設定はVagrantfileに記述する
- box (=雛形)
- Vagrantfile ユーザーboxレベル(=設定ファイル)
- Vagrantfile 環境毎レベル(=設定ファイル)
- デフォルトのVagrantfileは共有フォルダでエラーが出る
Install
1. Install virtualbox by installer.
2. Install vagrant by installer.
________________________________________
## 2. How to Use
________________________________________
Get box from web & add plugin.
```shell
vagrant box add ubuntu/focal64
vagrant box list
vagrant plugin install vagrant-vbguest
```
Create vagrant settings & vm
```shell
mkdir Vagrant\vm02
cd Vagrant\vm02
# vagrant init ubuntu/focal64 (or prepare the following vagrantfile.)
vagrant up
vagrant reload
```
Guest Addition がうまくいかない場合
1. sshでVMにログインしてsudo yum update -y
2. 外部に戻って、vagrant reload
3. VM起動中にGuest Addtionのインストール処理が正常に行われれば成功
4. これでも駄目な場合が稀にあり(最新版のCentOSとGuest Addtionで適切にバージョン解決できない場合)
- Oracle Linuxなど変則的なディストリビューションで頻出する。大抵はエラーにどのkernelを入れろと言われるので入れる
- sudo yum install kernel-xxx-devel-x.x.x...
Vagrantfile sample (for ubuntu/focal64)
```ruby
# デフォルトとの違い
# 1. ホスト名がVagrantfileの親フォルダ名になるように
# 2. 第2アダプタとしてブリッジ接続追加。ipを192.168.3.254で固定、localhostポートフォワードも明示
# 3. Vagrantfile(boxグローバル)のconfig.vm.synced_folder設定を無効化するような設定を記述
# 4. Guest Additionによる共有フォルダ設定を追加
# 5. gui=true、メモリ=1024
# 6. VM名が、ホスト名と一致するように
# 7. x11forwardingを有効化
# -*- 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://atlas.hashicorp.com/search.
config.vm.box = "ubuntu/focal64"
# Parent directory name for Vagrantfile
config.vm.hostname = File.basename(File.dirname(__FILE__))
# 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.
# config.vm.network "forwarded_port", guest: 80, host: 8080
# 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", ip: "192.168.3.254"
config.vm.network "forwarded_port", guest: 22, host: 2254, id: "ssh"
config.ssh.forward_x11 = true
# 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"
# Disable global Vagrantfile setting
config.vm.synced_folder ".", "/vagrant", disabled: true
config.vm.synced_folder "./vagrant_shared", "/home/vagrant/vagrant_shared", create:true, type:"virtualbox"
config.vm.synced_folder "./var_www", "/var/www", create:true, type:"virtualbox"
# 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"
# parent directory name
vb.name = config.vm.hostname
end
#
# View the documentation for the provider you are using for more
# information on available options.
# Define a Vagrant Push strategy for pushing to Atlas. Other push strategies
# such as FTP and Heroku are also available. See the documentation at
# https://docs.vagrantup.com/v2/push/atlas.html for more information.
# config.push.define "atlas" do |push|
# push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME"
# end
# 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
config.vm.provision "shell", inline: <<-SHELL
sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
if sudo getenforce | grep -c Enforcing; then
sudo setenforce 0
fi
SHELL
config.vm.provision "shell", run: "always", inline: <<-SHELL
if [ -e /etc/redhat-release ] || [ -e /etc/fedora-release ] || [ -e /etc/centos-release ] || [ -e /etc/oracle-release ]; then
distribution="redhat-like"
fi
if cat /etc/os-release | grep -c Ubuntu; then
distribution="ubuntu"
fi
echo "distribution="$distribution
if [ $distribution = "redhat-like" ]; then
if systemctl list-unit-files --type=service | grep -c httpd; then
if [ ! -e /etc/httpd/conf.d/nfsmode.conf ]; then
sudo touch /etc/httpd/conf.d/nfsmode.conf
{
echo ""
echo " EnableMMAP Off"
echo " EnableSendfile Off"
echo ""
} >> /etc/httpd/conf.d/nfsmode.conf
fi
echo "restart httpd"
mkdir -p -m 777 /var/www/html;
mkdir -p -m 777 /var/www/cgi-bin;
sudo systemctl restart httpd.service
else
echo "httpd not found."
fi
elif [ $distribution = "ubuntu" ]; then
if systemctl list-unit-files --type=service | grep -c apache2; then
echo "restart apache2"
sudo systemctl restart apache2.service
else
echo "apache2 not found."
fi
fi
SHELL
end
```
Login user
- vagrant/vagrant (ローカルログインの場合)
- vagrant/パスワードなし、秘密鍵 (sshの場合)(*1)
(*1) ./.vagrant/machines/default/virtualbox/private_key
エンコードエラーの場合
```ruby
# C:/HashiCorp/Vagrant/embedded/gems/gems/vagrant-1.9.5/lib/vagrant/util/io.rb:32
# Encoding::UndefinedConversionError
data << io.readpartial(READ_CHUNK_SIZE).encode("Windows-31J", Encoding.default_external)
```
________________________________________
## 3. VMのbox出力 & vagrant up
________________________________________
VMのbox化と利用
1. VM停止状態 + box化元のVagrantfileのある位置へ移動
2. vagrant package --output
3. Vagrantfileとboxファイルを渡す
4. vagrant box add <任意の命名(box名)>
5. Vagrantfileのbox名を<任意の命名(box名)>に書き換える
6. 任意の空フォルダ + 上記Vagrantfile
7. vagrant up
8. vagrant ssh-config
9. 他、共有フォルダ内に必須フォルダがいない場合、生成
VMのbox化と利用の補足
1. boxとVagrantfileをセットで用意する必要がある
2. Vagrantfile内のbox名は、addする時に命名した名前
3. 自前でbox化したboxの場合、private_keyの保存場所が異なる
4. インストール時に共有フォルダ先に自動生成されるディレクトリ等は、再現する必要がある
(本テキストのVagrantfileの場合、/var/www/htmlやcgi-bin)
________________________________________
## 4. ネットワーク資料
________________________________________
VM内部
```ini
# /etc/sysconfig/network
# 空
# /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE="eth0"
BOOTPROTO="dhcp"
ONBOOT="yes"
TYPE="Ethernet"
PERSISTENT_DHCLIENT="yes"
# /etc/sysconfig/network-scripts/ifcfg-eth1
#VAGRANT-BEGIN
BOOTPROTO=dhcp
ONBOOT=yes
DEVICE=eth1
#VAGRANT-END
# /etc/sysconfig/network-scripts/ifcfg-lo
# VirtualBoxで作成した場合と同一
```
VirtualBox
```text
アダプタ1:NAT、ssh://127.0.0.1:2222をゲストへport-forward
アダプタ2:Bridge(public_network指定の場合のみ)
※ Vagrantで作ったVMをデフォで複数起動するとport-forwardが被る
※ vagrant up時のオプションで上記を自動割り当てすることも可能
```
________________________________________
## 5. コマンド資料
________________________________________
box操作
- vagrant box add box名
- vagrant box remove box名
- vagrant box list
- vagrant package --output
- vagrant box add <任意の命名(box名)>
VM操作
- vagrant init box名
- vagrant up
- vagrant halt
- vagrant destroy
- vagrant ssh-config
VMへのログイン(複数起動中の場合は、指定)
- vagrant ssh
VMのsshエイリアスをhost環境にfooとして追記する方法
```shell
# MAC, Unix
# vagrant ssh-config --host foo >> ~/.ssh/config
# Windows
vagrant ssh-config --host foo >> %USERPROFILE%/.ssh/config
# 同時起動がないなら、上記でOK
# 複数同時起動の場合、BridgeのIP & Port=22に書き換えオススメ
```