Windows10 ProからNested Hyper-Vで遊んでみる(コンテナ付)

この記事は[富士通クラウドテクノロジーズ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/fjct) 5日目の記事です。

4日目は@herietさんの「[Prometheusのexporterを作ってニフクラRDBを監視する](https://qiita.com/heriet/items/7c31abedeadaa8ac3d13)」という記事でした。
このPrometheusウェーブに僕も乗り遅れないようにしたいと思います！

話はガラッと変わって今日のテーマはHyper-Vです！

# 動機

時々Windows10を使っているのでそこに載っているHyper-Vで遊んでみようと思いました
半分自分への備忘録です

# やったこと

- Nested Hyper-V(マシマシ)
- Docker for Windows
    - Linux コンテナ
    - Hyper-V コンテナ
    - minikube
- Windows Server コンテナ
    - Hyper-V コンテナ
    - Windows コンテナ

# やれてないこと

- Hyper-Vの機能に含まれるけどAD・DNS設定が必要なもの
    - クラスタ
    - ライブマイグレーション

# 予習

Windowsで動くコンテナ技術には大きく分けて3つあります

## Docker for Windows

Hyper-V上にLinuxのVMを立て、そこでコンテナを動かします。つまりWindows上でLinuxコンテナが動かせます

## Hyper-V コンテナ

Hyper-V上で動くWindowsコンテナです。Hyper-V上で仮想化されたコンテナなのでHyper-Vが必須ですが細かいことを考えずにコンテナを作ることができます

## Windows Server コンテナ

Windows Server上で動くWindowsコンテナです。仮想化がされていないコンテナです。ホストOSのプロセスとして実行されますがそれ故にパッチレベルまでホストとゲストのバージョンを合わせる必要があります

# 準備

- [Hyper-Vの要件](https://docs.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/reference/hyper-v-requirements)を満たした物理ホスト
    - 今回は2700k/16GBのマシンを用意しました

# Nested Hyper-V(マシマシ)

## 目的

Windows 10 Pro上にNested Hyper-Vを組みまくってリソースの食べ具合を図ります
また、VMを作りまくってHyper-Vに慣れていきます

## 結果

意外といけました！

- 物理ホスト(Hyper-V)(16GB)
    - Hyper-V(12GB)
        - Hyper-V(9.5GB)
            - Hyper-V(5.5GB)
                - VM(2GB)・・・Disk IOエラーにより死亡

![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/73816/bde6a006-2689-ae82-5a10-7de5c55e9f92.png)

## 雑感

手順がかなり多いです(特にセキュリティ周り)
Hyper-Vの仕様で躓くよりもWindowsの設定で躓く事が多かったです
Nestedの仮想ディスクを作らないよう保存場所を変えようと思ったのですが時間がなく試せませんでした。それ故にネストした仮想ディスクを使わざるを得ず、終盤はディスクのアクセスが非常に遅かったです

## 手順

### 物理ホスト上のWindows 10 Pro側の準備

#### Hyper-Vを有効化

1. win+r → `OptionalFeatures`
1. `Hyper-V`にチェック
1. 再起動を求められるので再起動
 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73816/76ad325f-a16a-f209-3d08-04c2777d9014.png)


#### リモートサーバー管理ツールをインストール

[ここ](https://www.microsoft.com/ja-JP/download/details.aspx?id=45520)から `WindowsTH-RSAT_WS_1709-x64.msu` をDLしてインストール
必須ではないですが、イベントログが見やすいのでトラブル時の切り分けに役立ちます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73816/7523dbcd-2529-01f8-c366-ec131b407688.png)


#### リモート管理するホストの許可設定

##### Powershellにて以下のコマンドを実行

``` PowerShell
# 全てのホストを信頼済みホストにする
Set-Item WSMan:\localhost\Client\TrustedHosts -Value *
# (もしくは)指定したホスト名を信頼済みホストにする
# `Set-Item` を使うので、現在の設定は上書きされる
# `Get-item wsman:\localhost\client\trustedhosts"で現在の設定を呼び出せる
Set-item wsman:\localhost\client\trustedhosts -Value "HOST1, HOST2, HOST3, HOST4"
# CredSSPの有効化(例)
# クライアントとサーバの認証に使うみたいです？
# `Get-WSManCredSSP` で現在の設定を表示
# `Disable-WSManCredSSP` で設定を削除
Enable-WSManCredSSP -Role client -DelegateComputer "HOST1, HOST2, HOST3, HOST4"
```

##### 資格情報の追加
1. win+rで`gpedit.msc`
1. `コンピューターの構成` > `管理用テンプレート` > `システム` > `資格情報の委任`
1. `NTLMのみのサーバー認証で新しい資格情報の委任を許可する`
1. `サーバーを一覧に追加`
1. `wsman/HOST1`, `wsman/HOST2`... のように追加していく 

![image.png](https://qiita-image-store.s3.amazonaws.com/0/73816/dfe1c988-7384-a486-1c7f-d19df468bba7.png)

#### isoディレクトリの共有設定

osのisoを格納するフォルダの共有設定を忘れずに行っておきます(手順省略)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73816/a32eaf73-33ac-d1c1-5062-57f55a704aea.png)

### ゲストOSに用いるOSを選定

リソースを余計に食いたくないのでHyper-V Serverを利用
firewallの名前のややこしさの関係上英語版を使います

#### (余談)Hyper-V Serverの特徴

1. GUIなし
1. 最初からHyper-Vついてる
1. コンテナ利用不可
1. 無料
1. 追加できる機能はファイル共有のみ

### nestedの準備

[公式ドキュメント](https://docs.microsoft.com/ja-jp/virtualization/hyper-v-on-windows/user-guide/nested-virtualization)にも要件が書いてありますが、実際のところこの他にも要件があるので一発でそれらを解決してくれるスクリプトを利用します

1. Hyper-V マネージャーからVMを作成
1. `Invoke-WebRequest https://raw.githubusercontent.com/MicrosoftDocs/Virtualization-Documentation/live/hyperv-tools/Nested/Enable-NestedVm.ps1 -OutFile .\Enable-NestedVm.ps1`
1. `.\Enable-NestedVm.ps1 VMNAME`プロンプトの質問への回答は基本YでOK
1. Hyper-V Serverをインストール

### Hyper-V Server内での操作

Hyper-V Serverではログインするとcmd.exe及びsconfigが開かれています

#### sconfigでの設定

CLIサーバー管理ツールです

1. `3` -> 管理者追加
1. `2` -> HostName変更
1. 再起動

![image.png](https://qiita-image-store.s3.amazonaws.com/0/73816/ac2beb13-b118-d3fc-d5ea-68d0d64385e0.png)

##### sconfigの内容はPowerShellでやってもいいです

```PowerShell
net user username /add password
net localgroup administrators user /add
net user user

Rename-Computer -NewName "HOSTNAME" -Force -Restart
```

#### cmd.exe上での設定

``` PowerShell
# powershellに切り替え
powershell

# PowerShellのリモート操作を許可
Enable-PSRemoting

# CredSspの設定
Enable-WSManCredSSP -Role server

# (Option)GUI版のWindows Serverを実行している場合
Set-WSManQuickConfig -Force

# firewallの設定
netsh advfirewall firewall set rule group="File and Printer Sharing" new enable=yes
netsh advfirewall firewall set rule group="Windows Remote Management" new enable=yes
netsh advfirewall firewall set rule group="Remote Event Log Management" new enable=yes
netsh advfirewall firewall set rule group="Remote Volume Management" new enable=yes

# 共有フォルダのマウント
net use Z: \\HOSTNAME\共有名 /user:username password

# isoのコピー(例)
Copy-Item Z:\SERVERHYPERCORE_OEM_X64FRE_EN-US.ISO .\

# Nested Hyper-Vの要件を満たすように設定してくれるスクリプトをDL
Invoke-WebRequest https://raw.githubusercontent.com/MicrosoftDocs/Virtualization-Documentation/live/hyperv-tools/Nested/Enable-NestedVm.ps1 -OutFile .\Enable-NestedVm.ps1
```

### Hyper-V Server上でVMを作成する

1. Windows 10 Pro上のHyper-V マネージャーからHyper-V Serverのホストを登録

![image.png](https://qiita-image-store.s3.amazonaws.com/0/73816/d0dc3149-de2f-b0d8-32df-4a970dce87cf.png)

2. 仮想スイッチの設定を行う(外部にしてvNICをアサインすればOK)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/73816/57f43d0a-7839-d52b-05b9-65170bc711b4.png)

(備考)
この仮想スイッチが曲者で、しばしば作成時にエラーを吐いて止まります。しかし根気強く作成をし続ければいずれ成功します。

### 終了

リソースの限り`nestedの準備`から`Hyper-V Server上でVMを作成する`までを繰り返す

(備考)
Hyper-V Serverインストール時に51%の進捗でエラーを吐いて止まる場合はVMの設定が良くないです。
`Enable-NestedVM`をもう一度回してみてください。

# Docker for Windows + Hyper-V コンテナ

Hyper-Vに慣れたのでDockerをWindows上で動かして軽いLinux(今回はalpine)とnanoserverを走らせてみます

## 目的

動けばいい

## 結果

動いた
おまけで走らせたminikubeも動いた

## 所感

Docker for WindowsのHyper-Vコンテナはexperimental扱いなので正式版のリリースが待ち遠しいです

## 手順

### 準備

以下のOSを用意しましょう

- Windows 10 Pro
- Windows Server Standard(VM)(未確認)
    - GUI版
- Windows Server DataCenter(VM)
    - GUI版

Docker for WindowsはGUIが必須です

### コンテナ機能を有効化

#### Windows 10 Pro

1. win+r → `OptionalFeatures`
1. `Hyper-V`, `コンテナー`にチェック
1. 再起動

#### Windows Server

1. サーバーマネージャーからHyper-V及びコンテナー機能をインストール
1. 再起動

### Dockerのインストール

今回は[chocolatey](https://chocolatey.org)を使います

``` PowerShell
Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
choco install -y docker docker-for-windows
Restart-Computer
```

### Dockerを立ち上げる

デスクトップに`Docker for Windows`があるのでダブルクリックして立ち上げます
Hyper-V マネージャーに`MobyLinuxVM`があれば成功です

### Alpineを動かす

Powershellから`docker run -it alpine`

#### エラー

`no matching manifest for windows/amd64 in the manifest list entries`
→[ISSUE](https://github.com/docker/for-win/issues/1100)
タスクトレイ内のdockerアイコンを右クリックして`Switch to Windows/Linux containers...`を何回か行うとエラーを回避できます

### nanoserverを立ち上げる

1. タスクトレイ内のdockerアイコンを右クリックしてSwitch to Windows containers...
1. `docker run -it microsoft/nanoserver powershell`

### 終了

ここまで環境が整えばminikubeを使ってお手軽k8sクラスタを構築できます
以下のコマンドで`minikube`というVMがHyper-V上に作成されます
Hyper-Vの仮想スイッチ名を入れる必要があるのでお忘れなく

```PowerShell
choco install minikube
minikube config set vm-driver hyperv
minikube start --hyperv-virtual-switch=vSWITCHNAME
minikube ssh
```

# Windows Server コンテナ

仮想環境に頼らないコンテナを作ってみます

## 目的

Windows Serverコンテナの雰囲気を掴む

## 結果

特に問題なく作れた

## 手順

### 準備

以下のOSを用意しましょう

- Windows Server Standard(VM)(未確認)
- Windows Server DataCenter(VM)

### Dockerのインストール

```PowerShell
Install-Module DockerProvider -Force
Install-Package Docker -ProviderName DockerProvider -Force
Restart-Computer -Force
docker run microsoft/dotnet-samples:dotnetapp-nanoserver
```

キモかわキャラが出てきたら成功です

ちなみに`docker run --isolation hyper-v`とするとDocker for Windowsの項目でも扱ったHyper-Vコンテナでコンテナを作成することが可能です

### 終了

今回はハマりませんでしたがWindows Server コンテナの場合ホストOSとコンテナイメージのバージョンをパッチレベルまで合わせる必要があります

# 最後に

とりあえず最低限Hyper-Vを遊ぶことができました。ESXiとは異なり簡単にハイパーバイザー型の仮想化環境を整えられるのは大きなメリットだと思います（特にドライバ周り）
時間があればHyper-VにNested ESXi+VSAN環境を作ったりAD・DNSサーバーを立ててライブマイグレーションやクラスタなんかもしてみたいです。長く遊べそうですね！

# おまけ

## Windows 10 dev environmentのススメ
![image.png](https://qiita-image-store.s3.amazonaws.com/0/73816/b9355a8d-a106-8419-315a-3dbf0b0abe7f.png)

Windows 10 のHyper-V マネージャーについてくるVMイメージです
VM作成時にクイック作成を選ぶと展開することができます
サクッと作れるのでとりあえず何か検証したいときなんかにおすすめ

- ISO不要
- ライセンスキー不要
- 90日間稼働可
- 商用利用不可(EULA必読)

## 参考文献

- [はじめてのコンテナーDocker & Windows & Linux](https://www.slideshare.net/kkamegawa/docker-windows-linux-82264286)
- [Hyper-V on Windows 10 Documentation](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/index)
- [Windows Server Virtualization Documentation](https://docs.microsoft.com/en-us/windows-server/virtualization/virtualization)
- [Docker for Windows Documentation](https://docs.docker.com/docker-for-windows/)
- [Windows Containers Documentation](https://docs.microsoft.com/en-us/virtualization/windowscontainers/index)
- [Windows にまつわる e.t.c](http://www.vwnet.jp/Windows/etc.asp)

6日目は@makky05さんの「アルバイトの思い出系の心温まるポエム」です。
あったけぇポエムお楽しみに～！