Docker & Kubernetes

O que Todo Dev Deve Saber sobre Istio em Kubernetes: Instalação, Traffic Management e mTLS

13 min de leitura

O que Todo Dev Deve Saber sobre Istio em Kubernetes: Instalação, Traffic Management e mTLS

Introdução ao Istio: O Service Mesh que Seu Kubernetes Precisa O Istio é um service mesh — uma camada de infraestrutura que se posiciona entre seus serviços em Kubernetes para gerenciar a comunicação entre eles. Se você está acostumado a pensar em microserviços rodando isoladamente em pods, o Istio oferece controle fino sobre como esses serviços conversam uns com os outros, sem modificar o código da aplicação. A razão pela qual você deve aprender Istio agora é simples: conforme seus clusters Kubernetes crescem, gerenciar tráfego, segurança e observabilidade entre centenas de serviços fica caótico. O Istio resolve esse problema injetando um proxy (Envoy) ao lado de cada pod, criando um plano de dados distribuído. Você não precisa más configurar manualmente cada conexão — o Istio faz isso por você, declarativamente, através de CRDs (Custom Resource Definitions). Instalação e Configuração do Istio Pré-requisitos e Ambiente Antes de começar, certifique-se de que você tem um cluster Kubernetes rodando (versão 1.20+) e o

<h2>Introdução ao Istio: O Service Mesh que Seu Kubernetes Precisa</h2>

<p>O Istio é um service mesh — uma camada de infraestrutura que se posiciona entre seus serviços em Kubernetes para gerenciar a comunicação entre eles. Se você está acostumado a pensar em microserviços rodando isoladamente em pods, o Istio oferece controle fino sobre como esses serviços conversam uns com os outros, sem modificar o código da aplicação.</p>

<p>A razão pela qual você deve aprender Istio agora é simples: conforme seus clusters Kubernetes crescem, gerenciar tráfego, segurança e observabilidade entre centenas de serviços fica caótico. O Istio resolve esse problema injetando um proxy (Envoy) ao lado de cada pod, criando um plano de dados distribuído. Você não precisa más configurar manualmente cada conexão — o Istio faz isso por você, declarativamente, através de CRDs (Custom Resource Definitions).</p>

<h2>Instalação e Configuração do Istio</h2>

<h3>Pré-requisitos e Ambiente</h3>

<p>Antes de começar, certifique-se de que você tem um cluster Kubernetes rodando (versão 1.20+) e o <code>kubectl</code> configurado corretamente. Você também precisará do <code>istioctl</code>, o CLI oficial do Istio, que facilita instalação e debugging. Um cluster local com <code>kind</code> ou <code>minikube</code> é suficiente para aprender.</p>

<p>Verifique sua versão do Kubernetes:</p>

<pre><code class="language-bash">kubectl version --short</code></pre>

<h3>Instalando o Istio</h3>

<p>A forma mais direta de instalar o Istio é usar o <code>istioctl</code>. Primeiro, baixe a release mais recente:</p>

<pre><code class="language-bash">curl -L https://istio.io/downloadIstio | sh -

cd istio-1.x.x # substitua pela versão que você baixou

export PATH=$PWD/bin:$PATH</code></pre>

<p>Agora instale o Istio no seu cluster com o perfil <code>demo</code> (ideal para aprendizado):</p>

<pre><code class="language-bash">istioctl install --set profile=demo -y</code></pre>

<p>O Istio criará um namespace chamado <code>istio-system</code> e instalará os componentes principais: Istiod (control plane), os proxies Envoy (data plane), e Prometheus para coleta de métricas. Você pode verificar o status com:</p>

<pre><code class="language-bash">kubectl get pods -n istio-system</code></pre>

<h3>Habilitando a Injeção Automática de Proxies</h3>

<p>O Istio funciona injetando um sidecar proxy (Envoy) em cada pod. Para isso acontecer automaticamente, você precisa adicionar um label ao seu namespace. Crie um namespace de teste e habilite a injeção:</p>

