Skip to content

Split View: Kubernetes Gateway API와 GRPCRoute 완벽 가이드: 서비스 메시부터 트래픽 라우팅까지

|

Kubernetes Gateway API와 GRPCRoute 완벽 가이드: 서비스 메시부터 트래픽 라우팅까지

Gateway API란?

Kubernetes Gateway API는 기존 Ingress 리소스의 한계를 넘어선 차세대 네트워킹 API입니다. 역할 기반의 리소스 모델(GatewayClass, Gateway, Route)을 통해 인프라 운영자와 애플리케이션 개발자의 관심사를 명확히 분리합니다.

왜 Gateway API인가?

기존 Ingress의 문제점:

  • 단일 리소스에 모든 설정이 집중
  • 구현체마다 다른 어노테이션
  • gRPC, TCP, UDP 등 HTTP 외 프로토콜 미지원
  • 역할 분리 불가

Gateway API는 이를 해결합니다:

# 1. 인프라팀이 관리하는 GatewayClass
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: istio
spec:
  controllerName: istio.io/gateway-controller
---
# 2. 플랫폼팀이 관리하는 Gateway
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: production-gateway
  namespace: infra
spec:
  gatewayClassName: istio
  listeners:
    - name: grpc
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: wildcard-cert
    - name: http
      protocol: HTTP
      port: 80

GRPCRoute 심층 분석

GRPCRoute는 Gateway API v1 (GA)에 포함된 gRPC 전용 라우팅 리소스입니다. HTTPRoute와 달리 gRPC의 서비스/메서드 기반 매칭을 네이티브로 지원합니다.

기본 구조

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: user-service-route
  namespace: app
spec:
  parentRefs:
    - name: production-gateway
      namespace: infra
      sectionName: grpc
  hostnames:
    - 'api.example.com'
  rules:
    - matches:
        - method:
            service: 'user.v1.UserService'
            method: 'GetUser'
      backendRefs:
        - name: user-service
          port: 50051
    - matches:
        - method:
            service: 'user.v1.UserService'
            method: 'CreateUser'
      backendRefs:
        - name: user-write-service
          port: 50051

헤더 기반 라우팅

특정 헤더 값에 따라 다른 백엔드로 라우팅할 수 있습니다:

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: ab-test-route
spec:
  parentRefs:
    - name: production-gateway
      namespace: infra
  rules:
    - matches:
        - method:
            service: 'recommendation.v1.RecommendationService'
          headers:
            - name: x-experiment-group
              value: 'treatment-a'
      backendRefs:
        - name: recommendation-v2
          port: 50051
    - matches:
        - method:
            service: 'recommendation.v1.RecommendationService'
      backendRefs:
        - name: recommendation-v1
          port: 50051

트래픽 스플리팅 (카나리 배포)

GRPCRoute의 backendRefs에 weight를 지정하면 트래픽을 비율로 분배할 수 있습니다:

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: canary-route
spec:
  parentRefs:
    - name: production-gateway
      namespace: infra
  rules:
    - matches:
        - method:
            service: 'order.v1.OrderService'
      backendRefs:
        - name: order-service-stable
          port: 50051
          weight: 90
        - name: order-service-canary
          port: 50051
          weight: 10

GAMMA: 서비스 메시 통합

GAMMA(Gateway API for Mesh Management and Administration)는 Gateway API를 서비스 메시로 확장하는 이니셔티브입니다.

GAMMA의 핵심: Service를 parentRef로

기존 Gateway API에서 Route의 parentRefs는 Gateway를 가리킵니다. GAMMA에서는 Service 자체를 parentRef로 지정하여 서비스 간 통신(East-West)을 제어합니다:

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: payment-mesh-route
spec:
  parentRefs:
    - group: ''
      kind: Service
      name: payment-service
      port: 50051
  rules:
    - matches:
        - method:
            service: 'payment.v1.PaymentService'
            method: 'ProcessPayment'
      filters:
        - type: RequestHeaderModifier
          requestHeaderModifier:
            add:
              - name: x-request-priority
                value: 'high'
      backendRefs:
        - name: payment-service
          port: 50051

