Envoy Proxy

Cloud-native high-performance proxy. Service mesh, API Gateway, and load balancer capabilities. Observability, dynamic configuration, and gRPC support.

Service MeshProxyLoad BalancerMicroservicesObservabilityxDSHTTP/2gRPC

Server

Envoy Proxy

Overview

Envoy Proxy is a high-performance edge proxy designed for cloud-native environments and microservice architectures. Developed in C++, it handles hundreds of thousands of requests per second with exceptional performance. With dynamic configuration management (xDS API), comprehensive observability features, and support for diverse protocols (HTTP/1.1, HTTP/2, HTTP/3, gRPC), it is widely adopted in modern microservice environments. It serves as the foundation for major service mesh solutions like Istio and AWS App Mesh, and is established as a trusted CNCF (Cloud Native Computing Foundation) graduated project.

Details

Envoy Proxy was initially developed at Lyft in 2016 and open-sourced in 2017. The current version 1.31 provides advanced features including HTTP/3 (QUIC), WebAssembly (WASM) filters, OAuth2 authentication, and external processing filters. Its event-driven asynchronous architecture and multi-threaded design achieve extremely high throughput and low latency. The pluggable filter chain architecture enables flexible extensions by combining HTTP filters, network filters, and listener filters.

Key Features

  • Dynamic Configuration Management: Real-time configuration updates via xDS API (LDS, CDS, RDS, EDS)
  • Advanced Load Balancing: Subset load balancing, zone-aware routing, custom policy support
  • Comprehensive Observability: Distributed tracing, metrics collection, and access logging
  • Modern Protocol Support: Complete support for HTTP/2, HTTP/3, gRPC, and WebSocket
  • Extensibility: Flexible customization through filter chains and WebAssembly
  • Security Features: mTLS, OAuth2, JWT validation, and rate limiting

Pros and Cons

Pros

  • De facto standard proxy for Kubernetes and service mesh environments
  • Extremely high performance and resource efficiency
  • Rich observability features significantly reduce operational overhead
  • Zero-downtime configuration changes through dynamic configuration
  • Supported by major cloud providers and service mesh solutions
  • Active development community with long-term CNCF support guarantee

Cons

  • High learning curve and configuration complexity creates initial adoption barriers
  • YAML configuration files become very complex in large-scale environments
  • Troubleshooting multi-layer filter chain issues can be challenging
  • Memory usage can be substantial, requiring attention in resource-constrained environments
  • Overhead exists compared to traditional simple load balancers
  • Production operations require specialized service mesh knowledge

Reference Pages

Code Examples

Basic Configuration and HTTP Proxy

# envoy.yaml
admin:
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 9901

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        address: 0.0.0.0
        port_value: 10000
    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: local_service
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: service_backend
          http_filters:
          - name: envoy.filters.http.router
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

  clusters:
  - name: service_backend
    connect_timeout: 0.25s
    type: STRICT_DNS
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: service_backend
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: backend.example.com
                port_value: 80

Load Balancing and Health Check Configuration

# Advanced load balancing configuration
clusters:
- name: web_service
  connect_timeout: 0.25s
  type: STRICT_DNS
  lb_policy: LEAST_REQUEST
  health_checks:
  - timeout: 1s
    interval: 5s
    unhealthy_threshold: 3
    healthy_threshold: 2
    http_health_check:
      path: "/health"
      expected_statuses:
      - start: 200
        end: 299
  load_assignment:
    cluster_name: web_service
    endpoints:
    - lb_endpoints:
      - endpoint:
          address:
            socket_address:
              address: web1.example.com
              port_value: 8080
          health_check_config:
            port_value: 8080
      - endpoint:
          address:
            socket_address:
              address: web2.example.com
              port_value: 8080
      - endpoint:
          address:
            socket_address:
              address: web3.example.com
              port_value: 8080

# Subset load balancing
- name: api_service
  connect_timeout: 0.25s
  type: EDS
  eds_cluster_config:
    eds_config:
      path: "./eds.yaml"
  lb_policy: LEAST_REQUEST
  lb_subset_config:
    fallback_policy: ANY_ENDPOINT
    subset_selectors:
    - keys: ["version"]
    - keys: ["stage", "version"]

SSL/TLS Termination and Advanced Security Configuration

# TLS configuration
listeners:
- name: https_listener
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 443
  filter_chains:
  - transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
        common_tls_context:
          tls_certificates:
          - certificate_chain:
              filename: "/etc/ssl/certs/server.crt"
            private_key:
              filename: "/etc/ssl/private/server.key"
          validation_context:
            trusted_ca:
              filename: "/etc/ssl/certs/ca.crt"
          alpn_protocols: ["h2", "http/1.1"]
    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_https
        codec_type: AUTO
        route_config:
          name: local_route
          virtual_hosts:
          - name: secure_service
            domains: ["secure.example.com"]
            routes:
            - match:
                prefix: "/"
              route:
                cluster: secure_backend
        http_filters:
        # JWT authentication filter
        - name: envoy.filters.http.jwt_authn
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
            providers:
              auth0:
                issuer: "https://your-domain.auth0.com/"
                audiences:
                - "your-api-audience"
                remote_jwks:
                  http_uri:
                    uri: "https://your-domain.auth0.com/.well-known/jwks.json"
                    cluster: jwks_cluster
                    timeout: 5s
            rules:
            - match:
                prefix: "/api/"
              requires:
                provider_name: "auth0"
        # Rate limiting filter
        - name: envoy.filters.http.local_ratelimit
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.http.local_ratelimit.v3.LocalRateLimit
            stat_prefix: http_local_rate_limit
            token_bucket:
              max_tokens: 1000
              tokens_per_fill: 1000
              fill_interval: 1s
        - name: envoy.filters.http.router
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

