Hyper-VでのNAT構成の仮想マシン

# このメモについて

* 自宅で使っているWindows10(pro)のHyper-Vに仮想マシンを作ることになったので、その時のメモ。
 * 基本的にぐぐれば出てくる情報のため真新しいものは無いが、Default Switchというのを使うのかどうか不明だったため、実際にやってみた。
* 既存で仮想マシンを1つ作ってあり、こちらはホストのWindows10や外のネットワークと同じセグメントに属している。
 * 既に少しリソース使っているので追加の仮想マシンはスペック控えめ
* 外からつながる必要のない仮想マシンを作るので、追加の仮想マシンはNAT構成にしてみた

# 環境

* ホスト : Windows 10 pro 64bit バージョン1903 OSビルド 18362
 * Intel(R) Core(TM) i5-8500 CPU @3.00GHz (6 core 6 thread)
 * 16.0 GB RAM
* 今回追加するゲスト : Ubuntu 18.04

# 手順

以下、簡単のため仮想マシンをVMと記載したりしているが同じ意味である。

1. Hyper-V有効化
1. Hyper-Vマネージャでクイック作成
1. OS選択、イメージのダウンロード、VM作成
1. VM初期設定
 1. VM起動後の入力項目
 1. 言語
 1. キーボードレイアウト
 1. 居住地域
 1. ホスト名、アカウント、パスワード
1. ログイン画面からのログイン
1. NAT用仮想スイッチ作成
1. インターネット接続の共有
1. NAT用仮想スイッチのアドレス取得
1. ゲストOS設定
1. ホストOSでのNAT設定
1. ゲストOSへの追加設定

# 詳細

## Hyper-V有効化

デスクトップ画面左下のWindowsメニュー　→　設定（歯車マーク）　→　アプリ
　→　「アプリと機能」の右ペインにて関連設定「プログラムと機能」
　→　Windowsの機能の有効化または無効化　→　Hyper-Vにチェック

![hyperv-apl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318326/57fb02fc-6c16-109c-ce7e-d04012dd76cd.png)

## Hyper-Vマネージャでクイック作成

デスクトップ画面左下のWindowsメニュー　→　Windows管理ツール
　→　Hyper-Vマネージャ　→　左ペインのホストのアイコン上で右クリック
　→　右クリックメニューから「クイック作成」

![hyperv-cre.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318326/ac6deb98-0024-9890-b22c-2cb73ec8d622.png)

## OS選択、イメージのダウンロード、VM作成

クイック作成画面
　→　オペレーティングシステムの選択「Ubuntu 18.04.3 LTS」を選択し「仮想マシンの作成」ボタン押下
　→　OSのイメージがダウンロードされる。今回は1.6GB
　→　イメージのダウンロードが完了すると、VMが作成される。
　→　ここで「接続」ボタン押下し、VMの初期設定に移る。

![hyperv-os.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318326/04d438be-159e-b28c-8912-c90628a6014b.png)

![hyperv-ubu-dl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318326/746c330c-dc32-b487-87a4-17c487977576.png)

![hyperv-img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318326/60b8aaed-5f7d-0d3b-03ba-ce4128521ab2.png)

![hyperv-conn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318326/c7a46d7e-d058-bc4d-f71f-4b104bfbdb74.png)


## VM初期設定

仮想マシン接続画面で画面中央の「起動」ボタン押下。
はじめerrorが表示されるが気にせず、少しの間待っていると初期設定画面になる。

![hyperv-ubu1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318326/914f6fde-3f98-681c-58ec-65162259894e.png)


### ubuntu起動後の入力項目

ubuntu 18.04の初期設定では、以下の項目を入力する。

* 言語
* キーボードレイアウト
* 地域
* アカウント、パスワード
* ホスト名

### 言語

Welcomeの画面では、一番下のほうにスクロールしていくと日本語があるので日本語にした。

### キーボードレイアウト

* キーボードレイアウトは日本語キーボードにした。
* 右のような詳細な選択もできる（が、今回は何もついてない「日本語」を選んだ）：Dvorak, Macintosh, OADG 109A, かな86, かな

### 居住地域

* Tokyoにした

### ホスト名、アカウント、パスワード

* 自分の名前、コンピュータ名（ホスト名）、ユーザ名とそのパスワードを入力。
 * 使用できない文字などは適宜、ツッコミが入るのでそれに従う
 * パスワードの強度が表示されるので、参考にする
* ログインのオプションとして、「自動的にログイン」ではなく、「ログイン時にパスワードを要求する」を選択した

## ログイン画面からのログイン

