症状を読むのは反射神経だ
한국어 원문으로 표시합니다.
한 줄 요약
문제 해결은 글로 배워지지 않습니다. kubectl get pod 에 뜬 글자를 보고 3초 안에 다음에 볼 곳이 떠올라야 하는데, 그건 직접 고장을 만들어 봐야 몸에 남습니다.
왜 진짜 고장이어야 하나
CKA 는 문제 해결이 배점의 큰 몫입니다. 그런데 앞 모듈들이 도는 가짜 클러스터에는 kubelet 도 컨테이너 런타임도 없어서, 고장 자체를 만들 수 없었습니다.
| 증상 | 가짜 클러스터에서는 |
|---|---|
ImagePullBackOff |
이미지를 받지 않으므로 생기지 않음 |
CrashLoopBackOff |
프로세스가 없으므로 죽지도 않음 |
OOMKilled |
메모리를 쓰지 않으므로 넘칠 일이 없음 |
| 프로브 실패 재시작 | 프로브를 돌리지 않음 |
PVC Bound |
프로비저너가 없어 영원히 Pending |
그래서 "이 증상은 무엇을 뜻하는가" 를 글로만 배울 수 있었습니다. 문제 해결은 그렇게 배워지지 않습니다. kubectl get pod 에 뜬 글자를 보고 3초 안에 다음에 볼 곳이 떠올라야 하는데, 그건 직접 만들어 봐야 몸에 남습니다.
비슷해 보이는데 원인이 다른 것들
Pending과ContainerCreating— 전자는 스케줄러, 후자는 kubelet 의 문제입니다.kubectl get pod -o wide의 NODE 열이 채워졌는지로 갈립니다.liveness실패와readiness실패 — 전자는 재시작, 후자는 트래픽에서만 제외합니다.- 없는 ConfigMap 을
env로 참조하면CreateContainerConfigError, 같은 것을 볼륨으로 참조하면Pending입니다.
세 가지만 기억하면 된다
describe의 Events 를 먼저 본다. 상태 이름은 어디서 막혔는지만 알려 줍니다. 무엇이 없는지는 언제나 이벤트에 있습니다.logs가 비었으면--previous. CrashLoopBackOff 인 파드의 지금 컨테이너는 아직 아무것도 안 찍었습니다.- NODE 열을 본다. 비어 있으면 스케줄러, 채워져 있으면 kubelet. 이 한 줄로 조사 범위가 절반이 됩니다.
증상마다 다음에 볼 곳
상태 이름을 원인으로 바로 잇지 말고, 다음에 어디를 볼지로 이으면 조사가 훨씬 빨라진다. 아래는 그 대응표다.
| 상태 | 다음에 볼 곳 | 흔한 원인 |
|---|---|---|
Pending, NODE 비어 있음 |
describe pod 의 Events |
requests 가 노드 여유보다 큼, 테인트, 노드 셀렉터가 아무 노드와도 안 맞음 |
Pending, 볼륨 관련 |
PVC 상태와 StorageClass | 프로비저너가 없거나 접근 모드가 안 맞음 |
ContainerCreating 이 길다 |
그 노드의 kubelet | 이미지가 크거나, 볼륨 마운트가 안 끝나거나, 시크릿이 없음 |
ImagePullBackOff |
Events 의 pull 실패 줄 | 태그 오타, 사설 레지스트리 자격 증명 없음, 네트워크 차단 |
CrashLoopBackOff |
logs --previous |
설정이 없어 즉시 종료, 의존 서비스에 못 닿음 |
OOMKilled |
describe 의 Last State |
limits 가 실제 사용량보다 작음 |
CreateContainerConfigError |
참조한 ConfigMap·Secret | 이름 오타이거나 아직 안 만들어짐 |
Running 인데 트래픽이 없음 |
엔드포인트와 readiness | 셀렉터가 라벨과 안 맞거나 readiness 가 계속 실패 |
마지막 줄이 특히 자주 사람을 잡는다. 파드는 Running 이고 로그도 정상인데 요청이 하나도 안 들어오는 상황이다. 이때 봐야 할 것은 파드가 아니라 서비스의 엔드포인트다. 비어 있으면 둘 중 하나다. 서비스의 셀렉터가 파드 라벨과 안 맞거나, readiness 프로브가 실패해 파드가 목록에서 빠진 것이다. 두 경우를 가르는 방법은 간단하다. 파드에 Ready 0/1 이 떠 있으면 프로브 문제이고, Ready 1/1 인데도 엔드포인트가 비어 있으면 셀렉터 문제다.
노드 자체가 문제일 때도 파드 증상으로 먼저 나타난다. 노드가 NotReady 가 되면 그 위의 파드는 한동안 Running 으로 남아 있다가 일정 시간이 지나야 정리된다. 그래서 "파드는 Running 인데 응답이 없다" 는 상황에서는 파드만 보지 말고 kubectl get nodes 를 한 번 치는 습관이 필요하다. 이 한 줄이 몇십 분을 아낀다.
실무에서 진짜 중요한 것
상태 이름이 아니라 Events 를 먼저 읽습니다. 상태는 어디서 막혔는지만 알려 주고, 무엇이 없는지는 언제나 이벤트에 있습니다. 시험에서도 실무에서도 이 순서를 바꾸면 시간을 두 배로 씁니다.
NODE 열 하나로 조사 범위가 절반이 됩니다. 비어 있으면 스케줄러, 채워져 있으면 kubelet 입니다. kubectl get pod -o wide 를 습관으로 두면 이 분기가 공짜로 따라옵니다.
CrashLoopBackOff 에서는 --previous 없이 로그를 보지 않습니다. 지금 컨테이너는 방금 다시 만들어져 아직 아무것도 찍지 않았습니다. 빈 로그를 보고 "로그가 없다" 고 판단하는 것이 가장 흔한 헛걸음입니다.
다음 두 실습에서 이것들을 직접 만들어 봅니다.