KVMでホストとブリッジ接続したVMを作成する
家にあるUbuntuPCでKVMを使ってVMを作成した。VMを外部ホストからsshで接続できるようにするため、ホストで作成したブリッジネットワークにVMを接続したが、色々と詰まったので全体の手順と一緒にまとめておく。
環境
ホストOS
Ubuntu 22.04.1 LTS
ゲストOS
Ubuntu 20.04.5 LTS
手順
UbuntuにKVMを入れる手順は省略(公式の手順を参照)
ブリッジを作成
こちらを参考にした。
デフォルトのネットワークを削除する
KVMをインストールすると、デフォルトでvirbr0というブリッジが作成されているはずである。
このブリッジはNATを使うことでVMが外のネットワークにアクセスできるようにしている。
これがあればホストとVMの間では通信ができるが、外部ホストからVMにアクセスすることはできない。今回は不要なので削除する。
KVM側ではdefaultという設定として記述されているのでこれを削除する。
$ virsh net-destroy default
$ virsh net-undefine default
netplanでブリッジを作成しNICを接続する
netplanを使う。/etc/netplan
配下のファイルで適当なものを修正するか新しく作成する。
ホストのNIC enxf8e43bb371e8
には静的に 192.168.0.130
を割り当てているのでこのアドレスを使う。
# /etc/netplan/99_config.yaml
network:
version: 2
ethernets:
enxf8e43bb371e8:
dhcp4: false
dhcp6: false
bridges:
br0:
interfaces: [enxf8e43bb371e8]
addresses: [192.168.0.130/24]
gateway4: 192.168.0.1
nameservers:
addresses: [192.168.0.1, 8.8.8.8]
parameters:
stp: false
dhcp4: false
dhcp6: false
$ sudo netplan apply
すると新しいブリッジ br0
が作成される。最初は enxf8e43bb371e8
についていたIPアドレスの記載が br0
に移る。また enxf8e43bb371e8
の欄に master br0
と書いてあるので、ちゃんとNICがブリッジに接続されていることがわかる。
$ 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: enxf8e43bb371e8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
link/ether f8:e4:3b:b3:71:e8 brd ff:ff:ff:ff:ff:ff
(skip)
16: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 72:e2:b6:e9:05:35 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.130/24 brd 192.168.0.255 scope global noprefixroute br0
valid_lft forever preferred_lft forever
inet6 fe80::70e2:b6ff:fee9:535/64 scope link
valid_lft forever preferred_lft forever
KVMにブリッジを認識させる。以下の host-bridge.xml
を作成する。
<network>
<name>host-bridge</name>
<forward mode="bridge"/>
<bridge name="br0"/>
</network>
KVMに登録する。
$ virsh net-define host-bridge.xml
$ virsh net-start host-bridge
$ virsh net-autostart host-bridge
正しく登録されていることを確認。
$ virsh net-list --all
Name State Autostart Persistent
------------------------------------------------
host-bridge active yes yes
Bridge Netfilterを無効化する
ここでVMが外部ネットワークに繋がらない根本原因はiptablesでFORWARDをDENYしていたことが原因だった。 なのでFORWARDのデフォルトポリシーをACCEPTに変更することでも解決可能である。
ここで詰まった。この後VMを作成してもVMが外部のネットワークに繋がらない。
原因はBridge Netfilterがブリッジを介した通信を遮断しているせいだった。
こちらを参考にホストでBridge Netfilerを無効化する。
/etc/sysctl.conf
に以下の行を追記。(環境によっては同様の設定が /etc/sysctl.conf
や /etc/sysctl.d/*
にあるかもしれないので要確認)
net.bridge.bridge-nf-call-iptables = 0
以下を実行して更新。
$ sudo sysctl -p
正しく更新されたことを確認。
$ sudo sysctl net.bridge.bridge-nf-call-iptables
net.bridge.bridge-nf-call-iptables = 0
VMを作成
Ubuntu20.04 でVMを作成する。メモリやコア数、ディスクサイズなどは適宜設定する。
$ virt-install \
--name vm1 \
--ram=2048 \
--disk size=10 \
--network network=host-bridge \
--vcpus 1 \
--os-type linux \
--os-variant ubuntu20.04 \
--graphics none \
--location 'http://archive.ubuntu.com/ubuntu/dists/focal/main/installer-amd64/' \
--extra-args "netcfg/disable_autoconfig=true console=ttyS0,115200n8 --- console=ttyS0,115200n8"
ここで要注意なのが --extra-args
の console=ttyS0,115200n8 --- console=ttyS0,115200n8
である。
全ての設定をCLIのみで行う場合、後程 virsh console vm1
でVMに接続してsshなどの設定を行う必要があるが、コンソールにシリアル接続できるようにしておかないと何も動かなくなる。
詳しい話はこちら。
また netcfg/disable_autoconfig=true
はインストール時に自動でDHCPで動的にアドレスを指定しようとするのを防ぐ。必要かどうかは環境によるが、今回は静的にアドレスを指定したかったのでこうする。(参照)
ここで静的にアドレスを指定できないのかと調べたが、RHELでは指定できそうだがUbuntuでは見つからなかった。
Ubuntuインストール
ウィザードが出てくるので説明手順に従ってインストールする。
sshの設定をする
インストール完了後、そのままコンソールに接続してくれたならそれで良いが、そうでない場合は手動で接続する。
$ virsh console vm1
sshサーバーをインストールして、鍵を登録する。
$ sudo apt update
$ sudo apt install openssh-server
$ mkdir ~/.ssh
$ wget "https://github.com/hiroyaonoe.keys" -O ~/.ssh/authorized_keys
これでexitしてから、インストール時に指定したユーザー名とIPアドレス(DHCPの場合はよしなに調べる)を使えばssh接続できるはずである。
まとめ
ネットワーク周りの設定は難しい。特にBridge Netfilterの設定は解決に時間がかかったので役にたてばうれしい。
これで自宅のUbuntuPCにVMを立てる用意が整ったので、Kubernetesクラスタ立てるとかやってみたい。