<pre><code class="language-bash">kubectl create namespace production

kubectl label namespace production istio-injection=enabled</code></pre>

<p>Agora, qualquer pod criado nesse namespace terá o Envoy injetado automaticamente. Se você listar os containers de um pod criado aqui, verá dois: seu serviço e o proxy <code>istio-proxy</code>.</p>

<h2>Traffic Management com Istio</h2>

<h3>Entendendo VirtualService e DestinationRule</h3>

<p>O Istio oferece dois recursos principais para controlar tráfego: <code>VirtualService</code> e <code>DestinationRule</code>. Pense assim: o <code>VirtualService</code> é quem <em>rota</em> o tráfego (decidindo para onde ele vai), enquanto o <code>DestinationRule</code> define <em>como</em> ele chega lá (balanceamento, timeout, retry policies).</p>

<p>Vamos criar um exemplo prático. Suponha que você tem um serviço <code>api</code> com duas versões rodando em Kubernetes. Primeiro, crie as deployments:</p>

<pre><code class="language-yaml">apiVersion: apps/v1

kind: Deployment

metadata:

name: api-v1

namespace: production

spec:

replicas: 2

selector:

matchLabels:

app: api

version: v1

template:

metadata:

labels:

app: api

version: v1

spec:

containers:

  • name: api

image: myregistry/api:v1

ports:

  • containerPort: 8080

---

apiVersion: apps/v1

kind: Deployment

metadata:

name: api-v2

namespace: production

spec:

replicas: 2

selector:

matchLabels:

app: api

version: v2

template:

metadata:

labels:

app: api

version: v2

spec:

containers:

  • name: api

image: myregistry/api:v2

ports:

  • containerPort: 8080

---

apiVersion: v1

kind: Service

metadata:

name: api

namespace: production

spec:

ports:

  • port: 80

targetPort: 8080

name: http

selector:

app: api</code></pre>

<p>Agora, use o <code>VirtualService</code> para rotear 80% do tráfego para v1 e 20% para v2 (canary deployment):</p>

<pre><code class="language-yaml">apiVersion: networking.istio.io/v1beta1

kind: VirtualService

metadata:

name: api

namespace: production

spec:

hosts:

  • api

http:

  • match:
  • uri:

prefix: &quot;/health&quot;

route:

  • destination:

host: api

subset: v1

  • route:
  • destination:

host: api

subset: v1

weight: 80

  • destination:

host: api

subset: v2

weight: 20</code></pre>

<p>E o <code>DestinationRule</code> para definir os subsets e políticas de conexão:</p>

<pre><code class="language-yaml">apiVersion: networking.istio.io/v1beta1

kind: DestinationRule

metadata:

name: api

namespace: production

spec:

host: api

trafficPolicy:

connectionPool:

tcp:

maxConnections: 100

http:

http1MaxPendingRequests: 50

maxRequestsPerConnection: 2

outlierDetection:

consecutive5xxErrors: 5

interval: 30s

baseEjectionTime: 30s

subsets:

  • name: v1

labels:

version: v1

  • name: v2

labels:

version: v2</code></pre>

<p>O que está acontecendo aqui? Quando um cliente acessa o serviço <code>api</code>, o Istio verifica se a URI começa com <code>/health</code> — se sim, roteia 100% para v1. Caso contrário, 80% vai para v1 e 20% para v2. A política de tráfego adiciona timeout, limite de conexões e detecção de anomalias (ejection): se um pod retornar 5 erros 5xx consecutivos em 30 segundos, ele é temporariamente removido.</p>

<h3>Retry Policy e Timeout</h3>

<p>Adicione resiliência ao seu <code>VirtualService</code> com retry e timeout. Isso é crítico em produção:</p>

<pre><code class="language-yaml">apiVersion: networking.istio.io/v1beta1

kind: VirtualService

metadata:

name: api

namespace: production

spec:

hosts:

  • api

http:

  • route:
  • destination:

host: api

subset: v1

retries:

attempts: 3

perTryTimeout: 2s

