CNF 블로그

CNF 블로그에서 최신 정보와 유용한 팁을 만나보세요. 다양한 콘텐츠와 전문 지식을 통해 더 나은 경험을 제공합니다.

목차 (Agenda)

Kubernetes

쿠버네티스 Pod 완벽 가이드 — 개념·생명주기·멀티컨테이너 패턴

핵심 요약 — 쿠버네티스 Pod(파드)는 쿠버네티스가 배포하는 가장 작은 실행 단위로, 네트워크와 스토리지를 공유하는 하나 이상의 컨테이너 묶음입니다. 쿠버네티스 Pod의 생명주기와 패턴을 이해하면 쿠버네티스 운영의 절반이 잡힙니다.

2026년 07월 28일

쿠버네티스 Pod

Kubernetes 도입·운영, 전문가와 상담하세요

프로덕션 Kubernetes 도입부터 안정화까지 — Cloud Native Forum 전문가가 무료 상담으로 함께합니다.

쿠버네티스 Pod란 무엇인가?

Pod는 쿠버네티스에서 생성·배포할 수 있는 가장 작은 컴퓨팅 단위이며, 컨테이너 하나가 아니라 컨테이너를 담는 그릇입니다.

쿠버네티스 Pod 내부 구조도. 하나의 Pod 안에 앱 컨테이너와 보조 컨테이너가 들어 있고, pause 컨테이너가 붙잡은 네트워크 네임스페이스로 Pod IP 10.244.1.7과 포트 공간을 공유하며 localhost로 통신하고, 선언된 볼륨을 함께 마운트하며, 스케줄링과 삭제가 함께 일어나는 구조. 그림 1. Pod 하나가 감싸는 것 — 공유 IP·공유 볼륨·공동 생명주기

쿠버네티스 공식 문서는 Pod를 “쿠버네티스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨팅 단위”로 정의합니다(출처: Kubernetes 공식 문서 — 파드). 핵심은 쿠버네티스가 컨테이너를 직접 다루지 않는다는 점입니다. 스케줄러가 배치하는 단위도, kubelet이 관리하는 단위도, 복제본을 세는 단위도 전부 Pod입니다.

하나의 Pod 안에는 보통 컨테이너가 하나 들어갑니다(1 Pod : 1 컨테이너가 가장 흔한 패턴). 하지만 필요하면 밀접하게 협력해야 하는 컨테이너 여러 개를 한 Pod에 함께 담을 수 있습니다. 같은 Pod의 컨테이너들은 다음을 공유합니다.

  • 네트워크 — Pod마다 고유한 IP가 하나 부여되고, 내부 컨테이너들은 이 IP와 포트 공간을 함께 씁니다. 서로는 localhost로 통신합니다.
  • 스토리지 — Pod에 선언한 볼륨(volume)을 여러 컨테이너가 함께 마운트해 파일을 주고받을 수 있습니다.
  • 생명주기 — Pod가 스케줄링되면 함께 배치되고, Pod가 삭제되면 함께 사라집니다.

비유하면 쿠버네티스 Pod는 “논리적인 한 대의 호스트”입니다. 같은 서버에서 함께 돌던 프로세스들을 컨테이너로 나눠 담되, 같은 IP와 디스크를 쓰게 묶어 놓은 형태입니다. Pod가 가진 성질을 항목별로 더 촘촘히 확인하려면 eBook 7.1.1 파드의 개념과 특징 절을 참고하시기 바랍니다.

컨테이너가 있는데 왜 Pod가 필요한가?

컨테이너 격리는 유지하면서 “함께 살아야 하는 프로세스”를 묶을 중간 단위가 필요했기 때문입니다.

컨테이너의 원칙은 “컨테이너 하나에 프로세스 하나”입니다. 격리와 재사용성 면에서 옳은 원칙이지만, 현실의 애플리케이션은 주 프로세스 하나로 끝나지 않습니다. 로그를 수집해 내보내는 프로세스, 설정을 동기화하는 프로세스, 프록시 역할의 프로세스가 주 애플리케이션과 같은 네트워크·디스크를 공유하며 함께 떠 있어야 하는 경우가 많습니다.