Istio에서 GAMMA 활성화

# Istio 1.22+ 에서 GAMMA 지원
istioctl install --set profile=ambient

# Gateway API CRD 설치
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/experimental-install.yaml

실전 핸즈온: gRPC 마이크로서비스 라우팅

1단계: gRPC 서비스 배포

apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service-v1
  namespace: app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: user-service
      version: v1
  template:
    metadata:
      labels:
        app: user-service
        version: v1
    spec:
      containers:
        - name: user-service
          image: myregistry/user-service:v1.0
          ports:
            - containerPort: 50051
              name: grpc
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 256Mi
          livenessProbe:
            grpc:
              port: 50051
            initialDelaySeconds: 10
          readinessProbe:
            grpc:
              port: 50051
            initialDelaySeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: user-service
  namespace: app
spec:
  selector:
    app: user-service
  ports:
    - name: grpc
      port: 50051
      targetPort: 50051
      appProtocol: kubernetes.io/grpc

2단계: Gateway 설정

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: grpc-gateway
  namespace: infra
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  gatewayClassName: istio
  listeners:
    - name: grpc-tls
      protocol: HTTPS
      port: 443
      hostname: '*.api.example.com'
      tls:
        mode: Terminate
        certificateRefs:
          - name: api-tls-cert
      allowedRoutes:
        namespaces:
          from: Selector
          selector:
            matchLabels:
              gateway-access: 'true'
        kinds:
          - kind: GRPCRoute

3단계: GRPCRoute로 라우팅 규칙 정의

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: user-grpc-route
  namespace: app
spec:
  parentRefs:
    - name: grpc-gateway
      namespace: infra
      sectionName: grpc-tls
  hostnames:
    - 'user.api.example.com'
  rules:
    - matches:
        - method:
            service: 'user.v1.UserService'
            method: 'GetUser'
        - method:
            service: 'user.v1.UserService'
            method: 'ListUsers'
      backendRefs:
        - name: user-service-reader
          port: 50051
    - matches:
        - method:
            service: 'user.v1.UserService'
            method: 'CreateUser'
        - method:
            service: 'user.v1.UserService'
            method: 'UpdateUser'
        - method:
            service: 'user.v1.UserService'
            method: 'DeleteUser'
      backendRefs:
        - name: user-service-writer
          port: 50051

4단계: 테스트

# grpcurl로 테스트
grpcurl -d '{"user_id": "123"}' \
  -H "x-request-id: test-001" \
  user.api.example.com:443 \
  user.v1.UserService/GetUser

# 카나리 배포 확인 (여러 번 호출하여 비율 확인)
for i in $(seq 1 100); do
  grpcurl -d '{"user_id": "123"}' \
    user.api.example.com:443 \
    user.v1.UserService/GetUser 2>&1 | grep "server_version"
done | sort | uniq -c

ReferenceGrant: 크로스 네임스페이스 접근 제어

다른 네임스페이스의 백엔드를 참조하려면 ReferenceGrant가 필요합니다:

apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
  name: allow-app-to-backend
  namespace: backend
spec:
  from:
    - group: gateway.networking.k8s.io
      kind: GRPCRoute
      namespace: app
  to:
    - group: ''
      kind: Service

모니터링과 디버깅

Gateway API 상태 확인

# Gateway 상태 확인
kubectl get gateway -A
kubectl describe gateway grpc-gateway -n infra

# GRPCRoute 상태 확인
kubectl get grpcroute -A
kubectl describe grpcroute user-grpc-route -n app

# Istio 라우팅 규칙 확인
istioctl proxy-config route deploy/istio-ingressgateway -n istio-system -o json

