vagrant+dockerで仮想環境を使い捨てるための環境の準備

# 改訂履歴
|更新日|内容|
|:-:|:-:|
|2021-05-04|ubuntuを16→20にした。<br />それに伴ってCVE-2019-5736対応が不要になったり、<br />tzdataのインストールが不要になったりした。<br />saharaプラグインを追加した。<br />wsl2と共存したときにvagrant upできなくなる現象を回避するための設定を追加した。[参考](https://bugs.launchpad.net/cloud-images/+bug/1829625) |
|2019-05-29|CVE-2019-5736対応で、ubuntu上でdockerを動かすにはカーネルアップデートが必要になったしまった・・・ので、それへの対応。<br />それとvagrant-disksizeプラグインを追加|
|2019-12-08|TZパラメタが効いてなかったぽいのでVagrantfileにtzdataのインストールを追加|

# この文書の目的
- 対象
  - 仮想環境ナニソレ？な人
- 対象に到達してもらう地点
  - vagrantまたはdockerで配布する仮想環境を、upコマンドで構築できる状態になること
- 補足
  - 調べてすぐ出てくるような箇所については、手順として触れるだけで端折ります

# 構築する環境、用いる用語
- 構築する環境

|対象|入れるもの|どうなる|
|:-:|:-:|:-:|
|Windows|VirtualBoxとVagrant|Vagrant形式で配布される環境を受け入れられるようになります|
|Vagrant|Docker用のlinux環境|Docker形式で配布される環境を受け入れられるようになります|

- 用いる用語

|用語|本記事における意味|
|:-:|:-:|
|ホストOS|Windows|
|ゲストマシン、ゲストOS|Vagrant上で構築するlinux環境マシンとそのOS。|
|コンテナ|ゲストOS上で構築するdocker環境|

# 手順
## BIOSの設定
- 概要
  - Windowsでは、仮想環境を使うために必要な設定項目がBIOS上にあります。未設定であればやってください。
- 手順
  - PCメーカーごとに異なるため、ここで全て説明するのは困難です。メーカーのwebサイトを参照ください。「BIOS 仮想環境」などでぐぐれば出ます。例：lenovo https://support.lenovo.com/jp/ja/solutions/ht500006

## VirtualBoxのインストール
- 概要
  - ゲストOSを作るためのソフトです。VirtualBoxの操作自体は後述のVagrantによって行うため、直接操作することは基本的にはありません。
- 手順
  - https://www.virtualbox.org/ からダウンロードしてインストールしてください。最新版にしておくのが無難だと思います。

## Vagrantのインストール
- 概要
  - VirtualBoxをはじめとした仮想環境ツールを、コマンドラインや設定ファイルで動かすためのソフトです。
- 手順
  - https://www.vagrantup.com/ からダウンロードしてインストールしてください。最新版にしておくのが無難かと思います。

## Vagrantのプラグインインストール
- 概要
  - 文書の目的にある「配布されるVagrant環境の利用」にあたって、必要になると思われるプラグインを一通りインストールします。
- 対象プラグイン
- 
| 名称 | なにそれ | 無かったらどうなる |
|:-:|:-:|:-:|
|vagrant-vbguest|VirtualBoxのGuestAdditionというツールのバージョンを自動調整してくれる|構築する環境ごとにVirtualBoxを再設定しないとエラーが出て面倒|
|vagrant-proxyconf|Vagrantでプロキシを設定できるようになる|proxy必須な環境だとゲストOS内でプロキシ設定作業が必要|
|vagrant-docker-compose|Vagrantで作るゲストOS上でdocker-composeが使えるようになる|ゲストOSでいちいちdocker-composeをインストールしないといけない|
|vagrant-disksize|ゲストOSのディスクサイズをVagrantfile上で指定できるようになる|ディスクを拡張するのが面倒|
|sahara|vmのsave/loadができるようになる|VirtualBoxの機能で代替できなくはないけど面倒|

- 手順
  - コマンドラインで以下を入力します

```
vagrant plugin install vagrant-vbguest
vagrant plugin install vagrant-proxyconf
vagrant plugin install vagrant-docker-compose
vagrant plugin install vagrant-disksize
vagrant plugin install sahara
```

## Vagrant環境の受け入れ準備完了
配布される環境がVagrantのものなら、ここまでで完了です。
配布されるのがDocker環境の場合はこの先も行ってください。

## Docker用ゲストOSの作成
### Vagrantfileの作成
- 概要
  - 配布されるdocker環境を動かすためのゲストOSの設定を作成します。
- 手順
  - テキストファイル（ファイル名：Vagrantfile）を新規作成します。

``` :Vagrantfile
Vagrant.configure("2") do |config|

  # --- boxの設定 ---
  # vagrant/dockerが動けばなんでもいいけど、安心できそうなubuntuで。
  # virtualboxの設定箇所に関連項目があるので注意。
  config.vm.box = "ubuntu/focal64"
  # config.disksize.size = "50GB"

  # 環境の変化を避けるため、チェックを省略とする
  # config.vm.box_check_update = false

  # 配布する環境が同一内容になることを意識し、ゲスト接続用のsshキーも共通のものを使う
  config.ssh.insert_key = false

  # ゲストOSにはプライベートネットワーク接続とする
  config.vm.network "private_network", ip: "192.168.3.11"

  # デフォルト以外の共有フォルダが必要なときはコメントを外して設定する
  # config.vm.synced_folder "../data", "/vagrant_data"


  # --- VirtualBoxの設定 ---
  config.vm.provider "virtualbox" do |vb|
    # ホストが32bitOSのときに64bitOSを動かすために必要。
    vb.customize ["modifyvm", :id, "--ostype", "Ubuntu_64"]
    # メモリを拡張しておかないと、コンテナによっては起動すらできない
    vb.memory = "2048"

    # VirtualBox6.1.16以降はWSL2と共存できるようになったが、
    # vagrant up時に "SSH auth method:" のところから進まない現象があった。
    # それを回避するための設定。
    # 参考：https://bugs.launchpad.net/cloud-images/+bug/1829625
    # vb.customize ["modifyvm", :id, "--nestedpaging", "off"]
    # vb.customize ["modifyvm", :id, "--paravirtprovider", "hyperv"]
    # vb.customize ["modifyvm", :id, "--uart1", "0x3F8", "4"]
    # vb.customize ["modifyvm", :id, "--uartmode1", "file", File::NULL]
  end

  # --- proxyプラグインの設定 ---
  # proxyが必要ならコメントを外して設定する。これによりゲストOSにProxy設定が為される
  # if Vagrant.has_plugin?("vagrant-proxyconf")
  #   config.proxy.http     = "http://hogeproxy:8080/"
  #   config.proxy.https    = "https://hogeproxy:8080/"
  #   config.proxy.no_proxy = "localhost,127.0.0.1,.example.com"
  # end


  # --- dockerの設定。これでゲストOSでdockerコマンドが使える ---
  config.vm.provision :docker

  # --- シェルでのプロビジョン ---
  # シェルでゲストOSの初期設定
  config.vm.provision "shell", privileged: false, inline: <<-SHELL
      # タイムゾーン設定。やっておかないとUTCになる。
      sudo timedatectl set-timezone Asia/Tokyo

      # パッケージ一覧更新
      sudo apt-get update

      # docker-composeでタイムゾーン設定をするために必要
      # boxに最初から入っていれば不要。ubuntu20では不要。
      # sudo apt-get install -y --no-install-recommends tzdata

      # ゲストOSにssh接続した際の初期ディレクトリは/home/vagrantだが、
      # ssh接続時に用があるのは大概/Vagrant以下なので、
      # .profile内の処理で初期ディレクトリを移動するようにする
      echo 'cd /vagrant' >> /home/vagrant/.profile

  SHELL

  # --- docker-composeの設定。これでゲストOSでdocker-composeコマンドが使える ---
  # ・https://github.com/leighmcculloch/vagrant-docker-compose
  #   バージョンを指定しない場合、デフォルト値は最新版ではない。
  #   2021/04/16時点では、デフォルト値1.24.1、最新版は1.29.1
  # ・vagrant up時にdocker-compose up まで行いたいときは、
  # 　行途中の#を外してymlオプションを有効にしてdocker-compose.ymlまでのパスを記載
  # config.vm.provision :docker_compose, compose_version: "1.24.0" #, yml: "docker-compose.yml"
  config.vm.provision :docker_compose
end
``` 
### ゲストOS用のディレクトリを確保
任意のディレクトリ内に、前項で作成したVagrantfileを置きます。
他にもワークファイルが作られたりするので、専用のディレクトリであることが望ましいです。
あとで移動したくなったら移動できます。

### ゲストOSを起動
以下、コマンドラインで。
OSイメージのダウンロードも一緒に行うため、回線によっては数分～数十分かかります。

```cmd.exe
cd [Vagrantfileを置いたディレクトリ]
vagrant up
```

### 接続テスト
1. vagrantのsshコマンドで接続

```cmd.exe
cd [Vagrantfileを置いたディレクトリ]
vagrant ssh
```

```結果
Welcome to Ubuntu 14.04.5 LTS (GNU/Linux 3.13.0-155-generic x86_64)
(略)
Last login: Sat Aug 18 14:50:31 2018 from XXX.XXX.XXX.XXX(伏)
vagrant@vagrant-ubuntu-trusty-64:/vagrant$
```

2. sshクライアント接続
sshクライアントがあればですが、プライベートネットワークのアドレスへも接続してみます。ユーザーとパスはvagrant/vagrantです。
タイムゾーンが正しいこともついでに確認します。
(Last Loginが、さっきのvagrant ssh の日時になるはずです)

```結果
login as: vagrant
vagrant@192.168.33.10's password:
Welcome to Ubuntu 14.04.5 LTS (GNU/Linux 3.13.0-155-generic x86_64)
(略)
Last login: Tue Aug 21 20:35:41 2018 from XXX.XXX.XXX.XXX(伏)
```

3. dockerコマンド
dockerコマンド、docker-composeコマンドが使えるかどうかも確認しておきます。

```
vagrant@vagrant-ubuntu-trusty-64:/vagrant$ docker --version
Docker version 18.06.0-ce, build 0ffa825
vagrant@vagrant-ubuntu-trusty-64:/vagrant$ docker-compose --version
docker-compose version 1.22.0, build f46880fe
vagrant@vagrant-ubuntu-trusty-64:/vagrant$
```

OK。

## Docker環境の受け入れ準備完了
以上で準備は完了です。
環境が配布される場合、この先の説明は配布元がしてくれるでしょう。

# 運用上必要になるコマンド
## vagrantコマンド
以下はゲストOSを操作するコマンドです。vagrantでゲストOSを操作するコマンドを実行する際は、Vagrantfileのあるディレクトリをカレントディレクトリとしてください。

| やること | コマンド | 備考 |
|:-:|:-:|:-:|
|起動|vagrant up|ゲストマシンがあれば起動します。なければ作成したうえで起動します。|
|一時停止|vagrant suspend|resumeで復帰します。|
|一時停止からの復帰|vagrant resume||
|停止(電源断に相当)|vagrant halt|upで再度起動します。|
|破棄|vagrant destroy|ゲストマシンが削除されます。Vagrantfileは残るので、upで再度作成できます。トラブルがあった時などはdestroy・upで一からやり直します。|

# 参考にさせていただいたページ
- https://qiita.com/hidekuro/items/fc12344d36d996198e96
- https://github.com/tmatilai/vagrant-proxyconf
- https://www.vagrantup.com/docs/provisioning/docker.html
- https://github.com/leighmcculloch/vagrant-docker-compose
- https://qiita.com/hibohiboo/items/c17459e0af84d2059d21