M1 MacでMultipassがステータスUnknownとなった場合の起動方法

こんにちは、みやがわです。

Multipassを使って Docker on Ubuntu on Mac で開発をしています。
Intel Macのときには起きていなかった事象がM1 Macで起きて困ったので、調査しました。

## 結論

```markdown
・起動できないのはMacのファイアウォールが原因
・Multipass内部プロセスをファイアウォールから除外する or ファイアウォールを一時的にオフにして起動する
```

## 何が起きたか

PCをシャットダウンしてから立ち上げ直すと、Multipassのインスタンスが Unknown 状態になっていました。

```bash
❯ multipass list

Name                    State             IPv4             Image
docker                  Unknown           --               Ubuntu 20.04 LTS
```

この状態で起動しようとしても、「稼働中だよ、unknown状態だけど」として何も変わりません。（一度 stop して start しても同様です）

```bash
❯ multipass start docker -vvv

[2022-10-24T10:56:54.197] [warning] [daemon] Instance 'docker' is already running, but in an unknown state
[2022-10-24T10:56:54.197] [debug] [docker] Waiting for SSH to be up
start failed: The following errors occurred:
Instance 'docker' is already running, but in an unknown statedocker: timed out waiting for response
```

## 原因

> [Firewall randomly messing with Multipass networking on macOS · Issue #2387 · canonical/multipass](https://github.com/canonical/multipass/issues/2387#issuecomment-1143180291)
> I've started to run into this too and suspect it's a bug in Apple's firewall due to the randomness of when it triggers, that it doesn't happen for some folks at all

要約すると、「全員には起こらないかつ発生にランダム性があるので、MacのFirewallのバグと疑っている」です。
Issueの会話を見てもFirewallの話題が何度も上がっているので確からしいです。

## 対処方法

`（追記 2023-02-09）` より良い方法がissueに上がっていたのでこちらがよさそうです。

> ```
> /usr/libexec/ApplicationFirewall/socketfilterfw --add /usr/libexec/bootpd
> /usr/libexec/ApplicationFirewall/socketfilterfw --unblock /usr/libexec/bootpd
> ```
> https://github.com/canonical/multipass/issues/2387#issuecomment-1409321719

こちらを実行した場合、Firewall有効のままで起動できるようになります。
ちなみに、Multipass 1.12 ではこちらのコマンドがインストール後に自動で実行されるようにようです。
> https://github.com/canonical/multipass/issues/2387#issuecomment-1416317533

---

> ~~[Firewall randomly messing with Multipass networking on macOS · Issue #2387 · canonical/multipass](https://github.com/canonical/multipass/issues/2387#issuecomment-1143180291)~~
> ~~To that point, if you're hitting this you can work around it by turning the firewall off in the GUI and enabling it in debug mode like: /usr/libexec/ApplicationFirewall/socketfilterfw -d. (see #2387 (comment) for where I got this).~~

~~同コメントのこちらです。~~
~~要約すると、「GUIでファイアウォールをオフにするか、コマンドでファイアウォールのデバッグモードを有効にするか」です。~~

~~実際私はファイアウォールを一時的にオフにして起動しています。~~
~~起動後は再度オンにしても問題ありません。~~
~~（私のケースではデバッグモードを有効にしても解決しませんでした。）~~

![Screen Shot 2022-12-16 at 11.15.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390133/a9e357af-9731-cbe7-a5e8-885abd9ee9c4.png)

---

### 起動してみる

同じメッセージが出つつも起動します🎉

```bash
❯ multipass start docker -vvv
[2022-12-15T16:48:37.753] [warning] [daemon] Instance 'docker' is already running, but in an unknown state
start failed: The following errors occurred:
Instance 'docker' is already running, but in an unknown state
```

```bash
❯ multipass list
Name                    State             IPv4             Image
docker                  Running           192.168.64.4     Ubuntu 20.04 LTS
                                          172.23.0.1
                                          172.18.0.1
```


## おわりに

Multipassでの開発はDocker for Macと比較して圧倒的に速いです。
PC移行した際に起きたことなので、原因の特定に時間が掛かり苦労しました。
誰かの役に立てばうれしいです👍

毎回一時的にオフにするのはちょっと大変なので、治ってほしいですね🙏

## 備考

半年前まで[Docker for Mac](https://qiita.com/NaoyaMiyagawa/items/22a870112377a91e1c99)を使っていましたが、ホストPCとのファイルマウントの速度が遅くMultipassに移行しました。
特に画面遷移やフロントエンドのビルド時に効果を実感します。
とても速いので快適です。