Windows10でLinux仮想環境構築(VirtualBox + Vagrant)

Windows環境にて、自然言語処理および機械学習のため、
Linux開発環境が必要となり、それが一通り形となったので忘備録としてまとめます。

# この記事の対象者
- Windowsユーザー
- Linuxの開発環境が必要
- GCPやAWSでLinuxを使用する前に、同一環境をLocalで仮想化したい。


# 環境
- ホストOS：Windows10 Pro 32bit , 64bit
- ゲストOS：Ubuntu-18.04
- VirtualBox：5.2.32
- Vagrant：2.2.5

# VirtualBoxをインストール
https://www.virtualbox.org/wiki/Download_Old_Builds_5_2

「Windows hosts」からダウンロード

VirtualBox 6.0.10がリリースされていますが、本記事では安定稼働している5.2ビルドを使用します。

# Vagrantをインストール
https://www.vagrantup.com/downloads.html

「Windows」>「32-bit | 64bit」からインストーラーをダウンロード

現行の最新版「2.2.5」を使用しています。（2019年8月29日時点）

## Vagrantについて
こちらの記事が非常に参考になります。
https://qiita.com/ozawan/items/160728f7c6b10c73b97e

# Vagrantの事前設定
好きな場所にフォルダを作成し、Vagrantfile（起動用ファイル）を作成します。
今回はCドライブ直下に、Vagrant専用のフォルダを作成します。

```powershell
# Cドライブ直下にフォルダ作成
cd C://
mkdir Vagrant
cd Vagrant
# インスタンス起動用フォルダを作成
mkdir instance1
cd instance1
# 共有フォルダ作成
mkdir workspace
# Vagrantfile作成
vagrant init
```

## VagrantのboxのGuest Additionsの自動アップデートをしてくれるライブラリをインストールします。

```powershell
cd instance1
vagrant plugin install vagrant-vbguest
```
こちらの記事を参照
https://qiita.com/isaoshimizu/items/e217008b8f6e79eccc85

## Proxy環境で作業する際、必要となるライブラリをインストールします。(Proxy環境のみ)

```powershell
cd instance1
vagrant plugin install vagrant-proxyconf
```

こちらの記事を参照
https://qiita.com/kota344/items/304979feaf965afffb1a

# 仮想環境の作成
initコマンドにより、Vagrantfileが作成されたので
以下の内容で上書きします。

```rb
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|

  # プロキシ設定（プロキシ環境のみ）
  if Vagrant.has_plugin?("vagrant-proxyconf")
      puts '- Proxy Setting ----------------------------------'
      config.proxy.http     = "http://{user}:{password}@{proxy_ip_or_domain}:{proxy_port}/"
      config.proxy.https    = "http://{user}:{password}@{proxy_ip_or_domain}:{proxy_port}/"
      config.proxy.no_proxy = "localhost,127.0.0.1"
      puts '--------------------------------------------------'
  end

  config.vm.box = "bento/ubuntu-18.04"
  config.vm.network "forwarded_port", guest: 8888, host: 8888

  config.vm.provider :virtualbox do |vb|
    vb.customize [
      "modifyvm", :id,
      "--memory", "4096",
      "--vram", "256",
      "--clipboard", "bidirectional",
      "--accelerate3d", "on",
      "--hwvirtex", "on",
      "--nestedpaging", "on",
      "--largepages", "on",
      "--ioapic", "on",
      "--pae", "on",
      "--paravirtprovider", "kvm",
    ]
  end

  config.vm.network "private_network", ip: "192.168.33.10"
  config.vm.synced_folder "C:\\Vagrant\\instance1", "C:\\Vagrant\\instance1\\workspace"
  # 初期構築スクリプト
  config.vm.provision :shell, :inline => <<-EOS
    # Ubuntuの最新パッケージ情報を取得
    sudo apt update -y
    # apt-getをアップデート
    sudo apt-get upgrade -y
    # Ubuntuの日本語環境をインストール
    sudo apt-get install ubuntu-defaults-ja -y

    # タイムゾーンを日本時間に変更
    sudo timedatectl set-timezone Asia/Tokyo
    # デフォルトのエディタを nano から vim に変更
    sudo update-alternatives --set editor $(update-alternatives --list editor | grep 'vim.basic')

  EOS

end

```

## プロキシの設定
{user}{password}{proxy_ip_or_domain}{proxy_port}などは適宜環境に応じて書き換えてください。
もしプロキシ環境でない場合は、以下の部分は不要ですので削除します。

```rb
  # プロキシ設定（プロキシ環境のみ）
  if Vagrant.has_plugin?("vagrant-proxyconf")
      puts '- Proxy Setting ----------------------------------'
      config.proxy.http     = "http://{user}:{password}@{proxy_ip_or_domain}:{proxy_port}/"
      config.proxy.https    = "http://{user}:{password}@{proxy_ip_or_domain}:{proxy_port}/"
      config.proxy.no_proxy = "localhost,127.0.0.1"
      puts '--------------------------------------------------'
  end
```

## インストールするOSの設定
仮想環境にインストールしたいOSのVagrant Boxを設定します。
インストールできるOSは、こちらのサイトから探せます。
https://app.vagrantup.com/

```ruby
  config.vm.box = "bento/ubuntu-18.04"
```

