kube-apiserver 는 기본적으로 6443/TCP 에서 HTTPS 로 받는다. 상태 엔드포인트는 세 개다.
| 경로 | 뜻 |
|---|---|
/livez |
프로세스가 살아 있는가. 실패하면 재시작 대상 |
/readyz |
요청을 받을 준비가 됐는가. 실패하면 로드밸런서에서 빼야 한다 |
/healthz |
예전 경로. 위 둘로 대체됐고 더 이상 권장하지 않는다 |
인증 없이 TCP · TLS 계층까지만 확인할 때는 curl 로 친다. 정상이면 본문에 ok 가 온다.
curl -k https://<APISERVER>:6443/livez
curl -k https://<APISERVER>:6443/readyz
익명 접근이 막혀 있으면 401 이 오는데, 이것도 API 서버가 응답하고 있다는 증거다. 연결 자체가 안 되는 것과 구분해서 읽는다.
자격증명을 태워 항목별로 보려면 kubectl 의 raw 요청을 쓴다. verbose 를 붙이면 어떤 점검이 실패했는지 한 줄씩 나온다.
kubectl get --raw='/readyz?verbose'
kubectl get --raw='/livez?verbose'
[+]ping ok
[+]etcd ok
[+]poststarthook/start-kube-apiserver-admission-initializer ok
readyz check passed
클러스터 수준 요약은 cluster-info 다.
kubectl cluster-info
kubectl get --raw='/readyz/etcd' # etcd 만 따로
kubectl get componentstatuses(cs) 는 오래전에 폐기됐다. 값이 비거나 그럴듯한 거짓 정상을 돌려줄 수 있으므로 판단 근거로 쓰지 않는다.
포트 도달 여부만 볼 때는 다음을 쓴다. 방화벽이 막으면 filtered, 대상이 죽었으면 refused 로 갈린다.
nc -zv <APISERVER> 6443
ss -lntp | grep 6443 # 컨트롤 플레인 노드에서
initContainer 는 앱 컨테이너보다 먼저, 선언한 순서대로 하나씩 실행되고 각각 끝나야 다음으로 넘어간다. 그래서 Pod 가 Init:0/2 · Init:CrashLoopBackOff 에서 멈춘다.
이름을 먼저 확인한다.
kubectl get pod <POD> -o jsonpath='{.spec.initContainers[*].name}'
로그는 일반 컨테이너와 같은 명령에 -c 로 컨테이너를 지정해 본다. 이미 끝난 initContainer 도 Pod 가 살아 있는 동안에는 조회된다.
kubectl logs <POD> -c <INIT_CONTAINER>
kubectl logs -n <NS> <POD> -c <INIT_CONTAINER>
실패 후 재시작됐다면 지금 보이는 로그는 새 시도의 것이다. 실패한 회차를 보려면 --previous 를 붙인다.
kubectl logs <POD> -c <INIT_CONTAINER> --previous
로그가 비어 있으면 컨테이너가 뜨기도 전에 실패한 것이다. 이미지 풀 실패, 볼륨 마운트 실패, ConfigMap · Secret 누락이 여기에 해당한다. 원인은 로그가 아니라 이벤트에 남는다.
kubectl describe pod <POD>
kubectl get events -n <NS> --sort-by=.lastTimestamp | tail -30
describe 의 Init Containers: 절에서 State · Exit Code · Reason 을 본다.
| 표시 | 흔한 원인 |
|---|---|
Waiting / PodInitializing |
앞선 initContainer 가 아직 끝나지 않았다 |
Terminated / Error, Exit Code: 1 |
스크립트가 실패했다. 로그를 본다 |
Waiting / ImagePullBackOff |
이미지 이름 오타 또는 레지스트리 인증 누락 |
Waiting / CreateContainerConfigError |
참조한 ConfigMap · Secret 가 없다 |