IT/기타

Ingress-NGINX vs Gateway API, 우리 팀은 뭘 선택했나

gfrog 2026. 8. 12. 03:22

Ingress-NGINX를 4년 넘게 써왔다. 그동안 별문제 없이 잘 굴러갔는데, 올해 초부터 팀 내부에서 Gateway API로 넘어가야 하는 것 아니냐는 이야기가 계속 나왔다. 근거는 나쁘지 않았다. Gateway API v1.5가 2026년 2월에 나오면서 상당수 기능이 Stable로 승격됐고, 6월에 v1.6까지 이어졌다. Ingress에 없던 표준 트래픽 분할, 리트라이 버짓, BackendTLSPolicy 같은 것들이 실제로 필요했다.

두 달 넘게 검토했고, 결론은 "전면 이관은 아니고, 신규 서비스부터 단계적으로"였다. 그 결정에 이르기까지 뭘 봤는지 정리해둔다.

뭐가 다른가

가장 큰 차이는 리소스 모델이다. Ingress는 하나의 오브젝트가 라우팅과 컨트롤러 설정을 다 짊어진다. 그래서 어노테이션이 폭발한다. nginx.ingress.kubernetes.io/rewrite-target, use-regex, configuration-snippet... 우리 클러스터 하나에 어노테이션 종류가 30개 넘게 흩어져 있었다. 서비스팀이 뭘 붙였는지 인프라팀이 다 파악 못 하는 상태였다.

Gateway API는 이걸 Gateway, HTTPRoute, BackendTLSPolicy, RetryPolicy 같은 여러 리소스로 쪼갠다. 인프라팀이 Gateway와 리스너를 관리하고, 서비스팀은 HTTPRoute만 만든다. 역할 분리가 자연스럽다. 우리 팀에서는 이게 제일 매력적으로 보였다.

두 번째 차이는 확장 방식이다. Ingress-NGINX에서 스냅샷을 넣어야 되는 요구사항이 오면 대부분 configuration-snippet 어노테이션으로 nginx conf를 직접 밀어넣었다. 이게 좋게 말하면 유연하고, 나쁘게 말하면 컨트롤러가 리스타트될 때마다 조마조마하다. Gateway API에서는 filter 체인이 표준으로 있고, 벤더 확장은 ExtensionRef로 명시적으로 붙인다.

그럼 왜 전면 이관은 안 했나

솔직히 이론은 다 좋은데, 실무는 다르다.

첫 번째 이유는 Ingress-NGINX가 이미 잘 돌아가고 있다는 것이다. P99 레이턴시가 문제된 적도 없고, 컨트롤러가 죽어서 장애 난 적도 지난 2년간 한 번도 없다. 팀 내부 논의에서 "안 아프면 만지지 말자"는 의견이 꽤 설득력 있었다.

두 번째는 컨트롤러 선택 문제다. Gateway API는 스펙일 뿐이고, 실제 구현체는 골라야 한다. Istio, Cilium, Envoy Gateway, NGINX Gateway Fabric... 각각 지원하는 확장 필드가 미묘하게 다르다. Istio의 EnvoyFilter에 익숙한 팀이면 Istio를 쓰면 되는데, 우리는 서비스 메시를 안 쓴다. 서비스 메시 없이 Gateway API를 도입한다는 건 사실상 새로운 컨트롤러를 하나 더 얹는다는 뜻이다. 운영 부담이 늘어난다.

세 번째는 어노테이션 이관 비용이다. 30개 넘는 어노테이션이 각각 Gateway API의 어떤 리소스나 필터로 매핑되는지 하나하나 매핑표를 만들어야 한다. 일부는 벤더 확장이 필요하고, 일부는 아예 매핑이 안 되는 것도 있다. 예를 들어 configuration-snippet으로 넣은 nginx custom lua 로직 같은 건 그냥 못 옮긴다. 다시 짜야 한다.

네 번째는 GitOps 툴과의 궁합이다. ArgoCD로 관리하는 앱이 200개가 넘는데, 각 앱의 Ingress 리소스가 HTTPRoute로 바뀌면 각 팀이 자기 Helm 차트를 다 고쳐야 한다. 이걸 인프라팀이 강제로 몰아붙일 순 없다.

결정한 방식

이런 상황에서 우리가 잡은 방향은 이렇다.

신규 서비스는 Gateway API로 시작한다. 컨트롤러는 Cilium Gateway로 골랐다. 우리가 이미 CNI로 Cilium을 쓰고 있어서 추가 컴포넌트가 없다. 이건 결정적이었다. 새 컨트롤러를 얹는 게 부담이었는데, 이미 있는 걸 확장하는 거면 이야기가 다르다.

기존 서비스는 이관하지 않는다. Ingress-NGINX에서 잘 돌면 그대로 둔다. 단, 신규 요구사항 중에 Ingress로 안 되는 것(예: 리트라이 버짓, 세밀한 트래픽 분할)이 있으면 그 서비스만 Gateway API로 옮긴다.

인프라팀이 Gateway 리소스를 관리하고, gateway-system 네임스페이스에 두 종류의 리스너(public, internal)를 만들어뒀다. 서비스팀은 자기 네임스페이스에서 HTTPRoute만 만들어서 parentRefs로 붙인다. ReferenceGrant로 크로스 네임스페이스 접근을 명시적으로 허용했다.

한 가지 문제는 관측이다. Ingress-NGINX의 프로메테우스 메트릭에 익숙해져 있어서 Gateway API 쪽 대시보드를 새로 만들어야 했다. Cilium이 제공하는 Hubble 메트릭으로 대체했는데, 라벨 카디널리티 관리에 신경 써야 한다. http_route, parent_gateway 라벨이 많아지면 프로메테우스 부하가 순식간에 튄다.

아직 애매한 것들

전면 이관을 언제 할지는 아직 정하지 못했다. Ingress-NGINX 프로젝트가 언젠가 유지보수 모드로 갈 가능성은 있지만, 지금은 아니다. 그날이 왔을 때 이관 부담이 얼마나 될지가 걱정이긴 하다. 그래서 최소한 신규 서비스 쪽에서라도 팀 내 Gateway API 경험을 쌓아두려는 목적도 있다.

또 하나 애매한 건 서비스 메시와의 관계다. 나중에 서비스 메시를 도입하면 Gateway API의 Gateway가 메시의 인그레스 게이트웨이와 어떻게 얽힐지, 아직 명확한 그림을 못 그렸다. 그 시점에 다시 검토할 예정이다.

결론이라기엔

Ingress vs Gateway API를 이분법으로 물으면 답은 "상황 따라 다르다"밖에 안 나온다. 우리 팀 상황에서는 이미 잘 돌아가는 걸 억지로 옮기는 비용이 새 기능 얻는 이득보다 컸다. 대신 신규 서비스에서 자연스럽게 학습하는 쪽을 택했다. 3년쯤 뒤에는 아마 Gateway API가 더 많아질 텐데, 그때 되면 다시 글 쓰겠다.

혹시 팀에서 전면 이관 결정 내리신 분들 있으면 어떤 근거로 갔는지 궁금하다.