Skip to content

Instantly share code, notes, and snippets.

@yano3nora
Last active April 23, 2022 19:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yano3nora/86f5a77dd139803ee321210ce5cfc6e0 to your computer and use it in GitHub Desktop.
Save yano3nora/86f5a77dd139803ee321210ce5cfc6e0 to your computer and use it in GitHub Desktop.
[dev: VirtualBox & Vagrant] VirtualBox & Vagrant note. #dev

Overview

VirtualBox - virtualbox.org

  • Oracle 社の OS 仮想化 (VM = Virtual Machine) 製品で OSS
  • いわゆるハイパーバイザ型の仮想化 (よく比較される VMware はホスト型)
  • Docker が流行ってからあんまり触ってないが、Windows 確認でたまに使う

For macOS

Windows VM

Virtual Machines - developer.microsoft.com

Microsoft が IE / Edge の開発・検証のための VM を、VirtualBox など各プラットフォーム向けに無償提供してくれている。いけめん。

  • パスワードは Passw0rd!
  • メモリ 8 GB / CPU 2 スレ / グラボ 128 MB くらいに設定しておく
  • ネットワークはデフォルトでホスト NAT 経由にしておけばだいたいいいはず
  • /Users/{USER_NAME}/Downloads とかを「共有フォルダ」として D: あたりにマウントしとくと楽
  • 準仮想化インターフェイスを Hyper-V にすると早い

ホスト OS の localhost に接続したい

Virtual Boxからlocalhostにアクセスする

  • 一応 10.0.2.2 で host に接続できる (default 設定)
  • hosts 上書きは新しいバージョンだとできないっぽい
  • netsh で portproxy を必要な port 分だけかますしかない
  • 管理者権限 command prompt から ↓ connectport を変えて localhost:3000 でいける
# よくある 3000 port の proxy
$ netsh interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=3000 connectaddress=10.0.2.2 connectport=3000

# 9000 とか 9099 とかあれば必要に応じてやる
$ netsh interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=9000 connectaddress=10.0.2.2 connectport=9000
$ netsh interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=9099 connectaddress=10.0.2.2 connectport=9099

Port Forwarding

CUIでのポートフォワード設定

# VM の確認
$ VBoxManage list vms
> "myproject_default_1528084845822_7803" {a770c439-141e-42b1-96a0-74998df80b68}

# ポートフォワーディングの Rule 未適用を確認 ( NIC 1 に Rule(0) しかない ) 
$ VBoxManage showvminfo myproject_default_1528084845822_7803 | grep '^NIC'
> NIC 1:           MAC: 080027C363C3, Attachment: NAT, Cable connected: on, Trace: off (file: none), Type: 82540EM, Reported speed: 0 Mbps, Boot priority: 0, Promisc Policy: deny, Bandwidth group: none
> NIC 1 Settings:  MTU: 0, Socket (send: 64, receive: 64), TCP Window (send:64, receive: 64)
> NIC 1 Rule(0):   name = ssh, protocol = tcp, host ip = 127.0.0.1, host port = 2222, guest ip = , guest port = 22
> NIC 2:           MAC: 08002722D18C, Attachment: Host-only Interface 'vboxnet0', Cable connected: on, Trace: off (file: none), Type: 82540EM, Reported speed: 0 Mbps, Boot priority: 0, Promisc Policy: deny, Bandwidth 

# ポートフォワーディング設定 ( 8000 ポートを利用 )
$ VBoxManage controlvm "myproject_default_1528084845822_7803" natpf1 "http,tcp,10.0.1.151,8000,,80"

# ポートフォワーディングの Rule 適用を確認 ( NIC Rule(0) に http が追加された )
$ VBoxManage showvminfo myproject_default_1528084845822_7803 | grep '^NIC'
> NIC 1:           MAC: 080027C363C3, Attachment: NAT, Cable connected: on, Trace: off (file: none), Type: 82540EM, Reported speed: 0 Mbps, Boot priority: 0, Promisc Policy: deny, Bandwidth group: none
> NIC 1 Settings:  MTU: 0, Socket (send: 64, receive: 64), TCP Window (send:64, receive: 64)
> NIC 1 Rule(0):   name = http, protocol = tcp, host ip = 10.0.1.151, host port = 8080, guest ip = , guest port = 80
> NIC 1 Rule(1):   name = ssh, protocol = tcp, host ip = 127.0.0.1, host port = 2222, guest ip = , guest port = 22
> NIC 2:           MAC: 08002722D18C, Attachment: Host-only Interface 'vboxnet0', Cable connected: on, Trace: off (file: none), Type: 82540EM, Reported speed: 0 Mbps, Boot priority: 0, Promisc Policy: deny, Bandwidth 

