最近 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 概要
Docker Engine は、アプリケーションを構築してコンテナ化するためのオープンソースのコンテナ化技術です。
参考情報: Docker のアーキテクチャ
Linux は Docker Engine のみでコンテナを扱える
Docker Engine は Docker のホスト側・クライアント側両方の役割を提供するので、 Docker Desktop いらずでコンテナを動作させることが可能。
Mac OS 向けの Docker Engine も存在するがコンテナは動かせない
Docker Engine はバイナリインストールも手段として提供されている。
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
These instructions are mostly suitable for testing purposes.
同ページ内に Mac OS 向けの記載箇所があり、そこにはテスト目的であることに加えて dockerd
が含まれていない旨が書いてある。
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 表記のためかなり古い情報と思われるが以下が最も分かりやすいソースだった。
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
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 の該当ページのリンクを貼るだけに留めておきます。