Prometheus 메트릭

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: grpc-gateway-alerts
spec:
  groups:
    - name: grpc-gateway
      rules:
        - alert: GRPCHighErrorRate
          expr: |
            sum(rate(grpc_server_handled_total{grpc_code!="OK"}[5m])) by (grpc_service)
            /
            sum(rate(grpc_server_handled_total[5m])) by (grpc_service)
            > 0.05
          for: 5m
          labels:
            severity: warning

프로덕션 체크리스트

Gateway API를 프로덕션에 도입할 때 확인 사항:

  • GatewayClass 구현체 선택 (Istio, Envoy Gateway, Cilium 등)
  • TLS 인증서 자동화 (cert-manager 연동)
  • ReferenceGrant 정책 수립
  • 모니터링 (Gateway 상태, 라우팅 메트릭)
  • 레이트 리미팅 설정 (BackendTrafficPolicy)
  • 타임아웃 및 리트라이 정책
  • gRPC 헬스체크 설정
  • 점진적 마이그레이션 계획

📝 확인 퀴즈 (5문제)

Q1. Gateway API에서 역할 분리를 위한 세 가지 핵심 리소스는?

GatewayClass, Gateway, Route (HTTPRoute/GRPCRoute 등)

Q2. GAMMA 이니셔티브에서 GRPCRoute의 parentRefs가 가리키는 것은?

Gateway 대신 Service 자체를 parentRef로 지정하여 East-West(서비스 간) 트래픽을 제어합니다.

Q3. GRPCRoute에서 카나리 배포를 구현하려면 어떤 필드를 사용하나요?

backendRefs의 weight 필드를 사용하여 트래픽 비율을 분배합니다.

Q4. 다른 네임스페이스의 Service를 backendRef로 참조하려면 어떤 리소스가 필요한가요?

ReferenceGrant 리소스가 대상 네임스페이스에 생성되어야 합니다.

Q5. GRPCRoute에서 특정 gRPC 메서드를 매칭하려면 어떤 필드를 사용하나요?

rules.matches.method 필드에 service와 method를 지정합니다.

Kubernetes Gateway API and GRPCRoute Complete Guide: From Service Mesh to Traffic Routing

What Is Gateway API?

Kubernetes Gateway API is the next-generation networking API that goes beyond the limitations of the traditional Ingress resource. Through a role-based resource model (GatewayClass, Gateway, Route), it clearly separates the concerns of infrastructure operators and application developers.

Why Gateway API?

Problems with traditional Ingress:

  • All configuration concentrated in a single resource
  • Different annotations per implementation
  • No support for non-HTTP protocols like gRPC, TCP, UDP
  • No role separation

Gateway API addresses these issues:

# 1. GatewayClass managed by the infrastructure team
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: istio
spec:
  controllerName: istio.io/gateway-controller
---
# 2. Gateway managed by the platform team
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: production-gateway
  namespace: infra
spec:
  gatewayClassName: istio
  listeners:
    - name: grpc
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: wildcard-cert
    - name: http
      protocol: HTTP
      port: 80

GRPCRoute Deep Dive

GRPCRoute is a gRPC-specific routing resource included in Gateway API v1 (GA). Unlike HTTPRoute, it natively supports gRPC service/method-based matching.

Basic Structure

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: user-service-route
  namespace: app
spec:
  parentRefs:
    - name: production-gateway
      namespace: infra
      sectionName: grpc
  hostnames:
    - 'api.example.com'
  rules:
    - matches:
        - method:
            service: 'user.v1.UserService'
            method: 'GetUser'
      backendRefs:
        - name: user-service
          port: 50051
    - matches:
        - method:
            service: 'user.v1.UserService'
            method: 'CreateUser'
      backendRefs:
        - name: user-write-service
          port: 50051

Header-Based Routing

You can route to different backends based on specific header values:

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: ab-test-route
spec:
  parentRefs:
    - name: production-gateway
      namespace: infra
  rules:
    - matches:
        - method:
            service: 'recommendation.v1.RecommendationService'
          headers:
            - name: x-experiment-group
              value: 'treatment-a'
      backendRefs:
        - name: recommendation-v2
          port: 50051
    - matches:
        - method:
            service: 'recommendation.v1.RecommendationService'
      backendRefs:
        - name: recommendation-v1
          port: 50051

