LabHub
배우기 러닝패스 코스

Running Rootless Podman

A Map of podman's Configuration Files

LabHub 에서 이어서 보기

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

한 줄 요약

docker 의 설정이 daemon.json 하나에 모여 있다면, podman 은 역할별로 나뉜 여러 파일이고 사용자별 설정이 시스템 설정을 덮어쓴다.

Layer map: 역할별로 나뉜 여러 파일 · 사용자별 설정이 시스템 설정을 덮어쓴다 · 사용자별 파일이 시스템 파일을 덮어쓴다. · 이미지와 컨테이너 레이어가 쌓이는 곳.

왜 이게 필요했나

docker 에서 넘어온 사람이 가장 먼저 헤매는 지점이 이것이다. "레지스트리 미러를 어디에 적지?", "저장 경로는 어디서 바꾸지?" 데몬이 없으니 daemon.json 도 없다.

어떻게 동작하나

docker                          podman
──────────────────────────      ───────────────────────────────────────
/etc/docker/daemon.json         /etc/containers/containers.conf   (엔진·런타임 옵션)
                                ~/.config/containers/containers.conf
(레지스트리 미러도 daemon.json)  /etc/containers/registries.conf   (레지스트리·미러·차단)
                                ~/.config/containers/registries.conf
                                /etc/containers/storage.conf      (스토리지 드라이버·경로)
                                ~/.config/containers/storage.conf
                                /etc/containers/policy.json       (이미지 서명 정책)
~/.docker/config.json (인증)     ~/.config/containers/auth.json    (레지스트리 인증)

이미지·컨테이너 저장 위치
/var/lib/docker                 rootful:  /var/lib/containers/storage
                                rootless: ~/.local/share/containers/storage

사용자별 파일이 시스템 파일을 덮어쓴다. 그래서 rootless 설정은 대부분 ~/.config/containers/ 아래에서 이루어진다.

storage.conf

[storage]
driver = "overlay"
runroot = "/run/user/1000/containers"
graphroot = "/home/podster/.local/share/containers/storage"

[storage.options]
additionalimagestores = []

[storage.options.overlay]
mount_program = "/usr/bin/fuse-overlayfs"

registries.conf

unqualified-search-registries = ["docker.io"]

[[registry]]
prefix = "docker.io"
location = "mirror.internal.example.com/dockerhub"

[[registry]]
location = "blocked.example.com"
blocked = true

unqualified-search-registries 가 docker 와의 대표적인 차이다. docker 는 nginx 를 자동으로 docker.io 로 해석하지만, podman 은 설정을 따르거나 어느 레지스트리인지 묻는다. CI 스크립트라면 아예 docker.io/library/nginx 처럼 전체 경로를 쓰는 것이 가장 견고하다.

containers.conf

엔진 기본값을 정한다. 기본 OCI 런타임(crun/runc), 기본 네트워크 백엔드(netavark/cni), 기본 cgroup 관리자, 기본 환경변수 등.

[engine]
runtime = "crun"
cgroup_manager = "cgroupfs"

[containers]
default_ulimits = ["nofile=65535:65535"]

rootless 에서 systemd 가 없거나 cgroup 위임이 안 되면 cgroup_manager = "cgroupfs" 로 두어야 한다.

현장에서 만나는 모습

초기 설정 체크리스트. 새 서버에 rootless podman 을 세울 때 확인하는 순서가 정해져 있다.

  1. 전용 사용자와 홈이 있는가
  2. /etc/subuid, /etc/subgid 에 그 사용자 대역이 있는가
  3. newuidmap/newgidmap 이 설치돼 있는가
  4. graphroot 가 충분한 파티션에 있는가
  5. runroot 가 tmpfs 인가
  6. registries.conf 에 사내 미러와 unqualified 검색 설정이 있는가
  7. podman info 에서 rootless=true, 드라이버, 경로가 기대대로인가

7번이 최종 검증이다. podman info --format json 을 파싱해 CI 에서 자동 점검하는 팀도 많다.

다음 실습에서 할 것

사용자 podster 를 위한 subuid/subgid 를 넣고, 매핑을 손으로 계산하고, storage.confregistries.conf 를 작성하고, podman info 로 전부 검증한다.