ログイン画面からubuntuにログインする。

* SessionはXorgなど6種類くらいから選択できるので好みで選択
* username, passwordは初期設定で設定したものを入力する

無事、ログインできればOK。ただしまだインターネットにつなぐには設定が足りてない。

![ubu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318326/2695c5c2-5050-9228-73fd-d54f1ce3483d.png)

## NAT用仮想スイッチ作成

次に、ホスト側でHyper-VマネージャからNAT用仮想スイッチを作成する。

名前は何でもよいが、分かりやすいよう、「hyperv_nat」にする。
種類は内部ネットワークにする。ここではvlanは使っていない。

* Hyper-Vマネージャを起動し、右ペインで「仮想スイッチマネージャー」起動
 * 結論からいうと、ここで「Default Switch」というスイッチを使用せずに環境構築できた。
* 仮想スイッチマネージャーの左ペイン「新しい仮想ネットワークスイッチ」にて、仮想スイッチの種類を「内部」とし、「仮想スイッチの作成」ボタン押下
* 仮想スイッチのプロパティで、名前を「hyperv_nat」とする。接続の種類は「内部ネットワーク」にする。VLAN IDは有効にしない（チェックボックスにチェックをいれない）

## インターネット接続の共有

コントロールパネル　→　ネットワークとインターネット　→　ネットワークと共有センター
　→　アダプターの設定の変更
　→　インターネット接続に使用する物理NICを選択し右クリック
　→　物理NICの右クリックメニューにおいて、プロパティの「共有」タブで、
　　インターネット接続の共有を以下のように設定した。
　　※なお、物理NICはWi-Fi用のでもよい

　→　「ネットワークのほかのユーザに、このコンピューターのインターネット接続を
　　　とおしての接続を許可する」にチェックをいれ、
　　ホームネットワーク接続のプルダウンで、「vEthernet(hyperv_nat)」を選択。
　　「ネットワークのほかのユーザに、共有インターネット接続の制御や無効化を
　　　許可する」のチェックボックスもありにする。

　→　物理NICが「有効、共有」の状態になる。

## NAT用仮想スイッチのアドレス取得

* 仮想NIC(vEthernet(hyperv_nat))で、IPv4アドレスとネットワークアドレスをプロパティで調べる。
 * インターネット接続の共有を設定した直後の時点で「192.168.137.1/24」が自動で付与されていた
* DNSは空のままでよい。

## ゲストOS設定

### メモリなどの設定

一度、Hyper-VマネージャでVMを停止して、設定変更する。
仮想ハードディスクのディスクサイズはこの時点（ゲストOS初期設定直後）で4.7GBのvhdxファイルだった。
スペックは何でもよいが、今回そんなにパワフルなマシンでもないので控え目に2コア4Gメモリとかにしておく。

* 仮想プロセッサ : 2
* メモリ : 4096 MB (4GB)
* ネットワークアダプター：仮想スイッチ「hyperv_nat」

以下は、VMの起動後にVMへログインして設定する。

### NetworkManager停止

```
$ sudo systemctl stop NetworkManager
$ sudo systemctl disable NetworkManager
Removed /etc/systemd/system/dbus-org.freedesktop.nm-dispatcher.service.
Removed /etc/systemd/system/multi-user.target.wants/NetworkManager.service.
$ sudo systemctl status NetworkManager

```

### IPアドレス、名前解決の設定

* /etc/hosts

```
$ sudo vi /etc/hosts
$ sudo cat /etc/hosts
127.0.0.1	localhost
127.0.1.1	ubu1804
192.168.137.2	ubu1804.local
・・略・・
```

* /etc/netplan/01-network-manager-all.yaml

```
$ sudo vi /etc/netplan/01-network-manager-all.yaml 
$ sudo cat /etc/netplan/01-network-manager-all.yaml
# Let NetworkManager manage all devices on this system
network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: false
      addresses: [192.168.137.2/24]
      gateway4: 192.168.137.1
      nameservers:
        addresses: [8.8.8.8]

$ sudo netplan apply
$ ip a
```

* /etc/resolv.conf

netplanでの設定通りになっているか確認しておく

```
# sudo su
# cd /etc
# ln -sf ../run/systemd/resolve/resolv.conf resolv.conf
# ls -l /etc/resolv.conf
# cat resolv.conf 
```

### 参考：プロキシ設定（必要あれば）

もしプロキシ環境ならこの時点で次の3つくらいは変更すると思われる。

* /etc/apt/apt.conf

