gRPC

Google이 만든 원격 프로시저 호출(RPC) 프레임워크. HTTP/2 위에서 동작하고, Protocol Buffers로 데이터를 직렬화한다. REST보다 빠르고 스트리밍을 지원해서 마이크로서비스 간 통신이나 서버-클라이언트 장기 연결에 많이 쓰인다.

Kubernetes 컨트롤러들이 kube-apiserver와 통신할 때 내부적으로 gRPC를 사용한다.

연결 수명 관리

gRPC는 HTTP/2 연결을 장시간 유지하는 구조다. 그런데 연결을 무한정 유지하면 문제가 생긴다. 서버 입장에서 수천 개의 오래된 연결을 계속 들고 있으면 리소스가 낭비된다.

그래서 서버 측에서 연결 수명을 제한하는 설정이 있다.

MaxConnectionAge

서버가 하나의 연결을 유지할 수 있는 최대 시간. 이 시간이 지나면 서버는 클라이언트에게 GOAWAY 프레임을 보내고 연결을 종료한다.

서버 → 클라이언트: GOAWAY (연결 곧 닫힘)
클라이언트: 새 연결 수립

클라이언트(gRPC-Go 등)는 GOAWAY를 받으면 자동으로 새 연결을 만든다. 정상적인 동작이다.

문제가 생기는 순간

GOAWAY를 받고 새 연결을 수립하는 사이, 짧은 gap이 생긴다. 이 gap 동안 요청이 들어오면:

rpc error: code = Canceled desc = grpc: the client connection is closing

요청이 취소된다. 대부분의 경우 클라이언트가 자동으로 재시도하므로 문제가 없다. 하지만 재시도 전에 상태를 감시하는 시스템(ArgoCD 등)이 실패를 감지하면 알림이 발생할 수 있다.

관련 설정

설정설명
MaxConnectionAge연결 최대 수명. 초과 시 GOAWAY 전송
MaxConnectionAgeGraceGOAWAY 후 기존 요청 처리를 기다리는 유예 시간
KeepAliveTime연결이 idle 상태일 때 ping을 보내는 주기

EKS managed kube-apiserver는 이 설정을 외부에서 조회할 수 없다. AWS가 관리하는 컨트롤 플레인이기 때문이다.

참고