Docker for mac (ver 4.3以降) で「Failed to get D-Bus connection」エラーが出たときの対処法

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

Docker for macを使って開発をしています。
2021年12月に入ってAnsibleでの環境構築時に、題目のD-busエラーなるものが出て困ったので、調査しました。

※ 12月より以前から出ている場合は、おそらくこの記事とは関係ないのでこちらの記事が参考になるかもしれません。
👉 [CentOS7のDockerコンテナでsystemctlを使えるようにする - Qiita](https://qiita.com/mikene_koko/items/4c71c969f55e3fe24190)

## 結論

```markdown
・12月2日リリースのDocker for mac バージョン4.3からcgroupsv2になっている
・systemdのバージョンで対象環境か確認しよう
・OSバージョン挙げれるなら設定orコマンド変更、無理ならDocker Desktop設定ファイルを変更。
```

### 何が起きたか

■環境
・Host: Mac (Big Sur), Docker for mac (ver4.3) 利用
・Dockerコンテナ: AmazonLinux2 (image: `amazonlinux:2`)

今まで動いていたものが、急に下記エラー出始めました。

```bash
$ systemctl status httpd

Failed to get D-Bus connection: No such file or directory
```

### 原因

> Docker Desktop now uses cgroupv2. If you need to run systemd in a container then:
> - Ensure your version of systemd supports cgroupv2. It must be at least systemd 247. Consider upgrading any centos:7 images to centos:8.
> - Containers running systemd need the following options: --privileged --cgroupns=host -v /sys/fs/cgroup:/sys/fs/cgroup:rw.
> [Docker Desktop for Mac release notes](https://docs.docker.com/desktop/mac/release-notes/#docker-desktop-430)

要するに、「systemd 247以上を使ってるOSに変えてね。そしてコンテナ起動時このオプション付けてね」です。

Issueも上がっています (タイトルにM1とありますが関係ありません）
[Unable to run systemd services on M1 / Silicon computer · Issue #6073 · docker/for-mac](https://github.com/docker/for-mac/issues/6073)

#### systemdバージョン確認方法

```bash
$ rpm -q systemd

systemd-219-78.amzn2.0.15.x86_64
```

こちらの記事（[Amazon Linux2におけるsystemdのバージョンは古め - Qiita](https://qiita.com/thaim/items/fa8ae6ffe82548b840f5)）で説明されているとおり、私が使っていたAmazonLinux2は247より古いバージョンだったのでエラーが出ていたというわけでした。

## 対処法

### (cgroups v1使用の場合) Docker Desktopの設定ファイルの変更
`(*) 2022-01-24 追記` （コメントでの情報共有感謝です！）
Docker Desktop 4.4.2 より cgroups v1 を指定する方法が追加されたので、ダウングレードは不要となりました。

> Docker Desktop 4.4.2
> https://docs.docker.com/desktop/release-notes/#docker-desktop-442
> Added a deprecated option to settings.json: "deprecatedCgroupsv1": true, which switches the Linux environment back to cgroups v1. This option will be removed in future releases. If your software requires cgroups v1, you must update it to be compatible with cgroups v2.

一時的なオプションのようですが、下記の変更後、Docker Desktop再起動で完了です。

```jsonc
// ~/Library/Group\ Containers/group.com.docker/settings.json
{
  // ︙
  "dataFolder": "/Users/xxx/Library/Containers/com.docker.docker/Data/vms/0/data",
  "deprecatedCgroupv1": false,             // ← こちらを true へ
  "disableHardwareAcceleration": false,
  "disableTips": true,
  // ︙
}
```

<br>

Docker Desktop 4.4.2 より前の場合、4.2へのダウングレードでエラー回避することも可能です。

~~私の場合はこれで対応しました。Docker for mac バージョン4.2にダウングレード。~~
~~[https://docs.docker.com/desktop/mac/release-notes/#docker-desktop-420](https://docs.docker.com/desktop/mac/release-notes/#docker-desktop-420)~~

<br>

### (cgroups v2使用の場合) Docker設定orコマンド変更

リリースノートにある通り、下記のようなオプションを付けて起動すれば動作すると思います。

```bash
docker run {略} --privileged --cgroupns=host -v /sys/fs/cgroup:/sys/fs/cgroup:rw
```

<br>

~~docker-composeを使用している場合は、下記のようになると思います。（間違ってたらごめんなさい🙏）~~

`(*) 2022-01-24 追記`（コメントでの情報共有感謝です！）
まだdocker-compose側は対応してないようです。
https://github.com/compose-spec/compose-spec/issues/148

<br>

## おわりに

「何もしてないのに壊れました」というシーンを再現してしまって焦りました😇
誰かの役に立てばうれしいです。

壊れてた開発環境を直せたので、開発に戻ります👋