Windows10 Hyper-V 環境に Minishift をインストールする方法まとめ

Windows10 Hyper-V 環境に Minishift をインストールする際、なかなか安定稼働せず苦労しました。いろいろ試しつつ何台かセットアップしているうち、わりと安定するようなってきたので、やり方をまとめてみました。

# ポイント

Minishift のインストールガイドを読むと「外部ネットワーク用の仮想スイッチ」を作成するよう指示があります。それに従ってインストールを進めると、仮想ネットワークが DHCP 環境をベースとしてセットアップされ、外部ネットワーク環境の影響を強く受ける気がします。

例えばノートPCを外に持ち出した場合、仮想マシンのIPアドレスが変わってしまったり。その結果、内部での IP アドレスベースの認証が利かなくなり、パスワード無しでの SSH 実行ができなくなったりして、Minishift が動作しなくなる。こうなると内部の状態を更新する方法(Minikube の update-context 的な) がないので、時間のかかる仮想マシンの再作成を実行しないと復旧しない模様。

そこで仮想マシンの IP アドレスを固定するため、DHCP を使わない、静的な仮想ネットワークを構築することで、この問題に対応してみました。

# 事前のおまじない

通知エリアの電源アイコンを右クリックして [電源オプション] を選択し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/36290841-fa51-105a-b07b-acd8451988c2.png)
[電源ボタンの動作を選択する] をクリックし、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/74b0453c-5323-4f75-18cd-69c89b6e558a.png)
[現在利用可能ではない設定を変更します] をクリックした後、[高速スタートアップを有効にする (推奨)] のチェックを外します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/fa93cb7a-37fb-e349-b517-3c43a8ac116c.png)

[変更の保存] でウィンドウを閉じてから、PC を再起動して変更を有効にしてください。

# Hyper-V の有効化

まずは Hyper-V の有効化が必要です。個人的には [Docker Desktop for Windows](https://hub.docker.com/editions/community/docker-ce-desktop-windows) を先にインストールすることをお勧めします。インストールの最中に Hyper-V の有効化をしてくれますし、後で設定する WinNAT 環境の共存も簡単です。

Docker Desktop for Windows をインストールしない場合は、以下の手順で有効化します。

* Windows ボタンを右クリックし、[アプリと機能] を選択
* [関連設定] の下にある [プログラムと機能] を選択
* [Windows の機能の有効化または無効化] を選択
* 以下の赤枠の [Hyper-V] 項目を選択して [OK] をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/1ee9b5b7-11b8-6951-b0e6-a8fa1d785a8d.png)
どちらにしてもPCが再起動されます。

# Hyper-V 権限グループへの追加

Minishift のセットアップ時に Hyper-V を操作する権限が必要なため、自身に権限を追加します。Windows ボタンを右クリックし、[Windows Poweshell (管理者)] を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/2fb756e8-7457-6588-5302-688ac2fc5ce1.png)
Power Shell 上で以下のコマンドを実行することで、現在のユーザーを Hype-V Administrator 権限グループに追加できます。

```
([adsi]"WinNT://./Hyper-V Administrators,group").Add("WinNT://$env:UserDomain/$env:Username,user")
```

実行後は PC を再起動してください。

> 何らかの理由で権限グループを編集できない場合には、管理者権限の Power Shell (もしくはコマンドプロンプト) で、--skip-check-hyperv-driver オプションを付け、minishift start を実行してください


# 内部ネットワーク用の仮想スイッチの作成

さて、ここからが本番です。[Hyper-V マネージャー] で [仮想スイッチ] のメニューから、内部ネットワーク用のスイッチを新規に作成してください。今回は `Minishift_Switch` という名前にしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/67c10413-ca14-f2da-6d05-1c2d24a9a893.png)
するとコントロールパネルの [ネットワークとインターネット] の [ネットワークと共有センター] にある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/08dedbad-e54d-9a90-4361-8276923e7722.png)
[アダプター設定の変更] に以下のように仮想スイッチが追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/561ce36b-e67a-3f7a-77fd-5e1279d307d7.png)
この仮想スイッチのプロパティから [インターネットプロトコル バージョン4] のプロパティを開き、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/b0530a9f-30be-78c7-a507-7d94ca557407.png)
以下の赤枠の部分を設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/43008b38-b774-aa0f-6e15-5ec551862668.png)

