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

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

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 kubectl configurado corretamente. Você também precisará do istioctl, o CLI oficial do Istio, que facilita instalação e debugging. Um cluster local com kind ou minikube é suficiente para aprender.

Verifique sua versão do Kubernetes:

kubectl version --short

Instalando o Istio

A forma mais direta de instalar o Istio é usar o istioctl. Primeiro, baixe a release mais recente:

curl -L https://istio.io/downloadIstio | sh -
cd istio-1.x.x  # substitua pela versão que você baixou
export PATH=$PWD/bin:$PATH

Agora instale o Istio no seu cluster com o perfil demo (ideal para aprendizado):

istioctl install --set profile=demo -y

O Istio criará um namespace chamado istio-system 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:

kubectl get pods -n istio-system

Habilitando a Injeção Automática de Proxies

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:

kubectl create namespace production
kubectl label namespace production istio-injection=enabled

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 istio-proxy.

Traffic Management com Istio

Entendendo VirtualService e DestinationRule

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

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

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

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

apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: api
  namespace: production
spec:
  hosts:
  - api
  http:
  - match:
    - uri:
        prefix: "/health"
    route:
    - destination:
        host: api
        subset: v1
  - route:
    - destination:
        host: api
        subset: v1
      weight: 80
    - destination:
        host: api
        subset: v2
      weight: 20

E o DestinationRule para definir os subsets e políticas de conexão:

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

O que está acontecendo aqui? Quando um cliente acessa o serviço api, o Istio verifica se a URI começa com /health — 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.

Retry Policy e Timeout

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

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

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.

Segurança com mTLS (Mutual TLS)

O Que é mTLS e Por Que Importa

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.

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

Ativando mTLS Strict

Ative mTLS strict para todo o namespace production:

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
  namespace: production
spec:
  mtls:
    mode: STRICT

Aplique isso com kubectl apply -f 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.

AuthorizationPolicy: Controle de Acesso Granular

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

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: api-policy
  namespace: production
spec:
  selector:
    matchLabels:
      app: api
  action: ALLOW
  rules:
  - from:
    - source:
        principals:
        - "cluster.local/ns/production/sa/frontend"
    to:
    - operation:
        methods: ["GET", "POST"]
        paths: ["/api/v1/*"]

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

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

Certificados e Renovação Automática

O Istio gerencia certificados automaticamente. Você pode visualizá-los com:

kubectl exec -it <pod-name> -n production -c istio-proxy -- openssl s_client -connect <target-service>:443

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

Observabilidade e Debugging

Entendendo Logs de Tráfego

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:

kubectl logs <pod-name> -n production -c istio-proxy --tail=50

Você verá mensagens como:

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

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

Verificando Conectividade com istioctl

Diagnostique problemas de conectividade rapidamente:

istioctl analyze -n production

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

Para testar tráfego manualmente, use kubectl exec e curl:

kubectl exec -it <frontend-pod> -n production -- curl -v http://api/api/v1/users

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

Conclusão

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 VirtualService e DestinationRule permite canary deployments, retry automático e detecção de falhas sem tocar no código. Terceiro, mTLS + AuthorizationPolicy transforma seu cluster em uma fortaleza onde cada serviço autentica seus peers e apenas tráfego autorizado é permitido.

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.

Referências


Artigos relacionados