Đặc phái viên. 1. Giới thiệu

Lời chào hỏi! Đây là bài viết ngắn trả lời các câu hỏi: “sứ giả là gì?”, “tại sao lại cần thiết?” và "bắt đầu từ đâu?".

Cái này là gì

Envoy là bộ cân bằng L4-L7 được viết bằng C++, tập trung vào hiệu suất cao và tính khả dụng. Một mặt, đây là một dạng tương tự của nginx và haproxy, có hiệu suất tương đương với chúng. Mặt khác, nó thiên về kiến ​​trúc microservice nhiều hơn và có chức năng không thua kém gì các bộ cân bằng java và go, chẳng hạn như zuul hoặc traefik.

Bảng so sánh haproxy/nginx/envoy, nó không khẳng định là sự thật tuyệt đối mà đưa ra một bức tranh tổng quát.

nginx
haproxy
gởi
traefik

sao trên github
11.2k/gương
1.1k/gương
12.4k
27.6k

viết vào
C
C
C + +
go

API
không
chỉ ổ cắm/đẩy
mặt phẳng dữ liệu/kéo
kéo

kiểm tra sức khỏe tích cực
không
vâng
vâng
vâng

Truy tìm mở
plugin bên ngoài
không
vâng
vâng

J.W.T.
plugin bên ngoài
không
vâng
không

sự mở rộng
Lua/C
Lua/C
Lua/C++
không

Tại sao

Đây là một dự án còn non trẻ, còn nhiều thứ còn thiếu, một số ở giai đoạn đầu alpha. Nhưng gởi, cũng do tuổi trẻ nên đang phát triển nhanh chóng và đã có nhiều tính năng thú vị: cấu hình động, nhiều bộ lọc làm sẵn, giao diện đơn giản để viết bộ lọc của riêng bạn.
Các lĩnh vực ứng dụng tiếp nối điều này, nhưng trước tiên có 2 phản mẫu:

  • Độ giật tĩnh.

Thực tế là vào thời điểm hiện tại ở gởi không hỗ trợ bộ nhớ đệm. Các nhân viên Google đang thử điều này sửa. Ý tưởng sẽ được thực hiện một lần vào gởi tất cả sự tinh tế (tiêu đề sở thú) của việc tuân thủ RFC và đối với các triển khai cụ thể đều tạo ra một giao diện. Nhưng hiện tại nó thậm chí còn chưa phải là alpha, kiến ​​trúc đang được thảo luận, PR open (khi tôi đang viết bài PR thì PR bị đơ, nhưng điểm này vẫn phù hợp).

Hiện tại, hãy sử dụng nginx cho số liệu thống kê.

  • Cấu hình tĩnh.

Bạn có thể sử dụng nó, nhưng gởi Đó không phải là mục đích nó được tạo ra. Các tính năng trong cấu hình tĩnh sẽ không bị lộ. Có rất nhiều khoảnh khắc:

Khi chỉnh sửa cấu hình trong yaml, bạn sẽ nhầm lẫn, mắng các nhà phát triển vì tính dài dòng và cho rằng cấu hình nginx/haproxy tuy ít cấu trúc hơn nhưng lại ngắn gọn hơn. Đó là điểm. Cấu hình của Nginx và Haproxy được tạo để chỉnh sửa bằng tay và gởi để tạo từ mã. Toàn bộ cấu hình được mô tả trong sinh vật nguyên sinh, việc tạo nó từ các tệp proto sẽ khó mắc lỗi hơn nhiều.

Các kịch bản triển khai Canary, b/g và nhiều kịch bản khác thường chỉ được triển khai trong cấu hình động. Tôi không nói rằng điều này không thể được thực hiện một cách tĩnh tại, tất cả chúng ta đều làm điều đó. Nhưng để làm được điều này, bạn cần phải chống nạng vào bất kỳ thiết bị giữ thăng bằng nào, ở gởi kể cả.