이 요구를 컨테이너 하나에 프로세스를 몰아넣어 해결하면 격리 원칙이 깨지고, 완전히 분리된 컨테이너로 풀면 “반드시 같은 노드에, 같은 네트워크로” 배치할 방법이 마땅치 않습니다. 그래서 쿠버네티스는 컨테이너 위에 Pod라는 단위를 하나 더 두고, 함께 살아야 하는 컨테이너들을 원자적으로 스케줄링합니다(출처: Kubernetes 공식 문서 — 파드).

구현 관점에서는 Pod마다 인프라 컨테이너(일명 pause 컨테이너)가 먼저 만들어져 네트워크 네임스페이스를 붙잡고, 나머지 컨테이너들이 그 네임스페이스에 합류하는 방식으로 “IP 공유”가 실현됩니다. 애플리케이션 컨테이너가 재시작되어도 Pod의 IP가 유지되는 이유입니다. Pod를 어느 노드에 배치할지 결정하는 스케줄러와 실행을 맡는 kubelet의 관계는 쿠버네티스 아키텍처 완전 정복에서 자세히 다룹니다.

Pod 생명주기 — Phase 다섯 가지와 컨테이너 상태 정리

Pod는 Pending → Running을 거쳐 Succeeded 또는 Failed로 끝나며, 그 안의 컨테이너는 Waiting·Running·Terminated 세 상태를 오갑니다.

Pod 생명주기 2층 다이어그램. 위층은 Pending에서 Running을 거쳐 Succeeded 또는 Failed로 끝나는 Pod Phase 흐름과 Unknown을 보여주고, 아래층은 같은 시간축에서 컨테이너가 Waiting·Running·Terminated 상태를 오가는 모습을 놓았다. CrashLoopBackOff와 ImagePullBackOff는 Phase가 아니라 Waiting 상태의 사유임을 표시했다. 그림 2. Pod Phase 다섯 가지와 그 아래 컨테이너 상태 두 층

쿠버네티스 Pod의 생명주기는 두 층위로 나눠 봐야 정확합니다(출처: Kubernetes 공식 문서 — 파드 생명주기).

Pod Phase(파드 수준) — Pod 전체의 대략적인 위치를 나타냅니다.

Phase 의미
Pending 클러스터가 Pod를 수락했지만 아직 컨테이너가 다 준비되지 않은 상태. 스케줄링 대기, 이미지 다운로드가 여기 포함됩니다
Running 노드에 배치되어 최소 한 개 컨테이너가 실행 또는 시작 중인 상태
Succeeded 모든 컨테이너가 정상 종료(exit 0)했고 재시작되지 않는 상태. 배치 작업(Job)의 정상 결말입니다
Failed 모든 컨테이너가 종료됐고 하나 이상이 실패로 끝난 상태
Unknown 노드와의 통신 두절 등으로 상태를 알 수 없는 경우

컨테이너 상태(컨테이너 수준) — Pod 안의 컨테이너 각각은 Waiting(시작 대기 — 이미지 풀, 시크릿 대기 등), Running(실행 중), Terminated(종료 — 성공이든 실패든) 중 하나입니다. 자주 보는 CrashLoopBackOff는 Phase가 아니라 “컨테이너가 반복해서 죽어 kubelet이 재시작 간격을 늘려 가며 대기 중”이라는 Waiting 상태의 사유(reason)입니다.

