3.1. 파드
어떨 때 보는가
- 배포한 애플리케이션이 뜨지 않을 때
- 서비스가 느리거나 응답하지 않을 때
- 로그를 봐야 할 때
- 컨테이너 안에서 파일이나 설정을 확인해야 할 때
장애 조사는 대부분 이 화면에서 시작합니다.
파드란 무엇인가
Kubernetes 가 배포하고 관리하는 가장 작은 단위 입니다. 컨테이너 하나 또는 여럿을 묶은 것으로, 클러스터에서 실제로 도는 프로세스에 해당합니다.
파드 안의 컨테이너들은 다음을 공유합니다.
| 공유하는 것 | 뜻 |
|---|---|
| 네트워크 | 같은 IP 주소를 쓰고, 서로를 localhost 로 부릅니다 |
| 저장 공간 | 같은 볼륨을 붙여 파일을 주고받을 수 있습니다 |
| 수명 | 함께 만들어지고 함께 사라집니다 |
| 배치 노드 | 반드시 같은 노드에서 돕니다 |
왜 컨테이너가 아니라 파드인가
컨테이너 하나가 최소 단위였다면 더 단순했을 것입니다. 파드라는 껍데기를 한 겹 둔 이유는 함께 있어야만 하는 컨테이너 가 있기 때문입니다.
| 예 | 주 컨테이너 | 곁 컨테이너 |
|---|---|---|
| 로그 전송 | 애플리케이션 | 로그 파일을 읽어 보내는 수집기 |
| 설정 갱신 | 애플리케이션 | 설정을 주기적으로 내려받는 프로그램 |
| 통신 대리 | 애플리케이션 | 암호화·인증을 대신 처리하는 프록시 |
이런 짝은 같은 노드에서, 같은 파일을 보며, 함께 만들어지고 함께 없어져야 합니다. 따로 배포하면 한쪽만 다른 노드에 갈 수 있고 파일도 공유하지 못합니다.
대부분의 파드는 컨테이너 하나만 담습니다. 여럿이 필요할 때를 위한 장치입니다.
파드를 직접 만들지 않는 이유
파드를 직접 만들면 종료됐을 때 아무도 다시 띄우지 않습니다. 노드가 내려가도 마찬가지입니다.
그래서 실제로는 Deployment 같은 컨트롤러를 만들고, 컨트롤러가 파드를 만들고 관리하게 합니다(3.2 장).
이 화면에서 보는 파드는 대부분 컨트롤러가 만든 것입니다. 이름 뒤의 무작위 문자열이 그 표시입니다.
| 이름 예 | 만든 것 |
|---|---|
web-7d4f9c8b6-x8k2m | Deployment (ReplicaSet 해시 + 파드 해시) |
db-0 | StatefulSet (순번) |
backup-29579160-abcde | CronJob (실행 시각 + 해시) |
파드 목록
워크로드 > Pod 로 들어갑니다.

