Zone별 가용성을 위한 예약 설정과 운영 기록¶
GKE 클러스터를 운영하다가 특정 존의 노드 재고 부족으로 StatefulSet들이 재배포되지 못하는 일을 겪었다. 예약(Reservation)을 도입해서 해결한 과정과, 그 과정에서 새로 만난 노드풀 업그레이드 문제까지 기록해둔다.
현재 상황¶
- 스탠다드 모드 클러스터, 유지보수 기간은 토–일 6시간씩
- 수직형 Pod 자동 확장(VPA) 및 노드 자동 프로비저닝(NAP)은 사용 안 함
- 노드 자동 업그레이드가 되도록 설정되어 있음
문제 1. 존 재고 부족으로 노드가 사라짐¶
us-west1의 c존에서 n4-standard-2 노드가 일시적으로 부족한 상황이 발생했다.
하필 자동 업그레이드로 노드를 교체하는 와중에 재고 부족이 겹치면서 c존 노드가 사라졌고, Grafana 및 PVC를 사용하는 StatefulSet 파드들(loki-backend, tempo-ingester, loki-write, prometheus-kube-prometheus-stack-prometheus)이 재배포가 이뤄지지 않고 있었다.
PVC는 존에 종속되기 때문에, 해당 존에 노드가 없으면 그 존의 디스크를 사용하던 파드들은 다른 존으로 옮겨갈 수 없이 Pending 상태로 남게 된다.
해결 1. 예약(Reservation) 사용¶
노드가 사용할 용량을 미리 확보해두기 위해 예약(Reservation)을 사용하도록 변경했다.
이때 주의할 점은, 예약은 GKE뿐만 아니라 같은 프로젝트의 다른 서비스(VM 등)에도 뺏길 수 있다는 것이다. 기본 설정(열린 예약)에서는 머신 스펙이 일치하는 아무 VM이나 예약 용량을 소비할 수 있다. 지금은 GCP 에서 GKE만 운영하지만, 혹시 다른 서비스가 생기고 그 서비스를 위한 인스턴스가 예약 인스턴스를 선점해버리면 다시 같은 문제가 생겨버린다.. 이를 막기 위해 다음과 같이 구성했다.
- 예약 생성 시 "VM 인스턴스와 함께 사용" 옵션을 "특정 예약 선택"으로 설정하고,
- 예약만 사용하는 노드풀을 따로 만들어, 1)에서 만든 예약만을 지정해서 사용하도록 했다.
이렇게 하면 해당 예약은 이 노드풀 전용이 되어, 다른 워크로드가 용량을 가져갈 수 없다.
현재는 PRD기준 클러스터의 총 노드 수가 8개이고 3개의 zone을 사용 중이기 때문에, 단순하게 존당 1개씩 예약을 만들었다.
문제 2. reserved 노드풀이 유지보수 때 업그레이드 안 됨¶
예약으로 가용성 문제는 해결했는데, 이번에는 예약을 사용하는 노드풀이 유지보수 기간에 자동 업그레이드되지 않는 문제가 생겼다.
해결 2. max_surge=0으로 변경¶
원인을 확인해보니 각 존별로 총 용량(예약 용량)과 현재 사용량이 정확히 일치해서, 업그레이드 시 서지 노드를 추가로 띄우는 max_surge=1을 진행할 수 없어 업그레이드가 멈춰 있던 것이었다(이는 기존 노드풀 설정을 그대로 가져온 것이다). 예약 밖의 용량은 쓸 수 없으니, 기존 노드를 유지한 채 새 노드를 하나 더 띄우는 서지 방식 자체가 불가능한 상황이다.
- 기존: max_surge=1 / max_unavailable=1
- 이후: max_surge=0 (max_unavailable=1)
max_surge=0으로 변경하면 새 노드를 먼저 띄우는 대신 기존 노드를 하나씩 내리고 그 자리에 새 노드를 올리는 방식으로 동작하므로, 예약된 용량 안에서 업그레이드가 진행된다. 업그레이드 중 일시적으로 노드가 하나 줄어드는 트레이드오프는 있지만, 존당 예약을 꽉 채워 쓰는 구성에서는 이 방법이 맞다고 판단했다.
정리¶
- 존 단위 재고 부족은 실제로 발생하며, PVC를 사용하는 StatefulSet은 존에 묶여 있어 특히 취약하다.
- 예약으로 용량을 확보할 때는 "특정 예약 선택" + 전용 노드풀 조합으로 다른 서비스에 용량을 뺏기지 않도록 해야 한다.
- 예약 용량을 꽉 채워 쓰는 노드풀은 서지 업그레이드가 불가능하므로, max_surge=0으로 설정해야 자동 업그레이드가 정상 동작한다.