- Published on
Istio: Simplificando o gerenciamento de malhas de serviços
- Authors
- Name
- Paulo Cerqueira
Istio: Simplificando o gerenciamento de malhas de serviços
A evolução das arquiteturas de software nas últimas décadas impulsionou a adoção de microsserviços como a principal abordagem para o desenvimento de sistemas nativos para a nuvem. A busca por escalabilidade e resiliência fez com que as aplicações fossem decompostas em componentes menores, facilitando a manutenção, a atualização e a escalabilidade. No entanto, essa descentralização e distribuição de responsabilidades entre os componentes de uma aplicação também introduz novos desafios e complexidades de gerenciamento, comunicação, observabilidade e segurança.
Para lidar com esses novos desafios, surgiram as malhas de serviços (service meshes), uma camada de infraestrutura dedicada à orquestração da comunicação entre microsserviços. O Istio se destaca como uma das soluções mais robustas nesse cenário, oferecendo recursos avançados com pouca ou nenhuma intervenção no código das aplicações a que ele se propõe auxiliar.
Arquiteturas de Microsserviços
Em um sistema com arquitetura monolítica, a estrutura da aplicação pode ser caracterizada, de forma simplista, como uma unidade indivisível, onde todos os componentes (interface do usuário, lógica de negócios e acesso a dados) estão integrados em um único código base e geralmente executam como um único processo.
Essa abordagem simplifica o desenvolvimento inicial, a implantação e a execução, pois há menos complexidade na comunicação entre os componentes do sistema e menor sobrecarga de operação. No entanto, à medida que o sistema cresce, surgem desvantagens significativas, como dificuldade de escalar elementos específicos, maior acoplamento entre funcionalidades e desafios na manutenção e atualização, já que qualquer mudança exige a reimplantação de toda a aplicação.
O modelo de microsserviços surgiu como uma evolução natural dos sistemas monolíticos. Na década de 2000, big techs como Amazon, Netflix e eBay passaram a estimular e adotar abordagens descentralizadas para lidar com escalabilidade e agilidade, decompondo seus sistemas em serviços menores e independentes. O termo “microsserviços” ganhou popularidade em 2011 e foi consolidado em 2014 com artigos e palestras que definiram seus princípios, como baixo acoplamento e alta coesão.
A arquitetura de microsserviços é um modelo de desenvolvimento que estrutura um sistema como um conjunto de serviços independentes, cada um com uma responsabilidade bem definida. Diferente das abordagens monolíticas tradicionais, os microsserviços permitem que sistemas complexos sejam divididos em componentes menores e especializados, facilitando a escalabilidade, a manutenção e a evolução contínua. Neste modelo cada serviço opera de forma autônoma, o que possibilita que diferentes tecnologias, frameworks e linguagens de programação sejam utilizadas em cada módulo, conforme a necessidade.
A adoção dessa arquitetura foi impulsionada pelo avanço de tecnologias como containers (Docker, 2013), orquestradores de cargas de trabalho (Kubernetes, 2014) e práticas de DevOps, que facilitaram o desenvolvimento, a implantação e o gerenciamento de serviços distribuídos. Empresas passaram a valorizar a capacidade de escalar separadamente componentes específicos de uma aplicação, atualizar sistemas inteiros sem grandes períodos de indisponibilidade e usar linguagens diferentes para cada serviço. No entanto, desafios como a complexidade na comunicação entre serviços, consistência de dados e monitoramento também emergiram, exigindo novas ferramentas e padrões.
Ainda que haja debates sobre quando usá-los, já que sistemas pequenos podem não justificar sua complexidade, hoje os microsserviços são uma das principais arquiteturas para aplicações em nuvem, apoiados por ecossistemas maduros e frameworks como Spring Boot (Java), Node.js (Javascript), Kratos (Go) e protocolos como o gRPC.
Desafios do baixo acoplamento e comunicação
A principal característica de uma aplicação estruturada em microsserviços é o desacoplamento dos componentes do sistema. Cada uma das unidades precisa se comunicar constantemente, criando assim várias novas interações entre os microsserviços — em sua maioria, trocas de dados via rede. Conforme a aplicação aumenta seu porte, estas conexões se tornam mais numerosas e complexas e isso dificulta o gerenciamento, mapeamento das transações e visibilidade de outras informações do ambiente. Esta comunicação constante entre os módulos traz consigo novos desafios e necessidades.