アドレスは 10.0.3.1 としましたが、この 3 の部分は自由に変更しても大丈夫です。ただ 75 は Docker と干渉するので避けたほうが良いでしょう。

サブネットマスクは 255.255.255.0 で、`Minishift_Switch` には、いわゆる **クラスC** の静的なネットワークを定義したわけです。今回の Minishift はこの静的なネットワークを用いてインストールします。

## ここでもおまじない

[こちら](https://www.ipentec.com/document/windows-hyper-v-degraded-network-performance) などで報告されているように、Hyper-V 環境において仮想ネットワーク環境の動作が遅くなる問題が発生しているようです。

[アダプター設定の変更] 時に [構成] ボタンを押して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/20cba9ea-4581-9ae4-227d-f8be2cd2ff06.png)
設定画面で [詳細設定] のタブで、IPv4 用のチェックサムのオフロード (Checksum Offload) を 無効(Disable) に変更しておきます。3個ぐらいあると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/a687dfe3-fa25-017a-56a2-4ff4f2c73e41.png)
Minishift start の際には仮想マシンからネットワーク経由でのダウンロードがあり、この変更でその実行が速くなることが期待できます。この変更で劇的に速度が改善したケースもありましたので、できれば変更しておいてください。

# WinNAT の設定

WinNAT は Windows 内部で実装されている NAT 機能で、1つしか設定・利用できないようです。管理者権限の Power Shell を起動し、まずは``Get-NetNat`` コマンドで現在の設定状況を確認しましょう。

Docker が事前にインストールされていれば、``SharedNAT`` という名前で既に定義されているかもしれません。``Get-NetNat | Remove-NetNat`` を実行して削除しておきましょう。

そして以下のコマンドで、``SharedNAT`` を再作成します。

```
New-NetNat -Name SharedNAT -InternalIPInterfaceAddressPrefix 10.0.0.0/16
```

以下が実行の様子です。Docker によって作成されていた元の``SharedNAT`` と、新しく定義された ``SharedNAT`` の違いに注目してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/60227e35-2aa3-26e8-ebf8-d273179a787f.png)

新しく定義された ``SharedNAT`` ですが、いわゆる **クラスB** の範囲に対象を拡大されているのがポイントです。この WinNAT は 10.0. で始まる IP Address 全てが対象となります。

もともとあった Docker 用の ``SharedNAT`` を修正、もしくは新規作成して、より範囲の広い WinNAT を用意した。その目的はもちろん！今回の Minishift のために作成しておいた `Minishift_Switch` を WinNAT の対象にするためです。

# ネットワーク環境の確認

minishift start の実行中ですが、仮想マシン上で以下のような docker image ファイルのダウンロードが発生する場合があり、遅いネットワーク環境で実行するとかなりの時間がかかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/3bcba0f2-6ab2-48ad-b079-bd58240d2bc5.png)
ネットワーク環境の良い場所で実施する、多人数で start を同時に実行しない、など最初の start の際にはちょっと気をつけてください。ちゃんと設定が終わった後に stop/start する場合には、そんなに気にすることはないと思います。

# Minishift の実行