| 열 | 설명 | 이렇게 읽습니다 |
|---|---|---|
| 이름 | 파드 이름 | 뒤의 무작위 문자열은 컨트롤러가 붙인 것입니다 |
| 네임스페이스 | 파드가 속한 네임스페이스 | |
| 재시작 | 컨테이너가 다시 시작한 횟수 | 0 이 아니면 한 번 이상 종료됐다는 뜻입니다 |
| 준비 완료 | 준비된 컨테이너 / 전체 컨테이너 | 1/2 면 하나가 아직 준비되지 않았습니다 |
| 상태 | 현재 실행 상태 | 아래 참고 |
| CPU · 메모리 | 지금 쓰고 있는 양 | 제한값에 가까우면 성능 문제를 의심합니다 |
| IP | 파드 내부 주소 | 파드를 다시 만들면 바뀝니다 |
| 노드 | 파드가 배치된 노드 | 특정 노드의 파드만 문제면 노드를 의심합니다 |
| 경과 시간 | 만든 뒤 지난 시간 | 방금 재시작했는지 알 수 있습니다 |
상태 읽기
| 상태 | 뜻 | 확인할 것 |
|---|---|---|
| Running | 정상 실행 중 | 없음 |
| Succeeded | 작업을 마치고 정상 종료 | 없음 (Job 에서 정상) |
| Pending | 배치를 기다리는 중 | 노드 자원 부족, 볼륨 준비 여부 |
| ContainerCreating | 컨테이너를 만드는 중 | 오래 머물면 이미지 내려받기나 볼륨 연결 확인 |
| Failed | 실행 실패 | 로그와 이벤트 |
| CrashLoopBackOff | 시작과 종료를 반복 | 로그. 대개 설정 오류나 의존 서비스 미기동 |
| ImagePullBackOff | 이미지를 가져오지 못함 | 이미지 이름, 레지스트리 인증 정보 |
Terminating (중지 중) | 지워지는 중 | 오래 머물면 종료 처리가 막혀 있습니다 |
CrashLoopBackOff 의 BackOff 는 재시도 간격을 늘린다는 뜻입니다. 계속 실패하면
Kubernetes 가 10초, 20초, 40초... 로 간격을 늘려 최대 5분까지 벌립니다. 무한히 재시작해
노드를 소모하지 않기 위한 장치입니다.
재시작 횟수가 계속 늘어나면 컨테이너가 반복해서 종료되고 있다는 뜻입니다. 로그를 먼저 확인하십시오.
파드 생애 주기
파드가 만들어져 트래픽을 받기까지 여러 단계를 거칩니다. 어디서 멈췄는지 알면 원인이 좁혀집니다.
| 순서 | 단계 | 여기서 멈추면 |
|---|---|---|
| 1 | 스케줄링 — 어느 노드에 놓을지 결정 | 자원 부족, 노드 선택 조건, 테인트 |
| 2 | 볼륨 연결 | PVC 가 준비되지 않음 (6.1 장) |
| 3 | 이미지 내려받기 | 이미지 이름 오타, 레지스트리 인증 |
| 4 | 컨테이너 시작 | 명령어 오류, 필수 환경 변수 누락 |
| 5 | 준비 상태 검사 통과 | 애플리케이션이 아직 뜨는 중이거나 검사 경로가 틀림 |
상태 검사(Probe)
컨테이너가 떠 있는 것 과 일할 준비가 된 것 은 다릅니다. 프로세스는 시작됐지만 아직 설정을 읽는 중이거나 데이터베이스에 연결하지 못했을 수 있습니다.
Kubernetes 는 이것을 컨테이너 안을 들여다봐서 알 수 없습니다. 그래서 애플리케이션에 직접 물어봅니다. 그 물어보는 방식이 상태 검사(probe)입니다.
세 가지 검사
| 검사 | 묻는 것 | 실패하면 |
|---|---|---|
| 준비 상태(readiness) | "지금 요청을 받을 수 있나?" | 트래픽을 보내지 않습니다. Service 엔드포인트에서 빠집니다 |
| 활성(liveness) | "살아 있나?" | 컨테이너를 다시 시작합니다 |
| 시작(startup) | "시작이 끝났나?" | 재시작합니다. 끝나기 전까지 다른 두 검사를 미룹니다 |
준비 상태 검사가 무중단 배포의 핵심 장치입니다. 새 파드가 준비되기 전에는 트래픽을 받지 않으므로, 배포 중에 요청이 실패하지 않습니다(5.1 장).
시작 검사는 처음 뜨는 데 오래 걸리는 애플리케이션 을 위한 것입니다. 예를 들어 기동에 3분이 걸리는 Java 애플리케이션에 활성 검사만 걸면, 아직 뜨는 중인데 응답이 없다고 판단해 계속 재시작합니다. 시작 검사를 두면 그동안 활성 검사를 미룹니다.
검사하는 방법
| 방법 | 어떻게 판단하나 | 쓰는 곳 |
|---|---|---|
| HTTP GET | 지정한 경로를 부르고 응답 코드가 200~399 면 성공 | 웹 애플리케이션. 가장 많이 씁니다 |
| TCP 소켓 | 지정한 포트에 연결되면 성공 | HTTP 가 아닌 서버 (데이터베이스 등) |
| 명령 실행 | 컨테이너 안에서 명령을 실행하고 종료 코드가 0 이면 성공 | 앞의 두 방법으로 판단할 수 없을 때 |
HTTP GET 을 쓸 때는 전용 경로를 두는 편이 좋습니다. 실제 서비스 경로를 쓰면 검사 요청이 로그를 채우고, 그 경로가 데이터베이스를 부르면 데이터베이스가 느려질 때 파드까지 재시작됩니다.
조절 값
파드 상세에서 각 검사의 설정을 볼 수 있습니다.
| 값 | 뜻 | 기본값 |
|---|---|---|
| delay | 컨테이너가 시작하고 첫 검사까지 기다리는 시간 | 0초 |
| period | 검사 간격 | 10 초 |
| timeout | 응답을 기다리는 시간 | 1초 |
| success | 몇 번 연속 성공해야 성공으로 보는지 | 1회 |
| failure | 몇 번 연속 실패해야 실패로 보는지 | 3회 |
콘솔에서는 이 값들이 delay = 10s, period = 10s, failure = 3 처럼 표시됩니다.
실제로 조치까지 걸리는 시간 은 이 값들의 조합입니다.
첫 검사까지 = delay
실패 판정까지 = delay + (period × failure)
예를 들어 delay = 10s, period = 10s, failure = 3 이면 컨테이너가 시작하고 40초 뒤에
재시작이 걸립니다.
프로브 설정이 문제를 만드는 경우
프로브는 도움을 주려고 있는 장치지만, 잘못 잡으면 정상인 파드를 계속 죽입니다.
| 증상 | 원인 | 조치 |
|---|---|---|
| 재시작이 반복되는데 로그에 오류가 없다 | 활성 검사가 너무 엄격합니다 | delay·failure 를 늘리거나 시작 검사를 둡니다 |
| 뜨는 데 오래 걸리는 앱이 계속 재시작 | 기동 시간보다 delay 가 짧습니다 | 시작 검사를 씁니다 |
파드는 Running 인데 트래픽이 안 온다 | 준비 상태 검사가 실패 중입니다 | 검사 경로·포트가 맞는지 확인 |
| 부하가 몰릴 때만 재시작된다 | timeout 이 짧아 느려진 응답을 실패로 봅니다 | timeout 을 늘립니다 |
| 데이터베이스가 느려지면 앱도 재시작된다 | 검사 경로가 데이터베이스를 부릅니다 | 검사용 경로를 따로 둡니다 |
활성 검사에 데이터베이스 연결 확인을 넣지 마십시오. 데이터베이스가 잠시 느려지면 모든 파드가 동시에 재시작되어 상황이 더 나빠집니다. 그런 확인은 준비 상태 검사에 두는 편이 안전합니다 — 트래픽만 잠시 멈추고 재시작은 하지 않습니다.
어떤 검사를 둘 것인가
| 상황 | 권장 |
|---|---|
| 웹 서비스 | 준비 상태 검사는 반드시. 활성 검사는 여유 있게 |
| 기동이 오래 걸림 | 시작 검사 추가 |
| 배치 작업(Job) | 대개 필요 없습니다 |
| 검사를 무엇으로 할지 모르겠다 | 준비 상태 검사만 두십시오. 활성 검사는 없어도 됩니다 |
활성 검사가 없으면 멈춘 프로세스를 되살리지 못하지만, 대부분의 경우 프로세스가 끝나면 컨테이너도 함께 끝나 Kubernetes 가 재시작합니다. 잘못 잡은 활성 검사보다 없는 편이 낫습니다.
설정하는 법 — YAML
컨테이너 스펙에 검사 종류별로 적습니다.
containers:
- name: app
image: registry.example.com/my-app:1.0
ports:
- name: http
containerPort: 8080
startupProbe: # 기동이 끝났는지 — 이것이 통과해야 아래 둘이 시작합니다
httpGet:
path: /health/startup
port: http
periodSeconds: 10
failureThreshold: 30 # 10초 x 30회 = 최대 5분까지 기다립니다
readinessProbe: # 트래픽을 받아도 되는지
httpGet:
path: /health/ready
port: http
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
livenessProbe: # 살아 있는지
httpGet:
path: /health/live
port: http
periodSeconds: 20
timeoutSeconds: 3
failureThreshold: 3
| 항목 | 앞의 표에서 | 설명 |
|---|---|---|
initialDelaySeconds | delay | 첫 검사까지 기다리는 시간 |
periodSeconds | period | 검사 간격 |
timeoutSeconds | timeout | 응답을 기다리는 시간 |
failureThreshold | failure | 몇 번 연속 실패해야 실패로 볼지 |
successThreshold | success | 몇 번 연속 성공해야 성공으로 볼지 |
port 에 이름을 쓸 수 있습니다. 위 예처럼 containerPort 에 이름을 붙여 두면 포트
번호를 바꿔도 검사 설정을 고치지 않아도 됩니다.
시작 검사를 두면 initialDelaySeconds 로 시간을 벌 필요가 없습니다. 기동 시간이
들쭉날쭉한 애플리케이션에 특히 잘 맞습니다 — 빨리 뜨면 빨리 통과하고, 오래 걸리면
periodSeconds x failureThreshold 만큼 기다려 줍니다.
HTTP 가 아닌 서버는 다른 방식을 씁니다.
readinessProbe:
tcpSocket: # 포트가 열렸는지만 봅니다
port: 5432
livenessProbe:
exec: # 명령 종료 코드가 0 이면 성공
command: ["sh", "-c", "pg_isready -U postgres"]
파드 상세
목록에서 이름을 누르면 상세 화면이 열립니다.

