Загружаем каталог…
Загружаем каталог…
Podman 정리 — 데몬 없는 컨테이너와 쿠버네티스, 그리고 예약 API에 적용해 보기 목차 Podman 개요 Podman의 정의 데몬리스(daemonless) 구조 루트리스(rootless) 컨테이너 Pod 개념과 Infra 컨테이너 기존 쿠버네티스 환경과의 차이 컨테이너 엔진과 오케스트레이터의 계층 차이 Podman Pod와 Kubernetes Pod의 책임 범위 비교 kube generate / kube play를 통한 YAML 연동 systemd + Quadlet 기반 단일 머신 운영 장점과 단점 장점 단점 Docker와 Podman 비교표 실제 프로젝트 적용: 스터디룸 예약 API 설치와 첫 실행 이미지 빌드와 FROM 이미지 이름 정규화 podman compose로 기존 compose.yaml 실행 Pod 구성 전환: 서비스 이름에서 localhost로 kube generate / kube play 기반 쿠버네티스 YAML 작성 Quadlet 기반 단일 서버 배포 GitHub Actions podman 잡 추가 Podman 환경의 Testcontainers 적용 변경 범위 정리 헷갈리기 쉬운 부분 Podman과 쿠버네티스의 관계 rootless와 컨테이너 내부 UID의 관계 podman.sock과 Docker 데몬의 차이 kube play 실행과 클러스터 배포의 차이 Pod 내부 통신 주소(localhost) 마무리 참고 자료 Spring Study Week E에서 스터디룸 예약 API를 Docker 이미지로 묶고, GitHub Actions에서 MySQL과 같이 띄워 헬스 체크까지 자동으로 돌렸다. 그런데 회고를 쓰면서 한 가지가 계속 걸렸다. docker compose up 을 칠 때마다 뒤에서 항상 떠 있는 dockerd 라는 데몬이 뭘 하는지, 왜 root 권한이 필요한지는 한 번도 열어 보지 않았다는 것. 그러다 Red Hat 쪽 문서와 사내 인프라 글들에서 자주 보이는 Podman 이 "데몬 없이, root 없이 Docker랑 같은 명령어로 컨테이너를 돌린다"고 소개하는 걸 봤다. 다음 목표로 적어 둔 Testcontainers와 CD 파이프라인도 결국 컨테이너 런타임 위에서 도는 거라, 이번 기회에 Docker 말고 다른 런타임은 어떻게 생겼는지 한번 정리해 보기로 했다. 사실 여러 대안 중에 Podman을 고른 데는 개인적인 이유도 있다. 평소 오픈소스에 관심이 많아서, 도구를 고를 때 기능만큼 "누가, 어떤 방식으로 만들고 관리하는가"를 같이 보는 편이다. Podman은 Apache 2.0 라이선스로 공개돼 있고, Podman Desktop은 CNCF sandbox 프로젝트 로 특정 회사가 아닌 커뮤니티 중심으로 운영된다. 릴리스 노트, 이슈, 설계 논의가 전부 GitHub에 열려 있어서 이번 글도 공식 문서뿐 아니라 릴리스 노트와 이슈를 함께 읽으며 정리했다. 언젠가는 읽는 데서 그치지 않고 작은 기여까지 해 보는 게 목표다. 이 글에서는 Podman이 무엇인지(데몬리스·루트리스·Pod), 쿠버네티스와 같은 "Pod"라는 단어를 쓰면서 무엇이 다른지, 장단점은 뭔지 정리하고, 마지막으로 Week E에서 만든 예약 API를 Docker 대신 Podman으로 띄운다면 코드가 어떻게 바뀌는지 직접 옮겨 본다. 결론부터 말하면 Dockerfile은 이미지 이름 표기 정도만 손보면 그대로 쓰고, 바뀌는 건 "누가 컨테이너를 실행하고 관리하느냐"다. 1. Podman 개요 1) Podman의 정의 Podman(POD MANager) = 컨테이너, 이미지, 볼륨, 그리고 컨테이너 묶음인 Pod를 관리하는 OCI 컨테이너 엔진. 상주 데몬 없이 동작하고, 일반 사용자 권한(rootless)으로 컨테이너를 실행할 수 있다. Podman 공식 README 는 Podman을 컨테이너·이미지·볼륨·Pod를 관리하는 도구로 소개하고, 리눅스에서 직접 돌거나 Mac·Windows에서는 Podman이 관리하는 VM 위에서 돈다고 설명한다. 내부적으로는 컨테이너 생명주기를 관리하는 libpod 라이브러리 위에 만들어져 있다. 2026년 기준 최신 메이저는 6.x로, Podman 6.0이 2026년 6월에 나왔고 8월에 6.1.0이 나왔다. 핵심은 Docker와 같은 이미지, 같은 명령어 를 쓴다는 점이다. Podman은 OCI(Open Container Initiative) 표준 이미지를 그대로 다루기 때문에 Docker Hub의 이미지를 pull하고, 우리가 Week E에서 쓴 Dockerfile 로 그대로 빌드할 수 있다. 대부분의 명령은 바이너리 이름만 바뀐다. # Docker 명령어를 그대로 옮기면 된다 podman pull docker.io/library/mysql:8.0 podman images podman run -d --name db -e MYSQL_ROOT_PASSWORD=secret -p 3306:3306 docker.io/library/mysql:8.0 podman ps # 손에 익은 docker를 계속 치고 싶다면 alias docker=podman 2) 데몬리스(daemonless) 구조 데몬리스 = 컨테이너를 대신 관리해 주는 상주 프로세스(데몬) 없이, CLI가 직접 자식 프로세스를 만들어(fork/exec) 컨테이너를 실행하는 방식 Docker는 클라이언트-서버 구조다. 내가 치는 docker CLI는 클라이언트일 뿐이고, 실제 일은 root 권한으로 항상 떠 있는 dockerd 가 한다. CLI는 /var/run/docker.sock 소켓으로 요청만 보낸다. Podman은 이 중간 계층을 없앴다. podman run 을 치면 Podman 프로세스가 직접 OCI 런타임( crun 또는 runc )을 호출해 컨테이너를 띄우고, 컨테이너마다 conmon 이라는 작은 감시 프로세스가 붙어 로그와 종료 코드를 챙긴다. [Docker] docker CLI → /var/run/docker.sock → dockerd(root, 상주) → containerd → runc → 컨테이너 [Podman] podman CLI → (fork/exec) → conmon → crun/runc → 컨테이너 └ 명령이 끝나면 podman 프로세스는 종료, conmon만 남아 컨테이너를 지켜봄 데몬이 없다면 무엇이 좋아지는지는 반대로 생각하면 된다. dockerd 가 죽으면 그 데몬이 관리하던 컨테이너 관리 경로 전체가 영향을 받는다. 또 docker 그룹에 속한 사용자는 이 root 데몬에게 "호스트 / 를 마운트한 특권 컨테이너를 띄워 줘"라고 요청할 수 있어서, Docker 공식 문서도 이 점을 사실상 root 권한에 가깝다고 경고한다 . Podman은 실행한 사용자의 권한 그대로 컨테이너를 띄우기 때문에 이런 "권한 대행자"가 애초에 없다. 3) 루트리스(rootless) 컨테이너 루트리스 컨테이너 = 관리자 권한이 없는 일반 사용자가 만들고 실행하는 컨테이너. 컨테이너 안에서는 UID 0(root)처럼 보여도, 호스트에서는 user namespace를 통해 권한 없는 일반 UID로 매핑된다. # 지금 rootless로 돌고 있는지 확인 podman info --format '{{.Host.Security.Rootless}}' # true # 컨테이너 안의 UID가 호스트의 어떤 UID로 매핑되는지 확인 podman unshare cat /proc/self/uid_map # 0 1000 1 ← 컨테이너 안 root(0) = 호스트의 내 계정(1000) # 1 100000 65536 ← 나머지는 /etc/subuid에 할당된 범위 컨테이너 안 프로세스: "나는 root(UID 0)다" → user namespace가 UID 0을 호스트 UID 1000(내 계정)으로 변환 → 컨테이너 탈출이 일어나도 호스트에서는 일반 사용자 권한만 가짐 → 이미지·컨테이너 저장소도 /var/lib/containers가 아니라 ~/.local/share/containers/storage Red Hat Developer의 rootless 입문 글 은 이 방식의 장점으로, 컨테이너 엔진이나 런타임이 뚫려도 공격자가 호스트 root를 얻지 못한다는 점과 한 서버에서 여러 일반 사용자가 각자 컨테이너를 돌릴 수 있다는 점을 꼽는다. 다만 완벽한 경계는 아니다. 컨테이너가 뚫리면 그 사용자가 원래 접근할 수 있는 파일과 서비스에는 여전히 접근할 수 있다. 4) Pod 개념과 Infra 컨테이너 Pod(Podman) = 하나의 네트워크 네임스페이스(그리고 선택적으로 IPC·PID 네임스페이스)를 공유하는 컨테이너 묶음. 같은 Pod 안의 컨테이너끼리는 localhost 로 통신한다. 이름부터 "Pod Manager"다. Docker에는 docker pod 같은 명령이 없다. Docker는 컨테이너를 하나씩 띄우고 네트워크로 이어 붙이지만, Podman은 쿠버네티스처럼 여러 컨테이너를 하나의 실행 단위로 묶을 수 있다. 출처: Podman: Managing pods and containers in a local container runtime — Red Hat Developer 그림에서 파란색 Infra Container 가 핵심이다. podman pod create 를 하면 아무 일도 하지 않고 네임스페이스만 붙잡고 있는 작은 컨테이너가 먼저 뜬다. 이후 --pod 옵션으로 추가하는 컨테이너들은 이 네임스페이스에 합류한다. 쿠버네티스의 pause 컨테이너와 같은 역할이다. podman pod create --name myapp -p 8080:8080 podman run -d --pod myapp --name db -e MYSQL_ROOT_PASSWORD=secret docker.io/library/mysql:8.0 podman run -d --pod myapp --name api localhost/reservation-api:latest podman ps -a --pod # CONTAINER ID IMAGE NAMES POD NAME # a1b2... localhost/podman-pause:6.1.0 myapp-infra myapp ← Infra 컨테이너 # c3d4... docker.io/library/mysql:8.0 db myapp # e5f6... localhost/reservation-api api myapp podman pod create → Infra 컨테이너 생성(네트워크 네임스페이스 소유, 포트 8080 바인딩) → db, api 컨테이너가 --pod myapp으로 같은 네임스페이스에 합류 → api에서 DB 주소는 db:3306이 아니라 localhost:3306 출처: Podman: from Docker networks to pods, kube play, and going rootless — Podman Desktop Blog (2026.09) Pod 개념이 없다면, 로컬에서는 Compose로 컨테이너를 서비스 이름( db )으로 이어 붙여 개발하다가 쿠버네티스에 올릴 때는 localhost 로 통신하는 Pod 구조로 다시 바꿔야 한다. Podman Pod는 로컬에서부터 운영 환경과 같은 묶음 방식으로 개발하게 해 준다. 2. 기존 쿠버네티스 환경과의 차이 처음에 제일 헷갈렸던 건 "Podman도 Pod를 만들고 쿠버네티스도 Pod를 만드니까, Podman이 작은 쿠버네티스인가?"였다. 결론부터 말하면 아니다. 둘은 서로 다른 층의 도구 다. 1) 컨테이너 엔진과 오케스트레이터의 계층 차이 컨테이너 엔진 = 한 대의 머신에서 이미지를 받고, 컨테이너를 만들고, 실행·중지하는 도구 (Docker, Podman) 오케스트레이터 = 여러 대의 머신(노드)을 하나의 클러스터로 묶고, 어떤 컨테이너를 어느 노드에 몇 개 띄울지 결정하고, 죽으면 다시 살리는 시스템 (Kubernetes) 출처: Kubernetes Components — Kubernetes Docs , CC BY 4.0 그림을 보면 쿠버네티스의 각 Node 안에는 "container runtime"이라는 칸이 따로 있다. 쿠버네티스는 컨테이너를 직접 실행하지 않고, kubelet이 CRI(Container Runtime Interface)로 containerd나 CRI-O 같은 런타임에게 일을 맡긴다. Podman은 이 런타임 칸에 들어가는 도구가 아니라, 개발자가 한 대의 머신에서 직접 쓰는 엔진이다. 다만 CRI-O와 Podman은 같은 containers 생태계의 이미지·스토리지 라이브러리를 공유하는 형제 프로젝트라, 로컬에서 Podman으로 만든 이미지가 CRI-O 기반 클러스터(OpenShift 등)에서 같은 방식으로 다뤄진다. [로컬 개발] [운영 클러스터] 개발자 → podman build/run kubectl apply → API server → scheduler(노드 선택) → 내 노트북 1대에서 실행 → kubelet → CRI(containerd/CRI-O) → runc/crun → 여러 노드에 분산 실행, 죽으면 컨트롤러가 재생성 2) Podman Pod와 Kubernetes Pod의 책임 범위 비교 출처: Viewing Pods and Nodes — Kubernetes Docs , CC BY 4.0 "컨테이너 여러 개가 네트워크 네임스페이스를 공유하고 localhost 로 통신한다"는 Pod의 정의 자체는 같다. 1장의 Infra 컨테이너와 쿠버네티스의 pause 컨테이너도 같은 역할이다. 차이는 Pod 바깥에서 누가 무엇을 책임지느냐 다. 구분 Podman Pod Kubernetes Pod 실행 범위 명령을 친 머신 1대 클러스터의 여러 노드 중 scheduler가 고른 노드 누가 띄우나 사용자가 podman 명령 또는 systemd(Quadlet) kubelet이 API server의 선언을 보고 죽으면 restart policy 또는 systemd가 같은 머신에서 재시작 ReplicaSet·Deployment 컨트롤러가 다른 노드에서라도 재생성 스케일 아웃 직접 Pod를 하나 더 만들어야 함 replicas: 3 , HPA로 자동 서비스 디스커버리·로드밸런싱 없음(포트 publish 정도) Service, Ingress, DNS 상태 저장소 로컬 디스크의 Podman 상태(데몬 없음) etcd 기본 권한 rootless 가능(사용자 권한) 노드의 kubelet·런타임은 보통 root, Pod는 securityContext로 제한 Podman: "이 머신에서 이 Pod를 지금 띄워라" → 명령형(imperative) Kubernetes: "이 Pod가 항상 3개 떠 있는 상태여야 한다" → 선언형(declarative), 컨트롤러가 계속 맞춰 줌 이 차이를 모르면 Podman Pod를 띄워 두고 "죽으면 알아서 살아나겠지"라고 착각하기 쉽다. Podman에는 원하는 상태와 현재 상태를 계속 비교해 주는 컨트롤 루프가 없다. 그 역할을 한 대 머신 범위에서 대신 맡는 게 뒤에서 볼 systemd + Quadlet이다. 3) kube generate / kube play를 통한 YAML 연동 podman kube generate = 로컬에서 돌고 있는 Podman 컨테이너·Pod를 쿠버네티스 YAML로 내보내는 명령 podman kube play = 쿠버네티스 YAML을 읽어 로컬에서 Podman Pod와 컨테이너로 실행하는 명령 층이 다른 두 도구를 이어 주는 것이 이 두 명령이다. 예전 이름은 podman generate kube , podman play kube 였고, 지금은 podman kube 아래로 모였지만 옛 이름도 별칭으로 동작한다. # 1. 로컬에서 손으로 만든 Pod를 쿠버네티스 YAML로 추출 podman kube generate myapp -f myapp.yaml # 2. 그 YAML(또는 동료가 준 매니페스트)을 로컬에서 그대로 실행 podman kube play myapp.yaml # 3. 같은 YAML 기준으로 정리 podman kube down myapp.yaml # 4. 같은 파일을 실제 클러스터에 적용 kubectl apply -f myapp.yaml podman run --pod ... (손으로 구성) → podman kube generate → myapp.yaml → podman kube play로 로컬 재현 / kubectl apply로 클러스터 배포 → 하나의 YAML이 로컬과 클러스터 양쪽의 기준이 됨 출처: Podman Desktop Blog (2026.09) 다만 kube play 는 쿠버네티스를 흉내 내는 것이지 쿠버네티스가 아니다. podman-kube-play 매뉴얼 에 정리된 지원 kind는 Pod, Deployment, PersistentVolumeClaim, ConfigMap, Secret, DaemonSet, Job 정도이고, Service·Ingress·HPA처럼 클러스터가 있어야 의미가 있는 오브젝트는 목록에 없다. Podman Desktop 블로그 도 kube play 는 쿠버네티스의 admission 정책(예: Pod Security Standard의 non-root 강제)을 검사하지 않으므로, 그건 Kind 같은 실제(로컬) 클러스터에서 확인하라고 짚는다. 4) systemd + Quadlet 기반 단일 머신 운영 Quadlet = .container , .pod , .kube 같은 선언형 파일을 읽어 systemd 서비스 유닛으로 자동 변환해 주는 Podman의 systemd generator 쿠버네티스가 없는 서버 한 대에서 "부팅하면 자동으로 뜨고, 죽으면 다시 살리고, 로그는 journald로"를 원한다면 Quadlet이 답이다. podman-systemd.unit 문서 에 따르면 rootless는 ~/.config/containers/systemd/ , rootful은 /etc/containers/systemd/ 아래의 파일을 읽어 같은 이름의 .service 를 만든다. # ~/.config/containers/systemd/hello.container [Unit] Description=Hello container [Container] Image=docker.io/library/nginx:1.27 PublishPort=8080:80 [Service] Restart=always [Install] WantedBy=default.target hello.container 저장 → systemctl --user daemon-reload (Quadlet generator 실행) → hello.service 자동 생성 → systemctl --user start hello → 컨테이너가 죽으면 systemd가 Restart=always에 따라 재시작, 로그는 journalctl --user -u hello 정리하면, 쿠버네티스에서 컨트롤러·kubelet이 하던 "원하는 상태 유지"를 한 대 머신 범위에서는 systemd가 맡는 구조다. 노드가 여러 대로 늘어나고 자동 스케일링·롤링 업데이트가 필요해지는 순간이 쿠버네티스로 넘어갈 시점이다. 3. 장점과 단점 한 줄로 요약하면 보안과 라이선스, 쿠버네티스 친화성은 Podman이 낫고, 생태계와 "그냥 되는" 경험은 아직 Docker가 낫다. 1) 장점 1 보안: 데몬 없음 + rootless가 기본값. 1장에서 본 것처럼 root로 상주하는 데몬이 없고, podman CLI와 podman machine init 은 기본이 rootless다. Docker도 Engine 20.10부터 rootless 모드를 제공하지만 직접 켜야 한다 . "기본값이 안전한 쪽"이라는 차이가 크다. 2 라이선스와 비용. Podman과 Podman Desktop은 Apache 2.0 오픈소스이고, Podman Desktop은 CNCF sandbox 프로젝트 다. 반면 Docker Desktop은 직원 250명 이상 또는 연 매출 1천만 달러 이상 기업이 업무에 쓰면 유료 구독이 필요하다 . 학생인 지금은 상관없지만, 회사에서 Docker Desktop 대신 Podman Desktop을 표준으로 깔아 주는 이유가 대부분 이것이다. 참고로 이 조건은 Docker Desktop에만 해당하고, 서버의 Docker Engine(CLI)은 해당되지 않는다. 3 쿠버네티스 친화성. Pod 개념, kube generate / kube play 로 로컬과 클러스터가 같은 YAML을 공유할 수 있다. Pod
То, что RADAR обнаружил и классифицировал для этой возможности. Это опубликованный источником текст, а не подтверждение, что предложение ещё действует.
Podman 정리 — 데몬 없는 컨테이너와 쿠버네티스, 그리고 예약 API에 적용해 보기. Podman 정리 — 데몬 없는 컨테이너와 쿠버네티스, 그리고 예약 API에 적용해 보기 목차 Podman 개요 Podman의 정의 데몬리스(daemonless) 구조 루트리스(rootless) 컨테이너 Pod 개념과 Infra 컨테이너 기존 쿠버네티스 환경과의 차이 컨테이너 엔진과 오케스트레이터의 계층 차이 Podman Pod와 Kubernetes Pod의 책임 범위 비교 kube generate / kube play를 통한 YAML 연동 systemd + Quadlet 기반 단일 머신 운영 장점과 단점 장점 단점 Docker와 Podman 비교표 실제 프로젝트 적용: 스터디룸 예약 API 설치와 첫 실행 이미지…
Открыть источник