いよいよ Minishift を実行しましょう。まずは [こちら](https://github.com/minishift/minishift/releases) からダウンロードした zip ファイル (今回は minishift-1.34.1-windows-amd64.zip) を解凍します。私は c:\minishift というフォルダに配置しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/f902b307-3549-2a86-4038-66e253b4f670.png)
パスを設定するのが面倒なので、パス移動して実行しましょう。Power Shell を起動して以下のようにコマンドを実行して Minishift を実行します。

```
cd \minishift
.\minishift start --hyperv-virtual-switch "Minishift_Switch" --network-ipaddress 10.0.3.128 --network-gateway 10.0.3.1 --network-nameserver 8.8.8.8
```

今回作成した静的ネットワークでは DHCP サービスがありませんので、minishift start 時に ``--network-ipaddress`` オプションで仮想マシンの IP アドレスを、`--network-gateway` オプションで仮想ネットワークのゲートウェイアドレスを、`--network-nameserver` オプションで DNS サーバーのアドレスを明示します。

なお start 中の minishift-centos7.iso ダウンロードには時間がかかるので、既にお持ちの場合には同じフォルダに置いておいて、

```
.\minishift start --hyperv-virtual-switch "Minishift_Switch" --network-ipaddress 10.0.3.128 --network-gateway 10.0.3.1 --network-nameserver 8.8.8.8 --iso-url file://c:/minishift/minishift-centos7.iso
```

と `--iso-url` で指定すると、起動が早くなって快適です。

minishift start コマンドが無事に終わると、以下のような表示になります。 `.\minishift ip` コマンドを実行して、作成された仮想マシンの IP アドレスが正しいか確認しておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/290eff30-1ff7-6671-251d-8838cfae4062.png)
後は以下のような感じで、Minishift 環境を使い始めましょう。

```
.\minishift oc-env | Invoke-Expression
oc login -u system:admin
oc policy add-role-to-user admin admin
oc policy add-role-to-user admin developer
```

`.\minishift console` コマンドで、Web コンソールを表示して操作するのもお勧めです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/e567c151-c39b-d32f-9694-bc603cf1eb2d.png)

# 追加のおまじない

## 仮想マシンのメモリ設定を変更する

メモリを多く積んだPCでしか再現しないかもしれませんが、しばらく仮想マシンを動かしていると以下のように使用メモリ量が増大して、PCの動作に影響が出る場合があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/35d2be92-67b5-f4d9-d8fe-5987db5b8645.png)
これに対応するために、``.\minishift stop`` でいったん仮想マシンを停止し、Hyper-V マネージャーの仮想マシンのメモリ設定で、以下のチェックを外しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/6bfa023c-fee2-4feb-6226-d2bbd93106c9.png)
これで Minishift 仮想マシンのメモリは初期状態(標準だと4GB)に固定されます。``.\minishift start`` で仮想マシンを再起動します。start のオプションは minishift が覚えているので大丈夫です。気になる方は ``.\minishift config view`` で現在の指定を確認してから start しましょう。 

# 101 を実行してみる

さてこれで [Minishift 101 ワークショップ](https://github.com/IBMDeveloperUK/minishift101/blob/master/workshop/README-ja.md) の準備段階が完了したことになります。

[Lab3](https://github.com/IBMDeveloperUK/minishift101/blob/master/workshop/Lab3/README-ja.md) あたりから、OpenShift (Minishift) 体験を始めてみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/7574fa0a-4c71-288e-b54e-595d9f6c2731.png)
こんな感じ？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/10fe28db-a19c-3f4e-8072-7ca6d73fcdfd.png)

# start に失敗した場合

start に失敗した場合、以下の3種類のリトライ方法があります。

## 1) リスタート

``.\minishift stop`` でいったん仮想環境を止めて、``.\minishift start`` を再度実行します。Image のダウンロードなどでコケた場合、そのまま続けて実行してくれる感じ。

2～3 回リスタートして駄目であれば、次のステップに進みましょう。

## 2) 仮想マシン再作成

``.\minishift stop`` でいったん仮想環境を止めて、````.\minishift delete`` で仮想マシン自体をいったん削除します。 そこから ``.\minishift start`` を再度実行します。

これでも駄目なら最後の手段です。

## 3) 設定も消して再実行

``.\minishift stop`` でいったん仮想環境を止めて、````.\minishift delete`` で仮想マシン自体をいったん削除します。また自身のユーザーフォルダに作成されている ``.kube`` と ``.minishift`` フォルダを削除します。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/ee61619a-91f7-c58e-5cd4-f3f6acaf632f.png)
これでほぼ start 開始前の状態に戻ります。そして ``.\minishift start`` を再度実行します。

