Ethan Hur's blog

Kubernetes microserive rolling update issue

2019-03-18

Kubernetes Rolling Update 이슈

운영하고 있는 프로덕션의 서비스가 microservice 로 바뀜에 따라, public API 하나를 받을 때 k8s 클러스터 내부에서 http 통신을 하면서 여러 서비스를 오가는 시나리오가 생겼다.

그 와중에 무중단 배포를 통해 internal service 를 rolling update 하는 경우 internal service 들이 수십 ms 정도 error 를 내는 장애상황이 발생했다.

에러 상황

internal service 의 Pod 갯수를 36 -> 24 로 Scale Down 시도

문제 발생 시나리오

  1. Pod 들이 terminating 되기 시작함.
  2. HTTP Server Close, K8S 라우팅 테이블 제거가 동시에 시작됨 (in parallel)
  3. 라우팅이 제거되지 않은 상태에서, HTTP Server Close 가 먼저 되는 상태 존재 (수십 ms 예상)
  4. 해당 상태에서 Public API Server -> Internal Server 네트워크가 순간적으로 끊어짐
  5. Uncaught Exception 으로 처리되면서 API Error 가 남

해결책

bskim 에게 들은 힌트를 바탕으로 검색을 해보니, 비슷한 현상을 겪는 사람이 아래의 이슈를 올렸다.

https://github.com/kubernetes/kubernetes/issues/4357

따라서 해결할 수 있는 방안은 3개 정도 있다.

  1. internal service 에서 SIGTERM 이 오면 1000ms 정도 기다렸다가 HTTP Server Close 를 시작한다
  2. Pod 에 preStop hook 걸어서 1초 sleep 시킨다
  3. server to server 통신에서 retry logic 을 추가한다.

적용 및 교훈

1번 대안은 인프라 이슈로 인해 로직을 바꿔야 하는 상황이라고 판단하여 2번과 3번을 적용시켰고, 해당 이슈는 일단락 되었다.

이러한 장애 상황으로 인해 microservice 운영 시 주의해야 할 상황에 대해 익힐 수 있었던 것 같다.