Kubernetes Rolling Update 이슈
운영하고 있는 프로덕션의 서비스가 microservice 로 바뀜에 따라, public API 하나를 받을 때 k8s 클러스터 내부에서 http 통신을 하면서 여러 서비스를 오가는 시나리오가 생겼다.
그 와중에 무중단 배포를 통해 internal service 를 rolling update 하는 경우 internal service 들이 수십 ms 정도 error 를 내는 장애상황이 발생했다.
에러 상황
internal service 의 Pod 갯수를 36 -> 24 로 Scale Down 시도
문제 발생 시나리오
- Pod 들이 terminating 되기 시작함.
- HTTP Server Close, K8S 라우팅 테이블 제거가 동시에 시작됨 (in parallel)
- 라우팅이 제거되지 않은 상태에서, HTTP Server Close 가 먼저 되는 상태 존재 (수십 ms 예상)
- 해당 상태에서 Public API Server -> Internal Server 네트워크가 순간적으로 끊어짐
- Uncaught Exception 으로 처리되면서 API Error 가 남
해결책
bskim 에게 들은 힌트를 바탕으로 검색을 해보니, 비슷한 현상을 겪는 사람이 아래의 이슈를 올렸다.
https://github.com/kubernetes/kubernetes/issues/4357
따라서 해결할 수 있는 방안은 3개 정도 있다.
- internal service 에서 SIGTERM 이 오면 1000ms 정도 기다렸다가 HTTP Server Close 를 시작한다
- Pod 에 preStop hook 걸어서 1초 sleep 시킨다
- server to server 통신에서 retry logic 을 추가한다.
적용 및 교훈
1번 대안은 인프라 이슈로 인해 로직을 바꿔야 하는 상황이라고 판단하여 2번과 3번을 적용시켰고, 해당 이슈는 일단락 되었다.
이러한 장애 상황으로 인해 microservice 운영 시 주의해야 할 상황에 대해 익힐 수 있었던 것 같다.