여기에 재시작 정책(restartPolicy) 이 결합합니다. Always(기본값, 항상 재시작)·OnFailure(실패 시에만)·Never(재시작 안 함) 세 가지이며, 웹 서비스는 Always, 배치 작업은 OnFailure나 Never가 일반적입니다. 한 가지 더 기억할 점은 Pod가 “회복되는” 단위가 아니라 “대체되는” 단위라는 사실입니다. 노드가 죽으면 그 Pod는 다른 노드로 이사하는 것이 아니라 삭제되고, 컨트롤러가 새 Pod를 새로 만듭니다. Pod를 소모품으로 설계해야 하는 이유입니다. Phase와 컨테이너 상태, 재시작 정책의 관계를 도식과 YAML 예제로 다시 보려면 eBook 7.1.2 파드 생명 주기 절이 이어지는 자료입니다.

Pod의 건강을 지키는 프로브 세 가지 — 무엇을 언제 쓰는가?

kubelet은 liveness·readiness·startup 세 가지 프로브로 컨테이너의 생존과 준비 상태를 판단합니다.

쿠버네티스 프로브 비교표. liveness는 실패 시 컨테이너를 재시작하고, readiness는 재시작 없이 서비스 엔드포인트에서 제외하며, startup은 성공할 때까지 나머지 두 프로브를 보류한다. 각 프로브의 질문·실패 시 동작·대표 사용처를 같은 축으로 나란히 놓았다. 그림 3. 프로브 세 가지 — 실패했을 때 kubelet이 하는 일이 다르다

컨테이너 프로세스가 떠 있다고 애플리케이션이 정상이라는 보장은 없습니다. 그래서 쿠버네티스는 상태 진단 장치인 프로브(probe)를 제공합니다(출처: Kubernetes 공식 문서 — 파드 생명주기).

  • Liveness Probe(활성 프로브) — “살아 있는가?”를 검사합니다. 실패하면 kubelet이 컨테이너를 재시작합니다. 교착 상태(deadlock)에 빠진 프로세스를 자동 복구하는 용도입니다.
  • Readiness Probe(준비성 프로브) — “트래픽을 받을 준비가 됐는가?”를 검사합니다. 실패하면 재시작 대신 서비스의 엔드포인트에서 제외됩니다. 캐시 예열이나 외부 연결 준비가 끝나지 않은 Pod에 요청이 가는 사고를 막습니다.
  • Startup Probe(시작 프로브) — 기동이 느린 애플리케이션을 위해 “시작이 끝났는가?”를 먼저 검사하고, 성공할 때까지 다른 두 프로브를 보류합니다. 기동에 수 분 걸리는 레거시 애플리케이션을 컨테이너로 옮길 때 특히 유용합니다.

프로브 설정이 없으면 kubelet은 프로세스 생존만 봅니다. 반대로 liveness를 너무 공격적으로 잡으면 일시적 부하에도 재시작이 반복되는 역효과가 납니다. “재시작으로 해결되는 문제인가(liveness), 잠시 트래픽만 빼면 되는 문제인가(readiness)”를 구분하는 것이 설계의 출발점입니다.

프로브는 컨테이너 한 개의 판정 장치일 뿐이라는 한계도 있습니다. Pod가 반복 재시작되는 이유, 오토스케일링이 자원 부족으로 실패해 새 Pod가 뜨지 못한 사실 같은 정보는 클러스터 전체를 지켜보는 모니터링 계층이 있어야 드러납니다. 오픈마루가 정리한 쿠버네티스 모니터링 활용 사례는 노드 다운타임·Pod 실패·네트워크 장애와 컨테이너 단위 CPU·메모리 사용량을 함께 수집해 이 공백을 메우는 접근을 보여줍니다.

사이드카·앰배서더·어댑터, 언제 무엇을 쓰는가?

보조 컨테이너를 두는 위치와 목적에 따라 사이드카, 앰배서더, 어댑터 세 패턴으로 나뉩니다.

멀티컨테이너 패턴 비교도. 사이드카는 주 컨테이너 옆에서 기능을 확장하고, 앰배서더는 주 컨테이너와 외부 사이에 서서 나가는 통신을 대리하며, 어댑터는 주 컨테이너의 출력을 외부 표준 형식으로 변환해 내보낸다. 세 패턴을 같은 Pod 경계 안에서 트래픽 화살표 방향으로 구분했다. 그림 4. 멀티컨테이너 세 패턴 — 보조 컨테이너가 서는 위치와 트래픽 방향