# 必要ならば firewalld 設定
$ firewall-cmd --add-port=8000/tcp --zone=public --permanent
$ firewall-cmd --reload
$ firewall-cmd --list-ports --zone=public
> 8000/tcp

# Rule の削除
$ VBoxManage controlvm myproject_default_1528084845822_7803 natpf1 delete browse

# firewalld ポート設定の削除
$ firewall-cmd --remove-port=8080/tcp --zone=public --permanent
$ firewall-cmd --reload

Overview

VirtualBox - virtualbox.org
Vagrant - HashiCorp
Vagrant Documentation - www.vagrantup.com

Vagrant は Virtual Box のラッパーツール。Ruby で Virtual Box の CLI 操作やビルドスクリプトを管理できることに加えて、ビルド手順を Vagrantfile という Ruby スクリプトで設定することで、ローカル開発環境のビルド → デプロイを自動化・Git 管理可能にする。

Installation

Installing Vagrant - Vagrant Documentation

  1. VirtualBox インストール
  2. Vagrant インストール > 再起動
  3. Box ( VM イメージ ) の DL
    • $ vagrant box add ${BOX_NAME} ${URL}
  4. プラグインのインストール
    • $ vagrant plugin install vagrant-vbguest
    • $ vagrant plugin install vagrant-hostsupdater

未検証だけど、ホスト側の JIS 配列キーボードをゲスト側 US 配列に直すのは ↓ が参考になりそう。

https://qiita.com/the_red/items/a3a036b8d53418f59a5c

for mac

https://medium.com/@gigmuster/mac-os%E3%81%ABvirtual-box%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB-fd9d38ad7055

Plugins

Boxes

Boxes - Vagrant Documantation Vagrant Cloud

Vagrant は Box と呼ばれるイメージから VM をビルドする。仮想化プロバイダーは基本 VirtualBox ( HashiCorp 公式 Box は VMware も OK らしいが ) で、この Box を元ネタとして仮想マシンをビルドするのが一般的な環境構築手順。Vagrant Cloud では様々なベンダが開発している Box が公開されているので、用途に合わせて導入していく。

bento の box を使う

bento - Vagrant Cloud
chef/bento - github.com
Bentoを使って、安心でオイシイVagrant Boxを今すぐに!

Ubuntu や CentOS ( 6.x / 7.x ) など Linux ベースイメージは大体ここで揃う。


Usage

基本的にプロビジョンのための Ruby スクリプト Vagrantfile を書き上げて vagrant コマンドをぶったたく流れ。

Commands

Command-Line Interface - Vagrant Documentation

# VM 起動
$ vagrant up

# プロビジョン読込 ( 以下のいずれか )
$ vagrant provision
$ vagrant reload --provision
$ vagrant up --provision

# VM へ SSH 接続
$ vagrant ssh

# VM の停止
$ vagrant halt

# VM の削除
$ vagrant destroy

# VM のエクスポート
$ vagrant package  # package.boxという名前のBoxファイルが生成される

# 仮想マシンインポート
$ vagrant box add new_box package.box

# 全 VM ステータス
$ vagrant global-status
> id       name    provider   state    directory
> -------------------------------------------------
> 9dfaf82  default virtualbox poweroff D:/git/vm_hoge
> 0ca4fee  default virtualbox running  D:/git/vm_fuga

# プラグインインストール
$ vagrant plugin install vagrant-vbguest
$ vagrant plugin install vagrant-hostsupdater

# インストール済みプラグイン一覧
$ vagrant plugin list
> vagrant-hostsupdater (1.0.2)
> vagrant-share (1.1.9, system)
> vagrant-vbguest (0.15.0)

Vagrantfile

Vagrantfile - Vagrant Documentation

# ===========================================
# Vagrant sample ( v1.9.1 )
# @see https://github.com/yano3nora/lampcake
# ===========================================
Vagrant.configure("2") do |config|
  config.vm.box = "bento/centos-6.7"
  config.vbguest.auto_update  = false
  config.vbguest.no_remote    = true
  config.vm.hostname          = "example.test"
  config.hostsupdater.aliases = ["example.test"]
  config.vm.synced_folder ".", "/var/www"#, mount_options: ['dmode=777','fmode=777']
  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.provision "shell", inline: <<-SHELL
    # Setup server local time.
    sudo rm /etc/localtime
    sudo ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
  SHELL
  config.vm.provision :shell, :path => "./provision_batch.sh", :privileged => true, :env => {
    :ENV          => "development"
    :PROJECT_ROOT => "/var/www"
    :WEB_ROOT     => "/var/www/public"
  }
  config.vm.provision :shell, run: "always", :inline => <<-SHELL
    sudo setenforce 0
    sudo date
  SHELL
end

Netrworking

Basic Usage of Networking

Provisioning

Basic Usage of Provisioning

環境変数のセット

