Пратеник. 1. Вовед

Поздрав! Ова е кратка статија која одговара на прашањата: „што е пратеник?“, „зошто е потребно?“ и "од каде да почнам?".

Што е ова?

Envoy е балансер L4-L7 напишан во C++, фокусиран на високи перформанси и достапност. Од една страна, ова е на некој начин аналог на nginx и хапрокси, споредлив по перформанси со нив. Од друга страна, тој е повеќе ориентиран кон микросервис архитектура и има функционалност не полоша од java and go balancers, како што се zuul или traefik.

Споредбена табела на хапрокси/нгинкс/претставник, таа не тврди дека е апсолутна вистина, туку дава општа слика.

nginx
хапрокси
пратеник
трафик

ѕвезди на github
11.2 k/огледало
1.1 k/огледало
12.4k
27.6k

напишано во
C
C
C + +
go

API
Нема
само штекер/туркање
податочен авион/влече
се повлече

активна здравствена проверка
Нема
Да
Да
Да

Отворено следење
надворешен приклучок
Нема
Да
Да

Џ.В.Т.
надворешен приклучок
Нема
Да
Нема

продолжување
Луа/Ц
Луа/Ц
Луа/C++
Нема

За што

Ова е млад проект, недостасуваат многу работи, некои во рана алфа. Но пратеник, исто така поради својата младост, се развива брзо и веќе има многу интересни карактеристики: динамична конфигурација, многу готови филтри, едноставен интерфејс за пишување сопствени филтри.
Областите на примена следат од ова, но прво има 2 антишеми:

  • Статички одвратен удар.

Факт е дека во моментот во пратеник нема поддршка за кеширање. Момците од Google го пробуваат ова да се поправи. Идејата ќе се спроведе еднаш во пратеник сите суптилности (заглавија на зоолошката градина) на усогласеноста со RFC, а за специфични имплементации направи интерфејс. Но, засега не е ни алфа, архитектурата е предмет на дискусија, PR отворено (додека ја пишував статијата за ПР, ПР-от замрзна, но оваа точка е сеуште актуелна).

Засега користете nginx за статика.

  • Статичка конфигурација.

Можете да го користите, но пратеник Не е за што е создаден. Функциите во статичка конфигурација нема да бидат изложени. Има многу моменти:

Кога ја уредувате конфигурацијата во yaml, ќе згрешите, ќе ги карате програмерите за вербозност и ќе мислите дека конфигурите nginx/haproxy, иако помалку структурирани, се поконцизни. Тоа е поентата. Конфигурацијата на Nginx и Haproxy е создадена за рачно уредување и пратеник за генерирање од код. Целата конфигурација е опишана во протобуф, генерирањето од прото-датотеки е многу потешко да се направи грешка.

Сценаријата за распоредување Canary, b/g и многу повеќе обично се спроведуваат само во динамична конфигурација. Не велам дека ова не може да се прави статички, сите го правиме тоа. Но, за ова треба да ставите патерици, во кој било од балансерите, во пратеник вклучувајќи.

Задачи за кои пратеникот е неопходен:

  • Балансирање на сообраќајот во сложени и динамични системи. Ова ја вклучува сервисната мрежа, но не мора да е единствената.
  • Потребата за дистрибуирана функционалност за следење, сложено овластување или друга функционалност што е достапна во пратеник надвор од кутијата или практично имплементиран, но во nginx/haproxy треба да бидете опкружени со lua и сомнителни приклучоци.

И двете, доколку е потребно, обезбедуваат високи перформанси.

Како го прави ова дело

Пратеникот се дистрибуира во бинарни датотеки само како докер-слика. Сликата веќе содржи пример за статичка конфигурација. Но, ние сме заинтересирани за тоа само за да ја разбереме структурата.

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

Динамичка конфигурација

За кој проблем бараме решение? Не можете само да ја вчитате конфигурацијата на балансерот на оптоварување под оптоварување; ќе се појават „мали“ проблеми:

  • Валидација на конфигурацијата.

Конфигурацијата може да биде голема, може да биде многу голема, ако ја преоптовариме одеднаш, шансите за грешка некаде се зголемуваат.

  • Долготрајни врски.

