Rootless Podman 운영 · docker 와의 차이 · 실습
rootless 컨테이너 운영
목표
rootless 로 컨테이너를 실행하고, 볼륨·사용자 매핑·포트 제약을 직접 확인하고, Quadlet 유닛 파일을 작성합니다.
왜 중요한가
docker 에서 podman 으로 옮길 때 반드시 걸리는 것이 정해져 있습니다. restart: always 가 부팅 자동 시작을 뜻하지 않고(데몬이 없으니까), 1024 미만 포트에 바인딩할 수 없고, 볼륨 파일의 소유자가 낯선 UID 로 보이고, SELinux 환경에서는 :Z 라벨이 없으면 Permission denied 가 납니다. 이 네 가지를 미리 알면 전환이 30분이고 모르면 반나절입니다.
그리고 부팅 자동 시작의 podman 식 정답은 Quadlet 입니다. .container 파일을 두면 systemd 가 그것을 읽어 서비스 유닛을 생성합니다. podman generate systemd 는 구식이 됐습니다.\n\n## 이 실습은 가상머신에서 돕니다\n\nrootless podman 이 진짜로 돕니다. 파드에서는 newuidmap 이 CAP_SETUID 를 요구해서 subuid 대역을 줄 수 없었고, 그래서 이 실습이 반쪽이었습니다 — 컨테이너가 실제로 뜨지 않으니 채점도 파일만 볼 수밖에 없었습니다.\n\nVM 에서는 podman run 이 그대로 되고, 7단계의 Quadlet 도 정말 서비스로 번역되어 뜹니다. systemctl --user status labhub-web 로 직접 확인할 수 있습니다. 처음 뜨는 데 1분 남짓 걸립니다.
단계
1. /root/podrun 디렉터리를 만들고, podster 권한으로 /opt/images/labhub-alpine.tar 를 적재한 뒤 이미지 목록을 /root/podrun/images.txt 로 저장하세요.
2. 그 이미지로 컨테이너를 한 번 실행해 echo labhub-ok 를 수행하고, 출력을 /root/podrun/run.txt 로 저장하세요.
3. /home/podster/data 를 컨테이너의 /data 로 마운트해 컨테이너 안에서 /data/hello.txt 를 만들고, 호스트에서 그 파일이 보이는지 확인해 /root/podrun/volume.txt 에 파일 경로와 내용을 저장하세요.
4. 3번에서 만든 파일의 호스트 쪽 소유자 UID 를 숫자 한 줄로 /root/podrun/owner.txt 에 적으세요.
5. 특권 포트 게시를 시도해 실패시키고, 그 오류 메시지를 /root/podrun/port-fail.txt 로 저장하세요. 그다음 8090 포트로 다시 시도해 성공한 결과를 /root/podrun/port-ok.txt 로 저장하세요.
6. labhub-web 이라는 이름으로 컨테이너를 백그라운드 실행하고, podman ps 출력을 /root/podrun/ps.txt 로 저장하세요. 목록에 그 이름이 보여야 합니다.
7. /home/podster/.config/containers/systemd/labhub-web.container 를 작성하세요. [Unit], [Container], [Install] 세 섹션이 있어야 하고, [Container] 에는 Image, PublishPort, Volume 세 키가, [Install] 에는 WantedBy 가 있어야 합니다.
8. /root/podrun/diff.txt 를 다음 6줄로 만드세요.DAEMON=none / STORAGE=<podster 의 graphRoot 절대 경로> / PRIVPORT=denied / RESTART=quadlet / GPUFLAG=--device / SELINUX_LABEL=:Z
참고
- 실행은
su - podster -c "podman run --rm localhost/labhub-alpine:1 sh -c 'echo labhub-ok'"형태입니다. - 볼륨은
-v /home/podster/data:/data:Z로 마운트합니다. - 백그라운드 실행은
-d --name labhub-web입니다. 종료하지 말고 남겨 두세요. - Quadlet 파일은 실행되지 않아도 됩니다. 문법과 필수 키만 채점합니다.
- 이 노드에서 컨테이너 런타임이 막혀 있을 수 있습니다. 비특권 user namespace 생성이 차단되면 rootless podman 은
cannot re-exec process로 끝납니다. 그때도 명령을 실제로 실행하고 그 출력(오류 포함)을 지정된 파일에 그대로 저장하세요 — 채점기가 환경을 감지해 그 기록과 작성한 설정을 기준으로 판정합니다. - 흔한 실수 1: 3번에서 볼륨 디렉터리를 root 소유로 만들어 podster 가 못 쓰는 경우.
- 흔한 실수 2: 5번에서 실패 메시지를 표준 출력으로만 받으려는 경우. 오류는 표준 에러로 나옵니다.
단계 8개
- 이미지 적재
- 컨테이너 실행
- 볼륨 마운트
- 사용자 매핑 확인
- 특권 포트 실패 재현
- 실행 중 컨테이너 확인
- Quadlet 유닛 작성
- docker 와의 차이 정리