Ubuntu 20.04でMultipassをブリッジネットワークで動かす(Ver1.6.2まで)

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

```
【追記】
Multipass Version 1.7が2021/07/15(木)リリースされ、設定方法が変更になったので以下の記事を書きました。
```

Ubuntu 20.04でMultipassをブリッジネットワークで動かす(Ver1.7.0) - Qiita
https://qiita.com/ynott/items/01e2913539c664b6559d

# 0. はじめに

筆者はUbuntuのmultipassコマンドが大好きっ子です。
お手軽なコマンド体系と楽ちん操作で、仮想マシンを動かしたり止めたりが簡単にできるので、良い機能だなと思います。

しかし、ネットワーク部分があまりいけてませんでした。

仕方なく、iptablesを削除してルーティングしたり、
[Linux上のMultipassの仮想マシンへ外部ネットワークから接続する - Qiita](https://qiita.com/ynott/items/be8810f83d1db6f4540b)

remote.itを使って接続してみたり(これはこれで便利なのですが)
[multipassとremote.it(remot3.it)で仮想マシンのネットワークを快適にする - Qiita](https://qiita.com/ynott/items/649e653ed2aeadf812ae)
していました。

とはいえ、若干動作的に課題があったり、手間がかかったりでブリッジネットワークで利用できる機能が望まれていました。
[Support for bridged networking · Issue #118 · canonical/multipass](https://github.com/canonical/multipass/issues/118)

2020年11月にリリースされたmultipass 1.6.0でブリッジネットワークが利用できるようになりました。

WindowsやMacで試された方はいらっしゃったのですが、Ubuntu OS上で利用されている記事がなかったの試してみました。

Mac+Multipass+MicroK8s+Virtual Boxでネットワークブリッジを構成する | Glob
https://www.typea.info/blog/index.php/2020/11/20/mac_multipass_microk8s_virtuabox_networibridge/

WIndowsでMultipass(VirtualBox)のブリッジネットワークを構成する手順 | Glob
https://www.typea.info/blog/index.php/2021/03/06/create_vbox_bridgenw_on_multipass_windows/




# 1. 環境情報

OS: Ubuntu 20.04.2 LTS (GNU/Linux 5.8.0-59-generic x86_64)
Network: 192.168.xxx.0/24
NIC: enp2s0
Ubuntu母艦マシンIP: 192.168.xxx.yyy

# 2. 前提

- multipassのネットワークは、ネットワークのブリッジを先に作っておく必要があります。
- ネットワークブリッジは、netplanで作るのがお勧めです(NetworkManagerでも作れなくはないと思いますが、私はできませんでした)
- Ubuntu母艦マシンは固定IPにします(DHCPでも大丈夫だと思います)
- lxdが必要です。
- multipass 1.6.2でテストしています

# 3. netplanでネットワークのブリッジを作る

## 3-1. netplanの設定ファイルを作成

ブリッジ無しの場合はこんな感じに書くと思います。

```yaml:/etc/netplan/99-config.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    enp2s0:
      match:
        macaddress: 80:ee:73:zz:zz:zz 
      addresses: [192.168.xxx.yyy/24]
      dhcp4: false
      dhcp6: true
      gateway4: 192.168.xxx.1
      nameservers:
        addresses: [192.168.xxx.1,8.8.8.8,1.1.1.1 ]
```

以下のように書き換えます。

```yaml:/etc/netplan/99-config.yaml
network:
  version: 2
  renderer: networkd
  ethernets:
    enp2s0:
      dhcp4: false
      dhcp6: true
      match:
        macaddress: 80:ee:73:zz:zz:zz
  bridges:
    br0:
      dhcp4: false
      addresses: [192.168.xxx.yyy/24]
      interfaces:
        - enp2s0
      gateway4: 192.168.xxx.1
      nameservers:
        addresses: [192.168.xxx.1,8.8.8.8,1.1.1.1 ]
      parameters:
        forward-delay: 0
        stp: false
      optional: true
```

※dhcp6は使わなければfalseでもいいです。

## 3-2. 適用する

netplan tryしてエラーが出なければnetplan applyしましょう。
※tryの時にWarningが出ますが、エラーでなければ問題ないのでapplyしましょう。

```bash
$ sudo netplan try
br0: reverting custom parameters for bridges and bonds is not supported
Please carefully review the configuration and use 'netplan apply' directly.
$ sudo netplan apply
```

## 3-3. 確認

`ip a`コマンドでbr0ができたか確認します。
(注: loと別NICは省略、inet6も省略)

```io
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
    link/ether 80:ee:73:zz:zz:zz brd ff:ff:ff:ff:ff:ff
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 80:ee:73:zz:zz:zz brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.111/24 brd 192.168.10.255 scope global br0
       valid_lft forever preferred_lft forever
```

ネットワークの疎通も確認しておきましょう

```bash
dig www.google.co.jp | grep -v ';'
www.google.co.jp.	277	IN	A	216.58.220.99
```

# 4. multipassをインストール

```bash
$ sudo snap install multipass
multipass 1.6.2 from Canonical✓ installed
```

既に1.6.2がインストールされている場合は不要です。

# 5. lxdを設定
## 5-1. lxdをインストール

```bash
$ sudo snap install lxd
lxd 4.15 from Canonical✓ installed
```

こちらも既に 4.15がインストールされている場合は不要です。

## 5-2. lxdを初期化

このままだとlxdのネットワークとストレージプールが設定されていないのでmultipassから接続してもエラーになります。
以下のコマンドでlxdを初期化します。

```bash
$ sudo lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]:
Name of the storage backend to use (btrfs, dir, lvm, zfs, ceph) [default=zfs]:
Create a new ZFS pool? (yes/no) [default=yes]:
Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]:
Size in GB of the new loop device (1GB minimum) [default=30GB]: 400GB      <---※1
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]: no  <---※2
Would you like to configure LXD to use an existing bridge or host interface? (yes/no) [default=no]:
Would you like the LXD server to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
```

注意ポイントは※1と※2のところです。

※1 lxdで利用するストレージプールのサイズを聞かれます。このストレージプールにmultipassの仮想マシンイメージが保存されます(zfsを選んだ場合)。
大きめのサイズにしておきましょう。もしくは、zfsではなくて、dirとかを選んでもよいかもしれません。

```bash
Size in GB of the new loop device (1GB minimum) [default=30GB]: 400GB
```

※2 lxdで使うブリッジネットワークを作成するかどうか聞かれます。今回は既にbr0を作ってあるので`no`と答えましょう。

```bash
Would you like to create a new local network bridge? (yes/no) [default=yes]: no
```

# 6. multipassをlxdに接続する
## 6-1. multipassのローカルドライバーをqemuからlxdに変更

```bash
$ sudo multipass set local.driver=lxd
```

変更できたか確認する

```bash
$ multipass get local.driver
lxd
```

## 6-2. multipassをlxdに接続

```bash
$ sudo snap connect multipass:lxd lxd
```

変更できたか確認する

```bash
$ sudo snap connections multipass
Interface          Plug                         Slot                Notes
firewall-control   multipass:firewall-control   :firewall-control   -
home               multipass:all-home           :home               -
home               multipass:home               :home               -
kvm                multipass:kvm                :kvm                -
libvirt            multipass:libvirt            -                   -
lxd                multipass:lxd                lxd:lxd             -
multipass-support  multipass:multipass-support  :multipass-support  -
network            multipass:network            :network            -
network-bind       multipass:network-bind       :network-bind       -
network-control    multipass:network-control    :network-control    -
removable-media    multipass:removable-media    -                   -
unity7             multipass:unity7             :unity7             -
wayland            multipass:wayland            :wayland            -
x11                multipass:x11                :x11                -
```

# 7. multipassのネットワークブリッジ
## 7-1. multipassのネットワークブリッジを確認する
この時点では、`multipass networks -vvvv`コマンドはエラーになる

```bash
$ multipass networks -vvvv
[2021-06-29T11:09:06.536] [trace] [lxd request] Requesting LXD: GET unix://multipass/var/snap/lxd/common/lxd/unix.socket@1.0/networks?recursion=1&project=multipass

networks failed: LXD object not found
```

## 7-2. 仮想マシンを起動
一つ仮想マシンを起動する

```bash
$ multipass launch 20.04
Launched: dainty-rockfish
```

## 7-3. 再度ネットワークブリッジを確認する

再度、`multipass networks`コマンドを叩く

```bash
$ multipass networks
Name   Type    Description
br0    bridge  Network bridge
mpbr0  bridge  Network bridge for Multipass
```

ブリッジネットワークのbr0が認識されている。

# 8. ブリッジネットワークを使って multipassで仮想マシンを動かす

# 8-1. 動かし方

`multipass launch` に `--network <ブリッジネットワーク名>` オプションを付ける
何も指定しないとdhcpでIPアドレスを取得する

```bash
$ multipass launch 20.04 --network br0
Starting guided-papillon |
Launched: guided-papillon
```

確認する

```bash
$ multipass list
Name                    State             IPv4             Image
guided-papillon         Running           10.222.159.143   Ubuntu 20.04 LTS
                                          192.168.xxx.6
```

10.222.159.143のIPアドレスは、multipassとmultipass shell/exec等で接続するためのIPアドレスで、
192.168.xxx.6のIPアドレスは、ローカルネットワークのDHCPから割り振られたIPアドレス(ブリッジネットワーク)です。

## 8-2. Ubuntu母艦マシンのNICの確認

Ubuntu母艦マシンのNICを`ip a`で確認するとtapで始まるNICが作られています。mpbr0とbr0用のタップブリッジです。
(注:関係ないNICは省略)

```io
12: tapf03812d0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master mpbr0 state UP group default qlen 1000
    link/ether fa:33:67:9a:e3:ec brd ff:ff:ff:ff:ff:ff
13: tap336015f4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000
    link/ether 36:b0:66:50:1f:00 brd ff:ff:ff:ff:ff:ff
```

## 8-3. 仮想マシン内のNICの確認

上記のタップブリッジが仮想マシン内のNICでは以下のように見えます。

```io
$ multipass exec guided-papillon -- ip  address
2: enp5s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 52:54:00:f6:a3:43 brd ff:ff:ff:ff:ff:ff
    inet 10.222.159.143/24 brd 10.222.159.255 scope global dynamic enp5s0
       valid_lft 3376sec preferred_lft 3376sec
3: enp6s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 52:54:00:f1:45:17 brd ff:ff:ff:ff:ff:ff
    inet 192.168.xxx.6/24 brd 192.168.10.255 scope global dynamic enp6s0
       valid_lft 1345sec preferred_lft 1345sec
```

## 8-4. `--network` オプション詳細


| オプション名| 項目詳細 |
|------------|---------|
|name        |ホスト側のブリッジネットワークのインターフェース名を指定(nameのみの時はname=を省略できる) |
|mode        |autoまたはmanualを指定する。autoの時にはdhcpで設定しようとする。manualの場合は仮想マシン内のNICにIPアドレスを設定する必要がある|
|mac         |デバイスに使用するカスタムMACアドレス|

(参考URL)
Additional network interfaces | Multipass documentation
https://multipass.run/docs/additional-networks

(実行例)

```bash
multipass lauch 20.04 --network name=br0,mode=auto
```

# 9. 注意事項

1. **既存でMultipassを使っている場合は、lxdに切り替えた途端に既存の仮想マシンが見えなくなります！**  
戻すには、`sudo multipass set local.driver=qemu` コマンドを実行してください。

2. __lxdのpool storageはzfsじゃない方が良いかも。__  
  第571回　LXD 3.0のストレージ設定：Ubuntu Weekly Recipe｜gihyo.jp … 技術評論社 
https://gihyo.jp/admin/serial/01/ubuntu-recipe/0571

# 10. まとめ

Virtualboxで仮想マシンを使うのも便利なのですが、GUIなんていらないぜ！コマンドだけで生きていける人は便利でよいと思います。
ブリッジネットワークが使えるようになったので外から仮想マシンへ接続に行くようなアプリでも気にせず使えるようになりました。

# 11. 参考URL

1. `multipass networks` command | Multipass documentation
https://multipass.run/docs/networks-command/19542

2. 
Additional network interfaces | Multipass documentation
https://multipass.run/docs/additional-networks

1. 
`multipass networks` command - Multipass / Documentation - Ubuntu Community Hub
https://discourse.ubuntu.com/t/multipass-networks-command/19542/9

3. 
"networks failed: LXD object not found" after `sudo snap connect multipass:lxd lxd` · Issue #2139 · canonical/multipass
https://github.com/canonical/multipass/issues/2139