# Datadog (2023): como um patch de segurança do systemd derrubou 5 regiões simultaneamente

Em março de 2023, uma atualização automática de segurança do systemd-networkd reiniciou o subsistema de rede em dezenas de milhares de nós Kubernetes do Datadog ao mesmo tempo, cortando a conectividade gerenciada pelo Cilium em múltiplas regiões. O incidente expôs os riscos de auto-updates de SO sem controle de blast radius, a dependência crítica de CNI plugins no plano de dados e a ausência de isolamento regional em pipelines de atualização.

- URL: https://fernando.moretes.com/studies/datadog-2023-multiregion-outage

- Markdown: https://fernando.moretes.com/studies/datadog-2023-multiregion-outage/study.md?lang=pt

- Type: Post-mortem

- Company: Datadog

- Domain: Observabilidade/Resiliência

- Date: 2023-03-08

- Tags: postmortem, datadog, systemd, cilium, kubernetes, observability, blast-radius, auto-update

- Reading time: 11 min

---

## Ficha do Incidente

- **Empresa:** Datadog
- **Data do incidente:** 8 de março de 2023
- **Duração total:** ~5 horas para restauração parcial; degradação prolongada em algumas regiões
- **Regiões afetadas:** 5 regiões de produção simultaneamente
- **Escala de nós afetados:** Dezenas de milhares de nós Kubernetes
- **Impacto ao cliente:** Ingestão de métricas, logs e traces degradada ou interrompida; dashboards e alertas afetados em múltiplos produtos
- **Componente raiz:** systemd-networkd (atualização automática de segurança)
- **Stack relevante:** Kubernetes, Cilium (CNI), systemd, Ubuntu, nós bare-metal/cloud
- **Tipo de falha:** Mudança de infraestrutura não controlada → perda de conectividade de rede em larga escala

Um patch de segurança rotineiro, aplicado automaticamente pelo gerenciador de pacotes do sistema operacional, reiniciou o subsistema de rede em dezenas de milhares de nós ao mesmo tempo — e derrubou cinco regiões de produção do Datadog de uma só vez. Não houve bug de software complexo, nenhuma falha de hardware, nenhum ataque. Apenas a combinação de auto-update irrestrito, um CNI plugin sensível a reinicializações de rede e ausência de isolamento entre regiões no pipeline de atualização. Este post-mortem é um estudo de caso sobre blast radius, sobre o custo de conveniências operacionais e sobre por que 'funciona no staging' não é suficiente quando a mudança atinge produção global em paralelo.

## O que aconteceu

Na manhã de 8 de março de 2023, o Datadog começou a receber alertas de degradação severa em múltiplos produtos — ingestão de métricas, logs, APM e sintéticos. A característica mais perturbadora do incidente não era a falha em si, mas sua simultaneidade: cinco regiões de produção independentes começaram a apresentar problemas ao mesmo tempo, o que imediatamente descartou hipóteses de falha localizada e apontou para uma causa comum transversal.

A investigação revelou que o Ubuntu, sistema operacional dos nós de computação, havia aplicado automaticamente uma atualização de segurança para o pacote `systemd`. Especificamente, a atualização afetava o `systemd-networkd`, o daemon responsável pelo gerenciamento de interfaces de rede no nível do sistema operacional. Ao ser atualizado, o `systemd-networkd` foi reiniciado — comportamento esperado e documentado para aplicação de patches de segurança em componentes de rede.

O problema crítico estava na interação entre essa reinicialização e o **Cilium**, o CNI plugin (Container Network Interface) usado pelo Datadog para gerenciar a rede dos pods Kubernetes. O Cilium opera no espaço de kernel via eBPF e mantém estado de conectividade que depende de interfaces de rede estáveis. Quando o `systemd-networkd` reiniciou e reconfigurou as interfaces, o Cilium perdeu o estado de conectividade dos pods — efetivamente cortando a comunicação entre workloads em execução, sem que os pods em si tivessem sido reiniciados ou reportado falha.