今回は、ubuntu18.04を使用していきます。

仮にawslinuxをインストールしたい場合は、「config.vm.box = 」以降を以下のURL先の通りに書き換えればOKです。
https://app.vagrantup.com/mvbcoding/boxes/awslinux


## フォワードポートの設定
以下の設定をしておくと、仮想環境（ゲストOS）の8888ポートにてJupyter notebookなどでサーバーを立てて接続待ちしている際、ホスト側からブラウザなどで「http://localhost:8888 」と入力することで、仮想環境にアクセスできます。

```ruby
  config.vm.network "forwarded_port", guest: 8888, host: 8888
```

ゲストOSからnode.jsなどでサーバーを立てて、ホスト側からアクセスしたいときなどもこの設定が使えるようです。

Vagrantのネットワークの詳しいイメージとしては、こちらの記事がわかりやすかったです。
https://qiita.com/ftakao2007/items/0ec05c2ef3c14cdbea11

## 仮想環境に割り当てるリソースについて
割り当てるメモリーなどは、以下のように設定できます。

```ruby
  config.vm.provider :virtualbox do |vb|
    vb.customize [
      "modifyvm", :id,
      "--memory", "4096",
      "--vram", "256",
      "--clipboard", "bidirectional",
      "--accelerate3d", "on",
      "--hwvirtex", "on",
      "--nestedpaging", "on",
      "--largepages", "on",
      "--ioapic", "on",
      "--pae", "on",
      "--paravirtprovider", "kvm",
    ]
  end
```

メモリーは環境に応じて使える容量も変わってくるので、環境に応じて割り当てを調整してください。
本記事では4GB割り当てています。

```ruby
      "--memory", "4096",
```

## 仮想環境のIP設定
仮想環境のIPアドレスです。ホスト側から仮想環境に、ssh接続をする際に使用します。

```rb
  config.vm.network "private_network", ip: "192.168.33.10"
```

## 共有フォルダの設定
共有フォルダに設定します。以下の設定をすることで仮想環境からworkspaceフォルダを参照することができます

```rb
  config.vm.synced_folder "C:\\Vagrant\\instance1", "C:\\Vagrant\\instance1\\workspace"
```

参考：https://qiita.com/tbpgr/items/67125ea883409ae5fd51

# 初期構築スクリプト
初回のインストールのみ起動するスクリプトです。Ubuntu日本語化やタイムゾーンの設定、apt-getなどのアップデートをバッチ処理で実行できます。
Ubuntu以外のOSで実行する場合は、必要に応じて書き換えてください。

```rb
  # 初期構築スクリプト
  config.vm.provision :shell, :inline => <<-EOS
    # Ubuntuの最新パッケージ情報を取得
    sudo apt update -y
    # apt-getをアップデート
    sudo apt-get upgrade -y
    # Ubuntuの日本語環境をインストール
    sudo apt-get install ubuntu-defaults-ja -y

    # タイムゾーンを日本時間に変更
    sudo timedatectl set-timezone Asia/Tokyo
    # デフォルトのエディタを nano から vim に変更
    sudo update-alternatives --set editor $(update-alternatives --list editor | grep 'vim.basic')

  EOS
```

# インスタンスの起動、再起動、終了
vagrantflieがあるフォルダで、以下のコマンドを入力すると仮想環境が起動します。
## インスタンスの起動

```rb
vagrant up
```

## 再起動
vagrantfileの書き換えた内容を設定を反映する際によく使います

```rb
vagrant reload
```

## インスタンスの終了

```rb
vagrant halt
```
インスタンスの終了はVirtualBoxのGUIからもできます。


## 注意事項
### ①VirtualBoxのGUIからインスタンスを起動せず、　かならず「vagrant up」「vagrant reload」で起動すること。
Vagrantの仕様上、「vagrant up」（起動）もしくは「vagrant reload」（再起動）で仮想環境を起動したときのみ、
Vagrantfileの設定が反映されます。
### ②仮想環境の設定は、かならずVagrantfileで行うこと。
Vagrantで仮想環境を起動した際、すべてVagrantfileの設定で上書きされます。
なので、Vagrantを使用する際、VirtualBoxのGUIから設定しないほうが無難です。

# インスタンスへの接続
vagrantflieがあるフォルダで、以下のコマンドを入力すると仮想環境にssh接続できます。
※初回起動は時間がかかるので、すべての処理が終わってから接続すること

```rb
vagrant ssh
```

ちなみに、筆者は「TeraTerm」を利用してssh接続しています。
ホストは「192.168.33.10」(「config.vm.network "private_network"」で設定したIPアドレス)
VagrantでインストールしたOSのユーザーとパスワードは、デフォルトでは「vagrant」です。
秘密鍵は「C:\Vagrant\instance1\\.vagrant\machines\default\virtualbox\private_key」にあります。
他は初期設定のままで使えます。

# 動作確認
ssh接続後、vagrant@vagrantフォルダに接続されますので、以下のコマンドを入力して共有フォルダが認識されているかを確認します。

```bash
cd C\:\\Vagrant\\instance1\\workspace/workspace/
touch test.txt
```

「cd C」と入力した時点でTabキーを押せば、予測変換でフォルダ名が出てきます。
touchで新規作成したtest.txtを、Windows（ゲストOS）から確認できれば環境構築は終了です。


以上