Retro: EMR Serverless em IPv6-only e a subnet que ficou sem DNS64
cerca de 7 min · áudio gerado ao tocar
A pergunta perigosa sobre o IPv6 no EMR Serverless não é "meus jobs rodam em IPv6?", é "o que cada subnet da aplicação sabe fazer quando um job pede um endereço que só existe em IPv4?". O anúncio de 16/10/2026 é curto: Spark e Hive passam a rodar em subnets dual-stack ou IPv6-only, sem custo adicional, em todas as regiões e release versions do serviço. A documentação é mais honesta que o anúncio: o modo de endereçamento é derivado das subnets, e a responsabilidade de fazer o tráfego IPv6 chegar aos seus dados é sua. Este texto é um retro antecipado, um incidente que não aconteceu, montado a partir da documentação e dos modos de falha que ela mesma lista. Prefiro escrever o postmortem antes do que depois.
O cenário: subnets /22 que não cabem mais três aplicações
O ponto de partida é o que a própria AWS usa como exemplo de planejamento. Cada worker do EMR Serverless consome um endereço IP na subnet em que sobe, por meio de uma ENI. Uma aplicação com workers de 4 vCPU e teto de 4.000 vCPU chega a 1.000 workers, ou seja, 1.000 ENIs. Uma subnet /22 tem 1.024 endereços e 1.019 utilizáveis, porque a AWS reserva cinco. Com três aplicações dividindo as mesmas subnets e uma cota de 12.000 vCPU na conta, a recomendação da documentação vira 3.000 endereços livres por subnet, em pelo menos duas zonas de disponibilidade.
Em plataforma de dados de banco, isso costuma bater num muro: o bloco IPv4 da VPC foi negociado com o time de rede corporativa anos atrás, não sobrepõe com o on-premises e não cresce sem uma rodada de aprovação. É exatamente o caso que o IPv6 resolve. Uma subnet IPv6 da VPC é um /64, e a conversa sobre endereço acaba.
No cenário, o time decide ir direto para IPv6-only em três subnets, uma por AZ, criadas por um módulo de IaC. Duas foram montadas à mão no piloto e receberam DNS64. A terceira veio do módulo, que não sabia que DNS64 existia. Nenhum teste de integração pegou isso, porque o job de teste rodou duas vezes e caiu nas duas subnets boas.
Os números que movem a decisão
Linha do tempo do incidente simulado
- 1
D-7: troca de subnets
O time para a aplicação, roda
update-applicationcom as três subnets IPv6-only no--network-configuratione inicia de novo. O modo é avaliado a cada start, então a mudança só vale depois do restart. Dois jobs de teste passam. - 2
02:00: o batch noturno começa
Cerca de um terço dos jobs falha com
UnknownHostExceptionao chamar endpoints que só publicam registro A. Cada job roda em uma única subnet escolhida do conjunto, e os que caíram na subnet sem DNS64 não resolvem nada que não seja IPv6. - 3
02:40: o retry esconde o padrão
A política de retry do orquestrador reenvia os jobs. Parte passa porque cai em outra subnet. A falha parece intermitente, e intermitente vira "rede instável" na primeira hipótese do plantão.
- 4
04:10: correlação por subnet
Alguém abre o detalhe de cada job run, que mostra a subnet usada, e cruza com sucesso e falha. 100% das falhas estão na mesma subnet.
modify-subnet-attribute --enable-dns64resolve a resolução de nomes. - 5
05:00: a segunda falha
Um job de ingestão com driver JDBC antigo falha com
UnresolvedAddressException. Havia-Djava.net.preferIPv4Stack=trueemspark.driver.extraJavaOptions, um contorno de anos atrás. A documentação proíbe forçar a pilha IPv4 em qualquer modo. - 6
D+5: a conta chega
O Cost Explorer mostra salto em processamento de dados do NAT gateway. As leituras do S3, que antes saíam pelo gateway endpoint, agora resolvem via DNS64 para
64:ff9b::/96e atravessam o NAT64.
Causa raiz
O EMR Serverless deriva o modo de endereçamento das subnets e não valida se a rede está pronta para ele. A prontidão de cada subnet (CIDR IPv6, auto-assign, DNS64, rota 64:ff9b::/96 para o NAT gateway, rota ::/0 para o egress-only gateway) não estava codificada no módulo de IaC, e a seleção de uma subnet por job transformou um defeito determinístico em falha aparentemente aleatória.
Por que a falha parecia aleatória: as regras do modo de endereçamento
Vale entender as regras antes de culpar a rede. Subnet só IPv4 roda como sempre rodou. Subnet dual-stack roda IPv4 até você ligar spark.emr-serverless.networking.ipv6.enabled=true no spark-defaults da aplicação (para Hive, hive.emr-serverless.networking.ipv6.enabled no hive-site). Subnet IPv6-only roda IPv6 sem propriedade nenhuma.
Quando o conjunto mistura tipos, a aplicação inteira roda no único modo que todas suportam. IPv4-only com IPv6-only é rejeitado na validação. IPv6-only com dual-stack roda tudo em IPv6-only, inclusive as subnets dual-stack, que então precisam cumprir os mesmos pré-requisitos. IPv4-only com dual-stack roda tudo em IPv4.
Três detalhes produzem incidente:
- O modo vale no start: uma aplicação em execução mantém o modo com que subiu. Você corrige a subnet e nada muda até o próximo
stop/start. - Um job, uma subnet: o job roda em uma única subnet escolhida da lista. Uma subnet defeituosa entre três falha um terço das vezes, e retry mascara.
- Dual-stack não prefere IPv6 por padrão: mesmo com o opt-in ligado, o engine usa IPv4 até você setar
spark.emr-serverless.driverEnv.SPARK_PREFER_IPV6espark.executorEnv.SPARK_PREFER_IPV6. Setar isso numa subnet só IPv4 derruba o job.
A lição: o modo de endereçamento é estado derivado, não configurado. A API não deixa você declarar o modo; ela deixa você declarar subnets e deduz o resto. Estado derivado precisa de teste que prove a derivação em cada subnet, não na média.
Por onde sai cada byte de um job em subnet IPv6-only
O caminho depende do registro DNS do destino: AAAA sai direto, A vira 64:ff9b::/96 e paga NAT64.
- Spark driver · SPARK_PREFER_IPV6 automático
- Executors · 1 ENI IPv6 por worker
- Route 53 Resolver · DNS64 na subnet
- NAT gateway · rota 64:ff9b::/96 (NAT64)
- Egress-only IGW · rota ::/0
- Interface endpoints · Glue, STS, KMS, Logs
- S3 dual-stack · s3.dualstack.<region>
- Endpoint só IPv4 · JDBC legado, API pública
- Endpoint IPv6 · AAAA publicado
Remediação de rede: transformar pré-requisito em invariante
A correção do DNS64 levou um comando. A remediação que impede a reincidência levou mais trabalho, e é ela que importa.
Módulo de subnet com contrato: o módulo de IaC passa a exigir, para toda subnet marcada como destino de EMR Serverless, assign_ipv6_address_on_creation = true, enable_dns64 = true, rota 64:ff9b::/96 para o NAT gateway e rota ::/0 para o egress-only internet gateway. O auto-assign só vale para recursos criados depois da mudança, então ligar tarde não conserta ENI que já existe.
Validação antes do apply: uma checagem no pipeline (policy as code ou um teste que lê describe-subnets e describe-route-tables) falha o deploy se qualquer subnet do conjunto não cumprir o contrato. Validação que roda depois do incidente é postmortem, não controle.
Canário por subnet: como o job escolhe a subnet e você não, crio uma aplicação canário com uma subnet só, uma para cada AZ. Um job Spark mínimo resolve e conecta nos endpoints de que o batch depende (catálogo, STS, KMS, o bucket de dados, o banco de origem) e falha alto. Roda antes da janela do batch e depois de qualquer mudança de rede.
JVM limpa: varredura em todas as sparkSubmitParameters e runtimeConfiguration atrás de preferIPv4Stack. Um contorno de 2019 não pode decidir a pilha de rede de 2026.
Nada disso é sofisticado. O custo dele não é escrever, é manter o contrato quando alguém criar a quarta subnet daqui a dezoito meses sem ler este documento.
O custo que o anúncio não menciona: NAT64 e o S3
"Sem custo adicional" é verdade para o recurso. Não é verdade para o caminho que o tráfego passa a percorrer.
Em subnet IPv6-only, todo destino que só publica registro A recebe um endereço sintetizado em 64:ff9b::/96, e essa rota aponta para o NAT gateway. O NAT gateway cobra por hora e por GB processado; a página de preços da VPC usa US$ 0,045 por GB como exemplo em US East (Ohio). Uma plataforma que lê 8 TB por noite do S3 e manda isso pelo NAT64 paga cerca de US$ 360 por noite só de processamento, algo como US$ 10.800 em 30 noites. O gateway endpoint do S3 na subnet do workload não pega esse tráfego, porque o destino deixou de ser um prefixo IPv4.
O S3 só atende IPv6 pelos endpoints dual-stack (s3.dualstack.<region>.amazonaws.com), e o cliente precisa pedir isso explicitamente. Antes de medir, não confie: compare BytesOutToDestination do NAT gateway antes e depois da troca.
Outros serviços exigem o mesmo cuidado. Na tabela de suporte a IPv6 da AWS, o Glue tem dual-stack e endpoint privado com IPv6, mas o endpoint público não; o Lake Formation também só tem IPv6 pelo endpoint privado. Em IPv6-only, isso quer dizer interface endpoint para catálogo e permissões, ou NAT64 pago em cada chamada.
E a segurança: a documentação do S3 avisa que políticas com aws:SourceIp só em IPv4 fazem clientes perderem ou ganharem acesso indevidamente quando passam a usar IPv6. Revise toda bucket policy antes da troca, não depois.
Os três modos lado a lado
| Critério | IPv4-only | Dual-stack com opt-in | IPv6-only |
|---|---|---|---|
| Consumo de IPv4 | 1 por worker | 1 por worker, continua consumindo | Zero |
| Ativação | - | ipv6.enabled na aplicação + SPARK_PREFER_IPV6 no job | Automática pelas subnets |
| Destinos só IPv4 | Direto | Direto por IPv4 | Só com DNS64 + NAT64, pago por GB |
| Risco de incidente | Esgotar a subnet no pico | Baixo: falha volta para IPv4 | Alto se qualquer subnet ou dependência não estiver pronta |
| Quando usar | Folga de endereço e sem mandato de IPv6 | Transição e validação de dependências | Mandato de compliance ou esgotamento real, com dependências mapeadas |
Leitura pelo Well-Architected
Segurança
Endereço IPv6 é globalmente único: saída só por egress-only gateway, nunca rota ::/0 para o internet gateway nas subnets de workers. O EMR Serverless já recusa security group com porta aberta para 0.0.0.0/0 ou ::/0. Revise aws:SourceIp em bucket policies e prefira aws:SourceVpce.
Confiabilidade
Espalhe subnets por pelo menos duas AZs, como a documentação recomenda, mas trate cada uma como unidade de falha própria: canário por subnet e alarme por subnet. Retry automático sem correlação por subnet converte defeito determinístico em ruído.
Anti-padrões que este retro tenta evitar
- Validar com dois jobs: com três subnets e uma escolhida por job, dois jobs verdes não provam nada sobre a terceira.
- Ir direto para IPv6-only sem inventário de dependências: cada driver, SDK e endpoint que o job toca precisa suportar IPv6 ou passar por NAT64; o EMR Serverless não altera o código nem o endpoint de terceiros.
- Ligar
SPARK_PREFER_IPV6como padrão global: em subnet só IPv4 a preferência derruba o job. - Corrigir a subnet e não reiniciar a aplicação: o modo foi fixado no start, e o plantão conclui que a correção não funcionou.
Eu começaria por dual-stack com opt-in, numa aplicação nova, e deixaria a preferência por IPv6 ligada só nos jobs cujas dependências eu já medi. IPv6-only fica para quando houver mandato ou esgotamento real, e só depois de duas semanas de canário por subnet verde e de um gráfico de bytes no NAT gateway que eu consiga explicar linha a linha. A lição que tirei de outras migrações de rede é que o defeito quase nunca está no serviço novo, está na subnet que alguém criou com o módulo velho. Por isso o contrato mora no IaC, não na wiki.
Lições e recomendação
Adote o IPv6 no EMR Serverless quando o espaço IPv4 das subnets compartilhadas já limita o teto de vCPU ou quando houver exigência formal de IPv6. Use dual-stack com opt-in enquanto houver dependência só IPv4 relevante em volume; use IPv6-only quando todas as dependências publicarem AAAA ou estiverem atrás de interface endpoint, e o NAT64 ficar restrito a chamadas de controle. Em qualquer caso, codifique DNS64, rotas e auto-assign no módulo de subnet, rode canário por subnet e meça o NAT gateway antes de declarar a migração concluída. O recurso é gratuito; a rede mal preparada cobra por GB.
Referências
Continue lendo
Deep dives de arquitetura, AWS, IA e mercado: direto no seu email. Grátis.
Sem spam · cancele quando quiser
Pergunte ao Fernando sobre isto
Uma resposta focada sobre este artigo, do meu assistente de IA, baseada no meu trabalho.
Participe da conversa
Entre para comentar
Confirme seu e-mail para participar, você também recebe a newsletter. Sem senha.