TT Lab
はじめる
学ぶ 学習パス コース

Rootless Podmanの運用

移行で実際につまずくところ

TT Labで続きを見る

一言でいうと

dockerからpodmanへの切り替えは、コマンドの入れ替えではなく、運用モデルの入れ替えです。デーモンからfork-execへ、rootfulからrootlessへ、daemon.jsonからcontainers.confファミリーへ。

なぜ必要なのか

alias docker=podmanで、ほとんどのコマンドがそのまま動作します。そのため、切り替えは簡単に見えます。しかし、実際に移すと、いくつかの点で必ず引っかかります。その、いくつかを事前に知っていれば30分、知らなければ半日です。

どう動くのか

構造の違い

Docker:  docker CLI ──REST──▶ dockerd ──▶ containerd ──▶ runc ──▶ 컨테이너
Podman:  podman CLI ──fork/exec──▶ conmon ──▶ crun ──▶ 컨테이너

podmanには、デーモンがありません。podman runは、ごく普通のプロセスのように、コンテナを直接作ります。コンテナごとに、小さな監視プロセスのconmonが付いて、stdioとexit codeを管理し、実際の作成は、OCIランタイムのcrun(Cで書かれていて、runcより軽い)が行います。

この構造が持つ含意は大きいです。

必ず引っかかる5つのこと

1. restart: alwaysの動作が違います。デーモンがないので、「起動時の自動開始」を意味しません。podman流の正解は、Quadletです。

# ~/.config/containers/systemd/web.container
[Unit]
Description=Web service

[Container]
Image=docker.io/library/nginx:1.27
PublishPort=8080:80
Volume=/srv/www:/usr/share/nginx/html:Z

[Service]
Restart=always

[Install]
WantedBy=default.target

.containerファイルを置くと、systemdがそれを読んで、サービスユニットを生成します。podman generate systemdは、古い方式になりました。

2. SELinuxのボリュームラベル: RHEL/Fedoraで、ボリュームのマウントがPermission deniedなら、十中八九SELinuxです。-v ./data:/data:Z(専用)または:z(共有)のラベルを付けます。Ubuntuから持ってきたcomposeファイルが、最もよく引っかかる落とし穴です。

3. unqualifiedのイメージ名: podman pull nginxが、dockerと違う動作をします。registries.confに、unqualified-search-registries = ["docker.io"]を入れるか、CIなら完全なパスを書きます。

4. 保存場所: rootlessのイメージは、~/.local/share/containers/storageです。docker system dfの感覚で、/var/libを探しても、見つかりません。

5. 1024未満のポート: rootlessは、特権ポートにバインドできません。

composeはどうするのか

道は2つあります。

本番指向なら、composeの代わりとして、podman kube play(KubernetesのYAMLを直接実行する)も選択肢です。ローカルとクラスターのマニフェストを、統一できます。

現場での姿

段階的な切り替えが可能です。2つのエンジンは、ストレージが分離されているので、1台のマシンに共存できます。サービス単位で、1つずつ移せば済みます。

podman-dockerパッケージ: dockerコマンドをpodmanにつなげてくれる、shimパッケージです。スクリプトの互換には役立ちますが、チームメンバーに、このサーバーのdockerは実はpodmanであることを、必ず周知する必要があります。そうしないと、dockerのドキュメントを見て出したコマンドが、微妙に違う動作をしたときに、原因を見つけられません。

次のラボですること

イメージをロードしてコンテナを実行し、ボリュームとユーザーマッピングを確認し、特権ポートの失敗を再現して、Quadlet .containerファイルを作成します。最後に、dockerとの違いを、証拠と一緒に表にまとめます。