LabHub

Rootless Podman 운영 · docker 와의 차이 · 이론

전환에서 실제로 걸리는 것들

LabHub 에서 이어서 보기

한 줄 요약

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 보다 가볍다)이 한다.

이 구조의 함의가 크다.

반드시 걸리는 다섯 가지

1. restart: always 가 다르게 동작한다. 데몬이 없으므로 "부팅 시 자동 시작" 을 의미하지 않는다. podman 식 정답은 Quadlet 이다.

# ~/.config/containers/systemd/web.container[Unit]Description=Web service[Container]Image=docker.io/library/nginx:1.27PublishPort=8080:80Volume=/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(공유) 라벨을 붙인다. 우분투에서 넘어온 compose 파일이 가장 자주 걸리는 함정이다.

3. unqualified 이미지 이름. podman pull nginx 가 docker 와 다르게 동작한다. registries.confunqualified-search-registries = ["docker.io"] 를 넣거나, CI 라면 전체 경로를 쓴다.

4. 저장 위치. rootless 이미지는 ~/.local/share/containers/storage 다. docker system df 감각으로 /var/lib 를 뒤지면 못 찾는다.

5. 1024 미만 포트. rootless 는 특권 포트에 바인딩할 수 없다.

compose 는 어떻게 하나

두 가지 길이 있다.

  systemctl --user enable --now podman.socket  export DOCKER_HOST=unix://$XDG_RUNTIME_DIR/podman/podman.sock  docker compose up -d

프로덕션 지향이라면 compose 대신 podman kube play(쿠버네티스 YAML 을 직접 실행)도 선택지다. 로컬과 클러스터의 매니페스트를 통일할 수 있다.

현장에서 만나는 모습

점진 전환이 가능하다. 두 엔진은 스토리지가 분리돼 있어 한 머신에 공존할 수 있다. 서비스 단위로 하나씩 옮기면 된다.

podman-docker 패키지. docker 명령을 podman 으로 연결해 주는 심 패키지다. 스크립트 호환에 유용하지만, 팀원에게 "이 서버의 docker 는 사실 podman" 임을 반드시 공지해야 한다. 안 그러면 docker 문서를 보고 나온 명령이 미묘하게 다르게 동작할 때 원인을 못 찾는다.

다음 실습에서 할 것

이미지를 적재해 컨테이너를 실행하고, 볼륨과 사용자 매핑을 확인하고, 특권 포트 실패를 재현하고, Quadlet .container 파일을 작성한다. 마지막에 docker 와의 차이를 증거와 함께 표로 정리한다.