O resultado foi uma falha silenciosa e difusa: pods rodando, nós aparentemente saudáveis, mas sem capacidade de se comunicar. Pipelines de ingestão pararam de receber dados. Serviços internos de controle perderam conectividade entre si. O plano de controle do Kubernetes continuava funcionando, mas o plano de dados estava efetivamente partido.

## Linha do Tempo

1. **T-0: Patch disponibilizado** — Ubuntu publica atualização de segurança para o pacote systemd, incluindo mudanças no systemd-networkd. O pacote entra nos repositórios de atualização automática.

2. **T+0: Aplicação automática começa** — O mecanismo de auto-update (unattended-upgrades) começa a aplicar o patch nos nós de produção. Sem janela de manutenção, sem staging progressivo, sem isolamento regional — a atualização é aplicada em paralelo em múltiplas regiões.

3. **T+minutos: systemd-networkd reinicia em escala** — Em dezenas de milhares de nós, o systemd-networkd é reiniciado como parte da aplicação do patch. As interfaces de rede são reconfiguradas pelo daemon.

4. **T+minutos: Cilium perde estado de conectividade** — A reinicialização do systemd-networkd invalida o estado eBPF mantido pelo Cilium. A conectividade entre pods é cortada em larga escala. Os pods continuam rodando e reportando 'healthy' ao kubelet, mas não conseguem se comunicar.

5. **T+~10-20min: Alertas disparam** — Pipelines de ingestão de métricas, logs e traces começam a falhar. Alertas de latência e erro disparam em múltiplos produtos simultaneamente. A equipe de on-call é acionada.

6. **T+~30min: Diagnóstico inicial** — A equipe identifica que o problema é de conectividade de rede nos nós, não de lógica de aplicação. A correlação com a atualização do systemd é estabelecida. A simultaneidade em 5 regiões confirma a causa comum.

7. **T+~1-2h: Mitigação em andamento** — Início do processo de remediação: reinicialização do agente Cilium nos nós afetados, substituição de nós via rolling replacement, bloqueio de novas atualizações automáticas. A escala do problema torna a recuperação lenta.

8. **T+~5h: Restauração parcial** — A maioria das regiões começa a se recuperar. Algumas regiões apresentam degradação prolongada enquanto a substituição de nós é concluída. Monitoramento intensivo é mantido.

## Fluxo de Falha: do Patch ao Blackout de Conectividade

O diagrama reconstrói o caminho causal do incidente: como um pacote de atualização de SO atravessou o pipeline de auto-update, atingiu o systemd-networkd, e propagou a falha para o Cilium e consequentemente para toda a conectividade de pods em múltiplas regiões.

### 🌐 Ubuntu Package Repository

- Ubuntu Security Repository (external)

### 🔄 Auto-Update Pipeline (sem controle de blast radius)

- unattended-upgrades (OS daemon) (ci)

### 🖥️ Nó Kubernetes (replicado em dezenas de milhares)

- systemd-networkd (reiniciado pelo patch) (network)
- Cilium Agent (eBPF / CNI) (network)
- Pod A (running, sem rede) (compute)
- Pod B (running, sem rede) (compute)
- kubelet (reporta node=Ready) (compute)

### 📊 Plano de Dados Datadog (afetado)

- Ingestion Pipeline (métricas/logs/traces) (data)
- Serviços Internos (controle/coordenação) (compute)

### 🌍 5 Regiões (impactadas simultaneamente)

- Região 1 ❌ conectividade (edge)
- Região 2 ❌ conectividade (edge)
- Regiões 3-5 ❌ conectividade (edge)

### Fluxos