Nhiệm vụ không thể thiếu của Đặc sứ:

  • Cân bằng lưu lượng trong các hệ thống phức tạp và năng động. Điều này bao gồm lưới dịch vụ, nhưng nó không nhất thiết phải là lưới duy nhất.
  • Nhu cầu về chức năng theo dõi phân tán, ủy quyền phức tạp hoặc chức năng khác có sẵn trong gởi sẵn có hoặc được triển khai một cách thuận tiện, nhưng trong nginx/haproxy, bạn cần được bao quanh bởi các plugin lua và đáng ngờ.

Cả hai, nếu cần thiết, đều mang lại hiệu suất cao.

Làm thế nào nó hoạt động

Envoy chỉ được phân phối ở dạng nhị phân dưới dạng hình ảnh docker. Hình ảnh đã chứa ví dụ về cấu hình tĩnh. Nhưng chúng tôi quan tâm đến nó chỉ để hiểu cấu trúc.

cấu hình tĩnh envoy.yaml

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        protocol: TCP
        address: 0.0.0.0
        port_value: 10000
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: local_service
              domains: ["*"]
              routes:
              - match:
                  prefix: "/"
                route:
                  host_rewrite: www.google.com
                  cluster: service_google
          http_filters:
          - name: envoy.router
  clusters:
  - name: service_google
    connect_timeout: 0.25s
    type: LOGICAL_DNS
    # Comment out the following line to test on v6 networks
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: service_google
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: www.google.com
                port_value: 443
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.api.v2.auth.UpstreamTlsContext
        sni: www.google.com

Cấu hình động

Chúng ta đang tìm kiếm giải pháp cho vấn đề gì? Bạn không thể tải lại cấu hình cân bằng tải khi đang tải; các vấn đề “nhỏ” sẽ phát sinh:

  • Xác thực cấu hình.

Cấu hình có thể lớn, có thể rất lớn, nếu chúng ta quá tải tất cả cùng một lúc thì khả năng xảy ra lỗi ở đâu đó sẽ tăng lên.

  • Kết nối lâu dài.

Khi khởi tạo một trình nghe mới, bạn cần quan tâm đến các kết nối đang chạy trên trình nghe cũ; nếu các thay đổi xảy ra thường xuyên và có các kết nối tồn tại lâu dài, bạn sẽ phải tìm cách thỏa hiệp. Xin chào, kubernetes xâm nhập vào nginx.

  • Tích cực kiểm tra sức khỏe.

Nếu chúng tôi thực hiện kiểm tra tình trạng hoạt động, chúng tôi cần kiểm tra kỹ tất cả chúng trong cấu hình mới trước khi gửi lưu lượng truy cập. Nếu có nhiều thượng nguồn thì việc này sẽ mất thời gian. Xin chào haproxy.

Điều này được giải quyết như thế nào trong gởiBằng cách tải config động, theo mô hình pool, bạn có thể chia nó thành các phần riêng biệt và không khởi tạo lại phần chưa thay đổi. Ví dụ: một trình nghe, việc khởi tạo lại rất tốn kém và hiếm khi thay đổi.

Cấu hình gởi (từ tệp trên) có các thực thể sau:

  • người nghe — trình nghe treo trên một ip/cổng cụ thể
  • Máy chủ ảo - máy chủ ảo theo tên miền
  • tuyến đường - Quy luật cân bằng
  • cụm — một nhóm thượng nguồn với các thông số cân bằng
  • thiết bị đầu cuối — địa chỉ phiên bản ngược dòng

Mỗi thực thể này cùng với một số thực thể khác có thể được điền động; đối với điều này, cấu hình chỉ định địa chỉ của dịch vụ nơi cấu hình sẽ được nhận. Dịch vụ có thể là REST hoặc gRPC, ưu tiên gRPC.

Các dịch vụ được đặt tên lần lượt là: LDS, VHDS, RDS, CDS và EDS. Bạn có thể kết hợp cấu hình tĩnh và động, với hạn chế là tài nguyên động không thể được chỉ định trong tài nguyên tĩnh.

