はじめに
はじめまして!
ディップ株式会社にて11月より24新卒内定者インターンとしてインフラエンジニア見習いをしている者です。
こちらはディップ株式会社 Advent Calendar 2023の25日目の記事となります!
メリークリスマス!
本記事では、弊社の業務とは関係のないものですが、私がHyper-VにUbuntu Server 22.04 LTSで仮想マシンを構築する際に得た知見を共有していきたいと思います。
やりたかったこと
仮想マシン(VM)へデータベースの構築やWordpressのホスティング、Ansible実行等、様々な学習用途で利用したいことが目的でしたが、1点問題が発生しました。
Hyper-VのDefault SwitchはDHCPで仮想マシンへ自動でIPアドレスが振られるのですが、これがくせ者で、頻繁にセグメントやIPアドレスが勝手に変更されます。毎回Hyper-VからVMに接続してIPを確認した上でSSH接続しないと、コピペができない。。。
決まったIPアドレスに諸々を繋ぎたかったのですが、コロコロコロコロIPが変わるため、非常にやりづらく、IPを固定化しようと考えましたが、上記で示した通りの事情と、仮想マシンのUbuntuが比較的新しいバージョンで従来の方法で設定できず、調べてもこの状況にピッタリ合う文献が少なく少し時間を要したので私が行った方法を共有します。
(VirtualBox使えよ!という突っ込みはナシでお願いします!笑 Hyper-Vの軽さには勝てず。。。)
手順として、
①仮想スイッチの作成
②NATの設定
③仮想マシンのIPアドレス固定化
が必要になります。順番に説明します。
①仮想スイッチの作成
Hyper-Vの仮想ネットワークは、デフォルトの仮想スイッチ(vSwitch)が標準で有効になっている(無効化、削除は基本的にできません)他に、VirtualBoxやVMWare Workstation Player等と同様に自由に仮想スイッチを作成し、VMをアタッチできます。
そこで、固定セグメントの仮想スイッチを新たに作成します。
Hyper-Vマネージャを開き、仮想スイッチ マネージャーを開きます。
↓
新しい仮想ネットワーク スイッチをクリックし、内部ネットワークを選択し、仮想スイッチの作成をクリックします。
↓
左側に作成されたvSwitchが表示されるので、分かりやすい名前に変更し、適用をクリックします。
続いてvSwitchのネットワーク設定とVMのDGWとなるアドレスを設定します。
まず、コントロールパネルを開き、ネットワークと共有センターに移動します。
(Windowsが新しくなり、コントロールパネルに馴染みのない方が増えてきていることに驚きを感じつつ、一応開き方も手順として掲載します。)
WindowsキーとRキーを同時に押し、テキストボックスにControlと入力しEnterキーを押します。
↓
表示方法を小さいアイコンにし、ネットワークと共有センターをクリックします。
↓
↓
vEthernet(設定したvSwitch)のvNICをダブルクリックします。
↓
下の画像を右からプロパティ→インターネット プロトコル バージョン4→プロパティ→次の IP アドレスを使うの順にクリックし、IPアドレスとサブネットマスクの欄にそれぞれ適切な値を入力します。ここで入力したIPアドレスがこの後IPアドレスを固定設定するVMのDGWとなる点に留意してください。
ネットワークアドレスは自由ですが、Default SwitchがクラスBプライベートアドレス(172.16.0.0/12
)の一部をセグメントとして設定されるため、クラスA(10.0.0.0/8
)かクラスC(192.168.0.0/16
)のサブネットで作成することをおすすめします。私は他のサービスとの干渉が少なそうな192.168.100.0/24
を設定しました。
以上がvSwitch作成の手順です。
②NATの設定
上記で作成したvSwitchは内部ネットワークです。
利用する仕組みとしては、物理NICや物理ネットワークとは繋がっていないvSwitchを作成し、そこにVM(Ubuntu)とホストPC(Windows)のvNICを接続している状態になります。
つまり、この状態だとホストPCとVM同士の通信は可能なのですが、vSwitchが物理ネットワークと接続されていないため外部(インターネット)と通信することができません。
そこで、NATでアドレスを変換し、外部と通信できるように設定する必要があります。
まず、管理者権限でWindows Powershellを起動します。
(スタートメニュー→Windows ツール→Windows Powershellを右クリック→管理者として実行で起動できます)
↓
以下のコマンドを入力します。
New-NetNat -Name "vNetToExt" -InternalIPInterfaceAddressPrefix 192.168.100.0/24
名前は自由です。ネットワークアドレスは仮想ネットワークと同じものにしてください。
実行すればNATの設定は完了です。
誤ったアドレスを設定してしまったり、仮想環境を畳むなどの場合で設定を削除したい場合は以下のコマンドを入力してください。
Remove-NetNat -Name "vNetToExt"
③仮想マシンのIPアドレス固定化
最後に、VMのIPアドレスを固定設定(DHCPを使わずに任意のアドレスを設定する)します。
Hyper-V マネージャーを起動し、VMを起動せずに仮想マシン欄にある設定したいVMを右クリックし、設定を開きます。
↓
ネットワーク アダプターをクリックし、仮想スイッチの選択リストを設定したvSwitchに変更し、適用をクリックします。
↓
設定を閉じ、VMを起動・接続します。
(少し時間がかかります。途中でブートプロセスが止まっているように見えますが、異常ではなく、DHCPサーバが存在していない仮想ネットワークでDHCP discoveryのブロードキャストを行ってしまっている状態なので、タイムアウトし画面が進むまで気長に待ちましょう。)
この時点ではVMにDHCPが設定されているため、IPアドレスが割り当てられず、SSH接続ができません。以降完了するまでのコマンド入力はHyper-Vからマシンを直接接続して編集してください。
↓
/etc/netplan
ディレクトリへ移動します。
cd /etc/netplan
↓
ls -l
などでディレクトリ内のファイルを確認し、.yaml拡張子のファイルを確認します。
(Hyper-VでUbuntu Server 22.04 LTSをisoからインストーラを利用しインストールした場合、00-installer-config.yaml
という名前で存在しているはずです。)
↓
このファイルをバックアップとして変更します。
sudo mv 00-installer-config.yaml 00-installer-config.yaml.bak
Ubuntuの現在のネットワークマネージャは.yamlファイルを認識して設定を実行するので、バックアップとして変更するファイルの拡張子は.yaml以外にしてください。
↓
新規ファイル名でvim等で編集します。ファイル名は拡張子が.yamlであれば自由です。
sudo vim 01-staticip-config.yaml
↓
以下ものを、アドレス、NIC名(ip a
で確認可能)等を設定したものに適宜変更し記述してください。
network:
version: 2
renderer: networkd
ethernets:
eth0:
addresses: [192.168.100.1/24]
nameservers:
addresses: [1.1.1.1 , 1.0.0.1]
routes:
- to: default
via: 192.168.100.254
eth0の部分はVMのvNIC名です。
eth0:addressesはVMに設定したいアドレスを入力してください。
eth0:nameservers:addressesはDNSサーバのアドレスを入力してください。例にはCloudflareのパブリックDNSを設定しています。
routes:viaのアドレスはDGWとして設定したホストPCのvNICのアドレスです。
↓
入力後、Escキー→ :wq→Enterキーで保存します。
↓
設定を反映させます。以下のコマンドを実行してください。
sudo netplan apply
これで設定完了です。ip a
コマンドでIPアドレスが変更されていることを確認してください。
ついでにping google.com
等で外部疎通の確認も済ませておくと良いと思います。
例:↓(以下のものと同じであれば成功しています。)
user@ubuntu:/etc/netplan$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:15:5d:01:20:0c brd ff:ff:ff:ff:ff:ff
inet 192.168.100.1/24 brd 192.168.100.255 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::215:5dff:fe01:200c/64 scope link
valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:d4:dd:c8:ae brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
user@ubuntu:/etc/netplan$ ping google.com
PING google.com (142.251.42.206) 56(84) bytes of data.
64 bytes from nrt12s47-in-f14.1e100.net (142.251.42.206): icmp_seq=1 ttl=107 time=36.0 ms
64 bytes from nrt12s47-in-f14.1e100.net (142.251.42.206): icmp_seq=2 ttl=107 time=20.8 ms
64 bytes from nrt12s47-in-f14.1e100.net (142.251.42.206): icmp_seq=3 ttl=107 time=21.1 ms
64 bytes from nrt12s47-in-f14.1e100.net (142.251.42.206): icmp_seq=4 ttl=107 time=24.2 ms
^C
--- google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3006ms
rtt min/avg/max/mdev = 20.829/25.536/36.024/6.198 ms
user@ubuntu:/etc/netplan$
さいごに
説明が長くなってしまい申し訳ありませんが、以下が手順です。
あまりホストPCの環境への影響も抑えつつ対応したかったので、このように行いましたが、かなり扱いやすくなりました。
色々説明したので簡潔で分かりやすく無くなってしまいましたが、最後までお読みいただきありがとうございました!