Кога иницијализирате нов слушател, треба да се грижите за врските што работат на стариот; ако често се случуваат промени и има долготрајни врски, ќе мора да барате компромис. Здраво, кубернетите влегуваат на nginx.

  • Активни здравствени проверки.

Ако имаме активни здравствени проверки, треба повторно да ги провериме сите во новата конфигурација пред да испратиме сообраќај. Ако има многу нагоре, за ова е потребно време. Здраво хапрокси.

Како се решава ова во пратеникСо динамичко вчитување на конфигурацијата, според моделот на базен, можете да ја поделите на посебни делови и да не го иницијализирате повторно делот што не е променет. На пример, слушател, кој е скап за реиницијализирање и ретко се менува.

Конфигурација пратеник (од датотеката погоре) ги има следните ентитети:

  • слушател — слушател виси на одредена IP/порта
  • виртуелен домаќин - виртуелен хост по име на домен
  • пат - правило за балансирање
  • кластер — група на возводни текови со параметри за балансирање
  • крајната точка — Адреса на примерок од спротиводно

Секој од овие ентитети плус некои други може да се пополни динамички; за ова, конфигурацијата ја одредува адресата на услугата од каде што ќе се прима конфигурацијата. Услугата може да биде REST или gRPC, се претпочита gRPC.

Услугите се именувани соодветно: LDS, VHDS, RDS, CDS и EDS. Можете да комбинирате статичка и динамичка конфигурација, со ограничување дека динамичкиот ресурс не може да се наведе во статичен.

За повеќето задачи, доволно е да се имплементираат последните три услуги, тие се нарекуваат ADS (Aggregated Discovery Service), за Јава и оди таму има готова имплементација на gRPC dataplane во која само треба да ги пополниш објектите од твојот извор.

Конфигурацијата ја има следната форма:

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

При стартување пратеник со оваа конфигурација, ќе се поврзе со контролната рамнина и ќе се обиде да побара конфигурација RDS, CDS и EDS. Опишан е како се случува процесот на интеракција тука.

Накратко, пратеник испраќа барање кое го означува типот на ресурс што се бара, верзијата и параметрите на јазолот. Како одговор, тој добива ресурс и верзија; ако верзијата на контролната рамнина не е променета, таа не реагира.
Постојат 4 опции за интеракција:

  • Еден gRPC поток за сите видови ресурси, се испраќа целосниот статус на ресурсот.
  • Посебни потоци, целосна состојба.
  • Еден поток, инкрементална состојба.
  • Посебни потоци, инкрементална состојба.

Инкременталниот xDS ви овозможува да го намалите сообраќајот помеѓу контролната рамнина и пратеник, ова е релевантно за големи конфигурации. Но, тоа ја комплицира интеракцијата, барањето содржи листа на ресурси за отпишување и претплата.

Нашиот пример користи ADS - еден пренос за RDS, CDS, EDS и не-инкрементален режим. За да овозможите поединечен режим, треба да наведете api_type: DELTA_GRPC

Бидејќи барањето содржи параметри на јазол, можеме да испратиме различни ресурси до контролната рамнина за различни примери пратеник, ова е погодно за изградба на сервисна мрежа.

Загреј се

На пратеник при стартување или при примање нова конфигурација од контролната рамнина, се стартува процесот на загревање на ресурсите. Тој е поделен на загревање на слушателот и загревање кластер. Првиот се активира кога има промени во RDS/LDS, вториот кога CDS/EDS. Ова значи дека ако се променат само горните текови, слушателот не се пресоздава.

За време на процесот на загревање, се очекуваат зависни ресурси од контролната рамнина за време на тајмаутот. Ако дојде до истекот на времето, иницијализацијата нема да биде успешна и новиот слушател нема да почне да слуша на портата.
Редослед за иницијализација: EDS, CDS, активна здравствена проверка, RDS, LDS. Со овозможени активни здравствени проверки, сообраќајот ќе оди нагоре само по една успешна здравствена проверка.

Ако слушателот е повторно создаден, стариот преминува во DRAIN состојба и ќе се избрише откако ќе се затворат сите врски или ќе истече времето. --drain-time-s, стандардно 10 минути.

Да се ​​продолжи.

Извор: www.habr.com

Додадете коментар