Di chuyển từ Nginx sang Envoy Proxy

Xin chào, Habr! Tôi mang đến cho bạn sự chú ý bản dịch của bài viết: Di chuyển từ Nginx sang Envoy Proxy.

Envoy là một máy chủ proxy phân tán hiệu suất cao (viết bằng C++) được thiết kế cho các dịch vụ và ứng dụng riêng lẻ, nó cũng là một bus truyền thông và “mặt phẳng dữ liệu chung” được thiết kế cho các kiến ​​trúc “lưới dịch vụ” vi dịch vụ lớn. Khi tạo nó, các giải pháp cho các vấn đề phát sinh trong quá trình phát triển máy chủ như NGINX, HAProxy, bộ cân bằng tải phần cứng và bộ cân bằng tải đám mây đã được tính đến. Envoy hoạt động cùng với từng ứng dụng và tóm tắt mạng để cung cấp chức năng chung bất kể nền tảng. Khi tất cả lưu lượng dịch vụ trong cơ sở hạ tầng đều đi qua lưới Envoy, việc trực quan hóa các khu vực có vấn đề với khả năng quan sát nhất quán sẽ trở nên dễ dàng, điều chỉnh hiệu suất tổng thể và thêm chức năng cốt lõi ở một vị trí cụ thể.

Khả năng

  • Kiến trúc ngoài quy trình: envoy là một máy chủ khép kín, hiệu suất cao, chiếm một lượng RAM nhỏ. Nó hoạt động cùng với bất kỳ ngôn ngữ hoặc khung ứng dụng nào.
  • Hỗ trợ http/2 và grpc: envoy có hỗ trợ http/2 và grpc hạng nhất cho các kết nối đến và đi. Đây là proxy minh bạch từ http/1.1 đến http/2.
  • Cân bằng tải nâng cao: envoy hỗ trợ các tính năng cân bằng tải nâng cao bao gồm thử lại tự động, ngắt chuỗi, giới hạn tốc độ toàn cầu, theo dõi yêu cầu, cân bằng tải vùng cục bộ, v.v.
  • API quản lý cấu hình: envoy cung cấp API mạnh mẽ để quản lý linh hoạt cấu hình của bạn.
  • Khả năng quan sát: Khả năng quan sát sâu về lưu lượng L7, hỗ trợ riêng cho việc theo dõi phân tán và khả năng quan sát của mongodb, dynamodb và nhiều ứng dụng khác.

Bước 1 - Ví dụ về cấu hình NGINX

Tập lệnh này sử dụng một tệp được tạo đặc biệt nginx.conf, dựa trên ví dụ đầy đủ từ Wiki NGINX. Bạn có thể xem cấu hình trong trình chỉnh sửa bằng cách mở nginx.conf

cấu hình nguồn nginx

user  www www;
pid /var/run/nginx.pid;
worker_processes  2;

events {
  worker_connections   2000;
}

http {
  gzip on;
  gzip_min_length  1100;
  gzip_buffers     4 8k;
  gzip_types       text/plain;

  log_format main      '$remote_addr - $remote_user [$time_local]  '
    '"$request" $status $bytes_sent '
    '"$http_referer" "$http_user_agent" '
    '"$gzip_ratio"';

  log_format download  '$remote_addr - $remote_user [$time_local]  '
    '"$request" $status $bytes_sent '
    '"$http_referer" "$http_user_agent" '
    '"$http_range" "$sent_http_content_range"';

  upstream targetCluster {
    172.18.0.3:80;
    172.18.0.4:80;
  }

  server {
    listen        8080;
    server_name   one.example.com  www.one.example.com;

    access_log   /var/log/nginx.access_log  main;
    error_log  /var/log/nginx.error_log  info;

    location / {
      proxy_pass         http://targetCluster/;
      proxy_redirect     off;

      proxy_set_header   Host             $host;
      proxy_set_header   X-Real-IP        $remote_addr;
    }
  }
}

Cấu hình NGINX thường có ba yếu tố chính:

  1. Định cấu hình máy chủ NGINX, cấu trúc nhật ký và chức năng Gzip. Điều này được xác định trên toàn cầu trong mọi trường hợp.
  2. Định cấu hình NGINX để chấp nhận yêu cầu đến máy chủ one.example.com trên cổng 8080.
  3. Thiết lập vị trí mục tiêu, cách xử lý lưu lượng truy cập cho các phần khác nhau của URL.

Không phải tất cả cấu hình sẽ áp dụng cho Envoy Proxy và bạn không cần phải định cấu hình một số cài đặt. Ủy nhiệm sứ giả có bốn loại chính, hỗ trợ cơ sở hạ tầng cốt lõi do NGINX cung cấp. Cốt lõi là:

  • Người nghe: Họ xác định cách Envoy Proxy chấp nhận các yêu cầu gửi đến. Envoy Proxy hiện chỉ hỗ trợ trình nghe dựa trên TCP. Sau khi kết nối được thiết lập, nó sẽ được chuyển đến một bộ bộ lọc để xử lý.
  • Bộ lọc: Chúng là một phần của kiến ​​trúc đường ống có thể xử lý dữ liệu đến và đi. Chức năng này bao gồm các bộ lọc như Gzip, nén dữ liệu trước khi gửi đến máy khách.
  • Bộ định tuyến: Chúng chuyển tiếp lưu lượng truy cập đến đích được yêu cầu, được xác định dưới dạng một cụm.
  • Cụm: Chúng xác định điểm cuối cho các tham số lưu lượng và cấu hình.

Chúng tôi sẽ sử dụng bốn thành phần này để tạo cấu hình Envoy Proxy phù hợp với cấu hình NGINX cụ thể. Mục tiêu của Envoy là làm việc với API và cấu hình động. Trong trường hợp này, cấu hình cơ sở sẽ sử dụng cài đặt tĩnh, được mã hóa cứng từ NGINX.

Bước 2 - Cấu hình NGINX

Phần đầu tiên nginx.conf xác định một số phần bên trong NGINX cần được định cấu hình.

Kết nối công nhân

Cấu hình bên dưới xác định số lượng quy trình và kết nối của công nhân. Điều này cho thấy NGINX sẽ mở rộng quy mô như thế nào để đáp ứng nhu cầu.

worker_processes  2;

events {
  worker_connections   2000;
}

Envoy Proxy quản lý quy trình làm việc và kết nối theo nhiều cách khác nhau.

Envoy tạo một luồng công nhân cho từng luồng phần cứng trong hệ thống. Mỗi luồng công việc thực thi một vòng lặp sự kiện không chặn chịu trách nhiệm

  1. Lắng nghe từng người nghe
  2. Chấp nhận kết nối mới
  3. Tạo bộ lọc cho kết nối
  4. Xử lý tất cả các hoạt động I/O trong suốt thời gian kết nối.

Tất cả quá trình xử lý kết nối tiếp theo được xử lý hoàn toàn trong luồng công việc, bao gồm mọi hành vi chuyển tiếp.

Đối với mỗi luồng công nhân trong Envoy, có một nhóm kết nối. Vì vậy, nhóm kết nối HTTP/2 chỉ thiết lập một kết nối cho mỗi máy chủ bên ngoài tại một thời điểm, nếu có bốn luồng công việc thì sẽ có bốn kết nối HTTP/2 cho mỗi máy chủ bên ngoài ở trạng thái ổn định. Bằng cách giữ mọi thứ trong một luồng công việc, hầu hết tất cả mã có thể được viết mà không bị chặn, như thể nó là một luồng đơn. Nếu nhiều luồng công việc được phân bổ hơn mức cần thiết, điều này có thể dẫn đến lãng phí bộ nhớ, tạo ra một số lượng lớn kết nối nhàn rỗi và giảm số lượng kết nối được trả về nhóm.

Để biết thêm thông tin, hãy truy cập Blog ủy quyền của sứ giả.

Cấu hình HTTP

Khối cấu hình NGINX sau xác định cài đặt HTTP như:

  • Những loại mime nào được hỗ trợ
  • Thời gian chờ mặc định
  • Cấu hình Gzip

Bạn có thể tùy chỉnh những khía cạnh này bằng cách sử dụng các bộ lọc trong Envoy Proxy mà chúng ta sẽ thảo luận sau.

Bước 3 - Cấu hình máy chủ

Trong khối cấu hình HTTP, cấu hình NGINX chỉ định lắng nghe trên cổng 8080 và phản hồi các yêu cầu gửi đến cho miền one.example.com и www.one.example.com.

 server {
    listen        8080;
    server_name   one.example.com  www.one.example.com;

Bên trong Envoy, nó được điều khiển bởi Listener.

Thính giả sứ giả

Khía cạnh quan trọng nhất của việc bắt đầu với Envoy Proxy là xác định người nghe của bạn. Bạn cần tạo một tệp cấu hình mô tả cách bạn muốn chạy phiên bản Envoy.

Đoạn mã bên dưới sẽ tạo một trình nghe mới và liên kết nó với cổng 8080. Cấu hình sẽ cho Envoy Proxy biết cổng nào sẽ liên kết với các yêu cầu đến.

Envoy Proxy sử dụng ký hiệu YAML cho cấu hình của nó. Để biết phần giới thiệu về ký hiệu này, hãy xem tại đây liên kết.

Copy to Editorstatic_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 8080 }

Không cần phải xác định tên máy chủ, vì bộ lọc Envoy Proxy sẽ xử lý việc này.

Bước 4 - Cấu hình vị trí

Khi có yêu cầu đến NGINX, khối vị trí sẽ xác định cách xử lý và nơi định tuyến lưu lượng. Trong đoạn sau, tất cả lưu lượng truy cập đến trang web được chuyển đến một cụm ngược dòng (lưu ý của người dịch: ngược dòng thường là một máy chủ ứng dụng) có tên cụm mục tiêu. Cụm ngược dòng xác định các nút sẽ xử lý yêu cầu. Chúng ta sẽ thảo luận vấn đề này trong bước tiếp theo.

location / {
    proxy_pass         http://targetCluster/;
    proxy_redirect     off;

    proxy_set_header   Host             $host;
    proxy_set_header   X-Real-IP        $remote_addr;
}

Tại Envoy, Filters thực hiện việc này.

Bộ lọc đặc phái viên

Đối với cấu hình tĩnh, bộ lọc xác định cách xử lý các yêu cầu đến. Trong trường hợp này, chúng tôi đặt các bộ lọc phù hợp tên_máy chủ ở bước trước. Khi các yêu cầu đến phù hợp với các miền và tuyến nhất định, lưu lượng truy cập sẽ được chuyển đến cụm. Điều này tương đương với cấu hình NGINX từ dưới lên.

Copy to Editor    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
                - "one.example.com"
                - "www.one.example.com"
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: targetCluster
          http_filters:
          - name: envoy.router

tên envoy.http_connection_manager là một bộ lọc tích hợp trong Envoy Proxy. Các bộ lọc khác bao gồm Redis, Mongo, TCP. Bạn có thể tìm thấy danh sách đầy đủ tại tài liệu.

Để biết thêm thông tin về các chính sách cân bằng tải khác, hãy truy cập Tài liệu đặc phái viên.

Bước 5 - Cấu hình proxy và ngược dòng

Trong NGINX, cấu hình ngược dòng xác định một tập hợp các máy chủ mục tiêu sẽ xử lý lưu lượng truy cập. Trong trường hợp này, hai cụm đã được chỉ định.

  upstream targetCluster {
    172.18.0.3:80;
    172.18.0.4:80;
  }

Trong Envoy, điều này được quản lý bởi các cụm.

Cụm sứ giả

Tương đương ngược dòng được định nghĩa là các cụm. Trong trường hợp này, các máy chủ sẽ phục vụ lưu lượng đã được xác định. Cách truy cập máy chủ, chẳng hạn như thời gian chờ, được xác định là cấu hình cụm. Điều này cho phép kiểm soát chi tiết hơn các khía cạnh như độ trễ và cân bằng tải.

Copy to Editor  clusters:
  - name: targetCluster
    connect_timeout: 0.25s
    type: STRICT_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    hosts: [
      { socket_address: { address: 172.18.0.3, port_value: 80 }},
      { socket_address: { address: 172.18.0.4, port_value: 80 }}
    ]

Khi sử dụng dịch vụ khám phá STRICT_DNS Envoy sẽ giải quyết liên tục và không đồng bộ các mục tiêu DNS được chỉ định. Mỗi địa chỉ IP được trả về từ kết quả DNS sẽ được coi là một máy chủ rõ ràng trong cụm ngược dòng. Điều này có nghĩa là nếu một yêu cầu trả về hai địa chỉ IP, Envoy sẽ cho rằng có hai máy chủ trong cụm và cả hai phải được cân bằng tải. Nếu một máy chủ bị xóa khỏi kết quả, Envoy sẽ cho rằng nó không còn tồn tại và sẽ lấy lưu lượng truy cập từ bất kỳ nhóm kết nối hiện có nào.

Để biết thêm thông tin, hãy xem Tài liệu ủy quyền của phái viên.

Bước 6 - Truy cập nhật ký và lỗi

Cấu hình cuối cùng là đăng ký. Thay vì đẩy nhật ký lỗi vào đĩa, Envoy Proxy thực hiện cách tiếp cận dựa trên đám mây. Tất cả nhật ký ứng dụng được xuất ra tiêu chuẩn и tiêu chuẩn.

Khi người dùng đưa ra yêu cầu, nhật ký truy cập là tùy chọn và bị tắt theo mặc định. Để bật nhật ký truy cập cho các yêu cầu HTTP, hãy bật cấu hình truy cập_log cho trình quản lý kết nối HTTP. Đường dẫn có thể là một thiết bị như tiêu chuẩnhoặc một tệp trên đĩa, tùy theo yêu cầu của bạn.

Cấu hình sau sẽ chuyển hướng tất cả nhật ký truy cập đến tiêu chuẩn (lưu ý của người dịch - cần phải có stdout để sử dụng envoy bên trong docker. Nếu được sử dụng mà không có docker, hãy thay thế /dev/stdout bằng đường dẫn đến tệp nhật ký thông thường). Sao chép đoạn mã vào phần cấu hình cho trình quản lý kết nối:

Copy to Clipboardaccess_log:
- name: envoy.file_access_log
  config:
    path: "/dev/stdout"

Kết quả sẽ như thế này:

      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          access_log:
          - name: envoy.file_access_log
            config:
              path: "/dev/stdout"
          route_config:

Theo mặc định, Envoy có chuỗi định dạng bao gồm các chi tiết của yêu cầu HTTP:

[%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%"n

Kết quả của chuỗi định dạng này là:

[2018-11-23T04:51:00.281Z] "GET / HTTP/1.1" 200 - 0 58 4 1 "-" "curl/7.47.0" "f21ebd42-6770-4aa5-88d4-e56118165a7d" "one.example.com" "172.18.0.4:80"

Nội dung đầu ra có thể được tùy chỉnh bằng cách đặt trường định dạng. Ví dụ:

access_log:
- name: envoy.file_access_log
  config:
    path: "/dev/stdout"
    format: "[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%"n"

Dòng nhật ký cũng có thể được xuất ở định dạng JSON bằng cách đặt trường json_format. Ví dụ:

access_log:
- name: envoy.file_access_log
  config:
    path: "/dev/stdout"
    json_format: {"protocol": "%PROTOCOL%", "duration": "%DURATION%", "request_method": "%REQ(:METHOD)%"}

Để biết thêm thông tin về Phương pháp đăng ký đại sứ, hãy truy cập

https://www.envoyproxy.io/docs/envoy/latest/configuration/access_log#config-access-log-format-dictionaries

Ghi nhật ký không phải là cách duy nhất để hiểu rõ hơn khi làm việc với Envoy Proxy. Nó có khả năng theo dõi và đo lường nâng cao được tích hợp trong đó. Bạn có thể tìm hiểu thêm tại tài liệu truy tìm hay qua Kịch bản truy tìm tương tác.

Bước 7 - Khởi chạy

Bây giờ bạn đã di chuyển cấu hình của mình từ NGINX sang Envoy Proxy. Bước cuối cùng là khởi chạy một phiên bản Envoy Proxy để kiểm tra nó.

Chạy với tư cách người dùng

Ở đầu dòng cấu hình NGINX người dùng www www; chỉ định chạy NGINX với tư cách người dùng có đặc quyền thấp để cải thiện bảo mật.

Envoy Proxy áp dụng cách tiếp cận dựa trên đám mây để quản lý người sở hữu quy trình. Khi chạy Envoy Proxy thông qua một vùng chứa, chúng tôi có thể chỉ định người dùng có đặc quyền thấp.

Ra mắt ủy quyền sứ giả

Lệnh bên dưới sẽ chạy Envoy Proxy thông qua vùng chứa Docker trên máy chủ. Lệnh này cung cấp cho Envoy khả năng lắng nghe các yêu cầu đến trên cổng 80. Tuy nhiên, như được chỉ định trong cấu hình trình nghe, Envoy Proxy lắng nghe lưu lượng truy cập đến trên cổng 8080. Điều này cho phép quá trình chạy với tư cách là người dùng có đặc quyền thấp.

docker run --name proxy1 -p 80:8080 --user 1000:1000 -v /root/envoy.yaml:/etc/envoy/envoy.yaml envoyproxy/envoy

Kiểm tra

Với proxy đang chạy, giờ đây các bài kiểm tra có thể được thực hiện và xử lý. Lệnh cURL sau đây đưa ra yêu cầu với tiêu đề máy chủ được xác định trong cấu hình proxy.

curl -H "Host: one.example.com" localhost -i

Yêu cầu HTTP sẽ dẫn đến lỗi 503. Điều này là do các kết nối ngược dòng không hoạt động và không khả dụng. Do đó, Envoy Proxy không có sẵn đích đến cho yêu cầu. Lệnh sau sẽ bắt đầu một loạt dịch vụ HTTP khớp với cấu hình được xác định cho Envoy.

docker run -d katacoda/docker-http-server; docker run -d katacoda/docker-http-server;

Với các dịch vụ có sẵn, Envoy có thể ủy quyền thành công lưu lượng truy cập đến đích.

curl -H "Host: one.example.com" localhost -i

Bạn sẽ thấy phản hồi cho biết vùng chứa Docker nào đã xử lý yêu cầu. Trong nhật ký Envoy Proxy, bạn cũng sẽ thấy đầu ra chuỗi truy cập.

Tiêu đề phản hồi HTTP bổ sung

Bạn sẽ thấy các tiêu đề HTTP bổ sung trong tiêu đề phản hồi của yêu cầu thực tế. Tiêu đề hiển thị thời gian máy chủ ngược dòng dành để xử lý yêu cầu. Thể hiện bằng mili giây. Điều này hữu ích nếu khách hàng muốn xác định thời gian dịch vụ so với độ trễ mạng.

x-envoy-upstream-service-time: 0
server: envoy

Cấu hình cuối cùng

static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address: { address: 0.0.0.0, port_value: 8080 }
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        config:
          codec_type: auto
          stat_prefix: ingress_http
          route_config:
            name: local_route
            virtual_hosts:
            - name: backend
              domains:
                - "one.example.com"
                - "www.one.example.com"
              routes:
              - match:
                  prefix: "/"
                route:
                  cluster: targetCluster
          http_filters:
          - name: envoy.router
          clusters:
  - name: targetCluster
    connect_timeout: 0.25s
    type: STRICT_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    hosts: [
      { socket_address: { address: 172.18.0.3, port_value: 80 }},
      { socket_address: { address: 172.18.0.4, port_value: 80 }}
    ]

admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address: { address: 0.0.0.0, port_value: 9090 }

Thông tin bổ sung từ người dịch

Hướng dẫn cài đặt Envoy Proxy có thể được tìm thấy trên trang web https://www.getenvoy.io/

Theo mặc định, vòng/phút không có cấu hình dịch vụ systemd.

Thêm cấu hình dịch vụ systemd /etc/systemd/system/envoy.service:

[Unit]
Description=Envoy Proxy
Documentation=https://www.envoyproxy.io/
After=network-online.target
Requires=envoy-auth-server.service
Wants=nginx.service

[Service]
User=root
Restart=on-failure
ExecStart=/usr/bin/envoy --config-path /etc/envoy/config.yaml
[Install]
WantedBy=multi-user.target

Bạn cần tạo một thư mục /etc/envoy/ và đặt cấu hình config.yaml ở đó.

Có một cuộc trò chuyện bằng điện tín sử dụng proxy đại sứ: https://t.me/envoyproxy_ru

Proxy Envoy không hỗ trợ phục vụ nội dung tĩnh. Vì vậy, ai có thể bỏ phiếu cho tính năng này: https://github.com/envoyproxy/envoy/issues/378

Chỉ những người dùng đã đăng ký mới có thể tham gia khảo sát. Đăng nhập, xin vui lòng.

Bài đăng này có khuyến khích bạn cài đặt và thử nghiệm proxy đại diện không?

  • vâng

  • không

75 người dùng bình chọn. 18 người dùng bỏ phiếu trắng.

Nguồn: www.habr.com

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