다시 측정한 이유
2026년 3월 ingress-nginx의 지원이 끝났습니다. 가장 많이 쓰이던 Ingress 구현체가 사라지면서, 현장엔 한 가지 질문만 남습니다. “그럼 어떤 Gateway API 구현체로 옮겨야 하나?”
작년에 한 번 답을 내본 적이 있습니다. 7개 구현체를 17개 테스트로 100라운드 돌려 A/F 등급을 매겼지요. 그런데 그 채점 방식에 구조적인 허점이 있었습니다(지원하지 않는 기능이 감점으로 이어지지 않는 식으로요). 그 사이 구현체 버전과 Gateway API 표준도 올라갔고요. 그래서 이번에는 단순히 한 번 더 돌리는 대신, 채점 모델 자체를 공식 적합성(conformance) 체계로 갈아엎고 Gateway API v1.4 기준으로 처음부터 다시 만들었습니다. 결론도 꽤 바뀌었습니다. 작년에 점수가 낮았던 구현체들이 이번엔 사정이 달라졌거든요.
전체 수치와 재현 방법은 GitHub 저장소에 두었고, 이 글에서는 무엇을 어떻게 측정하기로 했는지, 어떤 발견이 흥미로웠는지를 풀어봅니다.
한눈에 보는 결과
7개 구현체(NGINX Gateway Fabric(이하 NGF), Envoy Gateway, Istio, Cilium, Kong, Traefik, kgateway)를 라이브 클러스터에서 다시 측정한 요약입니다.
먼저 “conformant"만 짚고 가겠습니다. Ingress 시절에는 구현체마다 동작이 제각각이라, 같은 설정도 다른 구현체로 옮기면 다르게 도는 일이 잦았습니다. Gateway API는 이 파편화를 막으려고, 구현체가 스펙을 제대로 구현했는지 검증하는 공식 적합성 테스트(conformance test) 를 운영합니다. 이 테스트의 필수 항목을 전부 통과한 상태가 Core conformant이고, 그러면 적어도 필수 기능에서는 어느 구현체로 옮겨도 같은 설정이 똑같이 동작한다는 뜻입니다.
- 7종 전부 Core conformant입니다. 필수 기능 7개를 모두 통과했고, 작년 PoC에서 점수가 낮았던 Kong과 Traefik도 포함됩니다.
- 갈리는 곳은 Extended 기능 폭입니다. 선택 기능 13개 중 지원 개수가 6개에서 13개까지 벌어집니다. conformant 인증은 같아도 실제로 쓸 수 있는 기능은 두 배 넘게 차이 납니다.
- rate-limit, 외부 인증, 본문 크기 제한 같은 구현체 고유 기능은 conformance 밖이라 등급에 넣지 않고 따로 비교했습니다. 여기서 구현체별 색깔이 가장 크게 드러납니다.
상세 표는 GitHub의 엄밀성 뷰와 출발점 뷰에 있습니다. 여기서부터는 왜 이런 결과가 나왔는지를 짚어보겠습니다.
작년과 가장 크게 바꾼 것: 단순 통과율에서 conformance 등급으로
작년에는 17개 테스트를 똑같은 무게로 두고 통과율(PASS / (PASS + FAIL), SKIP 제외)을 내서 A 아니면 F로 매겼습니다. 이 방식에는 구조적인 불공정이 세 가지 있었습니다.
- 미지원이 점수에 거의 반영되지 않았습니다. 통과율을 PASS와 FAIL로만 계산하고 SKIP은 빼다 보니, 기능을 지원하지 않아도 감점되는 대신 그냥 계산에서 빠졌습니다. 결국 기능이 적은 구현체가 오히려 유리했습니다.
- 필수 기능과 부가 기능을 같은 무게로 쟀습니다. 모두가 지원해야 하는 host 라우팅과, 표준에도 없는 rate-limiting을 똑같은 한 항목으로 셌습니다.
- 100%와 95%를 구분하지 못했습니다. A/F 이진 등급은 “거의 되는데 하나 빠진” 구현체와 “처음부터 안 되는” 구현체를 같은 등급으로 묶습니다.
그래서 이번에는 점수 체계를 새로 만들지 않고 Gateway API 공식 conformance 모델에 그대로 맞췄습니다. 17개를 하나의 통과율로 묶는 대신, 각 기능이 스펙에서 어디에 속하는지에 따라 나눴습니다.
- Core(7개): 모든 구현체가 지원해야 하는 필수 기능. 하나라도 빠지면 적합하지 않습니다.
- Extended(13개): 표준화된 선택 기능. 안 되는 것은 감점하지 않고, 지원하는 개수(기능 폭)로 구분합니다.
- 구현체 고유 기능과 비기능: 표준 밖이라 등급에 넣지 않고 별도 매트릭스로만 비교합니다.
등급은 임의로 정하지 않고 kubernetes-sigs/gateway-api v1.4.0 소스의 Support 표기로 확정했습니다. 그 결과 채점이 하나의 통과율이 아니라 세 축으로 갈립니다. Core를 전부 통과하는가(적합 여부), Extended를 몇 개 지원하는가(기능 폭), 구현체 고유 기능은 무엇을 갖췄는가(매트릭스). 작년의 A/F 한 글자보다 훨씬 많은 걸 보여줍니다.
측정 항목도 함께 손봤습니다. 채점 대상 Extended를 처음 5개에서 13개로 넓혔고, 두루뭉술하게 묶여 있던 SKIP도 “미지원 / 측정 미구성 / 인프라 문제” 세 가지로 구분했습니다.
같은 측정을 두 렌즈로 나눈 이유
같은 데이터를 두 가지 질문으로 나눠 봤습니다. 질문이 다르면 봐야 할 숫자도 다르기 때문입니다.
- 엄밀성 뷰는 “각 구현체가 스펙을 얼마나 충실히 구현했나"를 봅니다. 공식 Core/Extended 분류에 맞춰 실측하고, 여기에 conformance가 보지 않는 품질 지표(가중 라우팅 분포 수렴, 부하 성공률, 장애 복구)를 더했습니다.
- 출발점 뷰는 “ingress-nginx를 쓰던 내가 옮기면 뭐가 넘어가고 뭐가 막히나"를 봅니다. 어노테이션 단위로 난이도를 4등급(표준 / 주의 / 벤더 종속 / 불가)으로 나누고, ingress2gateway 변환 도구를 실제로 돌린 결과를 함께 적었습니다.
공식 conformance 리포트는 “누가 적합한가"만 알려줄 뿐, “내가 쓰던 인기 제품으로 옮겨도 괜찮은가"에는 답하지 않습니다. 후자가 바로 이 측정을 한 이유입니다.
흥미로운 발견들
작년에 F를 받았던 Kong과 Traefik이 통과한 이유
작년 PoC에서 점수가 낮았던 Kong과 Traefik이 이번에는 Core 7개를 모두 통과했고, 그때 제외했던 kgateway도 측정에 포함됐습니다. 한 가지 이유가 아니라 세 가지가 겹친 결과입니다.
- 생태계가 성숙했습니다. Gateway API v1.4에서 BackendTLSPolicy가 standard 채널로 승격되면서, Traefik의 backend-tls를 막던 CRD 버전 불일치(v1alpha3 vs v1)가 풀렸습니다. kgateway는 작년에 arm64 이미지가 없어 제외했는데, 이제 arm64를 지원해 포함했습니다.
- 현행 권장 경로로 측정했습니다. Kong을 작년의 KIC(unmanaged) 대신 KGO managed 경로로 설치했습니다. 지금 Kong을 Gateway API로 운영하는 표준 방식입니다.
- 측정을 정교화했습니다. Kong은 설정을 한 덩어리로 밀어 넣어, 못 받는 기능이 하나만 섞여도 전체가 거부되면서 기본 라우팅까지 죽었습니다. 하네스가 기능별로 라우트를 격리하자 Core가 살아났습니다. Traefik은 Gateway 리스너 포트와 내부 entrypoint 포트가 어긋나 Ready가 되지 못한 것이었고, 포트를 맞추자 정상 동작했습니다.
정리하면, Kong과 Traefik의 작년 실패는 제품의 근본 한계가 아니었습니다. 표준이 성숙하고, 설치 경로가 정리되고, 측정이 정교해지면서 사라진 문제였습니다.
conformant 인증을 받아도 기능 폭은 같지 않다
Gateway API 공식 권고는 “conformant 인증을 받은 구현체를 고르라"입니다. 그런데 인증을 받은 7종도 실제 지원하는 Extended 기능은 6개에서 13개까지 갈립니다. Envoy Gateway와 Istio는 13개를 모두 지원하고, Kong은 6개에 그칩니다.
즉 conformant는 합격선이지, 다 똑같다는 보증이 아닙니다. timeout, 응답 헤더 수정, 요청 미러링처럼 운영에서 자주 쓰는 기능이 구현체마다 되기도 하고 안 되기도 합니다. 인증 여부만 보고 고르면, 옮기고 나서 “이게 왜 안 되지"를 겪게 됩니다.
표준 외부 인증 필터는 아무도 강제하지 못한다
ingress-nginx에서 auth-url로 외부 인증을 붙여 쓰던 분들이 가장 궁금해할 부분입니다. Gateway API에는 외부 인증을 위한 표준 필터(GEP-1494)가 실험 단계로 들어와 있는데, 이 표준 필터를 제대로 강제하는 구현체가 하나도 없었습니다.
일부는 거부하거나 오류를 냈고, Cilium과 kgateway는 표준 필터를 아예 구현하지 않아 인증 없이 트래픽이 그대로 통과했습니다. GEP-1494가 아직 실패 동작(거부할지 통과시킬지)을 규정하지 않은 실험 단계이기 때문입니다. 결론은 분명합니다. 외부 인증은 아직 표준 필터로 옮길 수 없고, 각 구현체의 CRD에 의존해야 합니다.
변환은 되는데 동작은 안 하는 함정
ingress2gateway는 30개가 넘는 어노테이션을 자동 변환합니다. 그런데 변환되는 것과 실제로 동작하는 것은 다릅니다. CORS 어노테이션은 깔끔하게 변환되지만, 실측하면 7종 중 3종에서만 통과했습니다. 헤더를 추가하는 x-forwarded-prefix 같은 어노테이션은 변환 출력에서 경고 한 줄 없이 조용히 사라졌습니다.
그래서 출발점 뷰에서는 “변환됨"과 “동작함"을 일부러 다른 칸으로 나눴습니다. 변환 도구가 통과시켜도, 옮긴 뒤 실제로 도는지는 따로 확인해야 합니다.
마이그레이션에서 가장 막히는 것들
ingress-nginx에서 자주 쓰던 것 중 일부는 Gateway API로 그대로 옮기지 못합니다. 출발점 뷰에서 난이도를 4등급으로 나눴는데, 가장 까다로운 쪽만 추리면 이렇습니다.
- 설정 스니펫(
configuration-snippet,server-snippet)은 대체 수단이 없습니다. raw nginx 지시문을 직접 주입하는 기능인데, Gateway API는 그런 주입 통로를 아예 두지 않았습니다(IngressNightmare CVE도 바로 이 주입 방식에서 비롯됐습니다). 헤더 수정이나 타임아웃처럼 흔한 용례는 이미 표준 기능으로 흡수됐지만, 임의 지시문 주입에 기대고 있었다면 재설계가 필요합니다. - mTLS 클라이언트 인증(
auth-tls-*)은 v1.4에 표준 필드가 없습니다. v1.5에서 추가됐으니, 지금은 v1.5를 기다리거나 구현체 CRD에 기대야 합니다. - 세션 어피니티(쿠키 sticky)는 스펙은 있지만 쿠키 설정이 구현체마다 다릅니다. ingress2gateway도 이 어노테이션은 변환하지 못하고 거절합니다.
옮기기 전에 이 셋이 설정에 들어 있는지부터 확인하면, “변환은 됐는데 왜 안 되지"를 미리 피할 수 있습니다.
골랐다면, 장애 복구는 얼마나 빠른가
conformance가 보지 않는 운영 지표도 함께 쟀습니다. 기본 설치(데이터플레인 파드 1개) 기준으로 트래픽을 받는 프록시 파드를 강제 삭제하고, 2초 간격으로 요청을 보내며 트래픽이 돌아오기까지 걸린 시간을 쟀습니다. replica를 여럿 둔 HA 구성의 failover가 아니라, 파드 하나가 죽었을 때 얼마나 빨리 살아나는지를 본 측정입니다.
- Istio와 kgateway는 무중단이었습니다. 실패한 요청이 한 번도 없었습니다.
- NGF, Envoy Gateway, Traefik은 약 13초 만에 복구했습니다.
- Kong은 약 34초로 가장 느렸습니다.
- Cilium은 공유 eBPF 데이터플레인이라 이 측정에서 제외했습니다. 에이전트 재시작이 클러스터 전역에 영향을 주기 때문입니다.
파드를 지웠는데 어떻게 무중단일 수 있을까요? Kubernetes에서 파드는 삭제 명령을 받아도 곧바로 꺼지지 않습니다. 종료 신호를 받은 뒤 유예 시간 동안 살아 있고, 그 사이 Deployment가 새 파드를 띄웁니다. 이때 기존 파드가 받던 트래픽을 끝까지 처리하면서(graceful drain) 새 파드와 교대가 겹치면, 밖에서 보기엔 끊김이 없습니다. Istio와 kgateway는 이 교대가 깔끔했고, 13초나 34초가 걸린 쪽은 이 겹침 없이 새 파드가 뜰 때까지 빈 구간이 생긴 겁니다. 같은 실험을 세 번 반복해도 수치가 거의 같았습니다(Kong은 세 번 모두 34초).
운영에서는 replica를 여러 개 두는 게 기본이고, 그러면 어느 구현체든 파드 하나가 죽어도 나머지가 트래픽을 받아 사실상 끊기지 않습니다. 그래서 이 차이는 replica가 가려주지 못하는 곳에서 드러납니다. 단일 노드 엣지 클러스터처럼 replica를 늘리기 어려운 환경이라면 이 공백이 그대로 사용자에게 노출되고, replica를 여럿 둔 환경에서도 Kong의 34초는 롤링 업데이트나 노드 장애 뒤 가용량이 돌아오기까지 걸리는 시간으로 나타납니다.
그래서 어떤 구현체를 골라야 할까
7종 모두 Core는 통과했으니, 선택 기준은 기능 폭, 데이터플레인, 그리고 이미 쓰고 있는 생태계로 넘어갑니다.
| 상황 | 추천 | 이유 |
|---|---|---|
| 가장 넓은 기능 폭이 필요할 때 | Envoy Gateway, Istio | 표준 Extended를 전부 지원하고, 실험 채널 기능까지 가장 앞섬 |
| ingress-nginx에서 가장 매끄러운 이행 | NGF | F5의 공식 후속 경로, 운영 경험과 문서가 탄탄하다 |
| 이미 Cilium CNI를 쓰는 환경 | Cilium | eBPF 데이터플레인, CNI와 게이트웨이를 하나로 |
| 서비스 메시까지 함께 가는 환경 | Istio | 메시와 게이트웨이 통합, 자동 mTLS |
| 이미 Traefik을 쓰거나 간편한 운영을 원할 때 | Traefik | 자동 서비스 디스커버리와 대시보드, 손쉬운 설정 |
| Envoy 성능을 원하지만 풀 메시는 부담스러울 때 | kgateway | Gloo 계보의 Envoy 기반 게이트웨이, 전용 마이그레이션 가이드 |
| 엣지처럼 replica를 늘리기 어려운 환경 | Istio, kgateway | 파드가 죽고 다시 뜨는 동안에도 둘만 끊김이 없었다(나머지는 13~34초 공백) |
| API 게이트웨이 생태계가 중요할 때 | Kong | 플러그인 생태계가 강점, 단 표준 Extended는 가장 좁다 |
도입을 검토하신다면 한 가지만 기억해 주세요. 이 결과는 2026년 6월, Gateway API v1.4 기준의 스냅샷입니다. 구현체 버전은 빠르게 올라가고, 측정 이후 미지원이 해소된 항목도 일부 있습니다(엄밀성 뷰에 측정 버전과 함께 적어두었습니다). 참고하실 때는 지금 나와 있는 최신 버전에서도 그대로인지 한 번 확인해 주세요.
한 가지 더 있습니다. 구현체마다 받쳐주는 Gateway API 버전이 다릅니다. 컨트롤러가 지원하는 범위보다 CRD를 먼저 올리면, 새 리소스가 컨트롤러에 무시되거나 미검증 상태가 될 수 있습니다(직접 재현해 보니 옛 버전 컨트롤러가 지원 범위를 넘는 CRD를 건너뛰더군요). 2026년 중반 기준 대부분 v1.5까지 따라왔지만, 안정 릴리스 기준으로 어디까지 지원하는지는 제각각입니다. 올리기 전에 각 구현체 릴리스 노트의 Gateway API 지원 버전을 꼭 확인하세요. 우리가 v1.4로 잰 것도, 7종이 공통으로 안정 지원하는 버전이 v1.4였기 때문입니다.
마치며
이번 재측정에서 가장 또렷해진 교훈은 두 가지입니다. 하나는 conformant 인증은 출발선일 뿐이라는 것, 다른 하나는 표준과 생태계가 빠르게 발전한다는 것입니다. 작년 12월에 점수가 낮았던 구현체들이 반년 사이 전부 Core를 통과한 변화가, 순위표 한 줄보다 더 값진 발견이었습니다.
측정 하네스, 채점 기준(rubric), 구현체별 설치 스크립트, ingress2gateway 변환 증거는 모두 GitHub 저장소에 있습니다. 이 시점의 발행본은 gateway/v1.4 브랜치에 그대로 보존해 두었습니다.