Observability and Tracing Configuration

# Distributed tracing configuration
tracing:
  http:
    name: envoy.tracers.zipkin
    typed_config:
      "@type": type.googleapis.com/envoy.config.trace.v3.ZipkinConfig
      collector_cluster: zipkin
      collector_endpoint: "/api/v2/spans"
      shared_span_context: false

# Metrics configuration
stats_sinks:
- name: envoy.stat_sinks.statsd
  typed_config:
    "@type": type.googleapis.com/envoy.config.core.v3.StatsdSink
    address:
      socket_address:
        address: statsd.example.com
        port_value: 8125
- name: envoy.stat_sinks.metrics_service
  typed_config:
    "@type": type.googleapis.com/envoy.config.core.v3.MetricsServiceConfig
    grpc_service:
      envoy_grpc:
        cluster_name: metrics_service

# Access log configuration
http_connection_manager:
  access_log:
  - name: envoy.access_loggers.file
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
      path: "/var/log/envoy/access.log"
      format: |
        [%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%"
        %RESPONSE_CODE% %RESPONSE_FLAGS% %BYTES_RECEIVED% %BYTES_SENT%
        %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%"
        "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"
  - name: envoy.access_loggers.grpc
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.access_loggers.grpc.v3.HttpGrpcAccessLogConfig
      common_config:
        grpc_service:
          envoy_grpc:
            cluster_name: access_log_service
        log_name: "envoy-access-log"

Dynamic Configuration (xDS) and Service Discovery

# Dynamic configuration management
dynamic_resources:
  # Listener Discovery Service
  lds_config:
    api_config_source:
      api_type: GRPC
      grpc_services:
      - envoy_grpc:
          cluster_name: xds_cluster
      set_node_on_first_message_only: true
  
  # Cluster Discovery Service
  cds_config:
    api_config_source:
      api_type: GRPC
      grpc_services:
      - envoy_grpc:
          cluster_name: xds_cluster
      set_node_on_first_message_only: true

# Node information
node:
  cluster: service_cluster
  id: service_node_1
  metadata:
    zone: us-east-1a
    region: us-east-1
    version: "1.0"

static_resources:
  clusters:
  # xDS management server
  - name: xds_cluster
    connect_timeout: 0.25s
    type: STRICT_DNS
    lb_policy: ROUND_ROBIN
    typed_extension_protocol_options:
      envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
        "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions
        explicit_http_config:
          http2_protocol_options:
            connection_keepalive:
              interval: 30s
              timeout: 5s
    load_assignment:
      cluster_name: xds_cluster
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: control-plane.example.com
                port_value: 18000

WebAssembly Extensions and Custom Filters

# WebAssembly filter
http_filters:
- name: envoy.filters.http.wasm
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.http.wasm.v3.Wasm
    config:
      name: "custom_auth_filter"
      root_id: "custom_auth"
      configuration:
        "@type": type.googleapis.com/google.protobuf.StringValue
        value: |
          {
            "api_endpoint": "https://auth.example.com/validate",
            "timeout_ms": 1000
          }
      vm_config:
        vm_id: "custom_auth"
        runtime: "envoy.wasm.runtime.v8"
        code:
          local:
            inline_string: |
              class CustomAuth {
                constructor(rootContext) {
                  this.rootContext = rootContext;
                }
                
                onRequestHeaders() {
                  const authHeader = this.getRequestHeader("authorization");
                  if (!authHeader) {
                    this.sendLocalResponse(401, "Unauthorized", "Missing authorization header", []);
                    return FilterHeadersStatus.StopIteration;
                  }
                  return FilterHeadersStatus.Continue;
                }
              }

# Lua filter (lightweight scripting)
- name: envoy.filters.http.lua
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
    inline_code: |
      function envoy_on_request(request_handle)
        -- Add custom header
        request_handle:headers():add("x-custom-header", "added-by-lua")
        
        -- Request logging
        request_handle:logInfo("Processing request: " .. request_handle:headers():get(":path"))
      end
      
      function envoy_on_response(response_handle)
        -- Add response time
        local start_time = response_handle:headers():get("x-request-start")
        if start_time then
          local duration = os.time() - tonumber(start_time)
          response_handle:headers():add("x-response-time", tostring(duration) .. "ms")
        end
      end

TCP Proxy and Multi-Protocol Support

# TCP proxy configuration
listeners:
- name: tcp_proxy
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 3306
  filter_chains:
  - filters:
    - name: envoy.filters.network.tcp_proxy
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy
        stat_prefix: tcp_mysql
        cluster: mysql_cluster
        access_log:
        - name: envoy.access_loggers.file
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
            path: "/var/log/envoy/tcp_access.log"

# Redis Proxy
- name: redis_proxy
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 6379
  filter_chains:
  - filters:
    - name: envoy.filters.network.redis_proxy
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.filters.network.redis_proxy.v3.RedisProxy
        stat_prefix: redis_stats
        prefix_routes:
          routes:
          - prefix: "user:"
            cluster: redis_user_cluster
          - prefix: "session:"
            cluster: redis_session_cluster
          catch_all_route:
            cluster: redis_default_cluster
        settings:
          op_timeout: 5s
          enable_redirection: true

# gRPC proxy configuration
- name: grpc_proxy
  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: grpc_ingress
        codec_type: AUTO
        route_config:
          name: grpc_route
          virtual_hosts:
          - name: grpc_service
            domains: ["grpc.example.com"]
            routes:
            - match:
                prefix: "/api.UserService/"
              route:
                cluster: grpc_backend
                timeout: 30s
        http_filters:
        - name: envoy.filters.http.grpc_web
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
        - name: envoy.filters.http.router
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router