# 終了後

仮想マシンを実行したままだとメモリやCPUを消費します。利用が終わったら ``.\minishift stop`` で仮想マシンの実行を止めておきましょう。次回利用する時には ``.\minishift start`` で再実行できます。

長期間使用しない場合には、stop の後に ``.\minishift delete`` で仮想マシン環境を削除することができます。仮想マシンのハードディスクまで削除されますので、ハードディスク容量もセーブできます。ただし minishift 上で作成したプロジェクトなど全て消えてしまいますので、注意してください。

# 補足情報

## 仮想マシンの IP アドレス変更の影響について

``minishift start`` する際に ``--show-libmachine-logs -v 5`` オプションを付与すると、仮想環境作成時の詳細なログが表示されます。これを眺めていると、途中で仮想マシン内で以下のファイルを作成している部分があります。

```
/etc/docker/ca.pem
/etc/docker/server.pem
/etc/docker/server-key.pem
```

例えば server.pem はサーバー側の CERTIFICATE(証明書) ですが、中身をデコードしてみると

```
Subject Alternative Names: localhost, IP Address:10.0.3.128
Organization: win_user.minishift
Valid From: November 29, 2019
Valid To: November 13, 2022
Issuer: win_user
Serial Number: 5ae95f05991352c641a1d3966d2c8383
```

と、仮想マシンの IP アドレスが含まれています。minishift コマンドと仮想マシン間はこれら証明書を用いてパスワード無しの SSH コマンド実行で繋がっていると思われます。

ですので仮想マシンの IP アドレスが変わった場合、これらの証明書も新しい IP アドレスで更新しないと、セキュリティ上の問題から SSH コマンド実行ができなくなり、minishft コマンドが動作しなくなる感じ。

minishift コマンド側が利用する証明書は ``c:\Users\win_usr\.minishift\certs`` フォルダに生成されています。

oc コマンドも同様に、仮想環境の構築時に作成された ``c:\Users\win_usr\.kube\config`` ファイルに格納された証明書情報をもとに Minishift 環境上の OpenShift 機能にアクセスしており、この設定ファイルもまた IP アドレスに依存した記述になっています。

minishift コマンドが仮想環境の IP アドレス変更を察知して、これら証明書を自動で更新してくれれば良いのですが。。

## Docker Desktop について

Docker Desktop for Windows のもともとの環境について、(何かあったら戻せるよう) メモを残しておいたので、参考のため消さずに置いておきます。まずは WinNAT の初期状態。

```console
PS C:\> Get-NetNat

Name                             : SharedNAT
ExternalIPInterfaceAddressPrefix :
InternalIPInterfaceAddressPrefix : 10.0.75.1/24
IcmpQueryTimeout                 : 30
TcpEstablishedConnectionTimeout  : 1800
TcpTransientConnectionTimeout    : 120
TcpFilteringBehavior             : AddressDependentFiltering
UdpFilteringBehavior             : AddressDependentFiltering
UdpIdleSessionTimeout            : 120
UdpInboundRefresh                : False
Store                            : Local
Active                           : True
```

これが今回、参考にした DockerNAT 仮想 内部スイッチで、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/8cd9fd1f-8d3a-861c-8b48-182e6f679306.png)
そのプロパティと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/d5cd2e0d-e2e6-b462-b9e0-4e8080c27646.png)
IPv4 のプロパティがこちら。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/5c437a55-6ee7-cb67-7ee0-4ffa61edd0e6.png)
このような Docker Desktop の設定を理解できたことが、今回の静的アドレスベースの設定をする鍵となりました。上手く動いているものを真似てみた、ってやつですね。

# というわけで

いろんな環境での学びを追記していったら、かなり長い投稿になってしまいました。皆様の参考になれば幸いです。

それではまた！