Traffic Splitting (Canary Deployment)

By specifying weights in GRPCRoute's backendRefs, you can distribute traffic by ratio:

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: canary-route
spec:
  parentRefs:
    - name: production-gateway
      namespace: infra
  rules:
    - matches:
        - method:
            service: 'order.v1.OrderService'
      backendRefs:
        - name: order-service-stable
          port: 50051
          weight: 90
        - name: order-service-canary
          port: 50051
          weight: 10

GAMMA: Service Mesh Integration

GAMMA (Gateway API for Mesh Management and Administration) is an initiative to extend Gateway API into the service mesh domain.

The Core of GAMMA: Service as parentRef

In traditional Gateway API, the Route's parentRefs point to a Gateway. In GAMMA, the Service itself is specified as parentRef to control inter-service communication (East-West traffic):

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: payment-mesh-route
spec:
  parentRefs:
    - group: ''
      kind: Service
      name: payment-service
      port: 50051
  rules:
    - matches:
        - method:
            service: 'payment.v1.PaymentService'
            method: 'ProcessPayment'
      filters:
        - type: RequestHeaderModifier
          requestHeaderModifier:
            add:
              - name: x-request-priority
                value: 'high'
      backendRefs:
        - name: payment-service
          port: 50051

Enabling GAMMA in Istio

# GAMMA support in Istio 1.22+
istioctl install --set profile=ambient

# Install Gateway API CRDs
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.0/experimental-install.yaml

Hands-On: gRPC Microservice Routing

Step 1: Deploy gRPC Services

apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service-v1
  namespace: app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: user-service
      version: v1
  template:
    metadata:
      labels:
        app: user-service
        version: v1
    spec:
      containers:
        - name: user-service
          image: myregistry/user-service:v1.0
          ports:
            - containerPort: 50051
              name: grpc
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 256Mi
          livenessProbe:
            grpc:
              port: 50051
            initialDelaySeconds: 10
          readinessProbe:
            grpc:
              port: 50051
            initialDelaySeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: user-service
  namespace: app
spec:
  selector:
    app: user-service
  ports:
    - name: grpc
      port: 50051
      targetPort: 50051
      appProtocol: kubernetes.io/grpc

Step 2: Configure the Gateway

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: grpc-gateway
  namespace: infra
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  gatewayClassName: istio
  listeners:
    - name: grpc-tls
      protocol: HTTPS
      port: 443
      hostname: '*.api.example.com'
      tls:
        mode: Terminate
        certificateRefs:
          - name: api-tls-cert
      allowedRoutes:
        namespaces:
          from: Selector
          selector:
            matchLabels:
              gateway-access: 'true'
        kinds:
          - kind: GRPCRoute

Step 3: Define Routing Rules with GRPCRoute

apiVersion: gateway.networking.k8s.io/v1
kind: GRPCRoute
metadata:
  name: user-grpc-route
  namespace: app
spec:
  parentRefs:
    - name: grpc-gateway
      namespace: infra
      sectionName: grpc-tls
  hostnames:
    - 'user.api.example.com'
  rules:
    - matches:
        - method:
            service: 'user.v1.UserService'
            method: 'GetUser'
        - method:
            service: 'user.v1.UserService'
            method: 'ListUsers'
      backendRefs:
        - name: user-service-reader
          port: 50051
    - matches:
        - method:
            service: 'user.v1.UserService'
            method: 'CreateUser'
        - method:
            service: 'user.v1.UserService'
            method: 'UpdateUser'
        - method:
            service: 'user.v1.UserService'
            method: 'DeleteUser'
      backendRefs:
        - name: user-service-writer
          port: 50051

Step 4: Testing

# Test with grpcurl
grpcurl -d '{"user_id": "123"}' \
  -H "x-request-id: test-001" \
  user.api.example.com:443 \
  user.v1.UserService/GetUser

