본문으로 건너뛰기
김신건의 로그

[K8s] Ingress: L7 라우팅, TLS termination, Gateway API

· 수정 · 📖 약 2분 · 781자/단어 #kubernetes #ingress #gateway #network #k8s
Ingress, IngressController, nginx-ingress, Traefik Ingress, Gateway API, GatewayClass, HTTPRoute

정의

Ingress = 클러스터 외부 HTTP/HTTPS 트래픽 → 내부 Service 라우팅. L7 LB 역할. Service 의 LoadBalancer 다수 대안.

IMPORTANT

Ingress 오브젝트는 표준, 컨트롤러는 별도. nginx, Traefik, Envoy, AWS Load Balancer Controller 등 직접 설치 필요.

아키텍처

flowchart LR
    Internet --> ALB["ALB / nginx<br/>(IngressController)"]
    ALB -->|"Host: api.example.com<br/>Path: /v1/*"| Sv1[Service: api-v1]
    ALB -->|"Host: api.example.com<br/>Path: /v2/*"| Sv2[Service: api-v2]
    ALB -->|"Host: web.example.com"| Sv3[Service: web]
    Sv1 --> P1[Pods]
    Sv2 --> P2[Pods]
    Sv3 --> P3[Pods]

YAML 예시

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  tls:
    - hosts: [api.example.com]
      secretName: api-tls
  rules:
    - host: api.example.com
      http:
        paths:
          - path: /v1
            pathType: Prefix
            backend:
              service:
                name: api-v1
                port: { number: 80 }
          - path: /v2
            pathType: Prefix
            backend:
              service:
                name: api-v2
                port: { number: 80 }

Path Type

pathType동작
Exact정확 일치
Prefixprefix 일치 (/api matches /api/...)
ImplementationSpecific컨트롤러 정의

Ingress Controller 비교

Controller강점
ingress-nginx표준, 모든 기능, 무거움
Traefik자동 cert (Let’s Encrypt), 동적
Envoy / ContourL7 advanced, gRPC, service mesh 친화
AWS Load Balancer ControllerALB / NLB 직접
HAProxy Ingress매우 빠름
Istio Ingress Gatewayservice mesh 통합

TLS Termination

flowchart LR
    Client -->|HTTPS| Ingress
    Ingress -->|"HTTP (cluster-internal)"| Service
    Cert["cert-manager<br/>(Let's Encrypt ACME)"] -.자동 갱신.-> Ingress

cert-managerLet’s Encrypt 인증서 자동 발급 / 갱신. 거의 모든 클러스터 표준.

Rewrite / Redirect

rewrite-target 으로 업스트림에 전달되는 경로를 변환:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /api/v1(/|$)(.*)
            pathType: ImplementationSpecific
            backend:
              service: { name: api-v1, port: { number: 80 } }

/api/v1/users/users 로 upstream 전달. 캡처 그룹 $1, $2 사용.

영구 / 임시 리다이렉트:

annotations:
  nginx.ingress.kubernetes.io/permanent-redirect: "https://new.example.com"
  nginx.ingress.kubernetes.io/permanent-redirect-code: "301"
  # 임시 302: permanent-redirect 없이 app-root 사용
  nginx.ingress.kubernetes.io/app-root: "/app"

Rate Limiting

IP 기준 속도 제한:

annotations:
  nginx.ingress.kubernetes.io/limit-rps: "10"            # 초당 요청
  nginx.ingress.kubernetes.io/limit-rpm: "100"            # 분당 요청
  nginx.ingress.kubernetes.io/limit-connections: "20"    # 동시 연결
  nginx.ingress.kubernetes.io/limit-burst-multiplier: "5"
  nginx.ingress.kubernetes.io/limit-whitelist: "10.0.0.0/8"
어노테이션의미
limit-rps초당 허용 요청 (IP 기반)
limit-rpm분당 허용 요청
limit-connections동시 연결 수 제한
limit-burst-multiplier버스트 배수 (기본 5)

IMPORTANT

Rate limit 은 IngressController 파드 기준. 파드 3개면 실제 한도 = 3 × limit. 정밀한 제어는 API Gateway 레이어 (Kong, AWS API Gateway) 로.

Sticky Session / 세션 어피니티

stateful 앱 (파일 업로드 진행 상태, 세션 기반 인증 등) 에서 동일 파드로 고정:

annotations:
  nginx.ingress.kubernetes.io/affinity: "cookie"
  nginx.ingress.kubernetes.io/session-cookie-name: "INGRESSCOOKIE"
  nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
  nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
  nginx.ingress.kubernetes.io/session-cookie-path: "/"

WARNING