한 Pod에 컨테이너를 여러 개 담는 대표 멀티컨테이너 패턴은 세 가지입니다.

  • 사이드카(Sidecar) — 주 컨테이너의 기능을 보조 컨테이너가 확장합니다. 로그 수집기, 설정 리로더, 서비스 메시의 프록시(Istio의 Envoy)가 전형입니다. 오토바이 옆에 붙은 사이드카처럼 주 애플리케이션 코드를 고치지 않고 기능을 더합니다.
  • 앰배서더(Ambassador) — 주 컨테이너가 외부로 나가는 통신을 대리하는 컨테이너입니다. 애플리케이션은 localhost의 앰배서더에게만 접속하고, 실제 대상(샤딩된 DB, 원격 API)을 고르는 복잡함은 앰배서더가 떠안습니다.
  • 어댑터(Adapter) — 주 컨테이너의 출력을 외부 표준 형식으로 변환합니다. 제각각인 애플리케이션 로그·메트릭을 모니터링 시스템이 기대하는 형식으로 바꿔 노출하는 경우가 대표적입니다.

세 패턴 모두 “같은 네트워크·같은 볼륨을 공유한다”는 Pod의 성질을 활용합니다. 세 패턴의 구조도와 매니페스트 예시는 eBook 7.1.3 파드 디자인 패턴 절에서 확인할 수 있습니다. 사이드카로 로그를 모으고 나면 다음 숙제는 “쌓인 로그에서 원인을 얼마나 빨리 찾느냐”로 넘어가는데, 이 지점을 다룬 실무 글로 AI로 쿠버네티스 로그 분석 10초 만에 끝내는 법이 있습니다. 한 가지 실무 변화도 짚어 둘 필요가 있습니다. 쿠버네티스 1.28부터 사이드카 컨테이너가 네이티브 기능(알파)으로 도입되어, 초기화 컨테이너(init container)에 restartPolicy: Always를 지정하는 방식으로 “주 컨테이너보다 먼저 시작하고 나중에 종료되는” 순서 보장이 가능해졌고, 1.29에서 베타로 올라갔습니다(출처: Kubernetes 공식 블로그 — Native Sidecar Containers, 2023-08). 사이드카가 주 컨테이너보다 늦게 떠서 초기 요청이 실패하던 고전적인 문제를 표준 기능으로 풀 수 있게 된 셈입니다.

Pod 네트워킹 기초 — IP 하나를 공유하는 구조

모든 Pod는 클러스터 안에서 고유 IP를 하나 받고, Pod끼리는 NAT 없이 그 IP로 직접 통신합니다.

Pod 네트워킹 구조도. 같은 Pod 안 컨테이너는 localhost로 통신하고, 서로 다른 노드의 Pod는 NAT 없이 Pod IP로 직접 통신하며, Pod IP가 재생성으로 바뀌므로 실제 호출은 고정 ClusterIP와 DNS 이름을 제공하는 서비스를 거치는 세 경로를 나란히 보여준다. 그림 5. Pod IP 하나가 유효한 범위 — 같은 Pod 안, 노드 너머, 서비스 앞

쿠버네티스 네트워크 모델의 대원칙은 단순합니다. Pod마다 IP가 하나씩 있고, 모든 Pod는 NAT(주소 변환) 없이 서로의 IP로 통신할 수 있어야 한다는 것입니다(출처: Kubernetes 공식 문서 — 파드). 이 모델 덕분에 애플리케이션 입장에서는 “포트 충돌을 피해 호스트 포트를 나눠 쓰는” 가상 머신 시절의 고민이 사라집니다.

