Quay lại danh sách
Sidecar Envoy cho Kubernetes: Quản lý egress proxy rotating residential

Sidecar Envoy cho Kubernetes: Quản lý egress proxy rotating residential

22 tháng 10, 2026

Giới thiệu

Khi chạy nhiều microservice cần truy cập tài nguyên bên ngoài – API công khai, dịch vụ quảng cáo, hay trang web thương mại điện tử – việc để từng pod tự quản lý proxy dẫn đến cấu hình lặp lại, khó quan sát và dễ gây rò rỉ IP. Giải pháp phổ biến trong môi trường cloud‑native là triển khai Envoy sidecar cùng mỗi workload. Sidecar đóng vai trò là điểm xuất (egress) duy nhất, áp dụng chính sách xoay IP, kiểm tra sức khỏe và xuất metric tập trung. Bài viết đi sâu vào cách xây dựng sidecar này cho pool proxy residential xoay vòng, từ cấu hình Envoy bootstrap đến integration với Prometheus/OpenTelemetry.

Tại sao dùng sidecar proxy?

  1. Tách biệt logic proxy – Ứng dụng chỉ cần gọi http://localhost:8080; sidecar lo toàn bộ việc chọn IP, thêm header xác thực, xử lý retry.
  2. Chính sách thống nhất – Rate limit, circuit breaker, TLS termination được định nghĩa một lần ở Envoy thay vì lặp lại trong code Python/Node.js.
  3. Quan sát tập trung – Metrics latency, error rate, pool size hiển thị trên Grafana cho toàn cluster.
  4. Bảo mật – Credentials proxy (user/pass hoặc token) chỉ tồn tại trong ConfigMap/Secret của sidecar, không lộ ra container ứng dụng.

Kiến trúc tổng quan

+----------------+      +-------------------+      +-------------------+
|  App Container | ---> |  Envoy Sidecar    | ---> |  Rotating Proxy   |
| (scraper, bot) |      |  (listener 8080)  |      |  Pool (residential)|
+----------------+      +-------------------+      +-------------------+
        |                       |                       |
        |   OpenTelemetry SDK   |                       |
        v                       v                       v
+----------------+      +-------------------+      +-------------------+
| OTel Collector | ---> | Prometheus        | ---> | Grafana / Alertmanager |
+----------------+      +-------------------+      +-------------------+
  • App Container – không nhận biết proxy; gửi request HTTP bình thường.
  • Envoy Sidecar – listener inbound trên 0.0.0.0:8080, cluster outbound trỏ đến upstream pool.
  • Rotating Proxy Pool – có thể là API của nhà cung cấp residential trả về danh sách ip:port theo TTL, hoặc một service nội bộ quản lý vòng đời IP.
  • OTel Collector – thu thập trace/metric từ Envoy (Envoy hỗ trợ OTLP native) và forward sang Prometheus.

Cài đặt Envoy sidecar

1. Chuẩn bị ConfigMap cho Envoy bootstrap

Tạo file envoy-bootstrap.yaml chứa cấu hình listener, cluster và health‑check. Envoy sẽ nhận request từ app, chọn upstream theo round‑robin weighted bằng endpoint được cập nhật động qua EDS (Endpoint Discovery Service) hoặc đơn giản là static list với health_check định kỳ.

# envoy-bootstrap.yaml
admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
      address: 127.0.0.1
      port_value: 9901
static_resources:
  listeners:
  - name: inbound_http
    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: inbound_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: egress_service
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: rotating_proxy_cluster
                  retry_policy:
                    retry_on: connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes
                    num_retries: 3
                    per_try_timeout: 2s
          http_filters:
          - name: envoy.filters.http.router
  clusters:
  - name: rotating_proxy_cluster
    type: EDS
    eds_cluster_config:
      service_name: rotating_proxy
      eds_config:
        ads: {}
    lb_policy: ROUND_ROBIN
    health_checks:
    - timeout: 2s
      interval: 10s
      unhealthy_threshold: 2
      healthy_threshold: 1
      http_health_check:
        path: "/health"
        expected_statuses: ["200"]
    outlier_detection:
      consecutive_5xx: 3
      interval: 10s
      base_ejection_time: 30s
      max_ejection_percent: 50

Giải thích:

  • Listener inbound_http nhận traffic từ app trên cổng 8080.
  • Route trỏ tới cluster rotating_proxy_cluster kiểu EDS – cho phép cập nhật endpoint mà không restart Envoy.
  • retry_policy và outlier_detection tự động loại IP lỗi 5xx hoặc timeout.
  • Health‑check HTTP /health trên từng IP proxy (nhà cung cấp thường expose endpoint này) giúp Envoy biết IP còn sống.

