[트러블슈팅] 다른 노드에 POD 재생성

배경

어느날 워커노드로 SSH 접속이 안되어, 해당 노드의 점검이 필요한 상황.
노드가 물리적으로 멀리 떨어져있어 당장 점검이 불가능하므로, 우선 서빙중이던 포트폴리오 사이트의 pod를 다른 노드에서 구동시키기로 했다.

현재 간략한 아키텍처는 다음과 같다.

nginx와 harbor registry등 컨트롤플레인 노드의 모든 구성요소는 클러스터 외부에 위치한다.
클러스터 외부의 모니터링 시스템, harbor registry 등을 대상으로 트래픽을 포워딩해야 하므로,
nginx는 클러스터 외부에서 리버스 프록시 역할을 한다.

위 아키텍처에서 출발하여,
컨트롤플레인 노드에 기존 pod를 다시 띄운다.

과정

다음 절차를 수행하기로 한다.

  • 기존 pod 정리
  • 컨트롤플레인 노드의 Taint 제거
  • deployment 시작

기존 pod 정리

kubectl get pods -o wide 명령으로 확인해보니, 1/1 Terminating 상태에서 멈춰있었다.


죽어버린 워커노드 시체와는 대화가 불가능하므로, kube-api-server 입장에서는 pod가 제대로 정리되지 않은 상황이다.

deployment와 좀비 pod를 전부 제거한다.

deployment 제거

kubectl delete deploy porfolio-api

pod를 먼저 지워봤자 deployment 컨트롤러에 의해 좀비가 재생성되므로 deployment를 먼저 삭제한다.

좀비 pod 제거

kubectl delete pod <좀비pod 이름> --force --grace-period=0

force와 grace-period=0 옵션을 주어, 워커노드 kubelet과의 소통을 스킵하고 강제삭제한다.

워커노드 등록해제

kubectl delete node home52

추후 워커노드 점검이 모두 끝나면 다시 join 시키기로 하고, 지금은 제거한다.

Taint 제거

기존에는 컨트롤플레인 노드에 pod가 스케줄링되지 않도록 NoSchedule 테인트를 걸어두었다.


이제는 컨트롤플레인에 pod를 띄워야 하므로 테인트를 제거한다.

kubectl taint nodes home51 node-role.kubernetes.io/control-plane:NoSchedule-

deployment 다시 시작

kubectl apply -f deployment.yaml

이후 kubectl get pods 명령으로 pod들이 정상적으로 실행되었는지 확인한다.

nginx 프록시 설정

home52 노드로 보내던 proxy_pass 설정을 home51로 보내도록 수정한다.

회고

home52의 ingress controller 포트로 연결하던 nginx 설정에서 home52 -> home51만 교체했는데도 통신이 되었다.
쿠버네티스의 service, ingress, 내부통신 동작 방식 등에 대해 아직 잘 모르니, 아직 어떤 쿠버네티스 리소스가 어떻게 엮여 굴러가는지 그림이 안그려진다.

쿠버네티스를 더 정확하게 알고 쓰고 싶어서 당분간 쿠버네티스 기초를 제대로 공부하려한다.

현재 홈서버는 총 3대로, 한대는 소음이 심해 평소에 꺼두지만 Wake On Lan으로 언제든 가동할 수 있다.
이번처럼 워커노드가 죽는 경우를 대비해서, <노드 헬스체크 + 장애 감지 시 예비노드 가동 및 알림> 워크플로우를 구현해보면 재미있겠다.