Principais conclusões
Uma pergunta frequente é "O que é um proxy programável e por que preciso de um?" Este artigo tenta responder a essa pergunta a partir de diferentes perspectivas. Começaremos com uma breve definição do que é um proxy, depois discutiremos como os proxies evoluíram em diferentes estágios, explicando a quais necessidades eles atenderam e quais benefícios eles ofereceram em cada estágio. Por fim, discutiremos vários aspectos da programabilidade e forneceremos um resumo do motivo pelo qual precisamos de um proxy programável.
O que é um Proxy?
Um servidor proxy geralmente é implantado no meio de duas redes isoladas e é responsável pelas transferências de dados de um lado para o outro para que pareçam uma única rede. Em sua forma mais simples, um proxy é um gateway entre um usuário e a Internet, já que existe desde o nascimento das redes de computadores. Um proxy não atua apenas como um conector de rede, pois também permite funcionalidades adicionais e casos de uso como:
Os proxies que trabalham nas camadas 4 e 7 do modelo ISO/OSI às vezes são chamados de proxies de "modo de roteamento". A maioria dos serviços de proxy está disponível como software de código aberto e representa a maior parte do software de infraestrutura de rede, fornecendo funções especializadas em diferentes domínios, como proxies para protocolos específicos, proxies para balanceamento de carga, proxies para aceleração de cache e assim por diante.
Proxy Software Evolution
Patrocinador relacionado
Aprenda os fundamentos do Istio A maneira fácil de aprender o Istio. O Istio é uma plataforma de service mesh de código aberto que ajuda os microsserviços a se comunicarem entre si. Saiba mais.
Os servidores proxy evoluíram em diferentes estágios de desenvolvimento:
Era do arquivo de configuração
Esta geração de proxy é totalmente baseada em configuração. O usuário define vários parâmetros, configura regras em um arquivo de configuração e, em seguida, inicia o processo de serviço para executar essas regras.
Era DSL de configuração
Arquivos de configuração estáticos dificultam a expressão de lógica complexa; portanto, muitos proxies introduziram recursos de script fino sobre os arquivos de configuração. Estes são comumente referidos como "linguagens de configuração" ou linguagens específicas de domínio (DSL para abreviar), como Haprxoy's ACL ou Varnish's VCL.
Era da linguagem de script
À medida que a lógica se torna mais complexa, fica mais difícil expressá-la por meio de linguagens de configuração. Ao mesmo tempo, quando o número de linguagens de configuração distintas usadas na mesma rede atinge um determinado limite, seu gerenciamento se torna difícil.
Usando shell scripts, por exemplo, pode-se escrever uma lógica simples, mas quando o código shell atinge um certo nível de complexidade, geralmente é necessário avançar para linguagens de script mais estruturadas, como Perl ou Python.
Essas linguagens trazem a conveniência do script e a vantagem estrutural de uma linguagem de programação completa. Exemplos disso são OpenResty (Nginx + Lua) e Nginx Plus (Nginx + NJS). Esta categoria também inclui servidores proxy implementados em várias linguagens de programação de aplicativos, como StrongLoop Microgateway baseado em Node e Spring Cloud Gateway baseado em Java, que geralmente possuem recursos de script próprios.
Era do cluster
As linguagens de script resolvem a complexidade inerente à modularização e estruturação de lógica complexa. Outro requisito neste ponto é integrar proxies com outras ferramentas de controle administrativo, daí a necessidade de um REST ou interface similar. De fato, um plano de controle externo pode usar essa interface para atualizar dinamicamente a lógica no script.
Ao mesmo tempo, o uso de proxies mudou de instâncias únicas para clusters de proxies. Na verdade, softwares de proxy como o Envoy e o Kong baseado em OpenResty geralmente suportam os próprios recursos de clustering, implementando-os de alguma maneira centralizada ou compartilhada (via RDBMS, etc.), ao mesmo tempo em que fornecem interfaces administrativas REST para gerenciar as configurações.
Para proxies anteriores a esta era, o gerenciamento de cluster geralmente era possível por meio do gerenciamento de configuração. As ferramentas de gerenciamento de configuração também podem expor interfaces REST. Por exemplo, Ansible + Nginx implementa recursos semelhantes aos proxies da era da nuvem. Por outro lado, os proxies da era do cluster exigem mais componentes para formar o esquema, enquanto os proxies da era da nuvem removem o fardo de gerenciar partes móveis e são muito preferidos.
Era da nuvem
Na era da nuvem, os proxies são implantados de maneira distribuída. O cenário mais comum é implantar um proxy para cada processo de aplicativo, seguindo o padrão Sidecar Proxy.
No modo de clustering, geralmente existem diferentes configurações e políticas para diferentes serviços upstream, como diferentes modos de autenticação e mecanismos de controle de acesso. À medida que os serviços upstream crescem, as configurações desses diferentes serviços upstream são separadas logicamente, mas são executadas fisicamente no mesmo processo de proxy. Esse esquema tem algumas desvantagens: mais lógica rodando no mesmo processo traz mais complexidade. Além disso, diferentes serviços upstream compartilham recursos como CPU e memória, afetando uns aos outros. Se um script de um serviço upstream tiver uma vulnerabilidade de segurança, as configurações de outros serviços upstream podem vazar, resultando em riscos de segurança.
Na era da nuvem, os processos de proxy para cada serviço upstream são independentes e isolados uns dos outros. A adoção de proxies distribuídos abriu as portas para o uso de diferentes regras e políticas para diferentes serviços upstream, ou seja, para recursos multilocatários.
Os vários serviços upstream não só têm regras e políticas logicamente independentes. O isolamento físico também é fornecido, permitindo o gerenciamento granular no nível do processo e da interface. Esse isolamento é um requisito forte em um ambiente multilocatário – diferentes serviços de upstream pertencem a diferentes locatários e os locatários não devem afetar uns aos outros ou conhecer as configurações uns dos outros.
As malhas de serviço são representativas desta era. As malhas de serviço são compostas por dois componentes principais de arquitetura, um plano de dados e um plano de controle. Ao contrário do que o nome sugere, uma malha de serviço não é uma “malha de serviços”. É uma malha de proxies que os serviços podem conectar para abstrair completamente a rede. Exemplos típicos são istio+envoy, Linkerd + proxy Linkerd.
Criado por um dos autores deste artigo, o Pipy é um produto desta época e se enquadra nesta categoria. O Pipy é um proxy de rede programável, modular, leve, de alto desempenho e de código aberto para nuvem, borda e IoT. O Pipy é ideal para uma variedade de casos de uso que variam de (mas não limitado a) roteadores de borda, balanceadores de carga & soluções de proxy, gateways de API, servidores HTTP estáticos, sidecars de malha de serviço e outros aplicativos. O Pipy está em desenvolvimento ativo e é mantido por committers e contribuidores em tempo integral, embora ainda seja uma versão inicial, foi testado em batalha e em uso de produção por vários clientes comerciais.
A partir da discussão acima, fica claro que cada estágio é uma melhoria em relação ao anterior.
Requisitos de software proxy e sua evolução
Vamos dar outra olhada na evolução dos proxies considerando como seus requisitos evoluíram.
Era do arquivo de configuração
A primeira geração de proxies implementou principalmente uma funcionalidade de gateway entre os usuários e os serviços e forneceu recursos configuráveis básicos. A transmissão em tempo real de dados massivos requer alta taxa de transferência e baixa latência e baixo uso de recursos. Como todo software, os proxies também são necessários para oferecer suporte à modularidade e extensibilidade.
O software proxy nesta etapa foi desenvolvido principalmente em C, como foi o caso dos módulos de extensão que são carregados dinamicamente no início do processo.
Para resumir, os requisitos de proxy neste estágio são conectividade (recursos de rede), facilidade de uso (configurável por meio de arquivos de configuração), confiabilidade (requisitos para dispositivos de crosslinking ), alto desempenho e escalabilidade.
Configuração da era DSL
A segunda geração de proxies obteve melhorias adicionais em extensibilidade e flexibilidade, como alguma aquisição dinâmica de dados e a capacidade de executar algumas decisões lógicas nos dados adquiridos. A introdução de scripts baseados em DSL melhorou ainda mais a usabilidade. O suporte para lógica combinatória e recuperação dinâmica de dados fornecia flexibilidade enquanto melhorava a escalabilidade.
Era da linguagem de script
As principais melhorias dos proxies de 3ª geração em relação aos proxies de 2ª geração são gerenciabilidade, facilidade de desenvolvimento e programabilidade.
A produtividade dos desenvolvedores e a complexidade de manter scripts massivos exigem que essa geração de proxies use uma linguagem de script estruturada, mantendo o desempenho, a baixa utilização de recursos e outros recursos essenciais da geração anterior.
Os recursos de script são amplamente usados, principalmente porque é difícil desenvolver e manter extensões usando C. De fato, as linguagens de script são mais fáceis de aprender e fornecem retornos mais rápidos quando comparadas às linguagens compiladas.
O uso de linguagem de script estruturada e modular inaugurou a era dos proxies programáveis e proxies necessários para fornecer dois níveis de programabilidade: usar C para desenvolvimento de módulos principais e scripts para programar lógica dinâmica. Em outras palavras, os proxies programáveis forneceram ao usuário o poder de desenvolvimento de módulos principais e lógica dinâmica.
Era do cluster
A quarta geração de proxies começa com suporte a cluster, o que melhora a capacidade de gerenciamento.
Graças às interfaces REST, os proxies se tornam parte da implementação da infraestrutura de rede e um ponto de partida para a infraestrutura como código. As interfaces REST além de melhorar a gerenciabilidade dos proxies também contribuem para simplificar sua administração. As interfaces externas também são um recurso importante dos proxies programáveis e REST, como a forma mais comum de interface.
Neste ponto, a programabilidade consiste em três camadas: módulos centrais programáveis, lógica dinâmica programável e interfaces externas programáveis. O surgimento de clusters de servidores proxy reflete a mudança de perspectiva em escalabilidade de extensão de funcionalidade para expansão de recurso (onde os usuários podem modularizar a funcionalidade em várias instâncias, em vez de escrever um script monolítico). O surgimento de interfaces REST fornece a base técnica para autoatendimento e serviços gerenciados que fornecem, por exemplo, um painel de controle para configuração e controle.
Era da nuvem
A evolução da quinta geração de proxies é impulsionada pela popularidade e pelo rápido desenvolvimento da computação em nuvem, trazendo os requisitos de elasticidade, autoatendimento, multilocação, isolamento e medição.
Se a quarta geração de agentes é para administradores do sistema, a quinta geração de agentes é para serviços em nuvem. Mantendo totalmente as características das gerações anteriores de software de proxy, os proxies de quinta geração se tornam prontos para a nuvem.
Com a expansão da computação em nuvem para a borda, a quinta geração de proxies precisa suportar hardware heterogêneo, software heterogêneo e baixo consumo de energia para otimizar a integração da nuvem e da borda.
A quinta geração de proxies também mostra avanços em programabilidade: desde o módulo principal, lógica dinâmica e interface externa que vimos anteriormente até capacidade de nuvem, suporte para distribuição, multilocação e medição. A medição é um requisito derivado da multilocação, que requer isolamento, por um lado, e que os recursos possam ser medidos com a menor granularidade possível, por outro.
Vamos resumir a discussão acima em um formato tabular, onde as linhas correspondem a requisitos específicos e as colunas a proxies em diferentes estágios. Para cada estágio de evolução, também fornecemos exemplos típicos ou softwares conhecidos entre parênteses. Em cada célula, usamos * para indicar se tais recursos estão disponíveis e em que medida (1-5, 5 para suporte total e 1 * para suporte básico).
SN | Requisito | Configuração (squid, httpd, nginx) | Linguagem de configuração (verniz, haproxy) | Suporte a scripts (nginx+lua, nginx+js) | Agrupamento (kong, enviado) | Nuvem (istio+envoy, linkerd, pipy) | Comentários |
1. | Conectividade | * * * * * | * * * * * | * * * * * | * * * * * | * * * * * | A conectividade na era da nuvem começou com tecnologias de kernel como iptables e ebpf. Anteriormente, havia apenas processos de espaço do usuário. |
2. | Confiabilidade | * * * * * | * * * * * | * * * * * | * * * * * | * * * * * | A confiabilidade sempre foi a capacidade mais fundamental dos servidores proxy. |
3. | Alto desempenho | * * * | * * * * | * * * * * | * * * * * | * * * * * | O desempenho inclui taxa de transferência, latência, taxa de erro e desvio da média. Métricas de latência comuns são P99, P999 e outras. O software proxy antigo tem um efeito de cauda longa, portanto, os indicadores acima de P99 não são tão bons quanto os softwares posteriores. O proxy com scripts de alto desempenho geralmente tem um desempenho melhor do que seus predecessores ao retornar o mesmo conteúdo. Proxies que evitam caudas longas são mais estáveis (com menos desvio da média) enquanto fornecem o mesmo desempenho. |
4. | Flexibilidade | * | * * | * * * | * * * * | * * * * * | Em comparação com a quarta geração, os proxies de quinta geração aprimoram significativamente a capacidade de suporte multiprotocolo, por isso damos a esta geração uma avaliação de cinco estrelas. Além disso, o modelo de processamento da quinta geração pode se adaptar a vários protocolos e oferecer melhor adequação em comparação com a quarta geração. |
5. | Escalabilidade | * | * * | * * * | * * * | * * * * | Da mesma forma que a flexibilidade, os proxies de 5ª geração suportam vários protocolos e fornecem mecanismos de extensão fáceis para extensão da funcionalidade principal ou desenvolvimento de extensão de protocolo de camada de aplicativo personalizado (Camada 7), então oferecemos um star mais do que a 4ª geração. |
6. | Compatibilidade de hardware | * * * * | * * * * | * * * * | * * * * | * * * * | Proxies desenvolvidos em C ou C++ geralmente têm melhor compatibilidade de hardware e uma comunidade mais ativa para migrar aplicativos para novas arquiteturas de hardware. Proxies desenvolvidos usando Rust, Go e Lua têm sido relativamente lentos para migrar para compatibilidade de hardware. |
7. | Compatibilidade do sistema | * * * | * * * | * * * * | * * * * | * * * * * | O sistema inclui principalmente dois aspectos, um é o sistema operacional, o outro é a plataforma de nuvem. Em termos de compatibilidade do sistema operacional, cada geração de proxies é semelhante. No entanto, em termos de compatibilidade de plataforma de nuvem, os proxies de quarta e quinta geração fornecem melhor compatibilidade de nuvem. Por outro lado, a diferença significativa entre a quinta e a quarta geração está na capacidade de oferecer suporte à multilocação. |
8. | Facilidade de gerenciamento | * * | * * | * * | * * * | * * * * | A facilidade de gerenciamento é uma função da operação do sistema & funções de administrador. A primeira e a segunda geração usam principalmente arquivos de configuração, com base no uso de ferramentas de gerenciamento de configuração para obter gerenciamento automático e em lote. Na terceira geração, além de gerenciar arquivos de configuração, precisamos gerenciar ainda mais arquivos de script. Mas, em essência, não há diferença significativa entre a primeira e a segunda geração em termos de facilidade de gerenciamento. A quarta geração fornece interfaces REST, o que melhora muito a facilidade de gerenciamento. Além do REST, a quinta geração de proxies geralmente fornece um plano de controle baseado em nuvem para gerenciar proxies. Ele também fornece várias interfaces externas para atender a outros requisitos de gerenciamento, como monitoramento, auditoria e estatísticas. |
9. | Facilidade de uso | * | * | * | * * | * * * | Os principais usuários das três primeiras gerações de proxies são ops & administradores do sistema. Na quarta geração, os administradores começaram a fornecer algumas funções aos usuários, e o modelo como serviço começou a aparecer. A quinta geração leva em consideração mais cenários de usuário e fornece mais recursos de locatário. |
10. | Facilidade de desenvolvimento | * | * * | * * * | * * * * | * * * * * | O desenvolvimento em torno dos proxies inclui dois aspectos. Uma está dentro do proxy, visando atingir a funcionalidade; o outro está fora do proxy, visando alcançar a capacidade de gerenciamento do proxy. As três primeiras gerações fornecem uma interface para o desenvolvimento interno. As duas últimas gerações fornecem interfaces internas e externas. A melhoria significativa trazida pela quinta geração em comparação com a quarta geração é a interface em nuvem. |
11. | A interface principal é programável | * | * | * | * | * | Cada geração de proxies fornece a capacidade de estender as interfaces principais, mas essas interfaces são de nível muito baixo e difíceis de dominar. |
12. | A extensão de funcionalidade é programável | * | * * | * * * | * * * * | * * * * * | Fornecer a capacidade de estender funções com mais eficiência faz parte do processo que melhora a cada geração de proxies. É a métrica principal dos proxies programáveis. |
13. | As extensões de protocolo são programáveis | * * | * * * | As três primeiras gerações são principalmente para protocolo único ou protocolos fixos. A partir da quarta geração, os usuários começaram a buscar suporte para vários protocolos e protocolos personalizados. Na quinta geração, a extensão do protocolo é considerada um recurso central no design. | |||
14. | Script modular | * * * | * * * * | * * * * | Os proxies de terceira geração estão começando a prestar mais atenção à estruturação do script. A quarta e quinta gerações tentam permitir uma programação mais estruturada, como a tentativa do Envoy de fornecer suporte multilíngue por meio do WASM; Pipy apresenta scripts JS de alto desempenho para melhor estruturação | ||
15. | O gerenciamento de configuração é programável | * * | * * * | As três primeiras gerações de configuração de proxy visam principalmente o pessoal de gerenciamento de operações, e as ferramentas externas de gerenciamento de configuração são baseadas nessa premissa. A quarta geração suporta interfaces de gerenciamento REST. A quinta geração fornece ainda uma interface de nuvem padrão para gerenciamento de configuração. | |||
16. | As extensões de recursos são programáveis | * | * | * | * * | * * * * | Para as três primeiras gerações, a expansão da capacidade do proxy visava principalmente aumentar o número de threads ou processos. A quarta geração fornece capacidade de expansão para processos, conhecida como capacidade de clustering. Com base nisso, a quinta geração fornece, por um lado, capacidades de expansão horizontal e, por outro lado, capacidades sob recursos limitados para suportar medição e faturamento mais refinados. Ou seja, ele não apenas oferece suporte ao dimensionamento incremental, mas também fornece a capacidade de reduzir. Além disso, todos esses recursos fornecem interfaces de programação. |
17. | Extensão de inquilino programável | * * * | A nuvem é algo que surgiu ao mesmo tempo que a quarta geração de proxy, e a multilocação, como um recurso central da nuvem, não é bem suportada na quarta geração geração. A quinta geração é projetada com base na computação em nuvem, considerando e oferecendo aos inquilinos a possibilidade de programar suas próprias extensões. |
As linhas de 11 a 17 na tabela acima são os aspectos específicos de um proxy programável. Esses aspectos também constituem a resposta para a pergunta por que usar um proxy programável:
Resumo
Neste artigo, tentamos fornecer nossa resposta para o que é um proxy programável. Para tal, partimos da definição do que é um proxy e quais são as suas principais características. Em seguida, expandimos nossa discussão para incluir o proxy de evolução que passou, explicando os recursos e funcionalidades que foram adicionados em cada etapa. Por fim, resumimos nossa discussão sobre recursos de proxy, dividindo-os em 17 categorias diferentes e classificando cada geração de proxy. Essa classificação nos permitiu identificar as principais características e atributos necessários para que um proxy seja rotulado como programável.