timeout: 10s</code></pre>

<p>Aqui, se uma requisição falhar, o Istio tentará até 3 vezes, aguardando 2 segundos por tentativa. Se o tempo total ultrapassar 10 segundos, a requisição é abortada. Sem isso, falhas ocasionais cascateiam.</p>

<h2>Segurança com mTLS (Mutual TLS)</h2>

<h3>O Que é mTLS e Por Que Importa</h3>

<p>mTLS significa que tanto o cliente quanto o servidor se autenticam mutuamente usando certificados TLS. No contexto do Kubernetes, sem mTLS, tráfego entre pods viaja em texto plano pela rede — qualquer pod no mesmo nó pode sniffar seu tráfego. O Istio resolve isso automaticamente: cada proxy Envoy obtém um certificado assinado pela CA do Istio e usa-o para criptografar toda comunicação inter-pod.</p>

<p>O Istio tem dois modos de segurança: <code>PERMISSIVE</code> (permite tanto tráfego mTLS quanto plain text, útil na migração) e <code>STRICT</code> (apenas mTLS, recomendado em produção).</p>

<h3>Ativando mTLS Strict</h3>

<p>Ative mTLS strict para todo o namespace <code>production</code>:</p>

<pre><code class="language-yaml">apiVersion: security.istio.io/v1beta1

kind: PeerAuthentication

metadata:

name: default

namespace: production

spec:

mtls:

mode: STRICT</code></pre>

<p>Aplique isso com <code>kubectl apply -f</code> e todos os pods no namespace exigirão mTLS. Se um cliente não-Istio (ou um pod fora do namespace) tentar se conectar, a conexão será recusada.</p>

<h3>AuthorizationPolicy: Controle de Acesso Granular</h3>

<p>Com mTLS, você sabe quem é quem. Agora controle quem pode falar com quem usando <code>AuthorizationPolicy</code>. Por exemplo, apenas o serviço <code>frontend</code> pode acessar o serviço <code>api</code>:</p>

<pre><code class="language-yaml">apiVersion: security.istio.io/v1beta1

kind: AuthorizationPolicy

metadata:

name: api-policy

namespace: production

spec:

selector:

matchLabels:

app: api

action: ALLOW

rules:

  • from:
  • source:

principals:

  • &quot;cluster.local/ns/production/sa/frontend&quot;

to:

  • operation:

methods: [&quot;GET&quot;, &quot;POST&quot;]