# Verify canary deployment (call multiple times to check ratios)
for i in $(seq 1 100); do
  grpcurl -d '{"user_id": "123"}' \
    user.api.example.com:443 \
    user.v1.UserService/GetUser 2>&1 | grep "server_version"
done | sort | uniq -c

ReferenceGrant: Cross-Namespace Access Control

A ReferenceGrant is required to reference backends in other namespaces:

apiVersion: gateway.networking.k8s.io/v1beta1
kind: ReferenceGrant
metadata:
  name: allow-app-to-backend
  namespace: backend
spec:
  from:
    - group: gateway.networking.k8s.io
      kind: GRPCRoute
      namespace: app
  to:
    - group: ''
      kind: Service

Monitoring and Debugging

Checking Gateway API Status

# Check Gateway status
kubectl get gateway -A
kubectl describe gateway grpc-gateway -n infra

# Check GRPCRoute status
kubectl get grpcroute -A
kubectl describe grpcroute user-grpc-route -n app

# Check Istio routing rules
istioctl proxy-config route deploy/istio-ingressgateway -n istio-system -o json

Prometheus Metrics

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: grpc-gateway-alerts
spec:
  groups:
    - name: grpc-gateway
      rules:
        - alert: GRPCHighErrorRate
          expr: |
            sum(rate(grpc_server_handled_total{grpc_code!="OK"}[5m])) by (grpc_service)
            /
            sum(rate(grpc_server_handled_total[5m])) by (grpc_service)
            > 0.05
          for: 5m
          labels:
            severity: warning

Production Checklist

Items to verify when adopting Gateway API in production:

  • Choose a GatewayClass implementation (Istio, Envoy Gateway, Cilium, etc.)
  • Automate TLS certificates (cert-manager integration)
  • Establish ReferenceGrant policies
  • Set up monitoring (Gateway status, routing metrics)
  • Configure rate limiting (BackendTrafficPolicy)
  • Define timeout and retry policies
  • Configure gRPC health checks
  • Plan a gradual migration

Review Quiz (5 Questions)

Q1. What are the three core resources for role separation in Gateway API?

GatewayClass, Gateway, Route (HTTPRoute/GRPCRoute, etc.)

Q2. What does the GRPCRoute's parentRefs point to in the GAMMA initiative?

Instead of a Gateway, the Service itself is specified as parentRef to control East-West (inter-service) traffic.

Q3. Which field is used to implement canary deployments in GRPCRoute?

The weight field in backendRefs is used to distribute traffic by ratio.

Q4. What resource is needed to reference a Service in another namespace as a backendRef?

A ReferenceGrant resource must be created in the target namespace.

Q5. Which field is used to match specific gRPC methods in GRPCRoute?

The rules.matches.method field, where you specify service and method.

Quiz

Q1: What is the main topic covered in "Kubernetes Gateway API and GRPCRoute Complete Guide: From Service Mesh to Traffic Routing"?

Hands-on practice with gRPC traffic routing using Kubernetes Gateway API GRPCRoute. Covers service mesh integration through the GAMMA initiative, header-based routing, and traffic splitting.

Q2: What Is Gateway API?? Kubernetes Gateway API is the next-generation networking API that goes beyond the limitations of the traditional Ingress resource.

Q3: Explain the core concept of GRPCRoute Deep Dive. GRPCRoute is a gRPC-specific routing resource included in Gateway API v1 (GA). Unlike HTTPRoute, it natively supports gRPC service/method-based matching. Basic Structure Header-Based Routing You can route to different backends based on specific header values:

Q4: What are the key aspects of Traffic Splitting (Canary Deployment)? By specifying weights in GRPCRoute's backendRefs, you can distribute traffic by ratio:

Q5: How does GAMMA: Service Mesh Integration work? GAMMA (Gateway API for Mesh Management and Administration) is an initiative to extend Gateway API into the service mesh domain. The Core of GAMMA: Service as parentRef In traditional Gateway API, the Route's parentRefs point to a Gateway.