kubernetes 에서 배포할때 5xx 에러 해결하기

Updated on

kubernetes 에서 배포할때 롤링으로 배포하면서 중간에 502, 503에러가 발생하는 경우가 있다.

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

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

https://github.com/foriequal0/pod-graceful-drain

이 문제에 대한 이슈와 그걸 해결하려고 만든 pod-graceful-drain 이 있다.

물론 나는 sleep 을 사용해서 처리하기는 한다.

설명하자면 파드가 새로 배포되면서 기존의 파드는 터미네이팅이 되는데, 터미네이팅이 되더라도 터미네이팅 되고 있는 파드에 요청이 계속 들어온다.

이때 터미네이팅 상태였을때 요청이 들어오더라도 중간에 파드가 종료되면 안된다. 그래서 nginx 와 php-fpm 에 sleep을 주는 이유이다.

즉 php-fpm 이 먼저 끊어져버리면 nginx 는 stream 에러를 반환하게 된다. 그러니, php-fpm 은 항상 nginx 보다 늦게 종료가 되야한다.

근데 이러나 저러나 php-fpm 이랑 nginx 가 언제 종료되도 크게 상관은 없긴한데.

중요한건 AWS 네트워크에서 ALB, LB에서 연결이 빠지는 최소 시간 만큼은 꼭 sleep을 해줘야 하는 것이다.

그 시간이 약 15초가 걸린다.

즉, 15초 동안 터미네이팅이 되더라도 요청이 들어올 수 있다는 뜻이다.

그래서 최소 sleep을 15초 이상을 줘야만한다. (nginx, php-fpm)

그리고 이후의 sleep 을 추가로 주는 것은 서버 환경에 따라 다를 것 같다.

예를 들어 요청에 10초가 걸리는 요청이 있다면

15(네트워크) + 5(여유) + 10(최대 요청시간) = 30초를 주면 될 것이다.

그리고 terminationGracePeriodSeconds 값은 항상 sleep 보다 더 커야만 한다.

sleep이 30이라면, terminationGracePeriodSeconds 는 40정도를 주면 된다.

          lifecycle:
            preStop:
              exec:
                command:
                  - /bin/sh
                  - -c
                  - sleep 20
			terminationGracePeriodSeconds: 30

그래서 보통 이렇게 설정해주면 된다.

요약 정리

  1. 최소 sleep은 15초 이상
  2. terminationGracePeriodSeconds > sleep
  3. 터미네이팅이 되는 시점에도 요청이 들어오므로, 요청이 끝날때까지 파드들의 비정상 종료 방지가 목적