O padrão Sidecar: estendendo microsserviços sem modificar o código

O padrão Sidecar: estendendo microsserviços sem modificar o código

Em sistemas modernos nativos da nuvem, espera-se que os microsserviços façam muito mais do que executar a lógica de negócios. Eles devem lidar com o registro em log, gerenciar certificados SSL/TLS, coletar métricas, implementar mecanismos de nova tentativa e coordenar comunicações seguras com outros serviços.

Se incorporarmos toda essa funcionalidade transversal diretamente na base de código de cada aplicativo, acabaremos com inchaço de código, acoplamento rígido e aprisionamento de linguagem.

É aqui que entra o Sidecar Pattern. Neste guia, detalharemos o que é o padrão Sidecar, por que ele é essencial para arquiteturas modernas de microsserviços e como ele funciona usando analogias simples e exemplos de configuração do Kubernetes.


A analogia do mundo real: o sidecar da motocicleta

A maneira mais fácil de entender esse padrão é pensar em uma motocicleta com carro lateral.

Diagrama de arquitetura do padrão Sidecar mostrando aplicativos e contêineres Sidecar dentro de um pod

Imagine que você tem uma motocicleta de alto desempenho. Ele foi projetado para fazer uma coisa excepcionalmente bem: transportar um passageiro rapidamente. Agora, suponha que você precise transportar a bagagem do passageiro ou adicionar um assento extra.

Você poderia redesenhar completamente o quadro, o motor e as rodas da motocicleta para transformá-la em um carro. No entanto, isso exige um esforço enorme, arruína a simplicidade da bicicleta e dificulta a sua manutenção.

Em vez disso, você anexa um sidecar.

O sidecar é uma unidade separada e independente que se conecta à motocicleta. Ele compartilha a jornada da motocicleta, vai aonde a bicicleta vai e opera em conjunto. No entanto, o motor central da motocicleta permanece intacto.

Na arquitetura de software:

  • O Motorcycle é o contêiner principal do seu aplicativo (executando sua lógica de negócios principal, como checkout ou autenticação de usuário).
  • O Sidecar é um contêiner auxiliar separado (executando tarefas utilitárias, como encerramento de SSL, monitoramento ou envio de log).
  • A jornada é o ciclo de vida da implantação (por exemplo, um pod do Kubernetes).

O problema: preocupações transversais e inchaço do código

Antes dos sidecars, os desenvolvedores precisavam incluir bibliotecas auxiliares diretamente no código de seus aplicativos. Por exemplo, se você quisesse enviar logs para um servidor central, importaria uma biblioteca de logs. Se precisar de métricas, você adicionou um SDK de métricas.

Esta abordagem baseada em biblioteca criou vários desafios significativos:

  • Aprisionamento de linguagem: se uma biblioteca de monitoramento for escrita apenas em Go, você não poderá usá-la facilmente em um microsserviço Python ou Java. Você precisa encontrar ou construir uma biblioteca para cada linguagem da sua pilha.
  • Poluição de código: a lógica de negócios fica sobrecarregada com códigos específicos da infraestrutura para novas tentativas, descoberta de serviços, criptografia e registro em log.
  • Atualizações complexas: se uma vulnerabilidade de segurança for encontrada na biblioteca de comunicação, cada microsserviço deverá atualizar sua dependência, recompilar e reimplantar.
  • Contenção de recursos: o código auxiliar é executado no mesmo processo de tempo de execução do aplicativo principal, o que significa que um vazamento de memória no registrador pode travar todo o seu aplicativo principal.

A solução: o padrão Sidecar

O Sidecar Pattern resolve esses problemas removendo as tarefas auxiliares do processo principal do aplicativo e colocando-as em um processo separado e independente, executado ao lado do aplicativo.

Em ambientes em contêineres como o Kubernetes, o contêiner do aplicativo e o contêiner secundário são executados dentro do mesmo Pod. Porque eles compartilham o mesmo pod:

  • Mesmo Namespace de Rede: Eles compartilham o mesmo endereço IP e portas de rede. Eles podem conversar entre si instantaneamente através de localhost com latência praticamente zero.
  • Volumes de armazenamento compartilhado: Eles podem acessar exatamente o mesmo armazenamento em disco, permitindo que o sidecar leia arquivos de log ou carregue arquivos de configuração escritos pelo aplicativo principal.
  • Ciclo de vida idêntico: o arquivo secundário é implantado, iniciado, interrompido e dimensionado junto com o aplicativo primário.

Principais casos de uso do padrão Sidecar

Sidecars são incrivelmente versáteis. Algumas das aplicações mais comuns incluem:

1. Proxy de malha de serviço (por exemplo, Envoy, Linkerd)

Em vez de seu aplicativo fazer chamadas HTTP diretas para outros serviços, ele envia solicitações para seu proxy secundário local. O proxy sidecar lida com roteamento, novas tentativas, balanceamento de carga, quebra de circuito e criptografia TLS mútua (mTLS) e, em seguida, encaminha a solicitação. O aplicativo permanece completamente inconsciente dessas complexidades de rede.

2. Coleta e encaminhamento de log (por exemplo, Fluent Bit)

Seu aplicativo simplesmente grava suas instruções de log na saída padrão ou em um arquivo de log local. Um contêiner secundário monitora esse arquivo, analisa os logs e os encaminha para um mecanismo de análise central como Elasticsearch ou Datadog.

3. Configuração e recarga secreta

Um sidecar pode monitorar um servidor remoto (como Consul ou Vault) para atualizações de configuração ou rotações de chaves criptográficas. Quando uma alteração é detectada, ele baixa os novos arquivos para um volume compartilhado e sinaliza ao aplicativo principal para recarregá-los, sem precisar reiniciar.


Exemplo de implementação do Kubernetes

Configurar um sidecar é simples no Kubernetes. Aqui está uma configuração YAML simples mostrando um contêiner de aplicativo gravando logs em um volume compartilhado e um contêiner secundário Fluent Bit lendo e enviando esses logs:

apiVersion: v1
kind: Pod
metadata:
  name: app-with-logging-sidecar
  labels:
    app: billing-service
spec:
  containers:
    # 1. Primary Application Container
    - name: web-app
      image: node:18-alpine
      command: ["/bin/sh", "-c"]
      args:
        - >
          while true; do
            echo "$(date) [INFO] Transaction processed successfully" >> /var/log/app/output.log;
            sleep 5;
          done
      volumeMounts:
        - name: shared-logs
          mountPath: /var/log/app

    # 2. Sidecar Container (Log Shipper)
    - name: log-shipper
      image: fluent/fluent-bit:latest
      volumeMounts:
        - name: shared-logs
          mountPath: /var/log/app
      # In a real setup, Fluent Bit config would read /var/log/app/output.log
      # and forward it to an external logging system.

  # Shared disk storage accessible by both containers
  volumes:
    - name: shared-logs
      emptyDir: {}

Prós e contras do padrão Sidecar

Como qualquer padrão de design, os sidecars apresentam vantagens e desvantagens:

Vantagem (Pró) Desvantagem (Con)
Agnóstico de idioma: o sidecar é executado em seu próprio ambiente. Você pode usar o mesmo auxiliar auxiliar próximo aos aplicativos Go, Java, Python ou Ruby. Sobrecarga de recursos: a execução de vários contêineres por pod aumenta o consumo de CPU e memória.
Ciclo de vida dissociado: as equipes de infraestrutura podem atualizar os patches de segurança do sidecar sem mexer no código do aplicativo. Maior complexidade: gerenciar o dobro de contêineres complica as configurações de implantação, depuração e agendamento.
Isolamento independente de falhas: se o contêiner secundário travar, o Kubernetes poderá reiniciá-lo automaticamente sem desativar o aplicativo principal. Ligeira latência de rede: o roteamento de tráfego por meio de um sidecar de proxy local adiciona um pequeno salto, embora geralmente seja insignificante (< 1ms).

Conclusão

O padrão Sidecar é um elemento fundamental das arquiteturas modernas nativas da nuvem. Ao isolar preocupações transversais – como proxy de rede, segurança, registro e gerenciamento de configuração – em um processo complementar separado, ele permite que os desenvolvedores se concentrem puramente na criação de valor comercial.

Embora introduza sobrecarga extra de recursos e exija plataformas de orquestração de contêineres como o Kubernetes para um gerenciamento eficaz, os benefícios de bases de código mais limpas, flexibilidade de linguagem e escalonamento independente o tornam um padrão indispensável para microsserviços corporativos.


Explore mais insights sobre desenvolvimento de software e engenharia de back-end no Blog Ghaznix →