Na representação acima temos um exemplo de uma loja construída com arquitetura de microsserviços onde podemos imaginar que cada componente é desenvolvido com diferentes linguagens de programação e cada módulo conta com seu próprio repositório e esteira de CI/CD. Com base nesse esquema podemos, por exemplo, analisar a preocupação com a lógica de retry. Se o módulo do Checkout não conseguir uma resposta do módulo de Pagamentos, em quanto tempo ele deverá aguardar por uma resposta? Em quanto tempo ele deverá tentar novamente? Qual a configuração ideal de tentativas para evitar uma sobrecarga no sistema e na rede?
Dentre outros aspectos da comunicação também podemos considerar questões de segurança: Como os serviços se identificam e autenticam uns nos outros? Como será feita a gestão e controle de certificados TLS nas requisições entre os módulos? E os tratamentos de observabilidade? Como podemos saber quantas requisições cada módulo gerou por segundo? Qual a latência de cada uma dessas requisições? Quantos erros ocorreram? Quem está chamando quem? Qual a melhor maneira de garantir a presença de mecanismos que possibilitem o tratamento destas questões pelos módulos da aplicação?
Estas soluções podem ser implementadas durante o desenvolvimento do código de cada um dos microsserviços. Considerando, porém, que cada módulo da aplicação pode ser gerido por um time diferente, pode ser uma tarefa extremamente complexa garantir que todos implementem as mesmas lógicas e mecanismos para todas as possíveis necessidades relacionadas à comunicação dos módulos na rede de serviços. Uma outra preocupação importante é que este tipo de abordagem pode ocasionar que os times de desenvolvimento utilizem grande parte de seu tempo desenvolvendo soluções para contornar preocupações de infraestrutura ao invés de desenvolver features, melhorias e soluções diretamente relacionadas ao negócio a que se destina a aplicação.
Malhas de Serviços
Uma malha de serviços (service mesh) é basicamente uma camada de infraestrutura configurável que gerencia a comunicação entre serviços de aplicações distribuídas, especialmente aquelas baseadas em microsserviços. Ela abstrai e centraliza funcionalidades essenciais levantadas anteriormente, tais como roteamento de tráfego, segurança, observabilidade, mecanismos de resiliência, autenticação, autorização e balanceamento de carga. Essa camada é geralmente composta por serviços de proxy implantados como sidecars ao lado de cada unidade do sistema, que interceptam e controlam o tráfego de rede, permitindo um controle detalhado e transparente da comunicação entre os componentes do sistema.
A malha de serviços é fundamental para facilitar a gestão de ambientes complexos, onde a comunicação entre microsserviços se torna um desafio através da implementação de recursos como monitoramento, registros em logs, rastreamento, controle dinâmico de tráfego, descoberta automática de serviços, estratégias de caching e aplicação de padrões de resiliência como retries e circuit breakers. Tudo isso é feito de forma transparente, ou seja, sem que os desenvolvedores precisem se preocupar com essas questões ao desenvolver o código dos serviços. Isso permite que as equipes foquem na entrega de valor e inovação, enquanto a malha cuida das preocupações transversais relacionadas à comunicação e segurança.
Arquitetonicamente, a malha de serviços é dividida em dois planos principais: o plano de dados, que é formado pelos proxies que gerenciam o tráfego em tempo real, e o plano de controle, responsável pela configuração, políticas e monitoramento da malha. Essa estrutura lógica permite que a malha opere de forma independente da linguagem de programação dos serviços e dos sistemas de gerenciamento de contêineres, integrando-se a ambientes de Kubernetes e outras plataformas de orquestração. Em resumo, a malha de serviços é uma solução essencial para garantir a eficiência, segurança e observabilidade em arquiteturas modernas de microsserviços.
Istio - Mas o que é Istio?
Istio é uma das malhas de serviços (service mesh) mais populares, poderosas e confiáveis. Criado pela Google, IBM e Lyft em 2016, o Istio é um projeto graduado na CNCF (Cloud Native Computing Foundation), ao lado de projetos como Kubernetes, Prometheus, ArgoCD, Cert-Manager, harbor e Helm.