paths: [&quot;/api/v1/*&quot;]</code></pre>

<p>Este resource diz: &quot;Permita requisições GET e POST em <code>/api/v1/*</code> apenas se virem do service account <code>frontend</code> no namespace <code>production</code>.&quot; Qualquer outro tráfego é negado.</p>

<blockquote><p><strong>Dica prática:</strong> Use <code>principals</code> baseado em service accounts (identidades Kubernetes), não em IPs ou nomes de pods, porque estes mudam frequentemente.</p></blockquote>

<h3>Certificados e Renovação Automática</h3>

<p>O Istio gerencia certificados automaticamente. Você pode visualizá-los com:</p>

<pre><code class="language-bash">kubectl exec -it &lt;pod-name&gt; -n production -c istio-proxy -- openssl s_client -connect &lt;target-service&gt;:443</code></pre>

<p>O Istio renova certificados automaticamente antes da expiração (padrão: 24 horas). Você não precisa fazer nada — isso é transparente.</p>

<h2>Observabilidade e Debugging</h2>

<h3>Entendendo Logs de Tráfego</h3>

<p>Com Istio, você pode acessar logs de todas as requisições. O sidecar proxy registra cada conexão. Para ver o que está acontecendo, inspecione os logs do proxy:</p>

<pre><code class="language-bash">kubectl logs &lt;pod-name&gt; -n production -c istio-proxy --tail=50</code></pre>

<p>Você verá mensagens como:</p>

<pre><code>[2024-01-15T10:23:45.123Z] &quot;GET /api/v1/users HTTP/1.1&quot; 200 - via_upstream - &quot;-&quot; 0 250 15 14 &quot;-&quot; &quot;curl/7.64.1&quot; &quot;abcd-1234&quot; &quot;api:80&quot; &quot;10.0.0.5:8080&quot; outbound|80|v1|api.production.svc.cluster.local ...</code></pre>

<p>Isso mostra: método HTTP, status (200), latência (15ms), qual subset respondeu (v1), e muito mais.</p>

<h3>Verificando Conectividade com istioctl</h3>

<p>Diagnostique problemas de conectividade rapidamente:</p>

<pre><code class="language-bash">istioctl analyze -n production</code></pre>

<p>Este comando verifica configurações e avisa sobre problemas comuns — como um <code>VirtualService</code> sem <code>DestinationRule</code> correspondente, ou <code>AuthorizationPolicy</code> que bloqueia tráfego legítimo.</p>

<p>Para testar tráfego manualmente, use <code>kubectl exec</code> e curl:</p>

<pre><code class="language-bash">kubectl exec -it &lt;frontend-pod&gt; -n production -- curl -v http://api/api/v1/users</code></pre>

<p>Se receber um erro de conexão recusada após ativar <code>STRICT</code> mTLS, é porque o cliente ou a policy de autorização estão bloqueando. Use os logs para identificar.</p>

<h2>Conclusão</h2>

<p>Você aprendeu três coisas críticas: Primeiro, o Istio não é mágica — é um proxy (Envoy) rodando ao lado de cada pod, e você controla seu comportamento através de CRDs declarativos. Segundo, traffic management via <code>VirtualService</code> e <code>DestinationRule</code> permite canary deployments, retry automático e detecção de falhas sem tocar no código. Terceiro, mTLS + <code>AuthorizationPolicy</code> transforma seu cluster em uma fortaleza onde cada serviço autentica seus peers e apenas tráfego autorizado é permitido.</p>

<p>O próximo passo é praticar: crie um cluster local, implante dois serviços simples, e experimente rotear tráfego entre eles. Depois, ative mTLS e veja como o tráfego plain text para de funcionar. Essa é a melhor forma de internalizar esses conceitos.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://istio.io/latest/docs/" target="_blank" rel="noopener noreferrer">Documentação Oficial do Istio</a></li>

<li><a href="https://istio.io/latest/docs/concepts/traffic-management/" target="_blank" rel="noopener noreferrer">Istio Traffic Management</a></li>

<li><a href="https://istio.io/latest/docs/concepts/security/" target="_blank" rel="noopener noreferrer">Istio Security and mTLS</a></li>

<li><a href="https://kubernetes.io/docs/tasks/service-mesh/istio-intro/" target="_blank" rel="noopener noreferrer">Getting Started with Istio on Kubernetes</a></li>

<li><a href="https://www.envoyproxy.io/docs/envoy/latest/" target="_blank" rel="noopener noreferrer">Envoy Proxy Documentation</a></li>

</ul>

<p>&lt;!-- FIM --&gt;</p>

Comentários

Mais em Docker & Kubernetes

O que Todo Dev Deve Saber sobre Kubernetes Events e Auditoria: Rastreando Mudanças no Cluster
O que Todo Dev Deve Saber sobre Kubernetes Events e Auditoria: Rastreando Mudanças no Cluster

Introdução: Por que Rastrear Mudanças no Kubernetes? No dia a dia de um clust...

Dominando Docker Compose Avançado: Profiles, Depends On, Healthchecks e Secrets em Projetos Reais
Dominando Docker Compose Avançado: Profiles, Depends On, Healthchecks e Secrets em Projetos Reais

Docker Compose Avançado: Profiles, Depends On, Healthchecks e Secrets Quando...

RBAC em Kubernetes: Roles, ClusterRoles, Bindings e ServiceAccounts na Prática
RBAC em Kubernetes: Roles, ClusterRoles, Bindings e ServiceAccounts na Prática

O que é RBAC e por que você precisa disso? RBAC (Role-Based Access Control) é...