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

詳細

Hyper-V有効化

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

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

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

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

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

VM初期設定

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

ubuntu起動後の入力項目

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

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

言語

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

キーボードレイアウト

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

居住地域

  • Tokyoにした

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

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

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

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

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

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

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 から最新版を調べて取得する。

$ 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

参考