```
# サーバ名、ポート番号は適宜変更
Acquire::http::Proxy "http://proxy-server:8080";
Acquire::https::Proxy "http://proxy-server:8080";
Acquire::ftp::Proxy "http://proxy-server:8080";
```

* /home/ubuntu/.bashrc

```
# サーバ名、ポート番号は適宜変更
export http_proxy=http://proxy-server:8080
export HTTP_PROXY=http://proxy-server:8080
export https_proxy=http://proxy-server:8080
export HTTPS_PROXY=http://proxy-server:8080
export no_proxy=127.0.0.1,localhost,192.168.137.2
export NO_PROXY=127.0.0.1,localhost,192.168.137.2
```

* /etc/environment

```
# サーバ名、ポート番号は適宜変更。パスも同様
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
http_proxy=http://proxy-server:8080
HTTP_PROXY=http://proxy-server:8080
https_proxy=http://proxy-server:8080
HTTPS_PROXY=http://proxy-server:8080
no_proxy=127.0.0.1,localhost,192.168.137.2
NO_PROXY=127.0.0.1,localhost,192.168.137.2
```

なお、ubuntu18.04.3の/lib/systemd/system/snapd.serviceをみたらsnapdでもこの/etc/environmentを参照していた。

ハイフンから始まっているので、もしこのファイルが存在しなくても、読み込まれず、エラーやワーニングといったメッセージも出ない。
が、proxy設定必要な環境だがこのファイル（/etc/environment）が存在しない場合や、もしくは存在するがproxy設定を忘れた場合は、他でproxy設定しておかない限り、「error : unable to contact snap store」といったエラーが出る。

```
[Service]
・・略・・
EnvironmentFile=-/etc/environment

```

## ホストOSでのNAT設定

PowerShellを管理者として起動。New-NetNatコマンドによるNAT設定を行う。
物理NICとインターネット接続を共有している仮想スイッチに対して、NAT設定する。

```
PS C:\WINDOWS\system32> Get-NetAdapter
　→　アダプタの一覧でhyperv_natがあることを確認

PS C:\WINDOWS\system32> New-NetNat -Name hyperv_nat -InternalIPInterfaceAddressPrefix 192.168.137.0/24


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


PS C:\WINDOWS\system32> Get-NetNat


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


PS C:\WINDOWS\system32>
```

ここまで設定した時点で、VMからどこかにHTTPで接続してみる。
ここでホスト側と同様にインターネットに接続できていればOK。
なお、VMからゲートウェイアドレス（192.168.137.1）に対しては、ping不通である。

```
$ cd /tmp
$ wget https://www.google.com/
```

## ゲストOSへの追加設定

もうこの後はゲストOSに設定し放題なわけだが、自分がたいてい使いそうなのは書いておく。
コンテナなしでは生きられなくなってしまった。

### curl , make , git

```
$ sudo apt autoremove
$ sudo apt update
$ sudo apt install -y curl make git
```

### docker

#### パッケージインストール

```
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ ls get-docker.sh
$ sh get-docker.sh
```

#### 参考：プロキシ設定（必要あれば）

いろいろなところで書かれているのでリンクは特に張らないが、使うときは忘れずに。

* プロキシ環境ではdockerイメージのpull/pushで以下の設定が必要。

```
# /lib/systemd/system/docker.service
# サーバ、ポート番号は適宜、変更
・・略・・
[Service]
・・略・・
Environment="HTTP_PROXY=http://proxy-server:8080/"
Environment="HTTPS_PROXY=http://proxy-server:8080/"
Environment="NO_PROXY=127.0.0.1,localhost,192.168.137.2"
・・略・・
```

* build時はDockerfile内のENVに、またrun時はオプションで-e HTTP_PROXY=http・・・ みたいに指定。

```
$ sudo docker run -e HTTP_PROXY=http://proxy-server:8080 --name container_name container_tag:1.0
※サーバ名、ポート番号は適当に読み替え。タグやコンテナ名なども同様。
```

### docker-compose

[releases](https://github.com/docker/compose/releases) から最新版を調べて取得する。

```
$ curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-`uname -s`-`uname -m` -o docker-compose
$ ls -l docker-compose
$ sudo cp docker-compose /usr/local/bin/
$ sudo chmod +x /usr/local/bin/docker-compose
$ sudo ls -l /usr/local/bin/docker-compose
$ docker-compose --version
```


# 参考

* https://qiita.com/afukuma/items/18a53416a6c6591498bb
* https://www.atmarkit.co.jp/ait/articles/1612/16/news039.html
* https://uncle-atsushi.com/hyper-v_virtual_switch_configuration/