- ubuntu-repo -> unattended-upgrades: pacote systemd (segurança)
- unattended-upgrades -> systemd-networkd: aplica patch + reinicia daemon
- systemd-networkd -> cilium-agent: reconfigura interfaces → invalida estado eBPF
- cilium-agent -> pod-a: conectividade perdida
- cilium-agent -> pod-b: conectividade perdida
- kubelet -> pod-a: node=Ready (falso positivo)
- pod-a -> ingestion-pipeline: falha de comunicação
- pod-b -> internal-services: falha de comunicação
- unattended-upgrades -> region-1: sem isolamento regional
- unattended-upgrades -> region-2: paralelo
- unattended-upgrades -> region-n: paralelo

> **Causa Raiz: a convergência de três decisões de design independentes:** A causa raiz não foi o bug no systemd-networkd, nem o comportamento do Cilium isoladamente. Foi a **convergência de três decisões de design que individualmente pareciam razoáveis**:

1. **Auto-update irrestrito**: `unattended-upgrades` configurado para aplicar patches de segurança automaticamente, sem janela de manutenção, sem staging progressivo e sem isolamento entre regiões. A intenção era legítima — reduzir exposição a CVEs — mas o mecanismo não tinha nenhum controle de blast radius.

2. **Sensibilidade do Cilium a reinicializações do systemd-networkd**: O Cilium, operando via eBPF no kernel, mantém estado de conectividade que é invalidado quando o systemd-networkd reconfigura interfaces de rede. Essa dependência não estava documentada como risco operacional nos runbooks de atualização de SO.

3. **Ausência de isolamento regional no pipeline de atualização**: Não havia mecanismo que garantisse que uma mudança de infraestrutura fosse aplicada sequencialmente por região, com observação de métricas de saúde entre cada etapa. O resultado foi que todas as regiões foram atingidas simultaneamente, eliminando qualquer possibilidade de detecção precoce e rollback antes do impacto generalizado.

Isso é um **failure mode clássico de sistemas complexos**: cada componente se comportou conforme projetado, mas a interação entre eles produziu um resultado catastrófico não antecipado.

## Remediação e resposta ao incidente

A remediação imediata envolveu três frentes paralelas. Primeiro, a equipe bloqueou novos auto-updates em todos os nós remanescentes para evitar que o problema se espalhasse para nós que ainda não haviam sido afetados. Segundo, iniciou-se o processo de recuperação dos nós já afetados: em alguns casos, reiniciar o agente Cilium era suficiente para restaurar a conectividade após o systemd-networkd ter se estabilizado; em outros, os nós precisaram ser drenados e substituídos via rolling replacement, o que é um processo inerentemente lento quando se fala em dezenas de milhares de nós.

A escala foi o principal obstáculo à recuperação rápida. Em um incidente localizado — digamos, uma única região com centenas de nós — o procedimento de drain e replace seria concluído em minutos. Com dezenas de milhares de nós distribuídos em cinco regiões, o mesmo procedimento levou horas. Isso ilustra um ponto importante: **o blast radius de uma mudança não afeta apenas a severidade do impacto inicial, mas também o tempo de recuperação**. Quanto maior o raio de explosão, mais lenta e custosa é a remediação.

No médio prazo, o Datadog implementou um conjunto de controles estruturais. O auto-update irrestrito foi substituído por um pipeline de atualização de SO gerenciado, com rollout progressivo por região e observação de métricas de saúde entre cada etapa. A interação entre systemd-networkd e Cilium foi documentada e adicionada aos critérios de validação de patches de SO. Testes de compatibilidade entre atualizações de sistema operacional e o CNI plugin passaram a ser executados em ambiente de staging antes de qualquer rollout para produção. Adicionalmente, foram implementados mecanismos de detecção mais rápida de falhas de conectividade de rede em nível de nó — especificamente para capturar o padrão de 'pod running, node Ready, mas sem conectividade', que é um falso positivo do ponto de vista do kubelet.

## Por que a independência regional falhou

