LabHub
배우기 러닝패스 코스

Running Rootless Podman

When Images Fill Up Your Home Directory

LabHub 에서 이어서 보기

한국어 원문으로 표시합니다.

한 줄 요약

rootless podman 의 이미지는 ~/.local/share/containers/storage 에 쌓인다. 홈 파티션이 작으면 graph root 를 옮기는 것이 첫 번째 운영 작업이 된다.

Concept map: graph root 를 옮기는 것이 첫 번째 운영 작업 · 그렇다. · 중요한 것은 3번 이후 새 스토어가 비어 있다는 사실이다. · 다시 받는다

왜 이게 필요했나

서버 파티션 설계가 이런 경우가 흔하다.

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

CUDA 이미지 하나가 8GB 다. 두어 개만 받아도 홈이 찬다. 그리고 홈이 차면 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 은 더 이상 그것을 보지 않는다. 선택지는 둘이다.

폐쇄망이라면 후자밖에 없다. 그리고 옛 경로를 지우기 전에 반드시 새 경로에서 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 는 이미지·컨테이너·볼륨이 각각 얼마나 쓰는지 보여 준다. 정리 대상을 고를 때 첫 명령이다.

루트리스에서 저장소가 말썽을 부리는 이유

루트리스 포드만의 저장소 문제는 대부분 사용자 이름공간과 파일 소유권에서 나온다. 원리를 알면 증상이 바로 읽힌다.

컨테이너 안의 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 는 전용 라벨이다.

남은 것을 정기적으로 치운다. 루트리스는 사용자 홈 아래에 쌓이므로 홈 파티션이 차기 쉽다. 임시 이미지와 멈춘 컨테이너, 쓰이지 않는 볼륨을 함께 본다.

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

현장에서 만나는 모습

GPU 노드에서 특히 자주 겪는다. CUDA 베이스 이미지가 수 GB 라 몇 개만 받아도 홈이 찬다. 그래서 GPU 서버 표준 설정에는 graphroot 를 데이터 디스크로 보내는 항목이 아예 들어 있는 경우가 많다.

NFS 홈에 graphroot 를 두면 안 된다. overlay 계열 드라이버가 제대로 동작하지 않고, 파일 잠금 문제로 이상한 실패가 난다. 반드시 로컬 디스크여야 한다.

옛 경로를 안 지워 디스크를 두 배로 쓰는 경우. 옮긴 뒤 검증까지 마쳤으면 옛 경로를 정리해야 한다. 다만 podman system reset현재 설정된 스토어를 지우므로 옛 경로 정리에는 쓸 수 없다.

다음 실습에서 할 것

podster 의 graph root 를 새 경로로 옮기고, 새 스토어가 비어 있음을 확인한 뒤, 이미지 아카이브를 load 해서 채우고, podman info 로 최종 검증한다.