Đối với hầu hết các tác vụ, việc triển khai ba dịch vụ cuối cùng là đủ, chúng được gọi là ADS (Dịch vụ khám phá tổng hợp), dành cho Java và đến đó là một bản triển khai sẵn của bảng dữ liệu gRPC, trong đó bạn chỉ cần điền vào các đối tượng từ nguồn của mình.

Cấu hình có dạng sau:

cấu hình động envoy.yaml

dynamic_resources:
  ads_config:
    api_type: GRPC
    grpc_services:
      envoy_grpc:
        cluster_name: xds_clr
  cds_config:
    ads: {}
static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        protocol: TCP
        address: 0.0.0.0
        port_value: 10000
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          stat_prefix: ingress_http
          rds:
            route_config_name: local_route
            config_source:
              ads: {}
          http_filters:
          - name: envoy.router
  clusters:
  - name: xds_clr
    connect_timeout: 0.25s
    type: LOGICAL_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: xds_clr
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: xds
                port_value: 6565

Khi chạy gởi với cấu hình này, nó sẽ kết nối với mặt phẳng điều khiển và cố gắng yêu cầu cấu hình RDS, CDS và EDS. Quá trình tương tác xảy ra như thế nào được mô tả đây.

Nói ngắn gọn, gởi gửi yêu cầu cho biết loại tài nguyên được yêu cầu, phiên bản và tham số của nút. Đáp lại, nó nhận được một tài nguyên và một phiên bản; nếu phiên bản trên mặt phẳng điều khiển không thay đổi, nó sẽ không phản hồi.
Có 4 lựa chọn tương tác:

  • Một luồng gRPC cho tất cả các loại tài nguyên, trạng thái đầy đủ của tài nguyên sẽ được gửi.
  • Luồng riêng biệt, tình trạng đầy đủ.
  • Một luồng, trạng thái gia tăng.
  • Các luồng riêng biệt, trạng thái gia tăng.

XDS tăng dần cho phép bạn giảm lưu lượng giữa mặt phẳng điều khiển và gởi, điều này phù hợp với các cấu hình lớn. Nhưng nó làm phức tạp sự tương tác; yêu cầu chứa danh sách các tài nguyên để hủy đăng ký và đăng ký.

Ví dụ của chúng tôi sử dụng ADS - một luồng cho RDS, CDS, EDS và chế độ không tăng dần. Để bật chế độ tăng dần, bạn cần chỉ định api_type: DELTA_GRPC

Vì yêu cầu chứa các tham số nút nên chúng tôi có thể gửi các tài nguyên khác nhau đến mặt phẳng điều khiển cho các phiên bản khác nhau gởi, điều này thuận tiện cho việc xây dựng lưới dịch vụ.

Ấm lên

Trên gởi khi khởi động hoặc khi nhận được cấu hình mới từ mặt phẳng điều khiển, quy trình khởi động tài nguyên sẽ được khởi chạy. Nó được chia thành khởi động người nghe và khởi động cụm. Cái đầu tiên được khởi chạy khi có những thay đổi trong RDS/LDS, cái thứ hai khi có CDS/EDS. Điều này có nghĩa là nếu chỉ ngược dòng thay đổi thì trình nghe sẽ không được tạo lại.

Trong quá trình khởi động, các nguồn lực phụ thuộc sẽ được yêu cầu từ mặt phẳng điều khiển trong thời gian chờ. Nếu hết thời gian chờ, quá trình khởi tạo sẽ không thành công và trình nghe mới sẽ không bắt đầu nghe trên cổng.
Thứ tự khởi tạo: EDS, CDS, active health check, RDS, LDS. Khi bật kiểm tra tình trạng hoạt động, lưu lượng truy cập sẽ chỉ ngược dòng sau một lần kiểm tra tình trạng thành công.

Nếu trình nghe được tạo lại, trình nghe cũ sẽ chuyển sang trạng thái DRAIN và sẽ bị xóa sau khi tất cả các kết nối bị đóng hoặc hết thời gian chờ --drain-time-s, mặc định là 10 phút.

Tiếp tục.

Nguồn: www.habr.com

Thêm một lời nhận xét