3년간 Docker 운영 후 Podman 전환기: 메모리 40% 절감과 아키텍처 개선 실무 후기
새벽 2시, 60초 만에 무너진 클러스터
60초. 그 짧은 시간 안에 노드 세 개가 다운됐습니다. 6개 클러스터에 걸쳐 42개의 마이크로서비스가 한꺼번에 멈춰버렸고, 마치 고장난 엘리베이터처럼 런타임들이 재시작을 반복하고 있었습니다. 어둠 속에서 노트북을 켜고 프로세스 모니터를 열어보니, 믿기 어려운 화면이 펼쳐졌습니다.
dockerd 프로세스가 단순한 Go 서비스들을 실행하는 호스트에서 5.8기가바이트의 상주 메모리를 점유하고 있었거든요. 그런데 정말 끔찍했던 건 메모리 문제 자체가 아니라, 그 바로 위에 적힌 로그 항목이었습니다.
"dockerd 메모리 부족 현상 감지됨"
전에도 여러 번 봤던 경고였습니다. 그때마다 '괜찮겠지' 하고 스스로를 위로했던 그 메시지. 엔지니어들은 종종 사람들이 차 안에서 이상한 소리를 무시하는 것처럼, 스스로에게 거짓말을 합니다. 저 역시 그랬고요.

계속 외면했던 경고들
이 이야기에서 가장 부끄러운 부분을 고백하자면, 저는 2021년에 이미 Podman에 대한 글을 읽었다는 점입니다. 브라우저 탭을 열어놓고 첫 부분만 훑어본 후 바로 닫아버렸죠. 새로운 도구로 갈아타는 게 위험하게 느껴졌고, Docker가 훨씬 익숙하게 느껴졌거든요.
돌이켜보니 **인프라 엔지니어링에서 가장 값비싼 것은 바로 '익숙함'**이었습니다. 그 비용은 누구도 청구서에 기재하지 않지만, 결국 언젠가는 치르게 되어 있더라고요.
사건 다음 날 아침, 공동 팀장인 프리야에게 어젯밤 스크린샷을 보냈습니다. 아무런 설명도 없이요. 프리야는 한참 동안 화면을 보더니 이렇게 말했습니다.
"우리는 우리 점심을 갉아먹는 악마에게 돈을 지불하면서 계속 먹이를 주고 있었네요."
그녀는 틀리지 않았습니다. 프리야는 거의 틀리는 법이 없는데, 그게 가끔은 불편할 때도 있지만 이번엔 정말 옳았어요. 바로 그 대화가 마이그레이션을 시작하게 된 실질적인 계기였습니다.
Podman이 근본적으로 다른 이유
Docker와 Podman의 차이를 이해하려면 아키텍처부터 봐야 합니다. Docker는 모든 것을 중앙 데몬을 통해 실행합니다. 하나의 큰 백그라운드 프로세스가 전체 컨테이너 세계를 관리하는 구조죠. 이 프로세스에 문제가 생기면 시스템의 모든 것이 영향을 받습니다. dockerd를 재시작하면? 당연히 모든 컨테이너가 함께 재시작됩니다.
Podman은 완전히 다른 방식으로 작동합니다. 각 컨테이너는 해당 컨테이너를 실행한 주체의 자식 프로세스일 뿐입니다. 중간에 무거운 데몬이 개입하지 않아요. 하나의 컨테이너가 종료되더라도 호스트의 다른 프로세스들은 아무런 영향을 받지 않습니다.
이런 아키텍처적 차이가 처음에는 사소해 보일 수 있습니다. 하지만 최악의 순간에 6기가바이트의 상주 메모리를 마주하게 되면, 그 심각성을 뼈저리게 깨닫게 되더라고요.
두 번째로 저를 정말 놀라게 한 것은 루트리스 모드였습니다. Podman은 처음부터 루트리스 모드를 염두에 두고 설계되었거든요. 루트 액세스 없이 컨테이너를 실행하는 것은 저희에게 선택 사항이 아니라 필수였는데, 이 때문에 보안 검토 기간이 2주에서 3일로 단축되는 마법 같은 일이 벌어졌습니다.
마이그레이션은 생각보다 단순했다
마이그레이션 장벽은 거의 없었습니다. Dockerfile 구문도 동일하고, OCI 이미지도 동일하고, 레지스트리도 동일했어요. 명령어 또한 거의 같습니다.
podman build -t api:v2 .
podman run -d -p 8080:8080 api:v2
podman ps
alias docker=podman
예외적인 상황들을 확인하기 위해 2주 동안 스테이징 서버에서 철저한 테스트를 진행했습니다. 놀랍게도 대부분의 스크립트에서 아무런 문제도 발견되지 않았어요.
단계별로 진행한 실제 전환 과정
저희는 한 번에 스위치를 켠 게 아닙니다. 가장 안전한 방법을 택했어요.
먼저 서비스 중에서 가장 지루한 서비스, 즉 몇 시간 동안 다운되어도 아무도 눈치채지 못할 내부 메트릭 전송 서비스를 골라서 10일 동안 Podman에서 실행해 봤습니다. 그 다음에는 읽기 전용 API를, 그리고 나서 워커 풀을 차례로 추가했어요.
진짜 문제는 Docker Compose였습니다. Podman에도 자체 Compose 구현이 있지만, 저희가 의존하는 일부 네트워킹 플래그에서는 아직 뒤처져 있더라고요.
결국 해당 파일들을 컨테이너용으로 특별히 제작된 systemd 유닛 파일인 Podman 쿼드릿으로 다시 작성했습니다.
[Unit]
Description=API 서비스
[Container]
Image=registry.local/api:v2
PublishPort=8080:8080
Environment=ENV=prod
[Install]
WantedBy=default.target
그러면 systemctl start api로 서비스가 실행됩니다. Systemd가 재시작을 처리하고, 로그는 journald로 전송되죠. 이 모든 과정을 감시하는 별도의 데몬은 없습니다. 깔끔하더라고요.

