Envoy 雲原生服務代理

使用 Envoy 作為服務網格的資料平面代理,支援負載平衡、服務發現、可觀測性

專案簡介

Envoy 是由 Lyft 開發的雲原生 L7 代理和通訊匯流排。是 Istio、Consul Connect 等服務網格的資料平面核心,現為 CNCF 畢業專案。

GitHub Stars: 27K+

主要功能

  • L7 代理 - HTTP/2、gRPC、WebSocket
  • 負載平衡 - 多種演算法和健康檢查
  • 服務發現 - 動態配置更新
  • 可觀測性 - 指標、日誌、追蹤
  • 進階路由 - 流量分割、重試、熔斷

安裝

Docker

1
2
3
4
docker run -d --name envoy \
  -p 10000:10000 \
  -v $(pwd)/envoy.yaml:/etc/envoy/envoy.yaml \
  envoyproxy/envoy:v1.28-latest

Kubernetes

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: v1
kind: ConfigMap
metadata:
  name: envoy-config
data:
  envoy.yaml: |
    # 配置內容    
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: envoy
spec:
  template:
    spec:
      containers:
        - name: envoy
          image: envoyproxy/envoy:v1.28-latest
          volumeMounts:
            - name: config
              mountPath: /etc/envoy
      volumes:
        - name: config
          configMap:
            name: envoy-config

基本配置

最小配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# envoy.yaml
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
                route_config:
                  name: local_route
                  virtual_hosts:
                    - name: backend
                      domains: ["*"]
                      routes:
                        - match:
                            prefix: "/"
                          route:
                            cluster: backend_cluster
                http_filters:
                  - name: envoy.filters.http.router
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

  clusters:
    - name: backend_cluster
      connect_timeout: 5s
      type: STRICT_DNS
      lb_policy: ROUND_ROBIN
      load_assignment:
        cluster_name: backend_cluster
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: backend
                      port_value: 8080

負載平衡

演算法

1
2
3
clusters:
  - name: backend
    lb_policy: ROUND_ROBIN  # 或 LEAST_REQUEST, RANDOM, RING_HASH

權重

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
load_assignment:
  endpoints:
    - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: backend-v1
                port_value: 8080
          load_balancing_weight: 80
        - endpoint:
            address:
              socket_address:
                address: backend-v2
                port_value: 8080
          load_balancing_weight: 20

健康檢查

1
2
3
4
5
6
7
8
9
clusters:
  - name: backend
    health_checks:
      - timeout: 5s
        interval: 10s
        unhealthy_threshold: 3
        healthy_threshold: 2
        http_health_check:
          path: /health

路由配置

路徑匹配

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
routes:
  - match:
      prefix: "/api/v1"
    route:
      cluster: api_v1

  - match:
      path: "/exact/path"
    route:
      cluster: exact_service

  - match:
      safe_regex:
        google_re2: {}
        regex: "^/users/[0-9]+$"
    route:
      cluster: users_service

Header 匹配

1
2
3
4
5
6
7
8
routes:
  - match:
      prefix: "/"
      headers:
        - name: x-version
          exact_match: "v2"
    route:
      cluster: backend_v2

流量分割

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
routes:
  - match:
      prefix: "/"
    route:
      weighted_clusters:
        clusters:
          - name: backend_v1
            weight: 90
          - name: backend_v2
            weight: 10

重試和超時

重試策略

1
2
3
4
5
6
7
8
9
routes:
  - match:
      prefix: "/"
    route:
      cluster: backend
      retry_policy:
        retry_on: "5xx,reset,connect-failure"
        num_retries: 3
        per_try_timeout: 2s

超時設定

1
2
3
4
5
6
7
routes:
  - match:
      prefix: "/"
    route:
      cluster: backend
      timeout: 30s
      idle_timeout: 60s

熔斷

配置

1
2
3
4
5
6
7
8
9
clusters:
  - name: backend
    circuit_breakers:
      thresholds:
        - priority: DEFAULT
          max_connections: 100
          max_pending_requests: 100
          max_requests: 1000
          max_retries: 3

離群檢測

1
2
3
4
5
6
7
clusters:
  - name: backend
    outlier_detection:
      consecutive_5xx: 5
      interval: 10s
      base_ejection_time: 30s
      max_ejection_percent: 50

TLS 配置

下游 TLS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
listeners:
  - 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/cert.pem
                  private_key:
                    filename: /etc/ssl/key.pem

上游 mTLS

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
clusters:
  - name: backend
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
        common_tls_context:
          tls_certificates:
            - certificate_chain:
                filename: /etc/ssl/client-cert.pem
              private_key:
                filename: /etc/ssl/client-key.pem

可觀測性

存取日誌

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
http_connection_manager:
  access_log:
    - name: envoy.access_loggers.stdout
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
        log_format:
          json_format:
            timestamp: "%START_TIME%"
            method: "%REQ(:METHOD)%"
            path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"
            status: "%RESPONSE_CODE%"
            duration: "%DURATION%"

統計端點

1
2
3
4
5
admin:
  address:
    socket_address:
      address: 0.0.0.0
      port_value: 9901

訪問 http://localhost:9901/stats

追蹤

1
2
3
4
5
6
7
8
http_connection_manager:
  tracing:
    provider:
      name: envoy.tracers.zipkin
      typed_config:
        "@type": type.googleapis.com/envoy.config.trace.v3.ZipkinConfig
        collector_cluster: jaeger
        collector_endpoint: "/api/v2/spans"

動態配置(xDS)

xDS API

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
dynamic_resources:
  lds_config:
    resource_api_version: V3
    api_config_source:
      api_type: GRPC
      transport_api_version: V3
      grpc_services:
        - envoy_grpc:
            cluster_name: xds_cluster

  cds_config:
    resource_api_version: V3
    api_config_source:
      api_type: GRPC
      transport_api_version: V3
      grpc_services:
        - envoy_grpc:
            cluster_name: xds_cluster

相關連結

延伸閱讀

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy