Blog

Um Guia Passo a Passo para Isolamento Multilocatário no Docker

Isole cargas de trabalho multilocatárias no Docker controlando os custos de hospedagem. Saiba como configurar namespaces, cgroups, políticas de rede e hardening de runtime.

Resumo

Gerenciar infraestrutura compartilhada para campanhas de múltiplos clientes ou propriedades web internas frequentemente gera atritos com a liderança executiva devido a custos de hospedagem e segurança de dados. Os contêineres Docker oferecem uma alternativa leve às máquinas virtuais dedicadas, mas as configurações padrão deixam lacunas graves de isolamento. Uma verdadeira multilocação (multi-tenancy) exige limites bem definidos nos níveis de kernel, processo, rede e armazenamento. Este guia apresenta uma estrutura prática em cinco etapas para proteger implantações multilocatárias no Docker usando primitivas nativas de isolamento do Linux. Você aprenderá como aplicar cotas de recursos, restringir privilégios de processos, segmentar redes de contêineres e selecionar a camada de isolamento ideal. Seguindo este planejamento, você protegerá os ambientes dos locatários e defenderá os orçamentos de infraestrutura diante dos tomadores de decisão não técnicos.

Seu gestor não técnico entra na sua sala com a fatura de hospedagem em nuvem do mês passado impressa. Os custos aumentaram, mas várias landing pages de alta prioridade sofreram picos de latência durante o lançamento simultâneo de um produto. Ele pede que você explique por que os ativos de marketing compartilham servidores, se os dados dos clientes estão expostos e por que a equipe não pode criar uma máquina virtual dedicada e cara para cada campanha individual.

Fornecer a cada propriedade digital sua própria máquina virtual (VM) elimina o problema de "vizinhos barulhentos" (noisy neighbors), mas consome rapidamente seu orçamento operacional. Implantações padrão do Docker resolvem o problema de custos ao rodar múltiplos sites no mesmo kernel do sistema operacional, mas configurações padrão deixam brechas de isolamento perigosas. Se a aplicação de um locatário sofrer com um script descontrolado ou uma invasão maliciosa, todas as outras aplicações hospedadas no mesmo host estarão em risco.

Use este guia técnico passo a passo para configurar um isolamento multilocatário rigoroso no Docker. Implemente estas cinco etapas operacionais para proteger a estabilidade do sistema, isolar dados de locatários e traduzir escolhas técnicas de infraestrutura em valor de negócio claro para a sua liderança.


1. Aplique Cotas Rígidas de Recursos Usando Control Groups

Defina limites explícitos de CPU, memória e E/S de disco em cada contêiner imediatamente. Quando múltiplos locatários compartilham o mesmo host, contêineres sem restrições competem por recursos do sistema. Uma única consulta descontrolada ao banco de dados ou uma campanha de alto tráfego pode consumir toda a memória do host, acionando o Out-Of-Memory (OOM) killer do Linux para encerrar processos arbitrários do sistema.

Os control groups (cgroups) do Linux determinam quanta capacidade computacional um contêiner pode consumir. Aplique esses limites diretamente nas suas definições de implantação:

services:
  tenant_app:
    image: nginx:alpine
    deploy:
      resources:
        limits:
          cpus: '0.75'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
  • Limites de Memória (limits.memory): Estabelece um teto rígido. Se o contêiner ultrapassar 512 megabytes, o kernel encerra os processos dentro desse contêiner sem prejudicar os locatários vizinhos.
  • Reservas de Memória (reservations.memory): Garante uma alocação mínima de memória para que aplicações de baixo tráfego continuem responsivas.
  • Limites de CPU (limits.cpus): Restringe o contêiner a uma fração máxima dos núcleos de CPU disponíveis, evitando que um único locatário monopolize a CPU.

Ao justificar essa arquitetura para executivos não técnicos, explique os cgroups como medidores de energia individuais. Assim como locatários em um edifício comercial pagam pelo próprio consumo de eletricidade em vez de sobrecarregar o disjuntor principal, os cgroups garantem que uma landing page de alto tráfego nunca derrube o portal de geração de leads de outro cliente. Para uma análise mais aprofundada dos prós e contras arquiteturais, confira nosso guia sobre como projetar uma arquitetura multilocatária.


2. Segmente os Processos dos Locatários com Namespaces e Usuários Não-Root

Nunca execute processos de contêiner como o usuário padrão root. Em ambientes comuns de contêiner Linux, o root dentro de um contêiner corresponde ao root no kernel do host subjacente, a menos que seja explicitamente remapeado. Se um invasor comprometer uma aplicação web em execução como root, ele obterá privilégios elevados sobre todo o host compartilhado.

Imponha o isolamento de processos por meio de namespaces de usuário e execução obrigatória sem root:

  1. Defina usuários de runtime sem privilégios: Crie usuários de serviço dedicados e de baixo privilégio em seus Dockerfiles.
    FROM php:8.2-fpm-alpine
    RUN addgroup -g 10001 tenantgroup && \
        adduser -u 10001 -D -G tenantgroup tenantuser
    USER tenantuser
    
  2. Habilite User Namespaces (userns-remap): Configure o daemon do Docker (/etc/docker/daemon.json) para remapear os IDs de usuário do contêiner para uma faixa sem privilégios no host.
    {
      "userns-remap": "default"
    }
    

Os namespaces do Linux particionam a visibilidade do sistema. O namespace de Process ID (PID) garante que o Locatário A não consiga visualizar, enviar sinais ou encerrar processos pertencentes ao Locatário B. O namespace Mount (MNT) dá a cada locatário uma visão isolada do sistema de arquivos, enquanto os namespaces IPC bloqueiam a comunicação interprocessos não autorizada.

O remapeamento de namespaces de usuário neutraliza vetores de escape de contêineres: um processo que acredita ser root (UID 0) dentro do contêiner é mapeado para um ID sem privilégios (como UID 165536) na máquina host. Se uma vulnerabilidade romper as barreiras do contêiner, o invasor cairá em um terminal sem privilégios, incapaz de modificar configurações do host ou acessar diretórios de locatários vizinhos.


3. Remova Privilégios do Kernel e Imponha Sistemas de Arquivos Somente Leitura

Reduza ao mínimo as Linux capabilities disponíveis e torne o sistema de arquivos raiz do contêiner imutável na inicialização. Os runtimes padrão de contêiner concedem cerca de uma dúzia de capabilities do kernel Linux, muitas das quais aplicações web nunca utilizam. Privilégios em excesso fornecem aos invasores ferramentas para manipular rotas de rede, alterar relógios do host ou ignorar controles de acesso a arquivos.

Proteja os contêineres em tempo de execução removendo todas as capabilities padrão e adicionando apenas os sinalizadores operacionais essenciais:

services:
  tenant_web:
    image: custom-nginx:latest
    read_only: true
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    security_opt:
      - no-new-privileges:true
      - seccomp=default.json
    tmpfs:
      - /tmp:rw,noexec,nosuid,size=64m
      - /var/run:rw,noexec,nosuid,size=16m
  • cap_drop: - ALL: Remove todas as capabilities do kernel do processo do contêiner.
  • cap_add: - NET_BIND_SERVICE: Permite explicitamente o vínculo a portas privilegiadas (como 80 e 443), bloqueando a manipulação direta de raw sockets de rede.
  • read_only: true: Monta todo o sistema de arquivos raiz do contêiner como somente leitura. Os invasores não conseguem baixar binários maliciosos, modificar scripts PHP ou alterar arquivos de configuração do servidor web.
  • tmpfs: Aloca diretórios voláteis em memória para arquivos temporários necessários (como /tmp), bloqueando a execução de binários (noexec) e a escalada de privilégios (nosuid).

Aplique filtros do secure computing mode (seccomp) e módulos de segurança como AppArmor ou SELinux para interceptar e restringir chamadas de sistema feitas ao kernel do host compartilhado. Se sua equipe gerencia builds de aplicações web personalizadas, siga nossas etapas estruturadas para fazer o hardening de contêineres Docker em seus pipelines de implantação.


4. Particione Redes Entre Ambientes de Locatários

Desative a rede bridge padrão e crie redes bridge personalizadas e isoladas definidas por software para a stack de cada locatário. Por padrão, contêineres colocados na rede bridge padrão do Docker podem descobrir e se comunicar entre si por meio de endereços IP internos. Uma vulnerabilidade no microsserviço de marketing de um locatário permite movimentação lateral para qualquer outro banco de dados e aplicação interna naquele host.

Isole completamente o tráfego dos locatários declarando bridges de rede independentes por locatário:

networks:
  tenant_alpha_net:
    driver: bridge
    internal: true
  tenant_beta_net:
    driver: bridge
    internal: true
  public_gateway_net:
    driver: bridge

services:
  alpha_app:
    image: tenant_a_app:latest
    networks:
      - tenant_alpha_net
      - public_gateway_net

  alpha_db:
    image: mariadb:10.11
    networks:
      - tenant_alpha_net

  beta_app:
    image: tenant_b_app:latest
    networks:
      - tenant_beta_net
      - public_gateway_net

  beta_db:
    image: mariadb:10.11
    networks:
      - tenant_beta_net
  • Isolamento de Locatários: alpha_app e alpha_db comunicam-se exclusivamente via tenant_alpha_net. O beta_app não consegue alcançar o alpha_db, mesmo que um invasor faça uma varredura na sub-rede interna.
  • Flag Internal (internal: true): Impede que as redes de banco de dados roteiem tráfego diretamente para a internet externa, restringindo o acesso de entrada e saída unicamente aos contêineres da aplicação.
  • Gateway de Proxy Reverso: Apenas o proxy de entrada conecta-se à public_gateway_net para rotear requisições HTTP/HTTPS recebidas para o contêiner do locatário designado de acordo com o hostname.

Para ambientes mais avançados, considere modos de Enhanced Container Isolation (ECI) do Docker ou runtimes como o Sysbox, que impõem automaticamente limites mais rigorosos de namespace de usuário e sistemas de arquivos /proc e /sys virtualizados sem a necessidade de scripts de rede manuais complexos.


5. Estabeleça uma Matriz Objetiva de Decisão Multilocatária

Questione a suposição de que todos os ativos digitais exigem máquinas virtuais dedicadas. Líderes de marketing frequentemente presumem que o isolamento de VM a nível de hardware é o único modelo de segurança válido. Na prática, provisionar VMs dedicadas para landing pages leves ou sites de campanhas temporárias gera uma enorme explosão de custos e sobrecarga operacional de manutenção, sem melhorar de fato a segurança da aplicação web.

Use a seguinte matriz comparativa para avaliar os requisitos de carga de trabalho e apresentar uma estratégia racional de implantação para os tomadores de decisão:

Camada de IsolamentoTecnologia SubjacenteLimite de SegurançaSobrecarga de RecursosMelhor Caso de Uso
Contêineres em Stack CompartilhadaNamespaces e Cgroups em SO únicoIsolamento lógico a nível de SOMuito BaixaLanding pages de alto volume, staging interno, sites temporários de campanha
Contêineres com Hardening (ECI / Sysbox)Namespaces de usuário, AppArmor, Raiz somente leituraNível de SO avançado e virtualizaçãoBaixaHospedagem para agências multicliente, portais autenticados, formulários de marketing confidenciais
Máquinas Virtuais Dedicadas (VMs)Virtualização por hardware via HypervisorSeparação estrita de hardware/kernelAltaProcessamento de pagamentos, dados regulamentados por HIPAA/PCI, execução de código não confiável
Híbrido (Contêineres em VMs Dedicadas)Contêineres com hardening dentro de VMs específicas por locatárioLimites multicamadas de hardware e SOModerada a AltaClientes corporativos de grande porte que exigem conformidade contratual dedicada

Avalie cada projeto com base em critérios rigorosos antes de alocar orçamento de infraestrutura:

  1. Sensibilidade dos Dados: O projeto armazena dados sujeitos a regulamentações (como registros de cartão de crédito ou informações de saúde)? Se sim, implante em uma VM dedicada.
  2. Origem do Código: Você está implantando código padronizado e auditado pela equipe ou permitindo plugins de terceiros não verificados? Código padrão pertence a contêineres com hardening; código não testado de terceiros exige isolamento por hypervisor.
  3. Orçamento e Ciclo de Vida: Para landing pages sazonais e sites institucionais principais, a multilocação em contêineres com hardening oferece o máximo de desempenho por custo.

Ao apresentar planos de infraestrutura para a gestão, consulte nosso guia sobre como avaliar quando os clientes precisam de VMs dedicadas para embasar suas recomendações com argumentos claros baseados em camadas.


Conclusão: Traduzindo Controles de Segurança em ROI para o Negócio

Proteger um ambiente Docker multilocatário não exige um orçamento astronômico de arquitetura em nuvem corporativa. Exige a aplicação rigorosa e disciplinada dos controles do próprio sistema operacional.

Ao revisar a infraestrutura com a liderança não técnica, estruture essas configurações técnicas em torno de três métricas executivas:

  • Eficiência de Custos: Contêineres multilocatários permitem que a equipe hospede dezenas de sites de marketing usando uma fração dos recursos computacionais exigidos por VMs individuais.
  • Proteção do Tempo de Atividade (Uptime): Os control groups garantem que picos de tráfego em uma campanha sazonal não degradem o desempenho dos sites principais da marca.
  • Contenção do Raio de Impacto: Sistemas de arquivos somente leitura, remoção de capabilities e bridges de rede isoladas garantem que uma invasão em um único site não consiga acessar bancos de dados adjacentes de outros clientes nem os controles do host.

Implemente essas barreiras sistematicamente em seus modelos de contêiner. Você entregará uma infraestrutura de alto desempenho e excelente custo-benefício que atende tanto aos padrões de segurança da engenharia quanto às restrições orçamentárias da diretoria.

Sources (5)