1 pontos por GN⁺ 6 시간 전 | Ainda não há comentários. | Compartilhar no WhatsApp
  • A plataforma de dados do Slack operava pipelines críticos de dados, como indexação diária de busca e tarefas analíticas, com mais de 700 Operators baseados em SSH, exigindo que todos os jobs fizessem acesso SSH direto a clusters AWS EMR de produção, criando uma ampla superfície de ataque
  • Essa dependência de SSH não apenas representava um risco de segurança, mas também se tornou um obstáculo central para a modernização da infraestrutura, incluindo a migração para Spark on Kubernetes, EMR on EKS e a conclusão da iniciativa Whitecastle
  • Como solução, foi usado o YARN Distributed Shell para permitir a execução até mesmo de comandos shell arbitrários dentro de contêineres YARN, e todas as submissões de jobs foram unificadas por meio do gateway REST interno do Slack, o Quarry
  • Mais de 700 jobs foram migrados sem interrupção (zero downtime) em 8 regiões de dados, e a remoção de SSH foi concluída em 100% ao longo de três trimestres
  • Como resultado, o Slack obteve redução da superfície de ataque, maior confiabilidade das tarefas e melhor visibilidade, além de estabelecer a base para concluir o Whitecastle e avançar para infraestruturas de próxima geração, como Spark on Kubernetes

Contexto: como surgiu a plataforma de dados baseada em SSH

  • A plataforma de dados do Slack, construída por volta de 2017, adotou o modelo com SSH como o caminho mais direto para o Airflow executar jobs em clusters EMR
    • Com SSHOperator, conectava-se ao nó mestre do EMR e executavam-se comandos como spark-submit
  • Depois disso, as equipes criaram seus próprios Operators personalizados baseados em SSH para diversos usos, não só Spark, mas também MapReduce, AWS CLI e scripts Python customizados
  • Como resultado, o ambiente de produção acumulou mais de 700 jobs baseados em SSH

O custo real do modelo com SSH

  • Riscos potenciais de segurança

    • O acesso SSH direto aos clusters de computação ampliava a superfície de ataque
    • A distribuição e rotação de chaves em todos os workers de orquestração aumentavam a carga operacional
    • Para auditoria detalhada, era necessário correlacionar logs de vários sistemas
    • A gestão de permissões ficava mais complexa, com security groups dedicados e configurações customizadas
  • Problemas operacionais

    • Os jobs não eram distribuídos e eram executados diretamente no nó mestre do EMR, gerando contenção de recursos
    • Quando um Pod do Kubernetes reiniciava, a conexão SSH era interrompida e o job falhava
    • Jobs de longa duração continuavam executando após a desconexão e viravam processos zumbis
    • Quando a conexão caía, não era possível confirmar se o job teve sucesso ou falhou
  • Fatores que bloqueavam a modernização

    • Era inviável avançar para Spark on Kubernetes e EMR on EKS (era preciso eliminar a dependência de SSH primeiro)
    • O último cluster EMR da conta principal não podia ser movido para uma conta filha, impedindo a conclusão da iniciativa Whitecastle
      • Whitecastle é a iniciativa do Slack de mover a infraestrutura AWS para contas filhas para reforçar segurança e isolamento de rede
    • Não era possível implementar monitoramento e visibilidade adequados dos jobs
  • Caso representativo — equipe de Search Infrastructure

    • Um pipeline que constrói diariamente índices de busca Solr com dados na casa dos terabytes, parte essencial do recurso de busca do Slack
    • Por depender de submissão de jobs via SSH, ficava exposto a todos os problemas de confiabilidade citados acima

Conceito básico de submissão de jobs via REST

  • Limites inerentes do SSH

    • Uma conexão SSH é uma conexão direta com estado; se ela cai por reinício de Pod ou outro motivo, o comando pode continuar rodando, falhar ou deixar processos órfãos
    • Não há um meio confiável de reconectar e verificar o estado
  • Alternativa com REST

    • Motores modernos de computação como YARN, Trino e Snowflake oferecem submissão de jobs por API HTTP
      • POST da solicitação de job → retorna um ID de job
      • GET do estado do job → permite verificar se está executando, concluído ou falhou
      • DELETE do job → permite cancelamento adequado
    • O ciclo de vida do job é gerenciado no lado do servidor, então mesmo se o cliente reiniciar, o job continua executando e seu estado segue consultável
  • O papel e os limites do YARN

    • Para workloads Hadoop como MapReduce, Spark e Hive, o YARN é o gerenciador de recursos e também fornece uma API REST
    • Porém, mais de 300 jobs baseados em CLI que executavam comandos arbitrários como aws s3 sync e hadoop distcp não tinham uma API REST pronta para uso
    • A peça-chave para resolver isso foi o YARN Distributed Shell