같은 Pod 안에서는 컨테이너들이 네트워크 네임스페이스를 공유하므로 localhost:포트로 통신하고, 다른 Pod와는 Pod IP로 통신합니다. 다만 Pod는 언제든 대체되고 IP도 바뀌므로, 실제 서비스 호출은 고정된 가상 IP와 DNS 이름을 제공하는 서비스(Service) 오브젝트를 거치는 것이 표준입니다. Pod IP·노드 IP·클러스터 IP가 각각 어느 범위에서 유효한지 헷갈린다면 eBook 8.1.2 쿠버네티스 IP 주소 종류 절이 세 주소를 나란히 비교합니다. 이 원칙을 각 노드에서 실제로 구현하는 주체는 CNI(Container Network Interface) 플러그인과 kube-proxy이며, 플러그인이 Pod에 IP를 붙이고 경로를 여는 과정은 eBook 8.1.3 컨테이너 네트워크 인터페이스(CNI) 절이 단계별로 다룹니다. 노드 위에서 kube-proxy가 이 규칙을 어떻게 유지하는지는 쿠버네티스 아키텍처 완전 정복의 워커 노드 편에서 이어집니다.

Pod가 안 뜰 때 — 트러블슈팅 체크리스트

증상별로 Pending은 스케줄링, ImagePullBackOff는 이미지, CrashLoopBackOff는 애플리케이션을 먼저 의심하면 빠릅니다.

Pod 트러블슈팅 매핑표. Pending은 스케줄링 계층, ImagePullBackOff는 이미지·레지스트리 계층, CrashLoopBackOff는 애플리케이션 계층, OOMKilled는 자원 한도, Running인데 트래픽이 없는 경우는 서비스·readiness 계층에 대응하며 각 증상마다 먼저 칠 kubectl 명령과 대표 원인을 함께 정리했다. 그림 6. 증상이 가리키는 계층 — Pending·ImagePullBackOff·CrashLoopBackOff·OOMKilled

현장에서 Pod 트러블슈팅을 하며 가장 자주 만나는 증상과 점검 순서를 체크리스트로 정리합니다.

  1. Pending이 길어질 때 — 아직 노드에 배치되지 못한 상태입니다. kubectl describe pod <이름>의 Events에서 스케줄링 실패 사유를 확인합니다. CPU·메모리 요청량 대비 여유 노드 부족, 노드 셀렉터·테인트 불일치, PVC(영구 볼륨 클레임) 바인딩 대기가 3대 원인입니다.
  2. ImagePullBackOff / ErrImagePull — 이미지를 받아오지 못하는 상태입니다. 이미지 이름·태그 오타, 프라이빗 레지스트리 인증(imagePullSecrets) 누락, 네트워크·프록시 문제 순서로 확인합니다.
  3. CrashLoopBackOff — 컨테이너가 시작 직후 반복해서 죽는 상태입니다. kubectl logs <이름> --previous로 직전 종료 로그를 봅니다. 설정·환경 변수 오류, 의존 서비스 접속 실패, liveness 프로브 과민 설정이 흔한 원인입니다.
  4. OOMKilled — 메모리 제한(limit) 초과로 강제 종료된 경우입니다. kubectl describe pod의 Last State에서 사유를 확인하고 메모리 limit과 애플리케이션 힙 설정을 함께 조정합니다.
  5. Running인데 트래픽이 안 올 때 — readiness 프로브 실패로 엔드포인트에서 빠져 있는지, 서비스의 셀렉터와 Pod 레이블이 일치하는지 확인합니다.
  6. 실행 중 컨테이너 내부를 봐야 할 때 — 셸이 없는 경량 이미지라면 kubectl debug로 임시(ephemeral) 컨테이너를 붙여 조사할 수 있습니다(출처: Kubernetes 공식 문서 — 파드).

순서의 요지는 하나입니다. Pod의 상태와 사유(reason)는 증상이 어느 계층(스케줄링·이미지·애플리케이션·네트워크)에서 났는지 알려 주는 1차 신호이므로, kubectl get pods의 STATUS를 읽는 눈이 곧 트러블슈팅 속도라는 점입니다.