O Istio garante que sistemas nativos para nuvem e sistemas distribuídos sejam resilientes, ajudando empresas modernas a manter suas cargas de trabalho em diversas plataformas enquanto permanecem conectadas e protegidas. Os recursos do Istio oferecem uma maneira uniforme e eficiente de proteger, conectar e monitorar serviços oferecendo possibilidades de:
- Comunicação segura entre serviços em um cluster com criptografia TLS mútuo (mTLS), autenticação e autorização robustas baseadas em identidade.
- Balanceamento de carga automático para tráfego HTTP, gRPC, WebSocket e TCP.
- Controle refinado do comportamento do tráfego com regras de roteamento avançadas, repetições (retries), failovers e injeção de falhas.
- Uma camada de políticas plugável e API de configuração, com suporte a controles de acesso, limites de taxa (rate limits) e cotas.
- Métricas, logs e rastreamentos (traces) automáticos para todo o tráfego dentro de um cluster, incluindo entrada (ingress) e saída (egress).
O Istio foi projetado para extensibilidade e pode atender a uma variedade de necessidades de implantação. O plano de controle (control plane) do Istio é executado no Kubernetes, e você pode adicionar aplicativos implantados nesse cluster à sua malha de serviços (mesh), estender a malha para outros clusters ou conectar até mesmo VMs ou outros endpoints fora do Kubernetes.
Arquitetura - Como ele funciona?
O Istio se utiliza de regras de firewall do Iptables e do proxy Envoy, outro projeto graduado da CNCF, para interceptar todo o tráfego de rede da malha, permitindo um amplo conjunto de recursos baseados em configurações previamente definidas. O plano de controle (control plane) recebe a configuração desejada, juntamente com sua visão dos serviços, e programa dinamicamente as instâncias de proxy Envoy no seu data plane, atualizando-os conforme as regras ou o ambiente mudam.

Control Plane
O control plane do Istio é a camada responsável por gerenciar e configurar os proxies Envoy que compõem o data plane, definindo as regras e políticas para o roteamento de tráfego, segurança, autenticação, autorização e coleta de telemetria entre os microsserviços. Ele atua como um centro de comando que distribui configurações, regras de tráfego, políticas de segurança e credenciais, garantindo a comunicação segura e eficiente entre os serviços sem a necessidade de modificar o código das aplicações. O control plane inclui componentes como o Pilot, que gerencia o tráfego e a descoberta de serviços, o Citadel, que cuida da segurança e certificados, e o Galley, que gerencia a configuração. Dessa forma, o control plane permite controlar, monitorar e proteger a malha de serviços de forma centralizada e dinâmica.
O IstioD atua como o cérebro do plano de controle do Istio, traduzindo regras de alto nível em configurações específicas para os proxies Envoy que fazem parte do plano de dados, gerencia a segurança via certificados para comunicação mTLS e do ponto de vista da observabilidade, o IstioD desempenha um papel fundamental na geração e exportação de métricas ricas e detalhadas, logs de acesso e rastreamentos distribuídos que permitem monitorar o comportamento dos serviços e do próprio plano de controle.
Data Plane
O data plane do Istio é composto por proxies inteligentes Envoy, implantados como sidecars ao lado das instâncias de aplicação, que interceptam, mediam e controlam todo o tráfego de rede entre os microsserviços. Esses proxies gerenciam o roteamento, balanceamento de carga, autenticação, autorização, criptografia TLS, injeção de falhas, circuit breakers e coleta de telemetria, tudo isso sem necessidade de alterações no código das aplicações. Ao operar diretamente no caminho dos dados, o data plane implementa as regras e políticas definidas pelo control plane, garantindo comunicação segura, resiliente e observável dentro da malha de serviços. Essa arquitetura permite adicionar funcionalidades avançadas de rede e segurança de forma transparente e dinâmica para os serviços
O Istio suporta dois modos de data planes:
- Modo sidecar, que implanta um proxy Envoy junto a cada pod iniciado no cluster ou em serviços executados em VMs (máquinas virtuais).
- Modo ambient, que utiliza um proxy de Camada 4 (L4) por nó e, opcionalmente, um proxy Envoy por namespace para recursos de Camada 7 (L7).
Mão na massa!
O primeiro passo para a instalação do Istio é a instalação do binário istioctl. Para instalar a última versão do binário pode-se utilizar o comando:
curl -L https://istio.io/downloadIstio | sh -
Em seguida vamos acessar o diretório do istio de acordo com a versão atual. Neste caso, a versão foi 1.25.2:
cd istio-1.25.2
Neste diretório vamos encontrar o binário do istioctl (no diretório bin/) e algumas aplicações de exemplo (diretório samples/).

O próximo passo é o mapeamento do binário istoctl ao path do seu sistema copiando o binário para o diretório /usr/local/bin ou outro diretório mapeado na variável PATH do seu linux:
sudo cp bin/istioctl /usr/local/bin/
Para validar se está tudo certo basta executar o binário com ocomando istioctl:

Instalação do Istio
Para este guia, utilizaremos o perfil de configuração de demonstração do istioctl instalado em um cluster Kubernetes do KIND - Kubernetes in Docker. O perfil de configuração de demonstração possui um bom conjunto de aplicações padrão prontas para a realização de testes e demonstrações das funcionalidades do Istio, mas há outros perfis para produção, teste de desempenho ou para utilização com o OpenShift.
Caso tenha alguma dúvida sobre como utilizar o Kind, no blog da 4Linux há um excelente tutorial de instalação da ferramenta no artigo Kubernetes – Criando um cluster local com Kind
Em versões anteriores do Istio, eram criados dois Gateways do Istio sendo um para Ingress e outro para Egress. Diferentemente dos Gateways do Istio, a criação de Gateways do Kubernetes, por padrão, também implanta servidores proxy de gateway. Como os Gateways do Istio não serão utilizados nesse exemplo, a implantação dos serviços padrão de gateway do Istio que normalmente são instalados como parte do perfil de demonstração não serão instaladas aqui.
A instalação do Istio sem os Istio Gateways pode ser realizada pelo manifesto demo-profile-no-gateways.yaml abaixo, encontrado no diretório de instalação do Istio, onde podemos observar o parâmetro enabled chaveado como false:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
spec:
profile: demo
components:
ingressGateways:
- name: istio-ingressgateway
enabled: false
egressGateways:
- name: istio-egressgateway
enabled: false
A instalação do manifesto pode ser feita utilizando o istioctl conforme abaixo:
istioctl install -f samples/bookinfo/demo-profile-no-gateways.yaml -y

A instalação pode ser validada verificando o pod e o serviço do istiod no recém-criado namespace istio-system:

Instalação dos CRDs do Kubernetes Gateway API
Os CRDs (Custom Resource Definitions) da Kubernetes Gateway API não vêm instalados por padrão na maioria dos clusters Kubernetes. Portanto, verifique se eles estão instalados antes de usar a Gateway API.
Caso queira saber mais sobre o Kubernetes Gateway API, aqui mesmo no blog exsite este outro artigo mais detalhado: Kubernetes Gateway API – um “adeus e obrigado” ao Ingress Controller
Caso os CRDs do Kubernetes Gateway API não estejam instalados, a instalação pode ser feita com o comando abaixo:
kubectl get crd gateways.gateway.networking.k8s.io &> /dev/null || \
{ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.2.1" | kubectl apply -f -; }

Deploy da aplicação
O aplicativo Bookinfo é um aplicativo de exemplo composto por quatro microsserviços separados, utilizados para demonstrar vários recursos do Istio. A aplicação exibe informações sobre um livro, semelhante a uma entrada de catálogo de uma livraria online. A página mostra uma descrição do livro, detalhes (ISBN, número de páginas, etc.) e algumas avaliações. A estrutura do app é dividida em quatro microsserviços separados:
- productpage: O microsserviço productpage chama os microsserviços details e reviews para preencher a página.
- details: O microsserviço details contém informações do livro.
- reviews: O microsserviço reviews contém as avaliações do livro e também chama o microsserviço ratings.
- ratings: O microsserviço ratings contém informações de classificação que acompanham as avaliações.
Existem 3 versões do microsserviço reviews:
- Versão v1: Não chama o serviço ratings.
- Versão v2: Chama o serviço ratings e exibe cada classificação como estrelas pretas de 1 a 5.
- Versão v3: Chama o serviço ratings e exibe cada classificação como estrelas vermelhas de 1 a 5.

Para podermos realizar o deploy da nossa aplicação de testes, iremos adicionar ao namespace default do Kubernetes uma etiqueta (label) que irá instruir o Isto a injetar automaticamente o sidecar com o Envoy Proxy nos pods deste namespace através do comando:
kubectl label namespace default istio-injection=enabled

Em seguida iremos realizar o deploy da aplicação através do arquivo samples/bookinfo/platform/kube/bookinfo.yaml:
kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml

Como adicionamos uma Label no namespace que induz o Istio a monitorar os recursos e injetar os sidecars com o Envoy Proxy em todos os pods do namespace, já podemos observar que cada Pod do nosso novo Deployment possui 2 contêineres:

Uma olhada mais de perto nas anotações do pod productpage-v1-9dbcc7688-dmxb2 também pode nos evidenciar que o Istio já entrou em ação:

Vamos validar que a nossa aplicação está sendo executada corretamente no cluster através da pesquisa pelo título HTML:
kubectl exec "$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')" -c ratings -- curl -sS productpage:9080/productpage | grep -o "<title>.*</title>"

A nossa aplicação já está funcional mas ainda não está acessível de fora do nosso cluster. Para isso vamos implementar os gateways de API e as rotas HTTP do Kubernetes Gateway API:
kubectl apply -f samples/bookinfo/gateway-api/bookinfo-gateway.yaml

Agora vamos alterar o tipo de serviço para ClusterIP adicionando uma anotação no Gateway bookinfo-gateway:
kubectl annotate gateway bookinfo-gateway networking.istio.io/service-type=ClusterIP --namespace=default

Acessando a aplicação
Uma vez instalados o Istio, o Kubernetes Gateway API, feito o deploy da aplicação e configurados os gateways, podemos acessar a nossa aplicação de testes. Para isso utilizaremos o recurso de Port-Forward do Kubernetes apontando a porta 8080 do nosso host para a porta 80 do cluster, onde temos o serviço de gateway bookinfo-gateway-istio escutando nesta porta:
kubectl port-forward svc/bookinfo-gateway-istio 8080:80
Agora é possível acessar a aplicação localmente com o endereço http://localhost:8080/productpage
:

Ao atualizar a página, é possível verificar que as resenhas e avaliações dos livros exibidas são diferentes, já que as requisições são distribuídas pelas diferentes versões do serviço reviews no namespace default do cluster.
Visualizando o Dashboard
O Istio possui integração com várias aplicações de telemetria diferentes que permitem entender melhor a estrutura da sua malha de serviços, exibir a topologia e/ou analisar sua integridade.
Vamos utilizar aqui as instalações dos dashboards do Kiali, Prometheus, Grafana, e do Jaeger disponíveis no diretório samples/addons com o comando abaixo:
kubectl apply -f samples/addons
E para verificar o status dos deployments você pode utilizar o comando abaixo:
kubectl rollout status deployment -n istio-system

Em seguida basta iniciar o Kiali Dashboards com o istioctl com o conforme o comando:
istioctl dashboard kiali
Este comando irá abrir o Kiali no seu navegador padrão:

Para que possamos visualizar o tráfego em nossa aplicação, primeiro precisaremos gerar tráfego. Para tal, utilizaremos um conteiner do Alpine Linux com o CURL. Inicialmente iremos iniciar um Pod temporário (Será excluído após o teste - parâmetro "--rm") do Alpine Linux e uma sessão de terminal com o shell sh, conforme o comando abaixo:
kubectl run -i --tty --rm alpine --image=alpine -- sh
Em seguida iremos atualizar os repositórios do APK e instalar o CURL no POD:
apk update && apk add curl
Para gerarmos o tráfego iremos utilizar em nosso pod de teste o comando a seguir onde são disparadas 500 requisições HTTP para a URL do nosso gateway com o path "/productpage":
for i in $(seq 1 500); do curl -s -o /dev/null "bookinfo-gateway-istio.default.svc.cluster.local/productpage" && echo $i; done
Agora basta acessarmos o gráfico de tráfego do Kiali para visualizarmos o gráfico das requisições que acabamos de gerar em nossa malha, incluindo, por exemplo, a visualização do serviço de reviews balanceando a carga entre os deployments reviews-V1, reviews-V2 e reviews-V3

Também é possível utilizar o Kiali para visualizar, logs, métricas de tráfego entrante e saite e as configurações do sidecar de Proxy do Envoy acessando o menu Workloads -> namespace: default -> productpage-V1

Conclusão
Conclusão
O Istio surge como uma excelente solução opensource para os desafios trazidos pela arquitetura de microsserviços, especialmente os desafios relacionados à comunicação entre os serviços de baixo acoplamento de uma aplicação distribuída. Ao fornecer uma malha de serviços completa, ele simplifica a implementação de funcionalidades críticas de comunicação e redes sem exigir alterações significativas no código da aplicação. Vimos também que a sua arquitetura, dividida em Control Plane e Data Plane, permite um gerenciamento centralizado das políticas de rede enquanto mantém o tráfego eficiente e seguro no nível dos proxies (Envoy).
A parte prática demonstrou como é simples e viável começar a utilizar o Istio, desde a instalação até o deploy de uma aplicação de exemplo, destacando a sua integração nativa com o Kubernetes e a facilidade de visualização dos fluxos de tráfego por meio dos dashboards do Kiali mas outros exemplos com este mesmo deployment podem ser verificados na documentação oficial do Projeto Istio como o roteamento de requisições, consulta de métricas do Prometheus ou como visualizar as suas métricas utilizando o Prometheus e Grafana.
Por fim, o Istio se consolida cada vez mais como uma ferramenta essencial para equipes que buscam escalabilidade, segurança e observabilidade em ambientes distribuídos. Sua capacidade de abstrair complexidades operacionais permite que os desenvolvedores foquem na lógica de negócio, enquanto as operações garantem um ambiente estável e bem monitorado.
Fontes: