Поздравления! Това е кратка статия, която отговаря на въпросите: "какво е пратеник?", "Защо е необходимо?" и "откъде да започна?".
Какво е това?
Envoy е L4-L7 балансьор, написан на C++, фокусиран върху висока производителност и достъпност. От една страна, това е по някакъв начин аналог на nginx и haproxy, сравним по производителност с тях. От друга страна, той е по-ориентиран към микросервизна архитектура и има функционалност не по-лоша от java и go балансьори, като zuul или traefik.
Сравнителна таблица на haproxy/nginx/envoy, тя не претендира за абсолютна истина, но дава обща картина.
Nginx
haproxy
изпратен
траефик
звезди в github
11.2k/огледало
1.1k/огледало
12.4k
27.6k
написано в
C
C
C + +
go
API
не
само гнездо/бут
dataplane/pull
издърпайте
активен здравен преглед
не
да
да
да
Отворено проследяване
външен плъгин
не
да
да
J.W.T.
външен плъгин
не
да
не
разширение
Lua/C
Lua/C
Lua/C++
не
Какво за
Това е млад проект, липсват много неща, някои в ранна алфа версия. Но изпратен, също поради младостта си, се развива бързо и вече има много интересни функции: динамична конфигурация, много готови филтри, прост интерфейс за писане на ваши собствени филтри.
Областите на приложение следват от това, но първо има 2 антимодели:
- Статичен откат.
Факт е, че в момента в изпратен няма поддръжка за кеширане. Момчетата от Google опитват това
Засега използвайте nginx за статика.
- Статична конфигурация.
Можете да го използвате, но изпратен Не е за това създадено. Функциите в статична конфигурация няма да бъдат изложени. Има много моменти:
Когато редактирате конфигурацията в yaml, ще сгрешите, ще се карате на разработчиците за многословие и ще мислите, че конфигурациите на nginx/haproxy, макар и по-малко структурирани, са по-сбити. Това е смисълът. Конфигурацията на Nginx и Haproxy е създадена за редактиране на ръка и изпратен за генериране от код. Цялата конфигурация е описана в
Сценариите за разгръщане на Canary, b/g и много други обикновено се изпълняват само в динамична конфигурация. Не казвам, че това не може да стане статично, всички го правим. Но за това трябва да поставите патерици, във всеки от балансьорите, в изпратен включително.
Задачи, за които Envoy е незаменим:
- Балансиране на трафика в сложни и динамични системи. Това включва сервизната мрежа, но не е непременно единствената.
- Необходимостта от функционалност за разпределено проследяване, сложна авторизация или друга функционалност, която е налична в изпратен извън кутията или удобно имплементиран, но в nginx/haproxy трябва да сте заобиколени от lua и съмнителни плъгини.
И двете, ако е необходимо, осигуряват висока производителност.
Как работи
Envoy се разпространява в двоични файлове само като докер изображение. Изображението вече съдържа пример за статична конфигурация. Но ние се интересуваме от него само за разбиране на структурата.
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
Динамична конфигурация
На какъв проблем търсим решение? Не можете просто да презаредите конфигурацията на балансиращото натоварване при натоварване; ще възникнат „малки“ проблеми:
- Валидиране на конфигурацията.
Конфигурацията може да е голяма, може да е много голяма, ако я претоварим цялата наведнъж, шансовете за грешка някъде се увеличават.
- Дълготрайни връзки.
Когато инициализирате нов слушател, трябва да се погрижите за връзките, работещи на стария; ако промените се случват често и има дълготрайни връзки, ще трябва да потърсите компромис. Здравейте, kubernetes ingress на nginx.
- Активни здравни проверки.
Ако имаме активни проверки на здравето, трябва да ги проверим отново всички в новата конфигурация, преди да изпратим трафик. Ако има много нагоре по течението, това отнема време. Здравейте haproxy.
Как е решено това в изпратенЧрез динамично зареждане на конфигурацията, според модела на пула, можете да я разделите на отделни части и да не инициализирате отново частта, която не е променена. Например слушател, чието повторно инициализиране е скъпо и рядко се променя.
Конфигурация изпратен (от файла по-горе) има следните обекти:
- слушател — слушател, който виси на конкретен ip/порт
- виртуален хост - виртуален хост по име на домейн
- маршрут - правило за балансиране
- група — група нагоре по веригата с балансиращи параметри
- крайна точка — адрес на екземпляр нагоре по веригата
Всеки от тези обекти плюс някои други могат да бъдат попълнени динамично; за това конфигурацията указва адреса на услугата, от която ще бъде получена конфигурацията. Услугата може да бъде REST или gRPC, gRPC е за предпочитане.
Услугите са именувани съответно: LDS, VHDS, RDS, CDS и EDS. Можете да комбинирате статична и динамична конфигурация, с ограничението, че динамичен ресурс не може да бъде посочен в статичен.
За повечето задачи е достатъчно да внедрите последните три услуги, те се наричат ADS (Aggregated Discovery Service), за
Конфигурацията приема следната форма:
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