🔧 DevOps

Envoy

Envoy Proxy

클라우드 네이티브 프록시. Istio의 데이터 플레인.

상세 설명

Envoy는 Lyft에서 개발한 고성능 L7(애플리케이션 레이어) 프록시로, 현재 CNCF 졸업 프로젝트입니다. 마이크로서비스 아키텍처에서 서비스 간 통신을 처리하며, Istio, AWS App Mesh 등 서비스 메시의 데이터 플레인으로 광범위하게 사용됩니다.

핵심 특징

  • L7 프록시: HTTP/2, gRPC, WebSocket 등 애플리케이션 프로토콜 지원
  • 동적 설정: xDS API를 통한 런타임 설정 변경 (재시작 불필요)
  • 관측 가능성: 상세한 메트릭, 분산 트레이싱, 구조화된 로깅
  • 로드 밸런싱: Round Robin, Least Connections, Ring Hash 등
  • 서킷 브레이커: 장애 서비스 격리로 연쇄 실패 방지
  • TLS 종료/시작: 양방향 TLS(mTLS) 지원

Envoy 아키텍처

  • Listener: 다운스트림 연결을 수신하는 엔드포인트
  • Filter Chain: 요청/응답 처리 파이프라인
  • Cluster: 업스트림 서비스 그룹
  • Route: 요청을 적절한 클러스터로 매핑

코드 예제

envoy.yaml - 기본 프록시 설정

# envoy.yaml - HTTP 리버스 프록시 설정
static_resources:
  listeners:
    - name: listener_0
      address:
        socket_address:
          address: 0.0.0.0
          port_value: 8080
      filter_chains:
        - filters:
            - name: envoy.filters.network.http_connection_manager
              typed_config:
                "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                stat_prefix: ingress_http
                codec_type: AUTO
                route_config:
                  name: local_route
                  virtual_hosts:
                    - name: backend
                      domains: ["*"]
                      routes:
                        # API 라우트
                        - match:
                            prefix: "/api/"
                          route:
                            cluster: api_service
                            timeout: 30s
                        # 정적 파일
                        - match:
                            prefix: "/"
                          route:
                            cluster: frontend_service
                http_filters:
                  - name: envoy.filters.http.router
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

  clusters:
    - name: api_service
      connect_timeout: 5s
      type: STRICT_DNS
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: api_service
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: api-server
                      port_value: 3000
      # 헬스체크
      health_checks:
        - timeout: 3s
          interval: 10s
          unhealthy_threshold: 3
          healthy_threshold: 2
          http_health_check:
            path: /health
      # 서킷 브레이커
      circuit_breakers:
        thresholds:
          - priority: DEFAULT
            max_connections: 1000
            max_pending_requests: 1000
            max_requests: 1000
            max_retries: 3

    - name: frontend_service
      connect_timeout: 5s
      type: STRICT_DNS
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: frontend_service
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: frontend
                      port_value: 80

admin:
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 9901

Rate Limiting 설정

# Rate limit 필터 설정
http_filters:
  - name: envoy.filters.http.ratelimit
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
      domain: my_domain
      stage: 0
      rate_limit_service:
        grpc_service:
          envoy_grpc:
            cluster_name: ratelimit_service
        transport_api_version: V3
  - name: envoy.filters.http.router

# Route level rate limit
routes:
  - match:
      prefix: "/api/"
    route:
      cluster: api_service
      rate_limits:
        - actions:
            - request_headers:
                header_name: "x-api-key"
                descriptor_key: "api_key"

mTLS 설정

# TLS 리스너 설정
filter_chains:
  - filter_chain_match: {}
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
        require_client_certificate: true
        common_tls_context:
          tls_certificates:
            - certificate_chain:
                filename: /etc/certs/server.crt
              private_key:
                filename: /etc/certs/server.key
          validation_context:
            trusted_ca:
              filename: /etc/certs/ca.crt

실무 대화 예제

백엔드 개발자
"Istio를 도입하면서 사이드카 프록시라는 게 생겼는데, 이게 Envoy인가요?"
인프라 엔지니어
"맞아요. Istio는 Envoy를 사이드카로 주입해서 서비스 간 모든 트래픽을 가로채요. 서비스 코드 변경 없이 mTLS 암호화, 트래픽 관찰, 라우팅 정책을 적용할 수 있죠."
백엔드 개발자
"그런데 사이드카가 모든 파드에 붙으니까 리소스 오버헤드가 걱정되는데요."
인프라 엔지니어
"Envoy 하나당 보통 50-100MB 메모리, 10-50ms 레이턴시 정도예요. 성능에 민감한 서비스라면 리소스 limit을 조정하거나, 최근에는 사이드카 없이 노드당 공유 프록시를 쓰는 방식(Cilium, Ambient Mesh)도 있어요."

주의사항

설정 복잡도

Envoy YAML 설정은 매우 복잡합니다. 직접 작성보다는 Istio, Contour 같은 상위 레벨 도구를 사용하거나, xDS 컨트롤 플레인을 활용하세요.

리소스 오버헤드

사이드카 패턴으로 배포 시 파드당 추가 메모리/CPU가 필요합니다. 대규모 클러스터에서는 리소스 계획을 신중히 하세요.

디버깅 어려움

프록시 레이어가 추가되면 네트워크 문제 디버깅이 복잡해집니다. Envoy admin API와 상세 로깅 활용법을 익혀두세요.

버전 호환성

xDS API 버전(v2, v3)에 주의하세요. 최신 Envoy는 v2를 지원하지 않을 수 있습니다.

더 배우기