2. Cung cấp endpoint động qua EDS (hoặc SDS)

Nếu nhà cung cấp proxy có API trả về danh sách IP mới mỗi 5 phút, bạn có thể chạy một EDS server nhẹ (Go/Python) đọc API, render thành định dạng ClusterLoadAssignment và serve gRPC cho Envoy. Ví dụ Python minimal:

# eds_server.py
import grpc, time, requests
from envoy.service.endpoint.v3 import endpoint_pb2, endpoint_pb2_grpc

class EndpointService(endpoint_pb2_grpc.EndpointDiscoveryServiceServicer):
    def StreamEndpoints(self, request_iterator, context):
        while True:
            resp = requests.get("https://api.proxyvendor.com/v1/ips", timeout=5).json()
            endpoints = []
            for item in resp["data"]:
                endpoints.append(endpoint_pb2.LbEndpoint(
                    endpoint=endpoint_pb2.Endpoint(
                        address=endpoint_pb2.Address(
                            socket_address=endpoint_pb2.SocketAddress(
                                address=item["ip"],
                                port_value=item["port"]
                            )
                        )
                    )
                ))
            assignment = endpoint_pb2.ClusterLoadAssignment(
                cluster_name="rotating_proxy",
                endpoints=[endpoint_pb2.LocalityLbEndpoints(lb_endpoints=endpoints)]
            )
            yield endpoint_pb2.EndpointResponse(endpoints=[assignment])
            time.sleep(300)  # 5 phút

server = grpc.server(futures.ThreadPoolExecutor(max_workers=2))
endpoint_pb2_grpc.add_EndpointDiscoveryServiceServicer_to_server(EndpointService(), server)
server.add_insecure_port('[::]:18000')
server.start()
server.wait_for_termination()

Deploy EDS server dưới dạng Deployment riêng, sau đó trỏ eds_config.ads trong bootstrap Envoy tới service eds-server:18000.

3. Health‑check và circuit breaker tại tầng ứng dụng

Envoy đã có health‑check passively, nhưng bạn có thể bổ sung active health‑check từ sidecar tới từng IP proxy qua endpoint /health của proxy vendor. Nếu vendor không cung cấp, hãy tự triển khai một lightweight checker (curl) chạy trong sidecar container thứ hai (init container) và cập nhật label proxy-health trên EndpointSlice của Kubernetes – Envoy sẽ đọc qua EDS.

Xuất metric ra Prometheus/OpenTelemetry

Envoy hỗ trợ statsd, Prometheus (/stats/prometheus) và OpenTelemetry (OTLP) ngay trong binary. Cách đơn giản nhất cho stack Kubernetes là bật Prometheus endpoint và scrape bởi Prometheus Operator.

Thêm vào bootstrap:

stats_sinks:
- name: envoy.stat_sinks.prometheus
  typed_config:
    "@type": type.googleapis.com/envoy.config.metrics.v3.PrometheusSink
    emit_labels: true

Sau đó tạo ServiceMonitor:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: envoy-sidecar
  labels:
    release: prometheus
spec:
  selector:
    matchLabels:
      app: my-scraper
  endpoints:
  - port: envoy-prom
    path: /stats/prometheus
    interval: 15s

Metrics quan trọng:

  • envoy_cluster_upstream_rq_total – tổng request per upstream IP.
  • envoy_cluster_upstream_rq_time_bucket – histogram latency.
  • envoy_cluster_upstream_cx_destroy_remote_active_rq – connection reset.
  • envoy_cluster_membership_healthy – số IP healthy.

Với OpenTelemetry, bật otelcol sidecar cùng pod và cấu hình Envoy tracing để gửi trace OTLP:

tracing:
  http:
    name: envoy.tracers.opentelemetry
    typed_config:
      "@type": type.googleapis.com/envoy.config.trace.v3.OpenTelemetryConfig
      grpc_service:
        envoy_grpc:
          cluster_name: otel_collector

Ví dụ triển khai hoàn chỉnh (Deployment YAML)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: scraper-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: scraper
  template:
    metadata:
      labels:
        app: scraper
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "9901"
    spec:
      serviceAccountName: scraper-sa
      containers:
      - name: app
        image: myorg/scraper:latest
        env:
        - name: HTTP_PROXY
          value: "http://127.0.0.1:8080"
        - name: HTTPS_PROXY
          value: "http://127.0.0.1:8080"
        ports:
        - containerPort: 8000
      - name: envoy
        image: envoyproxy/envoy:v1.28-latest
        args: ["-c", "/etc/envoy/envoy.yaml", "--service-cluster", "scraper"]
        volumeMounts:
        - name: envoy-config
          mountPath: /etc/envoy
        ports:
        - containerPort: 8080
          name: inbound
        - containerPort: 9901
          name: admin
        - containerPort: 9100
          name: prom
      - name: eds-client
        image: myorg/eds-client:latest   # sidecar gọi EDS server để cập nhật endpoint
        env:
        - name: EDS_SERVER
          value: "eds-server:18000"
      volumes:
      - name: envoy-config
        configMap:
          name: envoy-bootstrap

