Pod, 가장 작은 배포 단위
쿠버네티스의 최소 배포 단위는 컨테이너가 아니라 Pod입니다. 처음 배울 때 가장 헷갈리는 지점이 여기입니다 — "컨테이너 하나 띄우는 거면 그냥 컨테이너를 배포 단위로 쓰면 되지, 왜 Pod이라는 걸 하나 더 만들었을까?" 답은 간단합니다. 실무에서는 컨테이너 하나가 혼자 일하는 경우보다, 서로 강하게 묶여서 함께 뜨고 함께 죽어야 하는 컨테이너 묶음이 필요한 경우가 은근히 많기 때문입니다.
Pod은 "함께 배치되는 컨테이너들의 봉투"다
Pod 안의 컨테이너들은 네트워크 네임스페이스를 공유합니다. 즉 같은 Pod 안의 두 컨테이너는 localhost로 서로를 부를 수 있고, IP 주소도 하나만 가집니다. 스토리지 볼륨도 공유할 수 있습니다. 이게 왜 유용하냐면, 로그 수집 사이드카나 서비스 메시 프록시처럼 "메인 애플리케이션 옆에 붙어서 도와주는 컨테이너"를 만들 때 정확히 이 특성이 필요하기 때문입니다.
# multi-container-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: web-with-sidecar
spec:
containers:
- name: app
image: nginx:alpine
ports:
- containerPort: 80
- name: log-shipper
image: busybox
command: ["sh", "-c", "tail -f /var/log/nginx/access.log"]
volumeMounts:
- name: shared-logs
mountPath: /var/log/nginx
volumes:
- name: shared-logs
emptyDir: {}그렇다고 모든 Pod에 컨테이너를 여러 개 넣어야 하는 건 아닙니다. 오히려 실무에서 보는 Pod의 90% 이상은 컨테이너가 하나뿐입니다. 여러 컨테이너를 한 Pod에 넣는 건 "이 컨테이너들이 반드시 같은 노드, 같은 생명주기를 공유해야 한다"는 명확한 이유가 있을 때만입니다. 서로 독립적으로 스케일링되어야 하는 컴포넌트(예: API 서버와 데이터베이스)를 하나의 Pod에 억지로 묶는 건 흔한 초보자 실수입니다 — 이 둘은 애초에 각자 다른 속도로 늘고 줄어야 합니다.
Pod을 직접 만들지 않는 이유
kubectl apply -f로 위 Pod을 만들 수는 있지만, 실무에서 이렇게 Pod을 단독으로 배포하는 일은 거의 없습니다. Pod을 직접 만들면 그 Pod이 죽었을 때 아무도 다시 만들어주지 않기 때문입니다. Pod 자체에는 "몇 개를 유지해야 하는가"라는 개념이 없습니다 — 그건 다음 장에서 다룰 Deployment의 몫입니다. 그래서 이 장에서 만드는 Pod은 어디까지나 개념을 익히기 위한 것이고, 다음 장부터는 이 Pod을 직접 만들 일이 사실상 없어집니다.
생명주기
Pod은 다음 단계를 거칩니다. kubectl get pod -w로 실시간으로 이 전환을 지켜볼 수 있습니다.
stateDiagram-v2 [*] --> Pending: "생성 요청, 노드 배정 대기" Pending --> Running: "이미지 pull 완료, 컨테이너 시작" Running --> Succeeded: "모든 컨테이너 정상 종료 (일회성 작업)" Running --> Failed: "컨테이너가 0이 아닌 코드로 종료" Running --> Running: "재시작 정책에 따라 재시도" Failed --> [*] Succeeded --> [*]
여기서 짚어둘 만한 함정이 하나 있습니다. Running 상태라고 해서 컨테이너 안의 애플리케이션이 실제로 요청을 받을 준비가 됐다는 뜻은 아닙니다. Running은 그저 컨테이너 프로세스가 떠 있다는 뜻일 뿐, 스프링 애플리케이션이 아직 초기화 중이라 5초 동안 요청을 못 받는 상황도 Running입니다. 이 둘을 구분하는 방법(readiness probe)은 10장에서 다룹니다.
자주 쓰는 명령
kubectl apply -f multi-container-pod.yaml
kubectl get pod web-with-sidecar
kubectl logs web-with-sidecar -c app # 컨테이너가 여럿이면 -c로 지정
kubectl logs web-with-sidecar -c log-shipper
kubectl exec -it web-with-sidecar -c app -- sh # Pod 내부로 들어가기-c 옵션을 빼먹으면 "Pod에 컨테이너가 여러 개라 어느 것인지 정해달라"는 에러가 납니다. 컨테이너가 하나뿐인 Pod에서는 생략해도 되지만, 사이드카를 쓰는 순간부터는 습관적으로 붙이는 게 좋습니다.