Windows10でVagrant(1.8.5)を使ってCentOS 7仮想マシンを構築する

[Link-Vagrant]:https://www.vagrantup.com/
[Link-VirtualBox]:https://www.virtualbox.org/
[Link-Cygwin]:https://cygwin.com/

# 概要

Windows10におけるVagrant(1.8.5)を使った、CentOS 7 仮想マシンの構築手順について示す。

# 環境

* ホストOS：Windows 10
* ゲストOS：CentOS7-x86_64
* Vagrant：1.8.5
* VirtualBox：5.1
* Cygwin

各ソフトウェアを用意する。CygwinはVagrantから仮想マシンへの接続を行う際に`rsync`と`ssh`を用いるためにインストールする。

# 手順

1. [Cygwin][Link-Cygwin]のインストール(`rsync`と`ssh`)
1. [VirtualBox][Link-VirtualBox]のインストール
1. [Vagrant][Link-Vagrant]のインストール
1. Vagrantで仮想マシンを構築

## Cygwinのインストール(`rsync`と`ssh`)

Vagrantは仮想マシンの起動時(`vagrant up`)に、ホストOSとゲストOS間のフォルダ同期のために`rsync`を、Vagrant自身と仮想マシン間の接続のためにsshを使用する。Windows10には`rsync`や`ssh`のコマンドが存在しないため、別途インストールする必要がある。

このためCygwinまたはMinGWを導入する必要がある。ここではCygwinの`rsync`と`ssh`を導入する。

> 仮想マシン構築そのものにはCygwinの`rsync`や`ssh`を導入する必要はないようだ。Vagrantfileへの設定によって、`vagratn up`時にrsyncやsshを使用しないようにできるかもしれない。

インストール手順詳細は以下を参照のこと。