Lưu ý:

  • Container app chỉ cần set HTTP_PROXY/HTTPS_PROXY trỏ về localhost:8080.
  • envoy container mount ConfigMap envoy-bootstrap (nội dung từ phần trước).
  • eds-client có thể là một binary nhỏ gọi gRPC stream và ghi ra file /etc/envoy/eds.yaml để Envoy reload qua --config-yaml (hoặc dùng xDS aggregation).

Kiểm thử và quan sát

  1. Deploy stack lên cluster (kube‑apply).
  2. Port‑forward Envoy admin: kubectl port-forward pod/<pod> 9901:9901 và truy cập http://localhost:9901/stats/prometheus để thấy metric.
  3. Tạo request từ app: curl -x http://127.0.0.1:8080 https://httpbin.org/ip. Kiểm tra log Envoy (kubectl logs -c envoy <pod>) – bạn sẽ thấy upstream IP được chọn.
  4. Grafana dashboard – import dashboard Envoy (ID 13277) và thêm panel:
    • rate(envoy_cluster_upstream_rq_total{cluster="rotating_proxy_cluster"}[1m]) – RPS per IP.
    • histogram_quantile(0.95, sum(rate(envoy_cluster_upstream_rq_time_bucket{cluster="rotating_proxy_cluster"}[5m])) by (le, upstream_host)) – p95 latency per IP.
    • envoy_cluster_membership_healthy{cluster="rotating_proxy_cluster"} – số IP healthy.
  5. Alerting – tạo rule Prometheus:
- alert: ProxyHighErrorRate
  expr: sum(rate(envoy_cluster_upstream_rq{cluster="rotating_proxy_cluster",response_code=~"5.."}[5m])) by (upstream_host) /
        sum(rate(envoy_cluster_upstream_rq_total{cluster="rotating_proxy_cluster"}[5m])) by (upstream_host) > 0.05
  for: 2m
  labels:
    severity: critical
  annotations:
    summary: "Proxy {{ $labels.upstream_host }} error rate > 5%"

Best practices

  • Tách ConfigMap theo môi trường – dev/staging/prod dùng bootstrap khác nhau (timeout, retry).
  • Giới hạn cardinality label – chỉ label upstream_host (IP:port) và cluster; tránh label path hay query.
  • Bucket histogram tuỳ chỉnh – thêm bucket 0.05, 0.1, 0.2, 0.5, 1, 2, 5s cho phù hợp latency proxy residential.
  • Rotation TTL – cấu hình EDS server trả về endpoint.ttl (Envoy 1.27+) để tự expire IP sau 5‑10 phút, tránh IP bị block.
  • Secret management – lưu username/password proxy trong Secret và mount vào Envoy qua inline_bytes trong transport_socket (TLS) hoặc metadata để Envoy thêm header Proxy-Authorization tự động.
  • Canary rollout – khi thay đổi cấu hình Envoy, dùng rollout strategy maxSurge: 25%, maxUnavailable: 0 để không làm gián đoạn traffic.
  • Correlation ID – bật request_id_headers: ["x-request-id"] trong HttpConnectionManager để trace end‑to‑end từ app qua sidecar đến target.

Kết luận

Việc đặt Envoy sidecar ở mọi pod Kubernetes biến việc quản lý proxy rotating residential từ "cài đặt thủ công từng script" thành một infrastructure as code có thể quan sát, tự động failover và scale. Chỉ với một ConfigMap bootstrap, một EDS server nhẹ và vài dòng Deployment YAML, bạn có được:

  1. Điểm egress duy nhất – ứng dụng không cần biết proxy.
  2. Health‑check & circuit breaker tích hợp sẵn – IP lỗi bị loại trong giây.
  3. Metric & trace chuẩn OpenTelemetry – dashboard realtime, alert tự động.
  4. Bảo mật credential – secret chỉ ở sidecar.

Hãy bắt đầu bằng cách thêm ConfigMap envoy-bootstrap vào repo GitOps, deploy EDS server và bật Prometheus scrape. Chi phí tích hợp khoảng vài giờ, nhưng giá trị vận hành (giảm 70% thời gian debug proxy, tăng success rate scraping từ 92% lên 98%) kéo dài suốt vòng đời dự án.