| 항목 | 무엇을 알 수 있는가 |
|---|---|
| 레이블 | Service 가 이 파드를 고르는 기준입니다 (5.1 장) |
| 주석 | 배포 도구가 남긴 정보. 다시 시작한 시각 등 |
| 제어자 | 이 파드를 만든 상위 자원. 눌러서 거슬러 올라갑니다 |
| 상태 | 지금 실행 상태 |
| 노드 | 배치된 노드. 눌러서 노드 상태를 확인합니다 |
| 서비스 계정 | 이 파드가 클러스터 API 를 부를 때 쓰는 계정 (7.1 장) |
| 호스트 IP · Pod IP | 노드 주소와 파드 주소 |
| QoS 클래스 | 자원이 모자랄 때 밀려나는 순서 |
아래로 내려가면 컨테이너별 정보가 나옵니다.
| 항목 | 설명 |
|---|---|
| 이미지 | 실행 중인 컨테이너 이미지와 태그 |
| 상태 | 컨테이너 단위 실행 상태와 마지막 종료 사유 |
| 환경 변수 | 주입된 설정값. ConfigMap·Secret 에서 온 것도 표시됩니다 |
| 마운트 | 연결된 볼륨과 경로 |
| 요청·제한 | 요청한 CPU·메모리와 상한 |
마지막 종료 사유 를 눈여겨보십시오. OOMKilled 면 메모리 상한을 넘어 강제 종료된 것이고,
Error 면 애플리케이션이 오류로 끝난 것입니다.
자원 요청량과 상한
컨테이너마다 요청량(request) 과 상한(limit) 두 값을 정할 수 있습니다. 이름이 비슷하지만 쓰이는 시점과 대상이 다릅니다.
| 값 | 뜻 | 언제 쓰이는가 |
|---|---|---|
| 요청량 | 이만큼은 보장되어야 한다 | 파드를 어느 노드에 배치할지 정할 때 |
| 상한 | 이 이상은 못 쓴다 | 파드가 실행 중일 때 |
요청량은 자리를 잡는 값입니다
Kubernetes 는 파드를 배치할 때 요청량을 더해 노드의 남은 자리를 계산합니다. 실제 사용량은 보지 않습니다.
CPU 8 코어짜리 노드에 요청량 2 코어인 파드가 3개 있으면, 그 파드들이 실제로 0.1 코어밖에
쓰지 않아도 노드에는 2 코어만 남은 것으로 계산됩니다. 요청량 4 코어인 파드는 배치되지
않고 Pending 상태로 기다립니다.
반대로 요청량을 정하지 않으면 자리를 잡지 않습니다. 배치는 쉬워지지만 노드가 붐빌 때 보장받는 몫이 없어 먼저 밀려납니다(아래 QoS 클래스).
상한은 실행 중에 막는 값입니다
상한을 넘으면 어떻게 되는지는 CPU 와 메모리가 다릅니다.
| 자원 | 상한을 넘으면 |
|---|---|
| CPU | 느려집니다. 상한만큼만 쓰도록 제한(스로틀링)될 뿐 죽지는 않습니다 |
| 메모리 | 강제 종료됩니다. 컨테이너가 OOMKilled 로 끝나고 다시 시작합니다 |
CPU 는 잠깐 나눠 쓰면 되지만 메모리는 이미 차지한 것을 회수할 수 없기 때문입니다.
OOMKilled 가 반복되면 상한을 올리거나 애플리케이션의 메모리 사용을 줄여야 합니다.
값 읽는 법
CPU 는 코어 수, 메모리는 바이트 크기 로 씁니다.
| 표기 | 뜻 |
|---|---|
2 또는 2000m | CPU 2 코어. m 은 1/1000 단위라 500m 은 0.5 코어입니다 |
1.5Gi | 메모리 1.5 기가바이트 |
512Mi | 메모리 512 메가바이트 |
하나만 정하면 어떻게 되는가
| 정한 것 | 결과 |
|---|---|
| 요청량만 | 상한이 없어 노드 자원이 남는 만큼 더 씁니다 |
| 상한만 | 요청량이 상한과 같은 값으로 자동으로 채워집니다 |
| 둘 다 | 정한 대로 |
| 아무것도 안 정함 | 자리를 잡지 않고 제한도 없습니다 |
상한만 정해도 요청량이 생긴다는 점이 중요합니다. COP 가 넣어 주는 애플리케이션 차트가
그렇습니다 — 상한만 cpu: "2", memory: 1.5Gi 로 정해 두므로 요청량도 같은 값이 됩니다.
이 파드는 실제 사용량과 무관하게 노드에서 2 코어를 차지합니다.
Console 에서는 파드 상세의 컨테이너 항목에서 요청·제한 을 확인합니다. 두 값이 같으면 상한만 정했거나 일부러 같게 정한 것입니다.
얼마로 정할 것인가
| 너무 작으면 | 너무 크면 | |
|---|---|---|
| 요청량 | 노드가 붐빌 때 밀려납니다 | 노드에 파드가 몇 개 못 들어가 자원이 놀게 됩니다 |
| 상한 | CPU 는 느려지고 메모리는 강제 종료됩니다 | 한 파드가 노드를 다 써서 다른 파드에 영향을 줍니다 |
실제 사용량을 먼저 재고 정하십시오. Console 의 파드 목록에 현재 CPU·메모리 사용량이 나오고, 모니터링 화면에서 시간에 따른 변화를 볼 수 있습니다(9.2 장). 평소 사용량을 요청량으로, 최대로 튀는 값을 상한으로 잡는 것이 출발점입니다.
Java 애플리케이션은 힙 크기와 함께 정해야 합니다. 힙을 512MB 로 잡았는데 메모리 상한이 512MB 면 힙 밖 영역(메타스페이스, 스레드 스택) 때문에 상한을 넘어 종료됩니다. 상한은 힙보다 넉넉하게 잡습니다.
QoS 클래스
자원이 모자랄 때 어떤 파드를 먼저 밀어낼지 정하는 등급입니다. 사용자가 지정하는 것이 아니라 자원 설정에 따라 자동으로 정해집니다.
| 클래스 | 조건 | 자원 부족 시 |
|---|---|---|
| Guaranteed | 모든 컨테이너의 요청량과 상한이 같다 | 가장 나중에 밀려납니다 |
| Burstable | 요청량만 있거나 요청량과 상한이 다르다 | 중간 |
| BestEffort | 요청량도 상한도 없다 | 가장 먼저 밀려납니다 |
중요한 애플리케이션이 BestEffort 면 자원이 모자랄 때 먼저 종료됩니다. 요청량을
명시하십시오.
Guaranteed 는 안정성이 가장 높지만 요청량만큼 자원을 계속 잡아 두므로 클러스터 밀도가
낮아집니다. 대부분은 Burstable 이 적당합니다.
이벤트로 원인 찾기
상세 화면 맨 아래의 이벤트는 문제 원인을 가장 빨리 알려 줍니다. 파드가 뜨지 않을 때 로그보다 먼저 보십시오.
로그는 컨테이너가 시작한 뒤에야 생기지만, 이벤트는 시작 전 단계(배치 실패, 이미지 내려받기 실패, 볼륨 연결 실패)도 기록합니다.
| 이유 | 뜻 | 조치 |
|---|---|---|
| FailedScheduling | 배치할 노드를 못 찾음 | 노드 자원, 노드 선택 조건, 테인트 확인 |
| Failed / ErrImagePull | 이미지를 못 가져옴 | 이미지 이름과 레지스트리 인증 정보 확인 |
| Unhealthy | 상태 검사 실패 | 애플리케이션이 검사 경로에 응답하는지 확인 |
| BackOff | 반복 실패로 재시도 간격을 늘림 | 근본 원인을 먼저 해결 |
| FailedMount | 볼륨을 연결하지 못함 | PVC 상태 확인 (6.1 장) |
| Evicted | 노드 자원 부족으로 밀려남 | QoS 클래스와 노드 여유 확인 |
로그 보기
상세 화면 오른쪽 위의 로그 버튼을 누릅니다.
| 기능 | 설명 | 쓰는 상황 |
|---|---|---|
| 컨테이너 선택 | 파드에 컨테이너가 여럿이면 볼 대상을 고릅니다 | 곁 컨테이너가 있는 파드 |
| 자동 갱신 | 새 로그가 나오면 화면을 따라 내립니다 | 지금 벌어지는 일을 볼 때 |
| 줄 수 | 가져올 줄 수를 정합니다 | 로그가 많아 느릴 때 줄입니다 |
| 이전 컨테이너 | 다시 시작하기 전 컨테이너의 로그 | 반복해서 재시작되는 파드 |
| 시각 표시 | 각 줄에 시각을 붙입니다 | 다른 기록과 시각을 맞출 때 |
| 내려받기 | 로그를 파일로 저장합니다 | 공유하거나 검색할 때 |
파드가 반복해서 재시작된다면 지금 로그는 비어 있고 이전 컨테이너 로그에 원인이 남아 있는 경우가 많습니다.
로그는 컨테이너의 표준 출력만 담습니다. 애플리케이션이 파일에만 기록하면 여기에 나오지 않습니다. 지워진 파드의 로그는 볼 수 없으므로, 필요하면 모니터링 화면을 쓰십시오(9.2 장).
웹 터미널
터미널 버튼을 누르면 컨테이너 안에서 명령어를 실행할 수 있습니다.
쓰는 상황은 이렇습니다.
| 확인할 것 | 방법 |
|---|---|
| 설정 파일이 제대로 붙었는가 | 마운트 경로의 파일을 봅니다 |
| 다른 서비스에 연결되는가 | curl, nc 로 불러 봅니다 |
| 환경 변수가 들어왔는가 | 환경 변수를 출력합니다 |
| 프로세스가 도는가 | 프로세스 목록을 봅니다 |
주의할 것이 있습니다.
- 컨테이너에 셸이 없으면 접속되지 않습니다. 최소 이미지에는 셸이 없는 경우가 많습니다.
- 여기서 만든 파일은 파드가 다시 시작하면 사라집니다.
- 운영 중인 파드에서 설정을 직접 고치면 다음 배포 때 되돌아갑니다. 임시 확인에만 쓰고, 실제 변경은 ConfigMap 이나 배포 정의로 하십시오(3.4 장).
자주 겪는 문제와 조치
| 증상 | 먼저 볼 곳 | 흔한 원인 |
|---|---|---|
| Pending 에서 안 넘어감 | 이벤트 | 노드 자원 부족, PVC 가 준비되지 않음 |
| CrashLoopBackOff | 이전 컨테이너 로그 | 설정 오류, 필수 환경 변수 누락, 의존 서비스 미기동 |
| ImagePullBackOff | 이벤트 | 이미지 태그 오타, 레지스트리 인증 정보 없음 |
| Running 인데 응답 없음 | 상태 검사 설정, 로그 | 애플리케이션이 아직 준비 중, 포트 불일치 |
| 재시작이 반복되는데 로그에 오류 없음 | 활성 검사 설정 | 검사가 너무 엄격합니다 |
| 자꾸 밀려남 | QoS 클래스, 노드 자원 | 요청량 미설정(BestEffort) |
| OOMKilled | 컨테이너 상태, 메모리 상한 | 상한이 실제 사용량보다 작습니다 |