Mac では Docker Engine が単体で使えない理由を調べてみた

最近 Macbook で開発を始めたのですが、Docker を使う際に Docker Engine 単体で使用する選択肢を取れないのが謎だったので調べてみました。

# とりあえず結論

## Mac で Docker Engine が使えないのはなぜ？

Docker Engine に含まれている `dockerd` が Linux の機能を使っているから。

## Mac では dockerd が動かないのに Docker Desktop でコンテナが動くのはなぜ？

Docker Desktop に含まれている LinuxKit が Docker Engine を実行しているから。

# 詳しく見ていく

## そもそも Docker Engine とは何か？

Docker のホスト側を担う `dockerd` （コンテナを管理するデーモン）と CLI クライアントの `docker` を提供する。

参考情報: [Docker Engine 概要](https://docs.docker.jp/engine/index.html)
> Docker Engine は、アプリケーションを構築してコンテナ化するためのオープンソースのコンテナ化技術です。

参考情報: [Docker のアーキテクチャ](https://docs.docker.jp/get-started/overview.html#docker-architecture)
![Docker のアーキテクチャ](https://docs.docker.jp/_images/architecture.png "Docker のアーキテクチャ")

### Linux は Docker Engine のみでコンテナを扱える

Docker Engine は Docker のホスト側・クライアント側両方の役割を提供するので、 Docker Desktop いらずでコンテナを動作させることが可能。

https://docs.docker.com/engine/install/

## Mac OS 向けの Docker Engine も存在するがコンテナは動かせない

Docker Engine はバイナリインストールも手段として提供されている。

[Install Docker Engine](https://docs.docker.com/engine/install/)

> Docker provides binaries for manual installation of Docker Engine. These binaries are statically linked and you can use them on any Linux distro.

上記ページ内の「binaries」のリンクを辿るとバイナリインストールはテスト目的である旨が記載されている。

[Install Docker Engine from binaries](https://docs.docker.com/engine/install/binaries/)

> These instructions are mostly suitable for testing purposes.

同ページ内に Mac OS 向けの記載箇所があり、そこにはテスト目的であることに加えて `dockerd` が含まれていない旨が書いてある。

[install-client-binaries-on-macos](https://docs.docker.com/engine/install/binaries/#install-client-binaries-on-macos)

> The following instructions are mostly suitable for testing purposes. The macOS binary includes the Docker client only. It does not include the dockerd daemon which is required to run containers. Therefore, we recommend that you install Docker Desktop instead.

というわけで Mac OS 向けの Docker Engine は存在しているが、ホスト側の役割を担う `dockerd` が不在なのでコンテナの実行はできない。

## なぜ Mac OS では dockerd が提供されていないのか？

`dockerd` は Linux カーネルの機能を使っているためそもそも　Mac OS では `dockerd` を動かすことができない。

OS X 表記のためかなり古い情報と思われるが以下が最も分かりやすいソースだった。

[Mac OS X](https://docs.docker.jp/engine/installation/mac.html)

> Docker デーモンは Linux 固有の kernel 機能を使う為、OS X 上で Docker をネイティブに実行できません。

## じゃあなぜ Mac OS の Docker Desktop ではコンテナが動いているのか？

Mac OS 向けの Docker Desktop には LinuxKit という軽量な仮想マシンが含まれており、これが Docker Engine と Linux コンテナの実行を行っている。

[Addressing Time Drift in Docker Desktop for Mac](https://www.docker.com/blog/addressing-time-drift-in-docker-desktop-for-mac/)

> Docker Desktop for Mac runs the Docker engine and Linux containers in a helper LinuxKit VM since macOS doesn’t have native container support.

つまり `dockerd` の実行を Linux VM に肩代わりしてもらっているような構図。

# おまけ

## `dockerd` が必要とする Linux カーネルの機能って何？

Linux の（コンテナに限らない）仮想化技術である cgroups と namespace を使ってる。

※この辺りの話は今回の記事の趣旨とは外れるため、 RHEL 9 の該当ページのリンクを貼るだけに留めておきます。

[cgroups](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/9/html/managing_monitoring_and_updating_the_kernel/setting-limits-for-applications_managing-monitoring-and-updating-the-kernel#doc-wrapper)

[namespace](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/9/html/managing_monitoring_and_updating_the_kernel/what-namespaces-are_setting-limits-for-applications)