Saúdos! Este é un artigo breve que responde ás preguntas: "que é enviado?", "por que é necesario?" e "por onde comezar?".
Que é isto?
Envoy é un equilibrador L4-L7 escrito en C++, centrado no alto rendemento e dispoñibilidade. Por unha banda, este é dalgún xeito un análogo de nginx e haproxy, comparable en rendemento a eles. Por outra banda, está máis orientado á arquitectura de microservizos e ten unha funcionalidade non peor que os equilibradores de java e go, como zuul ou traefik.
Táboa de comparación de haproxy/nginx/envoy, non pretende ser a verdade absoluta, pero dá unha imaxe xeral.
Nginx
haproxi
enviado
traefik
estrelas en github
11.2 k/espello
1.1 k/espello
12.4k
27.6k
escrito en
C
C
C ++
go
API
non
só toma/empuxar
plano de datos/pull
tirar
revisión de saúde activa
non
si
si
si
Trazado aberto
plugin externo
non
si
si
J.W.T.
plugin externo
non
si
non
extensión
Lua/C
Lua/C
Lua/C++
non
Para que serve
Este é un proxecto novo, faltan moitas cousas, algunhas en alfa inicial. Pero enviado, tamén pola súa xuventude, está a desenvolverse rapidamente e xa ten moitas características interesantes: configuración dinámica, moitos filtros preparados, unha interface sinxela para escribir os teus propios filtros.
Disto seguen as áreas de aplicación, pero primeiro hai 2 antipatróns:
- Retroceso estático.
O caso é que de momento en enviado sen soporte de caché. Os mozos de Google están intentando isto
Polo momento, usa nginx para a estática.
- Configuración estática.
Podes usalo, pero enviado Non foi para iso. As funcións nunha configuración estática non serán expostas. Hai moitos momentos:
Ao editar a configuración en yaml, equivocarase, reprende aos desenvolvedores pola verbosidade e pense que as configuracións de nginx/haproxy, aínda que están menos estruturadas, son máis concisas. Ese é o punto. A configuración de Nginx e Haproxy creouse para editar a man e enviado para a xeración a partir de código. Toda a configuración descríbese en
Os escenarios de implantación de Canary, b/g e moito máis adoitan implementarse só nunha configuración dinámica. Non digo que non se poida facer de forma estática, facémolo todos. Pero para iso cómpre poñer muletas, en calquera dos equilibradores, en enviado incluíndo.
Tarefas para as que Envoy é indispensable:
- Equilibrio de tráfico en sistemas complexos e dinámicos. Isto inclúe a malla de servizo, pero non é necesariamente a única.
- A necesidade dunha funcionalidade de rastrexo distribuído, autorización complexa ou outra funcionalidade dispoñible en enviado listo ou implementado convenientemente, pero en nginx/haproxy necesitas estar rodeado de plugins lua e dubidosos.
Ambos, se é necesario, proporcionan un alto rendemento.
Chat isto
Envoy distribúese en binarios só como imaxe docker. A imaxe xa contén un exemplo de configuración estática. Pero é interesante para nós só para comprender a estrutura.
configuración estática 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
Configuración dinámica
Para que problema buscamos solución? Non pode simplemente recargar a configuración do equilibrador de carga baixo carga; xurdirán "pequenos" problemas:
- Validación da configuración.
A configuración pode ser grande, pode ser moi grande, se a sobrecargamos todo á vez, as posibilidades de que se produza un erro nalgún lugar aumentan.
- Conexións de longa duración.
Ao inicializar un novo oínte, cómpre coidar das conexións que se executan no antigo; se os cambios ocorren con frecuencia e hai conexións de longa duración, terás que buscar un compromiso. Ola, entrada de kubernetes en nginx.
- Comprobacións sanitarias activas.
Se temos comprobacións de saúde activas, necesitamos verificalas todas na nova configuración antes de enviar tráfico. Se hai moitos ríos arriba, isto leva tempo. Ola haproxy.
Como se resolve isto en enviadoAo cargar a configuración de forma dinámica, segundo o modelo da piscina, pode dividila en partes separadas e non reiniciar a parte que non cambiou. Por exemplo, un oínte, que é caro reiniciar e raramente cambia.
Configuración enviado (do ficheiro anterior) ten as seguintes entidades:
- oínte — oínte colgado nun IP/port específico
- host virtual - host virtual por nome de dominio
- ruta - regra de equilibrio
- acio — un grupo de augas arriba con parámetros de equilibrio
- punto final - enderezo da instancia ascendente
Cada unha destas entidades e algunhas outras pódense cubrir de forma dinámica; para iso, a configuración especifica o enderezo do servizo desde onde se recibirá a configuración. O servizo pode ser REST ou gRPC, é preferible o gRPC.
Os servizos denomínanse respectivamente: LDS, VHDS, RDS, CDS e EDS. Pode combinar configuración estática e dinámica, coa limitación de que non se pode especificar un recurso dinámico nun estático.
Para a maioría das tarefas, abonda con implementar os tres últimos servizos, denomínanse ADS (Aggregated Discovery Service), para
A configuración toma a seguinte forma:
configuración dinámica 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
No inicio enviado con esta configuración, conectarase ao plano de control e intentará solicitar a configuración RDS, CDS e EDS. Descríbese como se produce o proceso de interacción
En resumo, enviado envía unha solicitude indicando o tipo de recurso que se solicita, a versión e os parámetros do nodo. En resposta, recibe un recurso e unha versión; se a versión no plano de control non cambiou, non responde.
Hai 4 opcións de interacción:
- Un fluxo gRPC para todo tipo de recursos, envíase o estado completo do recurso.
- Fluxos separados, estado completo.
- Un fluxo, estado incremental.
- Fluxos separados, estado incremental.
XDS incremental permítelle reducir o tráfico entre o plano de control e enviado, isto é relevante para configuracións grandes. Pero complica a interacción; a solicitude contén unha lista de recursos para cancelar a subscrición e subscribirse.
O noso exemplo usa ADS: un fluxo para RDS, CDS, EDS e o modo non incremental. Para activar o modo incremental, cómpre especificar api_type: DELTA_GRPC
Dado que a solicitude contén parámetros de nodo, podemos enviar diferentes recursos ao plano de control para diferentes instancias enviado, isto é conveniente para construír unha malla de servizo.
Quentar
En enviado ao inicio ou ao recibir unha nova configuración do plano de control, lánzase o proceso de quecemento do recurso. Divídese en quecemento do oínte e quecemento do clúster. O primeiro lánzase cando hai cambios en RDS/LDS, o segundo cando CDS/EDS. Isto significa que se só cambian as correntes ascendentes, o oínte non se recrea.
Durante o proceso de quecemento, espéranse recursos dependentes do plano de control durante o tempo de espera. Se se produce o tempo de espera, a inicialización non terá éxito e o novo oínte non comezará a escoitar no porto.
Orde de inicialización: EDS, CDS, comprobación de saúde activa, RDS, LDS. Cos comprobacións de saúde activas activadas, o tráfico irá ascendente só despois dunha comprobación de estado exitosa.
Se se recreou o oínte, o antigo pasa ao estado DRAIN e eliminarase despois de que se pechen todas as conexións ou caduque o tempo de espera --drain-time-s
, por defecto 10 minutos.
Continuar.
Fonte: www.habr.com