O avanço decisivo: YARN Distributed Shell

  • Para Spark, havia a API REST do Livy, e para Hive, o HiveServer2, então a migração era relativamente simples
  • Já os jobs MapReduce e mais de 300 jobs baseados em CLI eram um grande desafio, pois não havia uma API REST pronta para uso
  • Requisitos

    • Uma solução simples baseada em REST que se encaixasse naturalmente na arquitetura
    • Reaproveitar os mecanismos existentes de autenticação e autorização sem precisar de uma camada de segurança customizada
    • Usar um protocolo open source e não uma solução proprietária, aproveitando a API padrão do YARN
    • Complexidade mínima, evitando construir e operar infraestrutura própria para execução de jobs customizados
  • Abordagens consideradas e descartadas

    • Construir um serviço wrapper customizado para execução remota de comandos
    • Usar frameworks de execução remota como Ansible e Salt
    • Adicionar ao YARN um novo tipo de job do zero
    • Todas foram consideradas inadequadas por introduzirem complexidade excessiva, segurança customizada e novas dependências
  • Descoberta do YARN Distributed Shell

    • Com org.apache.hadoop.yarn.applications.distributedshell.ApplicationMaster, tornou-se possível executar scripts shell arbitrários dentro de contêineres YARN
    • Como esse recurso já faz parte do YARN, usa a mesma API REST e não exige uma camada de segurança customizada
  • Como funciona

    • 1. Fazer upload do script de comando para o S3 (por exemplo: aws s3 sync /tmp/data/ s3://bucket/output/)
    • 2. Submeter ao YARN com a configuração do Distributed Shell
      • Definir application-type como MAPREDUCE e incluir no am-container-spec variáveis de ambiente como DISTRIBUTEDSHELLSCRIPTLOCATION, DISTRIBUTEDSHELLSCRIPTLEN e DISTRIBUTEDSHELLSCRIPTTIMESTAMP
    • 3. O YARN aloca um contêiner, baixa o script e o executa
      • O YARN gerencia limites de recursos como memória e vCore, isolamento de contêineres, retries e tolerância a falhas, cancelamento apropriado e logging via UI do YARN
  • Essa decisão permitiu executar dentro de contêineres YARN não só workloads Hadoop, mas também aws s3 sync, hadoop distcp e scripts Python customizados

A solução: Quarry

  • O Quarry é o gateway de submissão de jobs baseado em REST do Slack, criado para enviar jobs para múltiplos motores de computação, como EMR/YARN, Trino e Snowflake
  • Ele já resolvia problemas de autenticação, confiabilidade e visibilidade, então se encaixava exatamente na eliminação do SSH
  • Funcionalidades do Quarry

    • Autenticação: usa tokens entre serviços em vez de chaves SSH
    • Submissão de jobs: envia jobs para YARN, Trino e Snowflake por APIs REST
    • Rastreamento de estado: monitora o status dos jobs no lado do servidor
    • Gestão do ciclo de vida: permite cancelamento e limpeza adequados com API REST
    • Visibilidade: fornece logs estruturados, métricas e tracing para todas as submissões de jobs
  • Mudança de arquitetura

    • Antes: Airflow → SSH Connection → EMR Master Node → Execute Command
    • Depois: Airflow → Quarry REST API → YARN ResourceManager → EMR Container
    • O Operator do Airflow passou a fazer requisições HTTP ao Quarry em vez de abrir conexões SSH; o Quarry submete ao YARN e faz polling do estado
    • Mesmo se o Pod do Airflow reiniciar, o job continua, pois o Quarry preserva esse vínculo
  • Pontos fortes do Quarry

    • Com suporte ao YARN Distributed Shell, ele se tornou um gateway genérico de submissão de jobs
    • Jobs Spark, queries Hive e scripts shell passam todos pela mesma API REST
    • Foram eliminadas as credenciais SSH e o acesso direto ao cluster, ficando apenas chamadas REST com autenticação e rastreamento de jobs no lado do servidor

A jornada de migração

  • Havia mais de 700 jobs de produção em 8 regiões de dados independentes, com diferentes configurações de rede e exigências de soberania de dados, além de workloads que exigiam zero downtime, como indexação de busca; por isso, foi necessário um plano estruturado
  • Abordagem em fases

    • Fase 1 – Prova de conceito (PoC): validar a abordagem com Quarry em jobs piloto, desenvolver o primeiro Quarry Operator e testá-lo em ambiente dev
    • Fase 2 – Revisão de segurança: trabalhar com a equipe de segurança para planejar a remoção de credenciais e verificar se a abordagem baseada em REST atendia aos requisitos
    • Fase 3 – Execução guiada por OKR: definir a migração como Key Result para dar visibilidade executiva; nessa fase foi alcançado o marco de 80% de migração
    • Fase 4 – Migração em massa: várias equipes, como Search Infrastructure, Data Engineering & Analytics e ML Services, migraram em paralelo os workloads restantes em todas as regiões
    • Fase 5 – Limpeza final: concluir DAGs pendentes, descontinuar todos os Operators legados baseados em SSH e chegar a 100%
  • Números da migração

    • Mais de 700 jobs migrados em 7 tipos de Operator
    • Implantação coordenada em 8 regiões de dados independentes
    • 5 equipes migraram para os novos Operators
    • Zero interrupção em serviços críticos do negócio
    • Da fase piloto à eliminação total do SSH, tudo foi concluído em três trimestres

Desafios enfrentados durante a migração

  • Desafio 1 — falha no Virtual Memory Check

    • Durante a migração de um DAG de exportação de dados, um job que funcionava com SSH falhou por erro de verificação de vmem
    • Causa: com SSH, o job rodava diretamente no nó mestre e contornava a aplicação de recursos do YARN; com Quarry, o job passou a ser submetido corretamente ao YARN, então contêineres que excediam o limite de memória virtual eram rejeitados
    • Solução: desabilitar o vmem check em todos os clusters, seguindo boas práticas da AWS — "yarn.nodemanager.vmem-check-enabled": "false"
      • Isso está alinhado à recomendação da AWS de que a contabilidade de memória virtual no Linux não é confiável e que o limite de memória física é suficiente
    • Lição: o SSH mascarava muitos problemas, então ao migrar para submissão correta no YARN, era preciso esperar o aparecimento de limites de recursos que antes ficavam invisíveis e testar bem em dev
  • Desafio 2 — isolamento de rede e conectividade com EKM

    • Ao mover jobs de Search Infrastructure em dev de um cluster dev para um cluster analítico de staging, ocorreram timeouts de conexão com o EKM (Enterprise Key Management)
    • Erro: Unable to execute HTTP request: Connect to sts.amazonaws.com:443 failed: connect timed out
    • Causa: o cluster original tinha roteamento de rede até o endpoint de gerenciamento de chaves, mas o cluster analítico de staging, em um segmento de rede mais restrito, não possuía conectividade equivalente, revelando uma dependência da topologia de rede que não estava explícita na configuração do job
    • Solução: mover os jobs de Search Infrastructure para um cluster dev ETL com roteamento para o serviço dev; manter em staging apenas os jobs que precisavam do catálogo Hive de produção; e ampliar o cluster dev ETL para absorver a carga adicional
    • Lição: a topologia de rede é extremamente importante; antes de decidir em qual cluster cada job vai rodar, é preciso entender isolamento de rede e fronteiras entre contas
  • Desafio 3 — complexidade multi-região

    • Por exigências de soberania de dados, havia clusters EMR operando em 8 regiões de dados independentes, então eliminar SSH significava, na prática, 8 migrações em paralelo
    • Fatores de complexidade

      • Gestão de configuração: cada região exigia configurações próprias do Quarry, endpoints de cluster e regras de roteamento de rede
      • Carga de testes: toda mudança de código precisava ser validada nas 8 regiões
      • Implantação sequencial: não era possível implantar tudo ao mesmo tempo; o rollout precisava ser gradual por região
      • Problemas específicos por região: diferenças em configuração de rede, regras de soberania de dados e versões de cluster
    • Como isso foi tratado

      • Validar primeiro em uma única região piloto, em geral baseada nos EUA
      • Documentar os requisitos de configuração por região
      • Construir um Quarry Operator com consciência de região
      • Fazer rollout gradual e incorporar aprendizados de cada região
      • Acompanhar separadamente o progresso da migração em cada região
    • Lição: infraestrutura multi-região não é apenas N vezes mais trabalho; ela é N vezes mais difícil por causa dos modos de falha específicos de cada região, então é preciso reservar tempo suficiente para coordenação entre regiões e debugging regional

Resultados

  • Eliminação de 100% do SSH, com todos os jobs de produção passando a usar submissão via REST por meio do Quarry
  • Ganhos de segurança

    • O acesso SSH foi removido de clusters EMR de produção em todas as 8 regiões de dados independentes, reduzindo drasticamente a superfície de ataque
    • A distribuição de chaves SSH foi substituída por autenticação com tokens entre serviços, e o logging da API REST passou a fornecer trilha de auditoria adequada
    • Todas as submissões de jobs passaram a ter logs estruturados via Quarry
    • O último cluster EMR da conta principal da AWS foi movido para uma conta filha, concluindo a iniciativa Whitecastle
    • A eliminação de security groups especiais e de uma gestão complexa de permissões simplificou o compliance
  • Melhorias operacionais

    • A contenção de recursos no nó mestre foi eliminada, e todos os jobs não Hadoop passaram a executar em contêineres YARN distribuídos com alocação adequada de recursos
    • Mesmo com reinício de Pods Kubernetes do cliente, os jobs continuavam ativos, trazendo grande melhora de confiabilidade, eliminando processos zumbis e permitindo encerramento correto via API REST
    • A API do Quarry passou a fornecer estado de job, logs e métricas estruturados, permitindo rastrear todo o ciclo de vida do job, consultar logs dos contêineres YARN e depurar com as ferramentas apropriadas
  • Base para o futuro

    • Com a dependência de SSH removida, tornou-se possível a migração para Spark on Kubernetes
    • A arquitetura baseada em REST está alinhada com práticas cloud-native
    • O Quarry Operator, mais simples e fácil de manter do que configurações SSH complexas, facilitou o onboarding das equipes
    • Houve desacoplamento entre o Airflow e os detalhes da infraestrutura EMR
    • A padronização de todas as submissões de jobs no Quarry tornou mudanças futuras mais simples
  • Após dois anos de operação em produção, a validade da decisão arquitetural foi confirmada, com melhorias em segurança, estabilidade operacional e flexibilidade de infraestrutura

Lições aprendidas

  • O que funcionou bem

    • Migração gradual: rollout sequencial Dev → GovDev/CommDev → Prod e migração por tipo de Operator, acumulando aprendizados a cada etapa
    • Forte colaboração entre equipes: cooperação entre Search, Analytics, Data Engineering, ML, Marketing e outras áreas, com code reviews rápidos e comunicação por canal compartilhado
    • Acompanhamento guiado por dados: criação de um dashboard para o progresso da migração em todas as regiões e uso de consultas ao banco do Airflow para identificar trabalhos restantes baseados em SSH
  • O que fariam diferente

    • Mapear antes a topologia de rede: problemas de isolamento de rede, como a conectividade com EKM, só foram descobertos mais tarde; seria preciso documentar fronteiras de conta do Whitecastle e roteamento de rede antes da migração dos clusters
    • Testar limites de recursos mais cedo: o problema do vmem check apareceu tardiamente; seria necessário incluir desde a fase piloto testes dos limites de recursos do YARN em comparação com SSH
    • Comunicar antes as restrições dos Operators: quando o uso de novos SSHOperator foi restringido na fase final, algumas equipes não sabiam; seria preciso reforçar a comunicação prévia com todos os usuários do Airflow
  • Boas práticas para migrações em larga escala

    • Construa monitoramento antes de migrar: crie cedo dashboards que permitam ver sempre o trabalho restante e use consultas ao banco do Airflow
    • Teste em vários ambientes: valide em Dev, CommDev e GovDev para detectar problemas específicos antes da produção, especialmente testes entre fronteiras de contas para identificar antecipadamente problemas de isolamento de rede
    • Descontinue Operators gradualmente: retire CrunchExecOperator, S3SyncOperator e outros um de cada vez, tratando cada etapa como um mini projeto com seus próprios testes e validação; é mais lento, mas reduz muito o risco

Ainda não há comentários.

Ainda não há comentários.