궁금해서 control-plane을 일부러 죽여보면서 어떤 상태가 되는지 확인함.
목표는 장애 복구를 바로 실행하는 게 아니라, control-plane 장애가 났을 때 어떤 것들이 살아 있고 어떤 것들이 안 되는지 구분하는 것.
정상 기준선.
k8s-cp1, k8s-cp2, k8s-cp3 Ready
worker 3대 Ready
etcd 3대 Running
kube-apiserver 3대 Running
ArgoCD Application 전체 Synced / Healthy
control-plane 1대 장애.
k8s-cp1에서 kubelet과 containerd를 중지함.
결과.
k8s-cp1
= 약 90초 뒤 NotReady
k8s-cp2, k8s-cp3
= Ready
Kubernetes API
= 계속 응답
사용자 서비스
= 비정상 Pod 없음
CoreDNS
= cp1에 있던 Pod가 종료되고 다른 노드로 재배치
판단.
control-plane 1대 장애는 나머지 2대와 etcd quorum이 유지되면 API와 사용자 서비스가 유지될 수 있음.
control-plane 2대 장애.
처음에는 cp1, cp2에서 kubelet/containerd만 중지함.
결과.
cp1, cp2
= NotReady
Kubernetes API
= 계속 응답
외부 서비스
= 계속 응답
프로세스를 직접 보니 kubelet/containerd는 inactive였지만, 기존 static Pod 프로세스는 살아 있었음.
etcd
kube-apiserver
kube-controller-manager
kube-scheduler
판단.
Node가 NotReady라고 해서 control-plane 프로세스가 죽었다고 바로 단정하면 안 됨.
이후 cp1/cp2의 kube-apiserver와 etcd 프로세스까지 실제로 종료함.
결과.
cp1/cp2 apiserver/etcd
= 종료
cp3 apiserver/etcd
= 남아 있음
API VIP 6443 TCP
= 열려 있음
kubectl get nodes
= timeout 또는 Forbidden
kubectl get pods -A
= Forbidden
기존 사용자 서비스 일부
= 계속 응답
판단.
API VIP 포트가 열려 있거나 일부 HTTP 응답이 있어도 Kubernetes API를 정상 제어할 수 있는 상태라고 보면 안 됨.
사용자 서비스 생존 여부와 Kubernetes 제어 가능 여부는 따로 봐야 함.
control-plane 3대 장애.
control-plane 3대가 통신 불가 상태가 됨.
결과.
cp1 SSH
= timeout
cp2 SSH
= timeout
cp3 SSH
= timeout
API VIP 6443 TCP
= 열려 있음
kubectl
= 사용 불가
yeonghoon.kim
= timeout
grafana.yeonghoon.kim/login
= HTTP/2 200
판단.
control-plane 3대가 통신 불가이면 kubectl이나 ArgoCD로 조치할 수 없음.
이때는 Kubernetes 내부 조치가 아니라 VM, 전원, 네트워크, OS 복구가 먼저임.
복구 관찰.
cp1만 복구했을 때.
cp1 SSH
= 성공
cp1 kubelet/containerd
= active
API VIP 6443 TCP
= 열려 있음
kubectl get nodes
= timeout
일부 사용자 서비스
= 응답
판단.
control-plane 3대 장애 후 1대만 복구되어도 Kubernetes API 제어면은 정상 복구되지 않을 수 있음.
cp1 + cp2 복구 후.
kubectl get nodes
= 정상 조회 가능
cp1/cp2
= Ready
cp3
= 처음에는 Ready로 남아 있다가 약 5분 뒤 NotReady
ArgoCD
= monitoring만 일시적으로 Progressing
판단.
etcd 3대 구성에서 2대가 복구되면 quorum이 회복되어 Kubernetes API 제어가 다시 가능해짐.
cp3까지 최종 복구.
전체 Node
= 6대 모두 Ready
etcd
= 3대 모두 Running
kube-apiserver
= 3대 모두 Running
비정상 Pod
= 없음
ArgoCD
= 전체 Synced / Healthy
CoreDNS도 같이 관찰됨.
최초
= cp1, cp3
cp1 장애 후
= cp2, cp3
cp1+cp2 장애 후
= worker3, cp3
CoreDNS는 control-plane static Pod가 아니라 Deployment라서 다른 노드로 재배치될 수 있음.
원래 노드로 돌아간다고 기대하면 안 됨.
정리.
사용자 서비스 생존 여부와 Kubernetes 제어 가능 여부는 분리해서 판단한다.
control-plane Node가 NotReady라고 해서 control-plane 프로세스 사망으로 단정하지 않는다.
static Pod가 Running으로 보여도 마지막 관측값일 수 있다.
API VIP 포트가 열려 있어도 kubectl 제어 가능 여부를 따로 확인한다.
etcd 3대 구성에서는 2대 이상 살아 있어야 quorum이 유지된다.
control-plane 3대 장애 시에는 Kubernetes 내부 조치보다 VM, 전원, 네트워크, OS 복구가 우선이다.
control-plane HA는 단순히 3대를 띄웠다는 것만으로 끝나지 않음.
같은 장애 도메인에 몰려 있으면 3대여도 실제 HA로 보기 어렵다.