5대 규모 클러스터에서는 control-plane HA를 하지 않았다
인터넷이 완전히 차단된 에어갭 환경, 왜 3노드 HA 대신 단일 control-plane + 셸 스크립트 롤링을 선택했는가.
문제: HA는 항상 옳은가
다른 프로젝트(위성 변화탐지 플랫폼 회고 - kube-vip 편)에서는 control-plane을 3노드로 이중화하고 kube-vip로 고정 진입점을 뒀다. 서비스가 9개로 늘고 관측 요구도 큰 환경이라 단일 장애점을 없애는 쪽이 명백히 맞았다.
그런데 다른 프로젝트에서는 정반대 선택을 했다. 인터넷이 완전히 차단된 에어갭 환경에, 서버 5대 규모 클러스터였다. control-plane은 단일 노드로 남겨뒀다.
같은 "control-plane 단일 장애점"인데 왜 한쪽은 HA로 없애고 다른 쪽은 그대로 뒀을까. HA가 공짜가 아니기 때문이다.
왜 이 환경에서는 HA 비용이 더 크게 느껴졌나
- 규모. 노드 5대짜리 클러스터에 control-plane만 3노드를 떼어주면, 워커로 쓸 수 있는 자원이 그만큼 줄어든다. 9개 서비스가 돌아가는 환경과 자원 비율 자체가 다르다.
- 배포 경로. ArgoCD 같은 GitOps 도구는 기본적으로 외부 Git/이미지 레지스트리 접근을 전제로 한다. 에어갭에서는 그 경로 자체가 없어서, 다른 프로젝트에서 표준으로 삼은 GitOps 배포를 이 환경에는 그대로 옮겨올 수 없었다.
- 장애 발생 시 대응 인력. 망분리 환경이라 원격 접근도 안 되고, 자동화 도구를 새로 반입하는 것도 절차가 무겁다. "자동 페일오버가 조용히 일어나는" 것보다 "무슨 일이 일어나는지 절차대로 확인할 수 있는" 쪽이 이 환경에서는 더 중요했다.
정리하면: control-plane HA가 주는 이득(단일 장애점 제거)은 두 환경에서 똑같지만, 그 이득을 얻는 비용(자원 점유, 배포 도구 제약, 반입 절차)은 이 환경에서 훨씬 크게 매겨졌다. 그래서 "이 규모·이 제약에서는 HA를 안 하는 게 맞다"는 판단으로 갔다.
다른 프로젝트 (서비스 9개, 일반 네트워크)
control-plane HA 이득 > 비용 → kube-vip 3노드 HA
이 프로젝트 (서버 5대, 에어갭)
control-plane HA 이득 < 비용 → 단일 노드 유지 + 대안 마련
대신 뭘로 메웠나
HA를 안 한다고 "장애가 나면 그냥 손 놓는다"는 뜻은 아니다. 두 가지로 그 자리를 메웠다.
노드별 순차 롤링 절차를 셸 스크립트로 표준화했다. 이미지 교체가 필요할 때 노드를 하나씩 cordon(스케줄링 제외) → drain(기존 파드를 다른 노드로 안전하게 이동) → 이미지 교체·재기동 → 정상 확인 → 다음 노드로 넘어가는 절차를 셸 스크립트로 고정했다. 사람이 매번 순서를 기억해서 하는 대신, 스크립트가 같은 순서를 강제한다.
노드1: cordon → drain → 이미지 교체·재기동 → 정상 확인
↓ (노드1 정상 확인 후에만 진행)
노드2: cordon → drain → 이미지 교체·재기동 → 정상 확인
↓
...노드5까지 반복
Zabbix로 하드웨어·서비스 관측을 붙였다. 이전에는 장애를 사용자 신고로 알았다. 즉 이미 서비스가 멈춘 뒤에야 인지하는 구조였다. Zabbix를 도입해 하드웨어(디스크·메모리·네트워크)와 서비스 상태를 직접 관측하게 하면서, 장애 인지 시점을 "사용자가 불편을 느낀 뒤"에서 "지표가 이상해진 시점"으로 앞당겼다. control-plane 자체를 이중화하지 않은 대신, 뭔가 잘못되고 있다는 걸 더 빨리 아는 쪽에 투자한 셈이다.
결과
5대 규모 클러스터를 이 방식으로 무중단 롤링 배포하며 운영했고, 별다른 서비스 영향 없이 이미지 교체를 반복할 수 있었다. control-plane 단일 장애점 자체는 이 환경에 남아있지만, 그게 "몰라서 안 한 것"과 "따져보고 안 한 것"은 다르다.
같은 회사, 같은 팀이 만든 두 클러스터가 같은 문제(control-plane SPOF)를 서로 다르게 풀었다는 게 이 글의 요점이다. 정답은 하나가 아니라, 규모·제약·비용을 따져서 그때그때 다시 판단해야 하는 문제였다.