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

Rootless Podmanの運用

イメージがホームを埋めるとき

TT Labで続きを見る

一言でいうと

rootless podmanのイメージは、~/.local/share/containers/storageに積まれます。ホームパーティションが小さければ、graph rootを移すことが最初の運用作業になります。

なぜ必要なのか

サーバーのパーティション設計が、こうなっていることはよくあります。

/          50G
/home      20G      <- rootless podman 의 이미지가 여기 쌓인다
/data      2T       <- 정작 큰 디스크는 여기

CUDAイメージは、1つで8GBあります。2つ3つ取得しただけで、ホームが埋まります。そして、ホームが埋まると、podmanだけでなく、そのユーザーのすべての作業が止まります。

どう動くのか

何を移すのか

項目 デフォルトのパス(rootless) 移す必要があるか
graphroot ~/.local/share/containers/storage はい。イメージ・コンテナのレイヤーです
runroot /run/user/<uid>/containers いいえ。tmpfsが正しいです
ボリューム <graphroot>/volumes graphrootを移せば、ついてきます
設定 ~/.config/containers いいえ。小さいです

手順

# 1. 현재 상태 확인
podman info --format '{{.Store.GraphRoot}}'
du -sh ~/.local/share/containers/storage

# 2. 새 경로 준비 (소유자가 그 사용자여야 한다)
sudo mkdir -p /srv/podman/podster
sudo chown podster:podster /srv/podman/podster
sudo chmod 700 /srv/podman/podster

# 3. 설정 변경
#    ~/.config/containers/storage.conf
#    [storage]
#    graphroot = "/srv/podman/podster"

# 4. 검증
podman info --format '{{.Store.GraphRoot}}'
podman images

重要なのは、ステップ3の後、新しいストアが空であるという事実です。既存のイメージは、古いパスにそのまま残っていて、podmanはもうそれを見ません。選択肢は2つです。

エアギャップ環境なら、後者しかありません。そして、古いパスを削除する前に、必ず新しいパスでpodman imagesが期待した一覧を表示するかを確認します。

システム全体で決める

複数のユーザーに同じポリシーを適用するには、/etc/containers/storage.confに書きます。ただし、rootlessユーザーの個人設定がこれを上書きするので、標準化が目的なら、個人設定ファイルを配布するか、ホームのスケルトン(/etc/skel)に入れます。

確認コマンド

podman info --format '{{.Store.GraphRoot}}'
podman info --format '{{.Store.RunRoot}}'
podman info --format '{{.Store.GraphDriverName}}'
podman system df

podman system dfは、イメージ・コンテナ・ボリュームが、それぞれどれだけ使っているかを見せてくれます。整理する対象を選ぶときの、最初のコマンドです。

rootlessでストレージが問題を起こす理由

rootless podman固有のストレージの問題は、大半がユーザー名前空間とファイルの所有権から生じます。原理を知れば、症状がすぐ読み取れます。

コンテナ内のUIDは、ホストでは別の数字になります。/etc/subuidに書かれた範囲の分だけ、ずれます。コンテナ内のroot(0)は、ホストでは自分のUIDで、コンテナ内の1000は、ホストではsubuid 시작 + 999です(韓国語で「開始」を意味する語です)。そのため、ホストでそのファイルを見ると、所有者がとても大きな数字に見えます。

grep "^$USER:" /etc/subuid /etc/subgid
podman unshare cat /proc/self/uid_map

ホストのディレクトリをマウントすると、権限が合いません。自分が作ったファイルは、ホストでは自分の所有なのに、コンテナ内ではnobodyに見えます。所有権を移すには、その名前空間の中でchownする必要があります。

podman unshare chown -R 1000:1000 ./data

podman unshareなしでsudo chownすると、ホストから見たときにだけ合い、コンテナ内では相変わらず間違ったままです。

graph rootを移すときに引っかかること: 新しい場所が別のファイルシステムなら、overlayをサポートしているかを先に見ます。NFSの上ではoverlayが使えず、その場合はvfsに落ちて、ディスク使用量が数倍に増え、遅くもなります。

podman info --format '{{.Store.GraphRoot}} {{.Store.GraphDriverName}}'

SELinuxが付いたディストリビューションでは、ラベルを付ける必要があります。ボリュームのマウントに:Zを付けないと、コンテナが読めません。:zは共有、:Zは専用のラベルです。

残ったものを、定期的に片付けます。rootlessはユーザーのホームの下に積まれるので、ホームパーティションが埋まりやすいです。一時的なイメージと、停止したコンテナ、使われていないボリュームを、一緒に見ます。

podman system df
podman system prune --volumes --filter until=168h

現場での姿

GPUノードで特によく経験します。CUDAのベースイメージが数GBあるので、いくつか取得しただけで、ホームが埋まります。そのため、GPUサーバーの標準設定には、graphrootをデータディスクへ送る項目が、最初から入っていることが多いです。

NFSホームにgraphrootを置いてはいけません。overlay系のドライバーが正しく動作せず、ファイルロックの問題で、おかしな失敗が起きます。必ずローカルディスクである必要があります。

古いパスを削除せず、ディスクを2倍使ってしまう場合があります。移したあと、検証まで終えたら、古いパスを片付ける必要があります。ただし、podman system resetは、現在設定されているストアを削除するので、古いパスの整理には使えません。

次のラボですること

podsterのgraph rootを新しいパスに移し、新しいストアが空であることを確認したあと、イメージアーカイブをloadして埋め、podman infoで最終検証します。