Sticky Session + HPA 조합: 신규 파드는 기존 쿠키가 없어 트래픽 불균등 발생. 가능하면 stateless + Redis 세션 공유 설계 권장.

Observability

ingress-nginx Prometheus 메트릭 (Helm values):

controller:
  metrics:
    enabled: true
    serviceMonitor:
      enabled: true   # kube-prometheus-stack ServiceMonitor CRD
메트릭의미
nginx_ingress_controller_requests요청 수 (status, ingress 별)
nginx_ingress_controller_request_duration_seconds레이턴시 분포
nginx_ingress_controller_connect_duration_secondsupstream 연결 시간
nginx_ingress_controller_ssl_expire_time_secondsTLS 인증서 만료 시각

Grafana 에서 rate(nginx_ingress_controller_requests[5m]) 로 per-ingress 처리량 실시간 모니터링.

Gateway API (Ingress 의 차세대)

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: prod-gateway
spec:
  gatewayClassName: nginx
  listeners:
    - name: https
      port: 443
      protocol: HTTPS
      tls:
        certificateRefs:
          - name: prod-tls
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: api
spec:
  parentRefs: [{ name: prod-gateway }]
  hostnames: [api.example.com]
  rules:
    - matches:
        - path: { type: PathPrefix, value: /v1 }
      backendRefs:
        - name: api-v1
          port: 80

Gateway API 리소스 계층

리소스관리 주체역할
GatewayClass인프라 팀구현체 선택 (nginx, envoy 등), ClusterScoped
Gateway플랫폼 팀포트 / 프로토콜 / TLS 정책
HTTPRoute앱 팀호스트 / 경로 / 헤더 기반 매칭, backendRef
GRPCRoute앱 팀gRPC method / service 매칭
TCPRoute플랫폼 팀L4 TCP 포워딩
TLSRoute플랫폼 팀TLS SNI 기반 라우팅

Ingress 와 달리 역할별 리소스 분리로 RBAC 제어가 세밀해짐. 각 팀이 독립적으로 배포 가능.

Ingress vs Gateway API

항목IngressGateway API
출시20152021+
표현력제한적 (annotation 의존)풍부 (HTTPRoute, TCPRoute, TLSRoute)
역할 분리단일GatewayClass / Gateway / Route 분리
트래픽 정책annotation정식 필드
상태stablebeta → GA (2026 대다수)

IMPORTANT

2026 시점 Gateway API 가 점점 표준. 신규 클러스터는 Gateway API 추천.

흔한 패턴: Canary

metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary: "true"
    nginx.ingress.kubernetes.io/canary-weight: "10"   # 10% 만 새 버전

또는 헤더 기반:

metadata:
  annotations:
    nginx.ingress.kubernetes.io/canary-by-header: "X-Canary"
    nginx.ingress.kubernetes.io/canary-by-header-value: "always"

흔한 함정

WARNING

  1. IngressClass 누락 = 다중 컨트롤러 환경에서 동작 안 함. spec.ingressClassName 명시.
  2. TLS secret namespace 다름 = Ingress 와 같은 namespace 의 secret 만 사용.
  3. cert-manager rate limit = Let’s Encrypt staging 으로 테스트 후 production.
  4. Ingress + WebSocket = nginx.ingress.kubernetes.io/proxy-read-timeout, proxy-send-timeout 늘려야 idle close 회피.

관련 위키

이 글의 용어 (5개)
[K8s] Service: ClusterIP / NodePort / LoadBalancer / ExternalNamekubernetes
정의 Service = Pod 집합에 안정 가상 IP + DNS 부여. Pod 가 죽고 다시 만들어져도 Service IP 는 그대로. 4가지 타입 1. ClusterIP (기본…
[Network] CORS: Same-Origin Policy, preflight, credentialsnetwork
정의 CORS (Cross-Origin Resource Sharing) 는 Same-Origin Policy (SOP) 의 완화 메커니즘. 브라우저가 origin 이 다른 리소스…
[Network] Load Balancer: L4 vs L7, 알고리즘, sticky sessionnetwork
정의 Load Balancer 는 트래픽을 여러 백엔드로 분산 하는 인프라. 수평 확장 + 가용성 + 무중단 배포 의 토대. L4 vs L7 | 구분 | L4 (Transport…
[Pattern] API Gateway: BFF, 라우팅, auth, rate limitdistributed-systems
정의 API Gateway = 클라이언트와 마이크로서비스 사이의 단일 진입점. 라우팅, auth, rate limit, transformation, monitoring 의 cro…
TLS / SSLnetwork
정의 TLS (Transport Layer Security) 는 (또는 위 ) 위에서 동작하는 암호화·인증 프로토콜이다. SSL 은 TLS 의 전신 (Netscape 1995, …

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기