Um dos princípios fundamentais de resiliência em sistemas distribuídos é o **isolamento de domínios de falha**. Regiões geográficas distintas existem exatamente para que uma falha em uma não se propague para as demais. O Datadog, como empresa de observabilidade, certamente tinha esse princípio incorporado na arquitetura de seus produtos. O problema foi que o **pipeline de atualização de infraestrutura não respeitava esses mesmos limites**.

Isso revela uma assimetria comum em organizações de engenharia maduras: investe-se muito em isolamento de falhas no plano de aplicação — circuit breakers, bulkheads, retry com backoff, multi-region deployments — mas o plano de infraestrutura subjacente pode ter acoplamentos globais que não são tratados com o mesmo rigor. O `unattended-upgrades` não sabia que estava operando em um sistema multi-região com requisitos de blast radius. Era apenas um daemon de sistema fazendo seu trabalho.

A lição aqui é que **qualquer mecanismo que possa modificar estado em múltiplos nós de produção precisa ser tratado como um deployment, com todas as garantias que isso implica**: canary release, progressive rollout, health gates entre etapas, e capacidade de rollback. Isso vale para patches de SO, atualizações de agentes, mudanças de configuração via Ansible/Chef/Puppet, e qualquer outra forma de mudança de infraestrutura em escala. A distinção entre 'mudança de aplicação' e 'mudança de infraestrutura' é operacional, não arquitetural — do ponto de vista do risco, ambas precisam dos mesmos controles.

Há também um aspecto de **observabilidade do próprio processo de mudança** que merece atenção. O Datadog é uma empresa de observabilidade — seus produtos são usados por outras empresas para detectar exatamente esse tipo de problema. A ironia do incidente é que a detecção da causa raiz levou tempo porque o próprio sistema de monitoramento estava parcialmente degradado pela falha. Isso reforça a importância de ter **observabilidade out-of-band** — mecanismos de monitoramento que não dependem da infraestrutura que estão monitorando.

## Lições Técnicas

- **Auto-update de SO em produção é um deployment disfarçado**: Qualquer mecanismo que aplica mudanças em nós de produção deve ter as mesmas garantias de um deployment de aplicação — rollout progressivo, health gates e rollback.
- **Blast radius é uma dimensão de design, não de operação**: O raio de impacto de uma mudança deve ser limitado por design (isolamento regional, canary gates) antes que a mudança seja executada, não gerenciado reativamente após o incidente.
- **Dependências de runtime entre componentes de sistema devem ser documentadas como riscos operacionais**: A interação entre systemd-networkd e Cilium não era um bug — era um comportamento de sistema não documentado como risco. Runbooks de atualização de SO devem incluir validação de CNI plugins.
- **'Node=Ready' não implica 'rede funcionando'**: O kubelet reportava nós saudáveis enquanto a conectividade de pods estava quebrada. Health checks de infraestrutura devem incluir verificações de conectividade de rede em nível de pod, não apenas status do kubelet.
- **Independência regional deve se estender ao pipeline de infraestrutura**: Não basta ter regiões independentes no plano de aplicação se o plano de infraestrutura tem acoplamentos globais. Pipelines de atualização de SO, agentes e configuração devem respeitar os mesmos limites de domínio de falha.
- **Observabilidade out-of-band é crítica**: Quando a infraestrutura de monitoramento está na mesma blast zone que o sistema monitorado, a capacidade de diagnóstico é comprometida exatamente quando mais é necessária. Mecanismos de monitoramento independentes da infraestrutura principal são essenciais.

> **Minha leitura sênior: o problema real não era o systemd:** Quando leio este post-mortem, o que me chama atenção não é a falha técnica em si — a interação entre systemd-networkd e Cilium é o tipo de comportamento emergente que aparece em sistemas complexos e que nenhum teste unitário vai capturar. O que me chama atenção é a **ausência de um princípio que deveria ser inegociável em qualquer sistema de produção em escala**: nenhuma mudança toca mais de um domínio de falha ao mesmo tempo sem observação intermediária.

