클러스터 문제 해결
클러스터 문제 해결 (Troubleshooting Clusters)
이 문서는 클러스터 문제 해결에 관한 내용이에요. 경험하는 문제의 근본 원인으로 애플리케이션을 이미 배제했다고 가정해요. 애플리케이션 디버깅 팁은 애플리케이션 문제 해결 가이드를 참고해요. 더 많은 정보는 문제 해결 개요 문서를 방문해도 돼요.
kubectl 문제 해결은 kubectl 문제 해결을 참고해요.
출처: 문서
본문
클러스터 나열하기
클러스터에서 가장 먼저 디버깅할 것은 노드가 모두 올바르게 등록되었는지예요.
다음 명령을 실행해요.
kubectl get nodes
보고 싶은 모든 노드가 존재하고 모두 Ready 상태인지 확인해요.
클러스터의 전반적인 건강 상태에 대한 상세 정보를 얻으려면 실행할 수 있어요.
kubectl cluster-info dump
예시: 다운/연결 불가 노드 디버깅
때로는 디버깅할 때 노드의 상태를 보는 것이 유용할 수 있어요. 예를 들어 노드에서 실행 중인 파드의 이상한 동작을 발견했거나, 파드가 왜 그 노드에 스케줄링되지 않는지 알아내기 위해서요. 파드와 마찬가지로 kubectl describe node와 kubectl get node -o yaml로 노드에 대한 상세 정보를 검색할 수 있어요. 예를 들어, 노드가 다운(네트워크에서 끊기거나 kubelet이 죽어 재시작되지 않는 등)되면 볼 수 있는 것이 이렇습니다. 노드가 NotReady임을 보여주는 이벤트와, 파드가 더 이상 실행되지 않는 것(NotReady 상태 5분 후 축출됨)을 주목해요.
kubectl get nodes
NAME STATUS ROLES AGE VERSION
kube-worker-1 NotReady <none> 1h v1.23.3
kubernetes-node-bols Ready <none> 1h v1.23.3
kubernetes-node-st6x Ready <none> 1h v1.23.3
kubernetes-node-unaj Ready <none> 1h v1.23.3
kubectl describe node kube-worker-1
Name: kube-worker-1
Roles: <none>
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=kube-worker-1
kubernetes.io/os=linux
node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Thu, 17 Feb 2022 16:46:30 -0500
Taints: node.kubernetes.io/unreachable:NoExecute
node.kubernetes.io/unreachable:NoSchedule
Unschedulable: false
Lease:
HolderIdentity: kube-worker-1
AcquireTime: <unset>
RenewTime: Thu, 17 Feb 2022 17:13:09 -0500
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
NetworkUnavailable False Thu, 17 Feb 2022 17:09:13 -0500 Thu, 17 Feb 2022 17:09:13 -0500 WeaveIsUp Weave pod has set this
MemoryPressure Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
DiskPressure Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
PIDPressure Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
Ready Unknown Thu, 17 Feb 2022 17:12:40 -0500 Thu, 17 Feb 2022 17:13:52 -0500 NodeStatusUnknown Kubelet stopped posting node status.
Addresses:
InternalIP: 192.168.0.113
Hostname: kube-worker-1
Capacity:
cpu: 2
ephemeral-storage: 15372232Ki
hugepages-2Mi: 0
memory: 2025188Ki
pods: 110
Allocatable:
cpu: 2
ephemeral-storage: 14167048988
hugepages-2Mi: 0
memory: 1922788Ki
pods: 110
System Info:
Machine ID: 9384e2927f544209b5d7b67474bbf92b
System UUID: aa829ca9-73d7-064d-9019-df07404ad448
Boot ID: 5a295a03-aaca-4340-af20-1327fa5dab5c
Kernel Version: 5.13.0-28-generic
OS Image: Ubuntu 21.10
Operating System: linux
Architecture: amd64
Container Runtime Version: containerd://1.5.9
Kubelet Version: v1.23.3
Kube-Proxy Version: v1.23.3
Non-terminated Pods: (4 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- ---
default nginx-deployment-67d4bdd6f5-cx2nz 500m (25%) 500m (25%) 128Mi (6%) 128Mi (6%) 23m
default nginx-deployment-67d4bdd6f5-w6kd7 500m (25%) 500m (25%) 128Mi (6%) 128Mi (6%) 23m
kube-system kube-proxy-dnxbz 0 (0%) 0 (0%) 0 (0%) 0 (0%) 28m
kube-system weave-net-gjxxp 100m (5%) 0 (0%) 200Mi (10%) 0 (0%) 28m
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 1100m (55%) 1 (50%)
memory 456Mi (24%) 256Mi (13%)
ephemeral-storage 0 (0%) 0 (0%)
hugepages-2Mi 0 (0%) 0 (0%)
Events:
...
kubectl get node kube-worker-1 -o yaml
apiVersion: v1
kind: Node
metadata:
annotations:
node.alpha.kubernetes.io/ttl: "0"
volumes.kubernetes.io/controller-managed-attach-detach: "true"
creationTimestamp: "2022-02-17T21:46:30Z"
labels:
beta.kubernetes.io/arch: amd64
beta.kubernetes.io/os: linux
kubernetes.io/arch: amd64
kubernetes.io/hostname: kube-worker-1
kubernetes.io/os: linux
name: kube-worker-1
resourceVersion: "4026"
uid: 98efe7cb-2978-4a0b-842a-1a7bf12c05f8
spec: {}
status:
addresses:
- address: 192.168.0.113
type: InternalIP
- address: kube-worker-1
type: Hostname
allocatable:
cpu: "2"
ephemeral-storage: "14167048988"
hugepages-2Mi: "0"
memory: 1922788Ki
pods: "110"
capacity:
cpu: "2"
ephemeral-storage: 15372232Ki
hugepages-2Mi: "0"
memory: 2025188Ki
pods: "110"
conditions:
- lastHeartbeatTime: "2022-02-17T22:20:32Z"
lastTransitionTime: "2022-02-17T22:20:32Z"
message: Weave pod has set this
reason: WeaveIsUp
status: "False"
type: NetworkUnavailable
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:13:25Z"
message: kubelet has sufficient memory available
reason: KubeletHasSufficientMemory
status: "False"
type: MemoryPressure
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:13:25Z"
message: kubelet has no disk pressure
reason: KubeletHasNoDiskPressure
status: "False"
type: DiskPressure
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:13:25Z"
message: kubelet has sufficient PID available
reason: KubeletHasSufficientPID
status: "False"
type: PIDPressure
- lastHeartbeatTime: "2022-02-17T22:20:15Z"
lastTransitionTime: "2022-02-17T22:15:15Z"
message: kubelet is posting ready status
reason: KubeletReady
status: "True"
type: Ready
daemonEndpoints:
kubeletEndpoint:
Port: 10250
nodeInfo:
architecture: amd64
bootID: 22333234-7a6b-44d4-9ce1-67e31dc7e369
containerRuntimeVersion: containerd://1.5.9
kernelVersion: 5.13.0-28-generic
kubeProxyVersion: v1.23.3
kubeletVersion: v1.23.3
machineID: 9384e2927f544209b5d7b67474bbf92b
operatingSystem: linux
osImage: Ubuntu 21.10
systemUUID: aa829ca9-73d7-064d-9019-df07404ad448
로그 보기 (Looking at logs)
지금으로서는 클러스터를 더 깊이 파고들려면 관련 머신에 로그인해야 해요. 다음은 관련 로그 파일의 위치예요. systemd 기반 시스템에서는 로그 파일을 검사하는 대신 journalctl을 사용해야 할 수도 있어요.
컨트롤 플레인 노드
/var/log/kube-apiserver.log— API 서버. API 제공을 담당/var/log/kube-scheduler.log— 스케줄러. 스케줄링 결정을 담당/var/log/kube-controller-manager.log— 대부분의 Kubernetes 내장 컨트롤러를 실행하는 컴포넌트. 스케줄링(kube-scheduler가 담당)은 예외
워커 노드
/var/log/kubelet.log— kubelet 로그. 노드에서 컨테이너 실행을 담당/var/log/kube-proxy.log— kube-proxy 로그. Service 엔드포인트로 트래픽을 안내하는 데 담당
클러스터 실패 모드 (Cluster failure modes)
다음은 잘못될 수 있는 것과 클러스터 설정을 조정해 문제를 완화하는 방법의 불완전한 목록이에요.
기여 원인 (Contributing causes)
- VM 종료
- 클러스터 내부 또는 클러스터와 사용자 사이의 네트워크 분할(network partition)
- Kubernetes 소프트웨어의 크래시
- 영구 스토리지의 데이터 손실 또는 사용 불가 (예: GCE PD 또는 AWS EBS 볼륨)
- 운영자 오류 (예: 잘못 구성된 Kubernetes 소프트웨어나 애플리케이션 소프트웨어)
특정 시나리오 (Specific scenarios)
- API 서버 VM 종료 또는 apiserver 크래시 — 결과: 파드·서비스·복제 컨트롤러를 중지·업데이트·시작할 수 없음. 기존 파드와 서비스는 Kubernetes API에 의존하지 않는 한 정상적으로 계속 동작해야 함
- API 서버 백킹 스토리지 손실 — 결과: kube-apiserver 컴포넌트가 성공적으로 시작하여 건강해지지 못함. kubelet은 그것에 도달할 수 없게 되지만, 같은 파드를 계속 실행하고 같은 서비스 프록시를 제공함. apiserver가 재시작되기 전에 apiserver 상태의 수동 복구 또는 재생성이 필요함
- 지원 서비스(노드 컨트롤러, 복제 컨트롤러 매니저, 스케줄러 등)의 VM 종료 또는 크래시 — 현재 그들은 apiserver와 공동 배치되며, 그들의 사용 불가는 apiserver와 비슷한 결과를 가짐. 미래에는 이것들도 복제되고 공동 배치되지 않을 수 있음. 그들은 자체 영구 상태가 없음
- 개별 노드(VM 또는 물리 머신) 종료 — 결과: 그 노드의 파드가 실행을 멈춤
- 네트워크 분할 — 결과: 분할 A는 분할 B의 노드가 다운되었다고 생각하고, 분할 B는 apiserver가 다운되었다고 생각함 (마스터 VM이 분할 A에 있다고 가정)
- kubelet 소프트웨어 결함 — 결과: 크래시된 kubelet은 노드에서 새 파드를 시작할 수 없음. kubelet이 파드를 삭제할 수도 있고 안 할 수도 있음. 노드는 비정상으로 표시되고 복제 컨트롤러가 다른 곳에서 새 파드를 시작함
- 클러스터 운영자 오류 — 결과: 파드·서비스 등의 손실. apiserver 백킹 스토어 손실. 사용자가 API를 읽을 수 없게 됨 등
완화책 (Mitigations)
- 조치: IaaS VM에 IaaS 프로바이더의 자동 VM 재시작 기능 사용 — 완화: API 서버 VM 종료 또는 apiserver 크래시 / 지원 서비스 VM 종료 또는 크래시
- 조치: apiserver+etcd가 있는 VM에 IaaS 프로바이더의 신뢰할 수 있는 스토리지(예: GCE PD 또는 AWS EBS 볼륨) 사용 — 완화: API 서버 백킹 스토리지 손실
- 조치: 고가용성 구성 사용 — 완화: 컨트롤 플레인 노드 종료 또는 컨트롤 플레인 컴포넌트(스케줄러, API 서버, controller-manager) 크래시. 하나 이상의 동시 노드 또는 컴포넌트 실패를 허용함. 완화: API 서버 백킹 스토리지(즉 etcd의 데이터 디렉터리) 손실 — HA(고가용성) etcd 구성을 가정
- 조치: apiserver PD/EBS 볼륨을 주기적으로 스냅샷 — 완화: API 서버 백킹 스토리지 손실 / 운영자 오류의 일부 경우 / Kubernetes 소프트웨어 결함의 일부 경우
- 조치: 파드 앞에 복제 컨트롤러와 서비스 사용 — 완화: 노드 종료 / kubelet 소프트웨어 결함
- 조치: 예기치 않은 재시작을 허용하도록 설계된 애플리케이션(컨테이너) — 완화: 노드 종료 / kubelet 소프트웨어 결함
다음 단계
- 리소스 메트릭 파이프라인에서 사용 가능한 메트릭 배우기
- 리소스 사용량 모니터링을 위한 추가 도구 발견하기
- Node Problem Detector로 노드 상태 모니터링
- kubectl debug node로 Kubernetes 노드 디버깅
- crictl로 Kubernetes 노드 디버깅
- Kubernetes 감사에 대한 더 많은 정보 얻기
- telepresence로 로컬에서 서비스 개발·디버깅