【Docker】ARM64 で failed to create endpoint *** on network bridge: failed to add the host *** <=> *** pair interfaces: operation not supported. のエラー【Armbian】

> Debian ベースの Linux ([Armbian](https://www.armbian.com/)) 環境で、Docker のイメージを `run` すると `operation not supported` でコンテナが起動できない。

```shell-session
$ docker run --rm test:local
docker: Error response from daemon: failed to create endpoint ****** on network bridge: failed to add the host (veth626b14d) <=> sandbox (veth6820d7a) pair interfaces: operation not supported.
```

- 環境
    - NanoPi NEO 2 (FriendlyARM, aarch64)
    - Armbian v22.05.3 (Debian Bullseye) with Linux v5.15.48-sunxi64
    - Docker v20.10.17, build 100c701

## TL; DR <sub><sup><sub><sup>（今北産業）</sup></sub></sup></sub>

1. **`docker` の実行に必要なライブラリ/パッケージが不足している**可能性があります
1. [moby](https://mobyproject.org/) 公式の [check-config.sh](https://raw.githubusercontent.com/moby/moby/master/contrib/check-config.sh) で、不足しているライブラリ/パッケージを確認します
1. 今回の筆者のケースは、以下の 2 つが不足していました。メインのパーティションを [Btrfs](https://ja.wikipedia.org/wiki/Btrfs) でフォーマットしていたことが原因です
    - [`EXT3` の拡張属性(XATTR)](https://cateee.net/lkddb/web-lkddb/EXT3_FS_XATTR.html) モジュール
    - `ZFS` 関連モジュール 

<details><summary>Docker なのに Moby？</summary>

:::note info
**Docker なのに Moby？**

Moby は、`docker` アプリを構成するコンポーネント（パーツやモジュール）を開発・管理している**オープンソースのプロジェクト**で、Docker 社が運営しています。

Moby と docker アプリ（以下 docker）の関係ですが、docker の上流（upstream）に Moby があると言っても過言ではありません。

Linux で言うところの[カーネル](https://ja.wikipedia.org/wiki/Linux%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB)的な位置に `moby` があり、[ディストロ](https://ja.wikipedia.org/wiki/Linux%E3%83%87%E3%82%A3%E3%82%B9%E3%83%88%E3%83%AA%E3%83%93%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)的な位置に「docker」や「kubernetes」があり、[POSIX](https://ja.wikipedia.org/wiki/POSIX) 的な位置に [OCI](https://ja.wikipedia.org/wiki/Open_Container_Initiative) があるといったイメージでしょうか。

Moby と docker の一番の違いは「自分で組む用」か「組んでもらったものを使う」かです。

つまり、Moby 版は「自分でコンポーネントを組み合わせて作った、コンテナを操作するアプリ」を意味するため、厳密には「Moby 版 Docker」というのは存在しません。Moby で作ったものに `docker` や `kubernetes` があるだけです。

Docker 社版の `docker` は、`containerd` に予めコンポーネントを組み合わせたものを中心に、各種機能を実装したアプリケーションです。

そして `docker` には、`Docker CE`（コミュニティ版 Docker、無償版 Docker）や `Docker EE`（エンタープライズ版 Docker、有償版 Docker）があります。そして、それらを GUI で総括したものが Docker Desktop です。

つまり、「Docker の無償版」（サポートなしの自己責任版）を使いたいなら `Docker CE`（コミュニティ版 Docker）を使うことになります。

単純なコンテナ操作だけで、たいそうな機能を必要としない場合は、最低限以下が必要です。

- `runc`: コンテナ・ランタイム。OCI イメージからコンテナを作成し実行・隔離する
- `containerd`: 上記 `runc` を管理するデーモン（サービス）

そして、これをベースに各種コンポーネントを追加していきます。

例えば、イメージを作成したい場合には `BuildKit`、複数マシンでコンテナを起動したい場合は `Swarm` を入れるなどです。

ちなみに、OS のパッケージマネージャーで検索すると出てくる `docker.io` と `docker-ce` がヒットすることがあります。

これらの違いですが、`docker.io` は、Ubuntu が「必要であろう」と思うコンポーネントをパッケージングしたものです。そのため、Debian 系以外の（`apt` が使えない）ディストロでは基本的に `docker.io` パッケージはありません。また、安定版ではあるものの、最新の安定版ではないことに注意です。

対して `docker-ce` は、コミュニティが「必要であろう」と思うコンポーネントをパッケージングしたものです。そのため、最新の安定版という場合は、こちらを選択することになります。

`docker.io` もしくは `docker-ce`、どちらも無料で利用できますが「無料・有料ではなく、昨今の Docker 社のエコシステムや企業ポリシーに賛同できない」といった場合は、Podman や Kubernetes などを検討することになります。

:::

</details>

## TS; DR <sub><sup>（問題解決までの切り分けの、コマケーこと）</sup></sub>

### イメージ側の問題か

現象が発生したのは、Go 言語で書いた CLI アプリの入った Alpine ベースの Docker イメージです。ARM64 マシン（NanoPi NEO2）で実行すると表題のエラーが発生しました。

しかし、この Docker イメージは Intel ベースの macOS や Debian や、ARM v6 の RaspberryPi Zero でも**動作確認できているマルチ・プラットフォームの Docker イメージです**。

つまり、アプリの問題ではなく、この Docker イメージの ARM64 環境における固有の問題である可能性があります。

そこで、イメージ固有の問題なのか確認するため `hello world` イメージを試してみましたが、同じエラーが出ました。やはり、アプリやイメージに関係なく発生している可能性があります。

```shell-session:dockerのhello-world
$ # 実行ユーザー確認
$ whoami
root

$ # docker のバージョン確認
$ docker --version
Docker version 20.10.5+dfsg1, build 55c4c88

$ docker version
Client:
 Version:           20.10.5+dfsg1
 API version:       1.41
 ** snip **
Server:
 Engine:
  Version:          20.10.5+dfsg1
  API version:      1.41 (minimum version 1.12)
 ** snip **

$ # イメージの pull
$ docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
7050e35b49f5: Pull complete 
Digest: sha256:62af9efd515a25f84961b70f973a798d2eca956b1b2b026d0a4a63a3b0b6a3f2
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest

$ # Hello, world コンテナの起動
$ docker run hello-world
docker: Error response from daemon: failed to create endpoint epic_taussig on network bridge: failed to add the host (veth11c232e) <=> sandbox (veth57b4f59) pair interfaces: operation not supported.
ERRO[0000] error waiting for container: context canceled
```

ここでのポイントは、`docker pull` も動いているし、バージョンも表示されているということです。

### サービスが落ちていないか

`docker version` は反応がある（`dokcer` コマンドは動いている）のにコンテナが起動できないケースで、<ruby>あるある<rt>・・・・</rt></ruby>なのが「実はサービスが起動していなかった」というケースです。

そこで、この `docker` のデーモン（サービス）に問題が発生して起動していないケースを潰すためにサービスの状態確認をしてみました。しかし、コンテナ起動の失敗後にコンテナが削除できない旨のログがあるだけで、**サービス自体は起動している**ようでした。

```shell-session
$ systemctl -l status docker
● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2022-09-15 21:25:21 JST; 2 weeks 4 days ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 1127 (dockerd)
      Tasks: 11
     Memory: 94.4M
        CPU: 44min 36.908s
     CGroup: /system.slice/docker.service
             └─1127 /usr/sbin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Oct 04 10:29:48 npi-neo2 dockerd[1127]: time="2022-10-04T10:29:48.534963700+09:00" level=error msg="14bd2d73209645a617387ec158dd4a32b71ef4a22b06ed1fa00733f28bfc14eb cleanup: failed to delete>
Oct 04 10:29:48 npi-neo2 dockerd[1127]: time="2022-10-04T10:29:48.535277061+09:00" level=error msg="Handler for POST /v1.41/containers/14bd2d73209645a617387ec158dd4a32b71ef4a22b06ed1fa00733f>
Oct 04 10:44:20 npi-neo2 dockerd[1127]: time="2022-10-04T10:44:20.158607026+09:00" level=warning msg="failed to prune image docker.io/library/alpine@sha256:bc41182d7ef5ffc53a40b044e725193bc1>
...skipping...

● docker.service - Docker Application Container Engine
     Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
     Active: active (running) since Thu 2022-09-15 21:25:21 JST; 2 weeks 4 days ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 1127 (dockerd)
      Tasks: 11
     Memory: 94.4M
        CPU: 44min 36.908s
     CGroup: /system.slice/docker.service
             └─1127 /usr/sbin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Oct 04 10:29:48 npi-neo2 dockerd[1127]: time="2022-10-04T10:29:48.534963700+09:00" level=error msg="14bd2d73209645a617387ec158dd4a32b71ef4a22b06ed1fa00733f28bfc14eb cleanup: failed to delete>
Oct 04 10:29:48 npi-neo2 dockerd[1127]: time="2022-10-04T10:29:48.535277061+09:00" level=error msg="Handler for POST /v1.41/containers/14bd2d73209645a617387ec158dd4a32b71ef4a22b06ed1fa00733f>
Oct 04 10:44:20 npi-neo2 dockerd[1127]: time="2022-10-04T10:44:20.158607026+09:00" level=warning msg="failed to prune image docker.io/library/alpine@sha256:bc41182d7ef5ffc53a40b044e725193bc1>
...skipping...
```

### 作成（ビルド）時の問題か、起動（`run`）時の問題か

ここまでの切り分けで「イメージやサービス・ダウンなどによる問題ではない」ことが確認できました。

Docker の主な流れとしては、以下の 4 ステップだと思います。

1. イメージの作成 or 取得（`build` or `pull`）
1. イメージからコンテナの作成
1. ネットワークやボリュームなどの準備（作成とバインド）
1. コンテナの起動（必要なら tty との接続）

最初の現象は `pull` されたイメージ（ビルド済みのイメージ）で発生したので、「新規で Docker イメージを作成してどうか」「コンテナを起動せずに作成だけしてどうか」を試してみました。どうやら作成だけなら出来ているようです。

```shell-session:新規イメージもビルドできるしコンテナも作れるが、起動できない
$ # ベースイメージの pull （→　OK）
$ docker pull alpine
Using default tag: latest
latest: Pulling from library/alpine
9b18e9b68314: Pull complete 
Digest: sha256:bc41182d7ef5ffc53a40b044e725193bc10142a1243f395ee852a8d9730fc2ad
Status: Downloaded newer image for alpine:latest
docker.io/library/alpine:latest

$ # シンプルな Dockerfile の作成
$ echo 'FROM alpine' > Dockerfile

$ # イメージのビルド （→　OK）
$ docker build --tag test:local .
Sending build context to Docker daemon  5.053MB
Step 1/1 : FROM alpine
 ---> a6215f271958
Successfully built a6215f271958
Successfully tagged test:local

$ # コンテナの作成と起動 （→　エラー）
$ docker run --rm test:local /bin/sh
docker: Error response from daemon: failed to create endpoint romantic_joliot on network bridge: failed to add the host (veth721a39f) <=> sandbox (vethcf10343) pair interfaces: operation not supported.

$ # コンテナの作成 （→　OK）
$ docker container create test:local
fd5dbdb46c773f3355278805a436725ee2709868514ac0afd6343adf9705b841

$ docker container ls -la
CONTAINER ID   IMAGE        COMMAND     CREATED         STATUS    PORTS     NAMES
fd5dbdb46c77   test:local   "/bin/sh"   2 minutes ago   Created             sweet_ishizaka

$ # コンテナの起動 （→　エラー）
$ docker container start -i sweet_ishizaka
ERRO[0000] error waiting for container: context canceled 
Error response from daemon: failed to create endpoint sweet_ishizaka on network bridge: failed to add the host (veth8478570) <=> sandbox (veth09d9049) pair interfaces: operation not supported
```

イメージやコンテナの作成は出来ていそうなものの、エラー内容を見ると、`failed to create *** on network bridge` や `failed to add the host *** pair interfaces` とあります。

つまり、前述した 4 ステップのうち 3 番のステップで、ネットワークがらみの問題が発生している可能性があります。

1. イメージの作成 or 取得（`build` or `pull`）
1. イメージからコンテナの作成
1. ネットワークやボリュームなどの準備（作成とバインド） // <---------- このステップのどこか
1. コンテナの起動（必要なら tty との接続）

そこで「Docker ネットワークは作成できるのか」を試してみました。しかし、これも**ネットワークの作成自体は問題がない**ようです。

```shell-session:ネットワークなども作れるが、起動できない
$ # 独自 Docker ネットワークの作成
$ docker network create tmp-network
fc9d01706c8e88849b181f5e0399292a457685937595143305aef3b630d8b1d0

$ docker network ls
NETWORK ID     NAME          DRIVER    SCOPE
b5511377e7e8   bridge        bridge    local
ca7aff01ad98   host          host      local
a4e2d53ec148   none          null      local
fc9d01706c8e   tmp-network   bridge    local

$ # 作成したネットワークでコンテナ起動 （→ NG）
$ docker run --rm --network tmp-network alpine /bin/sh
docker: Error response from daemon: failed to create endpoint friendly_beaver on network tmp-network: failed to add the host (vethbd97619) <=> sandbox (vethf4f00c8) pair interfaces: operation not supported.
```

... ふーむ。困った。

### `docker` を出荷時に戻してみる

動くようで動かない微妙な時の<ruby>あるある<rt>・・・・</rt></ruby>に、既存の Docker イメージやコンテナやキャッシュが悪さをしていることが、まれによくあります。

そこでシステムを `prune` `prune` して、未使用のイメージ、コンテナ、ネットワーク、ボリュームなどの削除を試してみましたが、やはり効果はありませんでした。

```shell-session
$ # System の prune (Docker 環境をスッキリんコにする）
$ docker system prune -af
Deleted Containers:
42b11ca4e983ad7a941ba8062a35c5ee168103f9c34a8c71a11c038d690a3bf3
** snip **

Deleted Networks:
tmp-network

Deleted Images:
untagged: hello-world:latest
untagged: hello-world@sha256:62af9efd515a25f84961b70f973a798d2eca956b1b2b026d0a4a63a3b0b6a3f2
deleted: sha256:46331d942d6350436f64e614d75725f6de3bb5c63e266e236e04389820a234c4
deleted: sha256:efb53921da3394806160641b72a2cbd34ca1a9a8345ac670a85a04ad3d0e3507
untagged: alpine:latest
** snip **

$ # イメージの pull
$ docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
7050e35b49f5: Pull complete 
Digest: sha256:62af9efd515a25f84961b70f973a798d2eca956b1b2b026d0a4a63a3b0b6a3f2
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest

$ # Hello, world コンテナの起動 （→ NG）
$ docker run hello-world
docker: Error response from daemon: failed to create endpoint epic_taussig on network bridge: failed to add the host (veth11c232e) <=> sandbox (veth57b4f59) pair interfaces: operation not supported.
ERRO[0000] error waiting for container: context canceled
```

### `check-config.sh` の実行

Moby の GitHub リポジトリに[同じエラー内容の issue](https://github.com/moby/moby/issues/27426) が上がっており、Docker の診断スクリプト（実行に必要なモジュールが揃っているか確認するスクリプト）を試すように指示がありました。

- "[Error response from daemon: failed to create endpoint (...) on network bridge: failed to add the host (veth1d85371) <=> sandbox (vethbc264f6) pair interfaces: operation not supported.](https://github.com/moby/moby/issues/27426)" | Issue #27426 | moby @ GitHub

> Looks like you're running a non-standard kernel for Ubuntu 14.04. Ubuntu 14.04 ships with Kernel 3.13. Can you try with a standard kernel? It's possible your kernel is missing modules that are required for docker to function properly; you can try running this script to see what's missing; https://github.com/docker/docker/blob/master/contrib/check-config.sh
>
> 【筆者訳】
> 非標準カーネルの Ubuntu 14.04 で動作させているようです。Ubuntu 14.04 にはカーネル 3.13 が搭載されていますが、標準のカーネルを試すことはできますか？Docker が正常に動作するために必要なモジュールがカーネルにない可能性があります。このスクリプトを実行して、何が足りないか確認してみてください： https://github.com/docker/docker/blob/master/contrib/check-config.sh

上記 issue では OS が Ubuntu ですが、筆者の場合は Debian を ARM ベースの [SBC](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%83%9C%E3%83%BC%E3%83%89%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF) 用に最適化されたカスタム・カーネルの [Armbian](https://www.armbian.com/) です。そのため必要モジュールが足りていない可能性があります。

そこで、指示通り [Docker 用の環境確認スクリプト](https://github.com/moby/moby/blob/master/contrib/check-config.sh)を任意のディレクトリにダウンロード/コピペして実行しました。

- [check-config.sh](https://raw.githubusercontent.com/moby/moby/master/contrib/check-config.sh) | Moby @ GitHub

<details><summary>check-config.sh の実行ログ</summary>

```shell-session
$ # 下記の `missing` に注目
$ ./check-script.sh
info: reading kernel config from /proc/config.gz ...

Generally Necessary:
- cgroup hierarchy: cgroupv2
  Controllers:
  - cpu: available
  - cpuset: available
  - io: available
  - memory: available
  - pids: available
- apparmor: enabled and tools installed
- CONFIG_NAMESPACES: enabled
- CONFIG_NET_NS: enabled
- CONFIG_PID_NS: enabled
- CONFIG_IPC_NS: enabled
- CONFIG_UTS_NS: enabled
- CONFIG_CGROUPS: enabled
- CONFIG_CGROUP_CPUACCT: enabled
- CONFIG_CGROUP_DEVICE: enabled
- CONFIG_CGROUP_FREEZER: enabled
- CONFIG_CGROUP_SCHED: enabled
- CONFIG_CPUSETS: enabled
- CONFIG_MEMCG: enabled
- CONFIG_KEYS: enabled
- CONFIG_VETH: enabled (as module)
- CONFIG_BRIDGE: enabled (as module)
- CONFIG_BRIDGE_NETFILTER: enabled (as module)
- CONFIG_IP_NF_FILTER: enabled (as module)
- CONFIG_IP_NF_TARGET_MASQUERADE: enabled (as module)
- CONFIG_NETFILTER_XT_MATCH_ADDRTYPE: enabled (as module)
- CONFIG_NETFILTER_XT_MATCH_CONNTRACK: enabled (as module)
- CONFIG_NETFILTER_XT_MATCH_IPVS: enabled (as module)
- CONFIG_NETFILTER_XT_MARK: enabled (as module)
- CONFIG_IP_NF_NAT: enabled (as module)
- CONFIG_NF_NAT: enabled (as module)
- CONFIG_POSIX_MQUEUE: enabled
- CONFIG_CGROUP_BPF: enabled

Optional Features:
- CONFIG_USER_NS: enabled
- CONFIG_SECCOMP: enabled
- CONFIG_SECCOMP_FILTER: enabled
- CONFIG_CGROUP_PIDS: enabled
- CONFIG_MEMCG_SWAP: enabled
    (cgroup swap accounting is currently enabled)
- CONFIG_BLK_CGROUP: enabled
- CONFIG_BLK_DEV_THROTTLING: enabled
- CONFIG_CGROUP_PERF: enabled
- CONFIG_CGROUP_HUGETLB: enabled
- CONFIG_NET_CLS_CGROUP: enabled (as module)
- CONFIG_CGROUP_NET_PRIO: enabled
- CONFIG_CFS_BANDWIDTH: enabled
- CONFIG_FAIR_GROUP_SCHED: enabled
- CONFIG_RT_GROUP_SCHED: enabled
- CONFIG_IP_NF_TARGET_REDIRECT: enabled (as module)
- CONFIG_IP_VS: enabled (as module)
- CONFIG_IP_VS_NFCT: enabled
- CONFIG_IP_VS_PROTO_TCP: enabled
- CONFIG_IP_VS_PROTO_UDP: enabled
- CONFIG_IP_VS_RR: enabled (as module)
- CONFIG_SECURITY_SELINUX: enabled
- CONFIG_SECURITY_APPARMOR: enabled
- CONFIG_EXT3_FS: enabled
- CONFIG_EXT3_FS_XATTR: missing # <----------------------------------- missing
- CONFIG_EXT3_FS_POSIX_ACL: enabled
- CONFIG_EXT3_FS_SECURITY: enabled
    (enable these ext3 configs if you are using ext3 as backing filesystem)
- CONFIG_EXT4_FS: enabled
- CONFIG_EXT4_FS_POSIX_ACL: enabled
- CONFIG_EXT4_FS_SECURITY: enabled
- Network Drivers:
  - "overlay":
    - CONFIG_VXLAN: enabled (as module)
    - CONFIG_BRIDGE_VLAN_FILTERING: enabled
      Optional (for encrypted networks):
      - CONFIG_CRYPTO: enabled
      - CONFIG_CRYPTO_AEAD: enabled
      - CONFIG_CRYPTO_GCM: enabled
      - CONFIG_CRYPTO_SEQIV: enabled
      - CONFIG_CRYPTO_GHASH: enabled
      - CONFIG_XFRM: enabled
      - CONFIG_XFRM_USER: enabled (as module)
      - CONFIG_XFRM_ALGO: enabled (as module)
      - CONFIG_INET_ESP: enabled (as module)
  - "ipvlan":
    - CONFIG_IPVLAN: enabled (as module)
  - "macvlan":
    - CONFIG_MACVLAN: enabled (as module)
    - CONFIG_DUMMY: enabled (as module)
  - "ftp,tftp client in container":
    - CONFIG_NF_NAT_FTP: enabled (as module)
    - CONFIG_NF_CONNTRACK_FTP: enabled (as module)
    - CONFIG_NF_NAT_TFTP: enabled (as module)
    - CONFIG_NF_CONNTRACK_TFTP: enabled (as module)
- Storage Drivers:
  - "aufs":
    - CONFIG_AUFS_FS: enabled (as module)
  - "btrfs":
    - CONFIG_BTRFS_FS: enabled
    - CONFIG_BTRFS_FS_POSIX_ACL: enabled
  - "devicemapper":
    - CONFIG_BLK_DEV_DM: enabled (as module)
    - CONFIG_DM_THIN_PROVISIONING: enabled (as module)
  - "overlay":
    - CONFIG_OVERLAY_FS: enabled (as module)
  - "zfs":
    - /dev/zfs: missing # <--------------------------- missing
    - zfs command: missing # <------------------------ missing
    - zpool command: missing # <---------------------- missing

Limits:
- /proc/sys/kernel/keys/root_maxkeys: 1000000
```

---

</details>

案の定、実行結果を見ると `CONFIG_EXT3_FS_XATTR` と `ZFS` 関連がゴッソリと不足していることが確認できます。

どちらもファイルシステム関連です。

[CONFIG_EXT3_FS_XATTR](https://cateee.net/lkddb/web-lkddb/EXT3_FS_XATTR.html) は EXT3 の拡張属性（`xattr`）のモジュールです。[拡張属性とは](https://qiita.com/KEINOS/items/e218c4d8da5451c9e59c)、Linux/UNIX のファイル属性のうち OS 固有の属性のことです。

そして `ZFS` は、`EXT3` などと同じ「ファイルシステムの 1 種」です。つまり、Windows で言う FAT32、extFAT や NTFS、macOS で言う APFS や HFS+ などのファイルシステムの Linux 版です。

しかし、これらのファイルシステム関連のモジュールが不足していることが原因であった場合、若干<ruby>腑<rt>ふ</rt></ruby>に落ちないところがあります。

これまでの検証結果から `docker run` を実行してコンテナの作成まではできるものの、コンテナを立ち上げる際のコンテナとネットワークのブリッジ（接点）の作成に問題が発生しています。また、`docker` 以外のアプリは動いているし、イメージやネットワーク含むファイルの作成は出来ています。

このことから、感覚的にはファイルシステムの問題ではない気がします。

推測できるのは「ブリッジを作成する際の `docker` 側の依存モジュール」にファイルシステム関連があるパターンです。つまり、`EXT3` のファイルシステムで使っていても、`ZFS` のモジュールにある関数を `docker` が使いたがっている場合です。

もしくは、`ZFS` のファイルシステムを使っていて、最低限のモジュールがインストールされているも、拡張モジュールが不足しているパターンです。なんか、こっちのパターンのような気がします。

### ファイルシステムの確認

「あれ？ ZFS を使っていたっけかな？しかも EXT3 でなく EXT4 だと思ったのに。いや、SSD を増設した際に、速いと噂の ZFS にした気もする」と不安になったので、`df -T` コマンドで、ファイルシステムを確認してみました。

```shell-session
$ df -T
Filesystem     Type     1K-blocks    Used Available Use% Mounted on
udev           devtmpfs    175404       0    175404   0% /dev
tmpfs          tmpfs        49444    1932     47512   4% /run
/dev/sda1      btrfs    500106564 2010816 496127264   1% / # <------------------ ここの type に注目
tmpfs          tmpfs       247216    6796    240420   3% /dev/shm
tmpfs          tmpfs         5120       0      5120   0% /run/lock
tmpfs          tmpfs       247216   95060    152156  39% /tmp
/dev/mmcblk0p1 ext4      29662940 1723836  27603328   6% /media/mmcboot # <----- ここの type に注目
/dev/zram1     ext4         49560   28268     17708  62% /var/log
tmpfs          tmpfs        49440       0     49440   0% /run/user/997
tmpfs          tmpfs        49440       0     49440   0% /run/user/0
```

上記によると、OS 領域を `btrfs` でフォーマットしており、ブート領域を `EXT4` でフォーマットしています。

つまり、OS の入ったメインのパーティション（`/dev/sda1`）が、なんと **`EXT` 系どころか `ZFS` のライバルである [btrfs](https://ja.wikipedia.org/wiki/Btrfs) でフォーマットしていた**のでした。

そういえば「SSD を使うなら `ZFS` より `BTRFS` の方がいい」的な記事を読んで、実験として試してみてたら動いたのでそのままにしていた気もしてきました。なんか、全ての記憶が間違っていました。アッチョンブリケッ

orz =3 ﾌﾞｯ

### 診断結果のエラーを回避する

何はともあれ、まずは、診断結果のエラー（モジュール不足）を回避する必要があります。

`CONFIG_EXT3_FS_XATTR` と `ZFS` の「どちらを先に手をつけるべきか」ですが、OS 領域に問題があるので、まずは `ZFS` の不足モジュールをインストールすることにします。

今回利用している OS は ARM 用に最適化された Armbian です。そのため、以下によると「不足しているカーネル・ヘッダー」を追加インストールしてから、「ZFS ユーティリティ」群をインストールする必要があるようです。

- "[odroidhc4 with 5.13.9-meson64, missing ZFS modules](https://forum.armbian.com/topic/18790-odroidhc4-with-5139-meson64-missing-zfs-modules/)" | Forum @ Armbian.com

```shell-session:カーネル・ヘッダーとZFS 関連ユーティリティのインストール
$ # カーネル・ヘッダー の追加
$ # テキストの GUI が起動するので [Software] -> [Headers_install (kernel headers)] を選択
$ sudo armbian-config
** snip **

$ # ZFS 関連ユーティリティのインストール（途中はすべて OK を選択）
$ sudo apt install zfsutils-linux zfs-dkms
** snip **

$ # カーネルがらみのインストールなので OS を再起動する
$ sudo reboot now
```

なんか理解しがたいのですが、これで治ってしまいました。

```shell-session
$ docker pull hello-world
Using default tag: latest
latest: Pulling from library/hello-world
7050e35b49f5: Pull complete 
Digest: sha256:62af9efd515a25f84961b70f973a798d2eca956b1b2b026d0a4a63a3b0b6a3f2
Status: Downloaded newer image for hello-world:latest
docker.io/library/hello-world:latest

$ docker run --rm hello-world

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (arm64v8)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

```

## 参考文献

- [Issue #27426](https://github.com/moby/moby/issues/27426): "Error response from daemon: failed to create endpoint (...) on network bridge: failed to add the host (veth1d85371) <=> sandbox (vethbc264f6) pair interfaces: operation not supported." | moby @ github.com
- "[odroidhc4 with 5.13.9-meson64, missing ZFS modules](https://forum.armbian.com/topic/18790-odroidhc4-with-5139-meson64-missing-zfs-modules/)" | forum @ armbian.com
- [G3LへのDockerインストールについて](https://armadillo.atmark-techno.com/forum/armadillo/2618) @ Armadilloフォーラム

### 関連記事:

- [xattr コマンドの使い方／ヘルプの日本語訳（macOS でパーミッションの@付き拡張属性の操作）](https://qiita.com/KEINOS/items/e218c4d8da5451c9e59c) @ Qiita