Eu já vi variações desse padrão em sistemas financeiros: um script de rotação de credenciais que rodava em paralelo em todos os ambientes, um pipeline de deploy que não respeitava a sequência de regiões, uma atualização de biblioteca de segurança que foi aplicada em todos os serviços simultaneamente porque 'era só um patch de segurança'. A lógica é sempre a mesma: a mudança parece pequena e segura, então o custo de fazer um rollout controlado parece desnecessário. E então você descobre que 'pequena e segura' era uma avaliação feita sem considerar as interações de runtime.

O que eu faria diferente? Três coisas concretas:

**1. Tratar patches de SO como releases de software.** Isso significa: ambiente de staging com o mesmo stack de produção (incluindo CNI plugin, versão de kernel, configuração de rede), testes de smoke automatizados pós-atualização que incluam verificação de conectividade de pod, e rollout por região com health gate de pelo menos 30 minutos antes de avançar para a próxima.

**2. Implementar um 'blast radius budget' por janela de mudança.** Não mais que X% dos nós de uma região podem ser atualizados simultaneamente, e nunca mais de uma região em paralelo sem aprovação explícita. Isso é configuração de política, não engenharia complexa — mas precisa ser uma decisão consciente e documentada.

**3. Separar o plano de observabilidade do plano de dados.** O Datadog tem o problema específico de que sua infraestrutura de monitoramento e sua infraestrutura de produto compartilham a mesma base de nós. Em sistemas financeiros, a separação entre o sistema de trading e o sistema de monitoramento de trading é um requisito regulatório. Para uma empresa de observabilidade, essa separação deveria ser um requisito arquitetural de primeira classe.

O post-mortem do Datadog é exemplar em sua honestidade e profundidade técnica.

## Veredicto: quando a conveniência operacional vira risco sistêmico

O incidente do Datadog em março de 2023 não foi causado por negligência ou incompetência — foi causado por decisões de design razoáveis que não foram reavaliadas à medida que o sistema cresceu em escala e complexidade. Auto-update de segurança é uma prática recomendada. Cilium é uma escolha técnica sólida para CNI em Kubernetes. Múltiplas regiões de produção são um requisito de resiliência. O problema foi que nenhuma dessas decisões foi tomada considerando a interação das três em conjunto, e que o pipeline de atualização de infraestrutura nunca recebeu o mesmo tratamento rigoroso que o pipeline de deploy de aplicação.

A lição central é sobre **governança de mudança em escala**: qualquer mecanismo que pode modificar estado em múltiplos nós de produção — seja um deploy de aplicação, um patch de SO, uma atualização de agente ou uma mudança de configuração — precisa de controles explícitos de blast radius, rollout progressivo e observação intermediária. A distinção entre 'mudança de aplicação' e 'mudança de infraestrutura' não deve existir do ponto de vista de risco.

Para times que operam Kubernetes em produção, este incidente é um lembrete de que o contrato entre o sistema operacional e os componentes de rede do cluster (CNI plugins, especialmente os baseados em eBPF como Cilium) é mais frágil do que parece. Mudanças no subsistema de rede do SO devem ser tratadas como mudanças de infraestrutura crítica, testadas em staging com o stack completo de produção e aplicadas com rollout controlado.

E para líderes técnicos: a pergunta 'qual é o blast radius desta mudança?' deveria ser tão automática quanto 'esta mudança tem testes?'. Não porque incidentes como este sejam inevitáveis, mas porque com os controles certos, eles são evitáveis.

## Referências

- [Datadog — 2023-03-08 Incident Post-Mortem (official)](https://www.datadoghq.com/blog/2023-03-08-multiregion-infrastructure-connectivity-issue/)

## Fontes do caso

- [Datadog — 2023-03-08 Incident Post-Mortem](https://www.datadoghq.com/blog/2023-03-08-multiregion-infrastructure-connectivity-issue/)
