macOS上でコンテナを動作させるには3つのパターンがある。
コンテナを動作させる3つのパターン
Docker Desktopのみのパターン
Docker DesktopがVMの管理をし、VM内でdockerdデーモンを動作させる。
Docker CLI
↓
Docker Desktop
↓
Apple Virtualization Framework (AVF)
↓
Linux VM
↓
dockerd
↓
containerd
↓
OCI runtime (runcなど)
↓
コンテナプロセス
Colima と Docker daemon を組み合わせるパターン
Colima(Lima)がVMの管理をし、VM内ではdockerdデーモンを動作させる。
Docker CLI
↓
Colima
↓
Lima
↓
Apple Virtualization Framework (AVF)
↓
Linux VM
↓
dockerd
↓
containerd
↓
OCI runtime (runcなど)
↓
コンテナプロセス
Podman のみのパターン
PodmanがVMの管理をし、Podmanが直接OCI runtimeを利用する。
Podman CLI
↓
Podman Machine
↓
Apple Virtualization Framework (AVF)
↓
Linux VM
↓
Podman
↓
OCI runtime (runcなど)
↓
コンテナプロセス
準備
- Apple Silicon を使っている場合は、現在のターミナルが Apple Silicon ネイティブで起動されていることを確認する。環境によっては、Rosettaが有効でx86_64でターミナルを起動している場合があるので注意する。
uname -mの結果がarm64であることを確認する。- 結果が
x86_64の場合は、現在のターミナルが Rosetta2 でエミュレートされたものになっているので、例えば、iTerm2 を使っているのなら、iTerm2 > Settings > Profiles > Commandに/bin/shなどを指定して、ネイティブで実行されるようにする。 - または、
Activity Monitor > CPU > KindにAppleまたはIntelが表示さるので、実行中のターミナルがApple Siliconネイティブで実行されていればAppleになる。
- Homebrewをインストールしておく。
ColimaとDocker daemonで使う方法
- Colimaをインストール
brew install colimacolima startでVMが作成され、dockerdがインストールされ、起動するcolima start --cpu 4 --memory 8
colima statuscolima listcolima stop
- Docker CLIをインストール
brew install docker docker-compose
- コンテナが動作する
docker run hello-world
Podmanを使う方法
- Podmanをインストール
brew install podman podman-composepodman --versionpodman machine initpodman machine startでVMが作成されるpodman info
- コンテナが動作する
podman run hello-world
- Docker Hubのimageも使える
podman run -d --name nginx -p 80:80 --network pasta docker.io/library/nginx- Podmanはnetworkにpasst(pasta)が使える。passtを使うと、コンテナ内のネットワークで完結させるのではなく、ホスト側のユーザ空間にネットワークを晒すことが可能であり、コンテナネットワークのNATとのやりとりを介さず、ホスト側のネットワークと直接やりとりするようになる。
Podmanを使う理由
- DockerもPodmanもrootlessで動作できるので、正しく使う分にはどちらも安全だが、ある側面ではPodmanが優位。
- Podmanの場合はVM内にデーモンを持たないが、Dockerの場合はVM内にroot権限のdockerdデーモンを持つ。dockerdデーモンは
/var/run/docker.sockを介してホストのCLIとやりとりしており、通常はVM内のコンテナにはマウントされないが、万が一コンテナにマウントした場合は、そのコンテナからdockerdを操作することが可能になるため、この視点だと、DockerよりもPodmanの方が安全性が高いということになる。 - rootで動作しているdockerdをrootlessで動作させることも可能だが、dockerdをrootで動作させてきた都合上、rootless化に伴うオーバーヘッドがある。
- Podmanの場合はVM内にデーモンを持たないが、Dockerの場合はVM内にroot権限のdockerdデーモンを持つ。dockerdデーモンは
--priviledgedでコンテナを起動した場合は、PodmanであろうがDockerであろうが、コンテナにrootレベルでのカーネルのアクセスを許すため、VM内部のカーネル経由でのセキュリティーのリスクが生じる。