config.vm.provision のプロビジョナー内で export FOO="hogehoge" のように環境変数をセットしても他のプロビジョナーは参照できない。この場合 env オプションにハッシュを渡すことで内部のバッチなどに環境変数を渡せる。

# Vagrantfile
envs_app_1 = {:DB_NAME => 'db_1', :DB_USER => 'db_user_1', :DB_PASS => 'password'}
envs_app_2 = {:DB_NAME => 'db_2', :DB_USER => 'db_user_2', :DB_PASS => 'password'}

Vagrant.configure("2") do |config|
  config.vm.provision :shell, :path => "./batch_for_app_1.sh", :privileged => true, :env => envs_app_1
  config.vm.provision :shell, :path => "./batch_for_app_2.sh", :privileged => true, :env => envs_app_2
end

Synced Folders

Basic Usage

同期ディレクトリを nfs ではなく rsync で行う

Vagrant 1.5 からの新機能。同期ディレクトリの I/O 速度向上、パーミッション問題を解決してくれる。利用にはホスト OS とゲスト OS 両方に rsync が必要。Linux なら Vagrant が自動的にインストールしてくれるが、ホスト OS が Windows なら先に Chocolateyrsync をインストールする必要あり。

# Vagrantfile
config.vm.synced_folder '.', '/app', type: 'rsync',
  rsync__args: %w(--verbose --archive --delete -z --copy-links --times),
  rsync__chown: false,
  rsync__exclude: ['.git/']

VM のメモリ設定

デフォルトだとメモリは 512 MB 程度になっているため、本番環境を想定した重ため処理などをテストする際には増設してあげる ( 当然ホスト OS 依存 ) 。加えて MySQL などミドルウェアのメモリ設定も調整してあげる と良い。

# Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.provider "virtualbox" do |vm|
    vm.memory = 2048  # 2048 MB に設定
  end
end

HTTPS 対応

Windows で Vagrant のクリーンアンインストール

Windows の場合通常のアンインストールに加えて、格納されていた C:\HashCorp~\.vagrant.d を削除する必要がある。

SFTP でアクセス

Vagrant は内部的に vagrant ssh でログインできるように、ビルド時にホスト OS とゲスト OS 間で SSH 鍵公開を済ませて、ユーザ名「vagrant」パスワード「vagrant」ポート「22」で接続可能にしている。よって、以下設定で SFTP 接続可能。

  • protcol: sftp
  • host: 192.168.33.10 ( private_networkで指定した奴 )
  • port: 22
  • user: vagrant
  • pass: vagrant

Trouble Shooting

VirtualBox や Ruby ( Vagrant ) のゾンビプロセスが原因のエラーが結構多い。プロセスを Kill して ( または PC を再起動して ) 再実行して再現するかどうか?が最初の切り分けポイント。

また、マウントエラーについてはホスト OS が利用している VirtualBox / Vagrant 両バージョンと、Box イメージ Linux カーネルとの相性問題がある。具体的に VirtualBox 系イメージであれば、イメージ内の VirtualBox Guest Addition ( ホスト OS とゲスト OS の環境差異を吸収するやつ ) のバージョンが違うことに起因するマウントエラーが頻発する。

これについて多くのケースでは vagrant-vbguest プラグインがうまいことやってくれる。逆にプラグインで解消できない場合、自分で解決するのは至難の業なのでアプリケーションのバージョンを揃えるなどしたほうが早い。

Vagrant 上 WEB サーバに Edge アクセスできない

Edge の Fuck セキュリティポリシーによるもの。ポートフォワーディングか、ホスト OS の localhost に開発用サーバを起動して VM にプロキシして対処。

Microsoft Edgeでローカルの仮想マシン上に構築したWebサイト(Webアプリケーション)にアクセスできない

config.vm.network "forwarded_port", guest: 8080, host: 8080
# http://localhost:8080 でアクセス可能
# 当然ポートは空けておくこと

VirtualBox と Vagrant のネットワークデフォルト IP アドレスが異なるケース

VirtualBox と Vagrant のバージョンによって、デフォルトで利用する Private Network のアドレス帯が異なるケースがある。この場合は VirtualBox の File > Preferences > Network > Host-only Networks から NIC の利用 IP アドレスを変更すること。

# Vagrantfile
config.vm.network "private_network", ip: "192.168.33.10"
 ↓
# VirtualBox NIC Adapter
IPv4 Address : 192.168.33.1
IPv4 Mask    : 255.255.255.0

VM 内部で npm install 等がエラー吐きまくる

前提として Vagrant というか VirtualBox によって同期されたディレクトリ内部では シンボリックリンクを適切に貼ることができない 。また Windows x Linux の組み合わせでは「ファイル名の長さ制限」の問題が ( Windows 側に ) あるためホスト OS でやれ。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment