Di chuyển từ Nginx sang Envoy Proxy

Привет, Хабр! Предлагаю вашему вниманию перевод поста: Di chuyển từ Nginx sang Envoy Proxy.

Envoy — это высокопроизводительный распределенный прокси-сервер (написанный на C++), предназначенный для отдельных сервисов и приложений, также это коммуникационная шина и «universal data plane», разработанный для больших микросервисных архитектур «service mesh». При его создании были учтены решения проблем, которые возникали при разработке таких серверов, как NGINX, HAProxy, аппаратных балансировщиков нагрузки и облачных балансировщиков нагрузки. Envoy работает вместе с каждым приложением и абстрагирует сеть, предоставляя общие функции независимо от платформы. Когда весь служебный трафик в инфраструктуре проходит через сетку Envoy, становится легко визуализировать проблемные области с помощью согласованной наблюдаемости, настройки общей производительности и добавления основных функций в определённом месте.

Khả năng

  • Архитектура вне процесса: envoy — это автономный, высокопроизводительный сервер занимающий небольшой объем оперативной памяти. Он работает совместно с любым языком приложения или фреймворком.
  • Поддержка http/2 и grpc: envoy имеет первоклассную поддержку http/2 и grpc для входящих и исходящих соединений. Это прозрачный прокси от http/1.1 до http/2.
  • Расширенная балансировка нагрузки: envoy поддерживает расширенные функции балансировки нагрузки, включая автоматические повторные попытки, разрыв цепи, глобальное ограничение скорости, затенение запросов, локальную балансировку нагрузки зоны и т. д.
  • API для управления конфигурацией: envoy предоставляет надежный API для динамического управления своей конфигурацией.
  • Наблюдаемость: глубокая наблюдаемость трафика L7, встроенная поддержка распределенной трассировки и наблюдаемость mongodb, dynamodb и многих других приложений.

Шаг 1 — Пример конфига NGINX

В этом сценарии используется специально созданный файл nginx.conf, основанный на полном примере из NGINX Wiki. Вы можете просмотреть конфигурацию в редакторе, открыв nginx.conf

Исходный конфиг 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;
    }
  }
}

Конфигурации NGINX обычно имеют три ключевых элемента:

  1. Настройка сервера NGINX, структуры журналов и функциональности Gzip. Это определяется глобально во всех случаях.
  2. Настройка NGINX для приема запросов на хост one.example.com на порту 8080.
  3. Настройка целевого местоположения, как обрабатывать трафик для разных частей URL.

Не вся конфигурация будет применяться к Envoy Proxy, и вам не нужно настраивать некоторые параметры. Envoy Proxy имеет четыре ключевых типа, которые поддерживают базовую инфраструктуру, предлагаемую NGINX. Ядро это:

  • Слушатели: Они определяют, как Envoy Proxy принимает входящие запросы. В настоящее время Envoy Proxy поддерживает только слушателей на основе TCP. Как только соединение установлено, оно передается на набор фильтров для обработки.
  • Bộ lọc: Они являются частью конвейерной архитектуры, которая может обрабатывать входящие и исходящие данные. Данная функциональность включает фильтры, такие как Gzip, который сжимает данные перед отправкой их клиенту.
  • Маршрутизаторы: Они перенаправляют трафик в требуемый пункт назначения, определенный как кластер.
  • Кластеры: Они определяют конечную точку для трафика и параметры конфигурации.

Мы будем использовать эти четыре компонента для создания конфигурации Envoy Proxy чтобы соответстветствовать определенной конфигурации NGINX. Цель Envoy работа с API и динамическая конфигурация. В этом случае базовая конфигурация будет использовать статические, жестко заданные параметры из NGINX.

Шаг 2 — Конфигурация NGINX

Phần đầu tiên nginx.conf определяет некоторые внутренние компоненты NGINX, которые должны быть настроены.

Worker Connections (Рабочие соединения)

Приведенная ниже конфигурация определяет количество рабочих процессов и соединений. Это указывает на то, как NGINX будет масштабироваться для удовлетворения спроса.

worker_processes  2;

events {
  worker_connections   2000;
}

Envoy Proxy по-разному управляет рабочими процессами и соединениями.

Envoy создает рабочий поток для каждого аппаратного потока в системе. Каждый рабочий поток выполняет неблокирующий цикл событий, который отвечает за

  1. Прослушивание каждого слушателя (listener)
  2. Принятие новых подключений
  3. Создание набора фильтров для соединения
  4. Обработка всех операций ввода-вывода за время существования соединения.

Вся дальнейшая обработка соединения полностью обрабатывается в рабочем потоке, включая любое поведение переадресации.

Для каждого рабочего потока в Envoy существует соединение в пуле. Таким образом, пулы соединений HTTP/2 устанавливают только одно соединение для каждого внешнего хоста за раз, при наличии четырех рабочих потоков будет четыре соединения HTTP/2 для каждого внешнего хоста в стабильном состоянии. Сохраняя все в одном рабочем потоке, почти весь код может быть написан без блокировок, как если бы он был однопоточным. Если рабочих потоков выделено больше чем необходимо, это может привести к не рациональному использованию памяти, созданию большого количества простаивающих соединений и уменьшения числа возвратов соединения обратно в пул.

Để biết thêm thông tin, hãy truy cập Envoy Proxy blog.

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