숫자로 확인한 놀라운 결과
8주에 걸쳐 한 클러스터 전체의 마이그레이션을 완료한 후, 지표를 분석해 봤습니다. 솔직히 15% 정도의 개선을 기대했는데, 실제 수치는 그 기대를 훨씬 뛰어넘었어요.
| 항목 | Docker | Podman |
|---|---|---|
| RAM (평균) | 4.9GB | 2.9GB |
| RAM (최대) | 7.2GB | 3.4GB |
| 시작 시간 | 1.8초 | 1.1초 |
| 실패한 풀 | 0.7% | 0.2% |
다음날 아침, 이 수치들을 프리야에게 보여줬습니다. 그녀는 잠시 표를 바라보더니 "인스턴스가 네 개네요."라고 말했어요. 그게 전부였습니다. EC2 인스턴스 네 개를 종료할 수 있었던 겁니다. 애초에 누구도 의도적으로 선택하지 않았던 중간 업체를 제거하는 것만으로 말이에요.
매년 절감된 비용 덕분에 그동안 조용히 잃어버리고 있던 실질적인 엔지니어링 역량을 되찾을 수 있었습니다.
아키텍처 변화를 그림으로 이해하기
팀원들을 위해 화이트보드에 그린 그림으로 설명하면 이렇습니다.
이전 (Docker)
엔지니어 -> Docker CLI -> dockerd (배고픈 데몬)
|
+-----------------+-----------------+
| | |
컨테이너 컨테이너 컨테이너
이후 (Podman + systemd)
엔지니어 -> podman -> 컨테이너 (systemd 소유)
엔지니어 -> podman -> 컨테이너 (systemd 소유)
엔지니어 -> podman -> 컨테이너 (systemd 소유)
중간 유통업체가 없습니다. 각 컨테이너는 완전히 독립적으로 운영되죠.
솔직하게 말하는 한계점들
Podman이 완벽한 도구는 아닙니다. 마이그레이션을 고려하신다면 이런 제약사항들을 미리 알고 계셔야 해요.
첫째, 호환성 문제가 있습니다. 일부 타사 시스템들은 여전히 Docker 소켓이 존재한다고 가정하거든요. CI 실행기에서 오류가 발생하지 않도록 하려면 Podman 소켓을 호환 모드로 노출해야 했습니다.
둘째, 네트워킹 성능 이슈가 있어요. slirp4netns를 사용한 루트리스 네트워킹은 브리지 네트워킹보다 속도가 현저히 느립니다. 그래서 최고 처리량을 요구하는 워커 서버에서는 여전히 루트 권한을 사용하는 Podman을 실행하고 있어요.
셋째, Docker Swarm 환경이라면 Podman은 적합한 선택이 아닙니다. 이건 명확한 제한사항이에요.
이런 부분들은 실제로 감수해야 할 트레이드오프입니다. 마이그레이션을 권하면서 이런 한계점을 숨기는 것은 정직하지 않다고 생각해요.

3년 운영 경험에서 얻은 교훈
지난 3년간 Docker를 운영하면서, 그리고 Podman으로 전환하면서 가장 큰 깨달음은 도구의 기본 철학이 얼마나 중요한지였습니다. Docker의 중앙집중식 데몬 구조는 초기에는 편리해 보였지만, 규모가 커질수록 단일 장애점이 되었거든요.
반면 Podman의 데몬리스 아키텍처는 처음에는 낯설었지만, 각 컨테이너가 독립적으로 운영되면서 전체 시스템의 안정성이 크게 향상되었습니다. 특히 루트리스 모드는 보안 측면에서 예상보다 훨씬 큰 이점을 가져다주었어요.
메모리 사용량 40% 절감이라는 수치도 중요하지만, 더 중요한 건 시스템 전체의 예측 가능성이 높아졌다는 점입니다. 더 이상 새벽에 dockerd 때문에 잠에서 깨는 일이 없어졌거든요.
물론 모든 환경에서 Podman이 정답은 아닙니다. 하지만 Docker의 리소스 사용량이나 안정성 문제로 고민이 있으시다면, 한 번쯤 진지하게 검토해 볼 만한 대안이라고 생각합니다.
결국 기술 선택에서 가장 중요한 건 현재 상황에 맞는 도구를 찾는 것이겠지만, 때로는 익숙함이라는 함정에서 벗어나는 용기도 필요한 것 같습니다.