[Window10にCygwinでrsyncとsshをインストールする](http://qiita.com/ringo0321/items/5ab066078ffa822b4f49#cygwin%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%ABrsync%E3%81%A8ssh)

## VirtualBoxのインストール

Vagrantで構築する仮想マシンを動かすプラットフォームとなるVirtualBoxをインストールする。ちなみに、Vagrantでは、このVirtualBoxのようなソフトウェアのことをプロバイダ/Providerと呼ぶ。VirtualBox以外には、Hyper-VやVMWareなどがある。

インストール手順詳細は以下を参照のこと。

[Windows10にVirtualBox 5.1をインストールする](http://qiita.com/ringo0321/items/afa176192d9b5edf923d)

## Vagrantのインストール

仮想マシン環境を構築するソフトウェアであるVagrantをインストールする。

インストール手順詳細は以下を参照のこと。

[Windows10にVagrant 1.8.5をインストールする](http://qiita.com/ringo0321/items/169dd0e99347ce45a4f6)

## Vagrantで仮想マシンを構築

Vagrantを用いてVirtualBox用の仮想マシン環境を構築する。手順は以下のとおり。

1. 仮想マシン環境用のフォルダを作成する
1. `vagrant init`でフォルダを初期化する
1. `vagrant up`で仮想マシン環境の構築と起動を行う

詳細を以降に示す。

### 仮想マシン環境用のフォルダを作成する

仮想マシンは用途に合わせて、フォルダ分けするのが良いだろう。ここではWindowsのユーザーフォルダ配下に"Vagrant"フォルダを作成し、この配下に仮想マシン用のフォルダを作成していく。なお、ここではVagrantの仮想マシンのベースとなるファイルであるBoxに対応したフォルダ構成とする。事前に導入するBoxをVagrant開発元の[HashiCorpが公開しているサイト](https://atlas.hashicorp.com/boxes/search)から検索しておく。今回は"centos/7"を導入するのでフォルダ構成は以下とする。

```
C:\Users\(ユーザー名)\Vagrant\centos\7
```

Windowのエクスプローラーからフォルダ作成してもよいが、以降の作業をコマンドプロンプトで行うので、フォルダの作成もコマンドプロンプトで実行していく。

![001_フォルダ作成.png](https://qiita-image-store.s3.amazonaws.com/0/4247/d35939fc-de4c-d6d2-44ba-0c9eb91a549b.png)

## Vagrantフォルダの初期化

作成したフォルダをVagrant用に初期化する。これはフォルダにVagrantの設定用ファイルである`Vagrantfile`を生成する。以下のコマンドを使用する。

```bash
vagrant init [name [url]]
```

通常、`[name [url]]`には、先のHashiCorpのサイトで検索したパスを指定する。今回は
`centos/7`を指定する。
![002_vagrant init.png](https://qiita-image-store.s3.amazonaws.com/0/4247/d84879b9-a247-ac2f-8211-90b5eed31228.png)

コマンドの実行により、フォルダ内に`Vagrantfile`が生成された。なお、指定した`centos/7`が設定に反映されており、この`Vagrantfile`に基づいて生成される仮想マシンはHashiCoprで公開されている`centos/7`のBoxに基づいたものになる。

## Vagrantによる仮想マシンの生成と起動

`vagrant init`により設定ファイルを生成すると、すでに仮想マシンが生成可能な状態となっている。以下のコマンドを使用する。

```bash
vagrant up [name|id]
```

カレントフォルダに`Vagrantfile`がある場合、`[name|id]`を省略することでカレントフォルダの`Vagrantfile`を用いて、仮想マシンを生成・起動する。今回は省略して実行する。
![003_vagrant up-1.png](https://qiita-image-store.s3.amazonaws.com/0/4247/70315798-9b98-2a52-5147-b8e73711188b.png)
![004_vagrant up-2.png](https://qiita-image-store.s3.amazonaws.com/0/4247/8d9eb26d-4532-30c7-8f80-63062d7c6413.png)

以上でVirtualBoxの仮想マシンが生成され、さらにその仮想マシンが起動された状態となる。VirtualBoxを起動して、状態を確認してみよう。
![006_up後のVirtualBox.png](https://qiita-image-store.s3.amazonaws.com/0/4247/c4cd1a67-baf1-2c61-aeb5-4a5a40033ac0.png)

"7_default_1471054331963_46735"が今生成したマシンであり、状態が"実行中"となっていることがわかる。

なお、通常`vagrant up`によりVirtualBoxの仮想マシンを起動しても、上記のようなVirtualBoxのウィンドウは表示されることはない。ただし、`Vagrantfile`の設定によって表示させることもできる。

## VagrantからのSSH接続

仮想マシンが起動したので、マシンへのアクセスが可能となっている。以下のコマンドを使用する。

```bash
vagrant ssh [name|id] [-- extra_ssh_args]
```

カレントフォルダに`Vagrantfile`がある場合、`[name|id]`を省略することでカレントフォルダの`Vagrantfile`で生成されたマシンに接続しようとする。また、`[--extra_ssh_args]`には、実際のSSHコマンド(今回の場合、CygwinのSSHコマンド)に受け渡すオプションを指定することができる。今回はともに省略して実行する。
![005_仮想マシン起動後のssh接続.png](https://qiita-image-store.s3.amazonaws.com/0/4247/7813af3e-8094-109f-e6b1-ce4ace8d827d.png)

プロンプトがLinuxのものに変更されたことがわかるだろう。

# 発生した問題

上記手順を示すにあたり、その順番や有無によっていくつかの問題が発生した。その問題と原因について示しておく。

## rsyncがない場合に発生した問題

### 問題

`vagrant up`時に下記のエラーが発生した。
![007_rsyncがない場合のエラー.png](https://qiita-image-store.s3.amazonaws.com/0/4247/896373a3-e967-5026-6a0b-166d9609e6c4.png)

エラーメッセージは以下のように出力されている。

```
"rsync" could not be found on your PATH. Make sure that rsync is properly installed on your system and availablie on the PATH
```

「"rsync"がPATHに見つからないので、きちんとインストールされていて、PATHに設定されているかを確認せよ」と言っている。

### 解決

手順に示した通り、Cygwinの`rsync`コマンドをインストールすることで解決できる。

## sshがない場合に発生した問題

### 問題

`vagrant up`時に下記のエラーが発生した。
![008_sshがない場合のエラー-1.png](https://qiita-image-store.s3.amazonaws.com/0/4247/cbf68223-c9d5-e40f-bc26-3967fcb04567.png)
![009_sshがない場合のエラー-2.png](https://qiita-image-store.s3.amazonaws.com/0/4247/c1d20315-f064-bd48-0be1-3864f1368e94.png)
![010_sshがない場合のエラー-3.png](https://qiita-image-store.s3.amazonaws.com/0/4247/701c7446-5f17-5c1b-709e-309991d5bec3.png)

エラーメッセージとして大量のメッセージが表示されているが、要点は以下である。
```
Error: rsync: Failed to exec ssh: No such file or directory (2)
```

「`rsync`が`ssh`を実行するのに失敗した。そんなファイルやディレクトリは知らない」と言っている。

### 解決

手順に示した通り、Cygwinの`ssh`(open-ssh)コマンドをインストールすることで解決できる。

## Vagrant 1.8.5のバグに起因する問題

Vagrant 1.8.5のあるバグによって、以下のようなエラーが発生した。
![011_Vagrant1.8.5のpublic_key.rbのバグに起因するエラー-1.png](https://qiita-image-store.s3.amazonaws.com/0/4247/8d55cb73-fac4-7c3b-c49f-ce32c9c2e7d6.png)
![012_Vagrant1.8.5のpublic_key.rbのバグに起因するエラー-1.png](https://qiita-image-store.s3.amazonaws.com/0/4247/4787a237-a4c9-47c0-b520-fec07735fd2f.png)

出力メッセージの末尾のほうに
```
default: Warning: Authentication failure. Retrying...
default: Warning: Authentication failure. Retrying...
```
とある。上記では2回しか出力されていないが、これは2回出力された時点でCtrl+Cを押下して、処理を中断したためであり、処理を続けた場合、このメッセージが繰り返し実行され、以降の処理に進めなかった。

上記、エラーメッセージでGoogle検索を行うと、GitHubの以下のIssueにたどり着いた。

[Authentication failure after inserting new key with Vagrant 1.8.5. [PATCH] #7610](https://github.com/mitchellh/vagrant/issues/7610)

すでに問題は認識されており、リリース版としてはVagrant 1.8.6で対応されるようだ。

### 解決

先のIssueから、Vagrant 1.8.6のリリースを待つ以外の方法を以下に示す。

* C:\HashiCorp\Vagrant\embedded\gems\gems\vagrant-1.8.5\plugins\guests\linux\cap\public_key.rb の56行目に以下を追加する。

```
chmod 0600 ~/.ssh/authorized_keys
```

なお、これを追加した状態での前後の行は以下の通りである。
```
if test -f ~/.ssh/authorized_keys; then
  grep -v -x -f '#{remote_path}' ~/.ssh/authorized_keys > ~/.ssh/authorized_keys.tmp
  mv ~/.ssh/authorized_keys.tmp ~/.ssh/authorized_keys
  chmod 0600 ~/.ssh/authorized_keys
fi
```

`~/.ssh/authorized_keyz.tmp`を`~/.ssh/authorized_keys`にコピーしたあとに、パーミッションを0600に変更する処理を追加したことになる。SSH認証を行う際に陥るよくある手順の抜けのようだ。。。

上記変更を加えたファイルを保存し、改めて仮想マシンを構築することで解決する。

# 最後に

手順をまとめるととても簡単なのではあるが、予想外のエラーにはまってしまいまとめるまでに数日かかってしまった。ようやくVagrantによるCentOS 7仮想マシンを構築することができたので、この仮想マシンをいろいろといじくっていこう。

なお、仮想マシンの構築に際しては、Vagrantのさまざまな機能を用いることで、より用途に適した設定で、容易に、何度でも仮想マシンを生成することができる。

Vagrantのさまざまな機能を用いるためにはVagrantの公式ドキュメントを読むのが一番であるが、英語であるためなかなか手が伸びないところであろう。拙記事ではあるが、Vagrant公式ドキュメントを意訳しているので、ご参考いただければと思う。ただし、訳には責任が持てないので、詳細については自己責任でお願いしたい。。。

参考：[【Vagrantドキュメント意訳】00.目次](http://qiita.com/ringo0321/items/70384c0ec09d5a7c4c76)