다만 Pod가 수십, 수백 개인 클러스터에서는 이 체크리스트를 사람이 순서대로 밟는 일 자체가 병목이 됩니다. 오픈마루는 이 반복 절차를 LLM에 맡기는 접근을 정리해 두었습니다. Pending·ImagePullBackOff·CrashLoopBackOff의 원인 분석과 수정안을 자연어 질의로 받는 쿠버네티스 트러블슈팅 — AI가 파드 분석부터 해결책까지, 그리고 대시보드를 메뉴 단위로 헤매는 대신 “이 서비스 메모리 괜찮아?” 한 문장으로 파드 리소스 사용량을 점검하는 방법이 대표적인 예입니다. 두 글 모두 kubectl을 대체하자는 이야기가 아니라, STATUS와 Events를 읽는 1차 판단을 자동화해 원인 후보를 좁히는 쪽에 초점을 둡니다.

쿠버네티스 Pod는 쿠버네티스라는 건물의 벽돌입니다. Deployment, StatefulSet, Job 같은 상위 오브젝트도 결국 Pod를 찍어내고 관리하는 틀이며, 서비스와 네트워킹도 Pod의 IP 모델 위에 서 있습니다. 쿠버네티스 Pod의 개념·생명주기·패턴이 잡히면 이후 어떤 워크로드 오브젝트를 만나도 “결국 Pod를 어떻게 만들고 유지하는가”라는 질문으로 환원해 이해할 수 있습니다.

본 사이트(Cloud Native Forum)를 운영하는 오픈마루는 국내에서 쿠버네티스·오픈시프트 환경의 구축과 모니터링을 지원해 온 기업입니다. 개념을 넘어 운영 단계 — Pod 단위 관측, 장애 원인 분석, 자원 계획 — 로 넘어가는 시점이라면 오픈마루의 자료와 문의 창구를 활용하실 수 있습니다.

자주 묻는 질문 (FAQ)

Pod와 컨테이너의 차이는 무엇인가요?

컨테이너는 애플리케이션 프로세스를 격리해 실행하는 기술이고, Pod는 그 컨테이너를 하나 이상 담아 쿠버네티스가 스케줄링하는 최소 단위입니다. 같은 Pod의 컨테이너들은 IP·포트 공간과 볼륨을 공유하며 항상 같은 노드에 함께 배치됩니다.

Pod 하나에 컨테이너를 몇 개 넣는 것이 좋나요?

기본은 1개입니다. 로그 수집기나 프록시처럼 주 컨테이너와 생명주기·네트워크를 반드시 함께해야 하는 보조 프로세스가 있을 때만 사이드카 등으로 추가합니다. 독립적으로 확장·배포해야 하는 컴포넌트라면 별도 Pod로 분리하는 것이 원칙입니다.

CrashLoopBackOff는 무엇이고 어떻게 해결하나요?

컨테이너가 시작 직후 반복해서 죽어 kubelet이 재시작 간격을 점점 늘리며 대기하는 상태입니다. kubectl logs --previous로 직전 종료 로그를 확인하고, 설정 오류·의존 서비스 접속 실패·과민한 liveness 프로브 순서로 원인을 좁히는 것이 정석입니다.

Pod가 삭제되면 데이터도 사라지나요?

Pod 내부 파일시스템과 emptyDir 볼륨은 Pod와 함께 사라집니다. 보존해야 하는 데이터는 PV(영구 볼륨)와 PVC로 Pod 밖에 두어야 하며, 이런 워크로드는 StatefulSet 같은 상태 유지형 오브젝트로 관리하는 것이 일반적입니다.

Pod의 IP는 고정되나요?

고정되지 않습니다. Pod가 재생성되면 새 IP를 받을 수 있습니다. 그래서 다른 워크로드가 Pod IP를 직접 바라보게 하지 않고, 고정 가상 IP와 DNS 이름을 제공하는 서비스(Service)를 앞에 두는 것이 표준 구성입니다.

Share This Story, Choose Your Platform!

Go to Top