Tupperware: o assassino do Kubernetes do Facebook?

Gerenciamento eficiente e confiável de clusters em qualquer escala com Tupperware

Tupperware: o assassino do Kubernetes do Facebook?

Hoje em Conferência Systems@Scale introduzimos o Tupperware, nosso sistema de gerenciamento de cluster que orquestra contêineres em milhões de servidores que executam quase todos os nossos serviços. Implantamos o Tupperware pela primeira vez em 2011 e, desde então, nossa infraestrutura cresceu de 1 centro de dados para todo 15 data centers distribuídos geograficamente. Todo esse tempo a Tupperware não parou e se desenvolveu conosco. Mostraremos como a Tupperware fornece gerenciamento de cluster de primeira classe, incluindo suporte conveniente para serviços com estado, um painel de controle único para todos os data centers e a capacidade de distribuir capacidade entre serviços em tempo real. Também compartilharemos as lições que aprendemos à medida que nossa infraestrutura evolui.

A Tupperware realiza diferentes tarefas. Os desenvolvedores de aplicativos o utilizam para entregar e gerenciar aplicativos. Ele empacota o código do aplicativo e as dependências em uma imagem e os entrega aos servidores como contêineres. Os contêineres fornecem isolamento entre aplicativos no mesmo servidor para que os desenvolvedores lidem com a lógica do aplicativo e não precisem se preocupar em encontrar servidores ou gerenciar atualizações. A Tupperware também monitora o desempenho do servidor e, caso encontre uma falha, transfere os contêineres do servidor problemático.

Os engenheiros de planejamento de capacidade usam o Tupperware para alocar capacidade de servidor às equipes com base no orçamento e nas restrições. Eles também o usam para melhorar a utilização do servidor. Os operadores de data centers recorrem à Tupperware para distribuir adequadamente os contêineres pelos data centers e parar ou mover contêineres durante a manutenção. Graças a isso, a manutenção de servidores, redes e equipamentos requer intervenção humana mínima.

Arquitetura Tupperware

Tupperware: o assassino do Kubernetes do Facebook?

A arquitetura Tupperware PRN é uma das regiões de nossos data centers. A região consiste em vários edifícios de data centers (PRN1 e PRN2) localizados nas proximidades. Planejamos criar um painel de controle que gerencie todos os servidores em uma região.

Os desenvolvedores de aplicativos fornecem serviços na forma de trabalhos da Tupperware. Um trabalho consiste em vários contêineres e todos eles normalmente executam o mesmo código de aplicativo.

A Tupperware é responsável por provisionar contêineres e gerenciar seu ciclo de vida. Consiste em vários componentes:

  • O frontend do Tupperware fornece APIs para a interface do usuário, CLI e outras ferramentas de automação por meio das quais você pode interagir com o Tupperware. Eles escondem toda a estrutura interna dos proprietários de empregos da Tupperware.
  • Tupperware Scheduler é um painel de controle responsável por gerenciar o contêiner e o ciclo de vida do trabalho. Ele é implantado nos níveis regional e global, onde o agendador regional gerencia servidores em uma região e o agendador global gerencia servidores de regiões diferentes. O agendador é dividido em fragmentos e cada fragmento gerencia um conjunto de trabalhos.
  • O Scheduler Proxy da Tupperware oculta a fragmentação interna e fornece um painel único e conveniente para usuários da Tupperware.
  • O alocador Tupperware atribui contêineres aos servidores. O agendador trata da parada, inicialização, atualização e failover de contêineres. Atualmente, um alocador pode gerenciar toda a região sem dividir em fragmentos. (Observe a diferença na terminologia. Por exemplo, o agendador no Tupperware corresponde ao painel de controle no Kubernetes, e o alocador Tupperware é chamado de agendador no Kubernetes.)
  • O corretor de recursos armazena a fonte da verdade para os eventos de servidor e serviço. Executamos um corretor de recursos para cada data center e ele armazena todas as informações sobre os servidores desse data center. O corretor de recursos e o sistema de gerenciamento de capacidade, ou sistema de provisionamento de recursos, decidem dinamicamente qual entrega do agendador controla qual servidor. O serviço de verificação de funcionamento monitora servidores e armazena dados sobre seu funcionamento no corretor de recursos. Se um servidor tiver problemas ou precisar de manutenção, o corretor de recursos informa ao alocador e ao agendador para parar os contêineres ou movê-los para outros servidores.
  • O Agente Tupperware é um daemon executado em cada servidor que lida com o provisionamento e remoção de contêineres. Os aplicativos são executados dentro de um contêiner, o que lhes proporciona mais isolamento e reprodutibilidade. Sobre conferência Systems @Scale do ano passado Já descrevemos como os contêineres Tupperware individuais são criados usando imagens, btrfs, cgroupv2 e systemd.

Características distintivas da Tupperware

O Tupperware é semelhante em muitos aspectos a outros sistemas de gerenciamento de cluster, como Kubernetes e Mesos, mas também existem diferenças:

  • Suporte integrado para serviços com estado.
  • Um único painel de controle para servidores em diferentes data centers para automatizar a entrega de contêineres com base na intenção, descomissionamento de clusters e manutenção.
  • Divisão clara do painel de controle para zoom.
  • A computação elástica permite distribuir energia entre serviços em tempo real.

Desenvolvemos esses recursos interessantes para oferecer suporte a uma variedade de aplicativos sem estado e com estado em uma enorme frota global de servidores compartilhados.

Suporte integrado para serviços com estado.

A Tupperware opera uma variedade de serviços críticos com estado que armazenam dados persistentes de produtos para Facebook, Instagram, Messenger e WhatsApp. Podem ser grandes armazenamentos de pares de valores-chave (por exemplo, ZippyDB) e monitorar repositórios de dados (por exemplo, Gorila ODS и Crepe Scuba). Manter serviços com estado não é fácil, porque o sistema deve garantir que os suprimentos dos contêineres possam suportar interrupções em grande escala, incluindo interrupções na rede ou de energia. E embora as técnicas convencionais, como a distribuição de contêineres entre domínios de falha, funcionem bem para serviços sem estado, os serviços com estado precisam de suporte adicional.

Por exemplo, se uma falha no servidor tornar uma réplica de banco de dados indisponível, você deverá ativar a manutenção automática que atualizará os núcleos em 50 servidores de um pool de 10? Depende da situação. Se um desses 50 servidores possuir outra réplica do mesmo banco de dados, é melhor esperar e não perder 2 réplicas de uma vez. Para tomar decisões dinâmicas sobre manutenção e desempenho do sistema, precisamos de informações sobre a replicação interna de dados e a lógica de posicionamento de cada serviço com estado.

A interface TaskControl permite que serviços com estado influenciem decisões que afetam a disponibilidade de dados. Usando esta interface, o agendador notifica aplicações externas sobre operações de contêiner (reinicialização, atualização, migração, manutenção). Um serviço stateful implementa um controlador que informa ao Tupperware quando é seguro realizar cada operação, e essas operações podem ser trocadas ou atrasadas temporariamente. No exemplo acima, o controlador de banco de dados poderia dizer à Tupperware para atualizar 49 dos 50 servidores, mas deixar um servidor específico (X) sozinho por enquanto. Como resultado, se o período de atualização do kernel passar e o banco de dados ainda não conseguir restaurar a réplica problemática, o Tupperware ainda atualizará o servidor X.

Tupperware: o assassino do Kubernetes do Facebook?

Muitos serviços com estado no Tupperware usam o TaskControl não diretamente, mas por meio do ShardManager, uma plataforma comum para a criação de serviços com estado no Facebook. Com o Tupperware, os desenvolvedores podem especificar exatamente como os contêineres devem ser distribuídos nos data centers. Com o ShardManager, os desenvolvedores especificam sua intenção sobre como os fragmentos de dados devem ser distribuídos entre contêineres. O ShardManager está ciente do posicionamento e replicação de dados de seus aplicativos e se comunica com o Tupperware por meio da interface TaskControl para agendar operações de contêiner sem envolvimento direto do aplicativo. Essa integração simplifica muito o gerenciamento de serviços com estado, mas o TaskControl é capaz de fazer mais. Por exemplo, nossa extensa camada da web não tem estado e usa TaskControl para ajustar dinamicamente a taxa de atualizações em contêineres. Eventualmente a camada web é capaz de concluir rapidamente vários lançamentos de software por dia sem comprometer a disponibilidade.

Gerenciando servidores em data centers

Quando o Tupperware foi lançado pela primeira vez em 2011, cada cluster de servidor era gerenciado por um agendador separado. Naquela época, um cluster do Facebook era um grupo de racks de servidores conectados a um switch de rede, e o data center abrigava vários clusters. O agendador só poderia gerenciar servidores em um cluster, o que significa que a tarefa não poderia se espalhar por vários clusters. Nossa infraestrutura cresceu, cada vez mais descartamos clusters. Como a Tupperware não conseguiu mover o trabalho do cluster desativado para outros clusters sem alterações, foi necessário muito esforço e coordenação cuidadosa entre desenvolvedores de aplicativos e operadores de data center. Esse processo resultou em desperdício de recursos quando os servidores ficaram inativos por meses devido a procedimentos de descomissionamento.

Criamos um corretor de recursos para resolver o problema de descomissionamento do cluster e coordenar outros tipos de tarefas de manutenção. O corretor de recursos monitora todas as informações físicas associadas a um servidor e decide dinamicamente qual agendador controla cada servidor. Vincular dinamicamente servidores a agendadores permite que o agendador gerencie servidores em diferentes data centers. Como um trabalho do Tupperware não está mais limitado a um único cluster, os usuários do Tupperware podem especificar como os contêineres devem ser distribuídos entre domínios de falha. Por exemplo, um desenvolvedor pode declarar sua intenção (digamos: "executar meu trabalho em 2 domínios de falha na região PRN") sem especificar zonas de disponibilidade específicas. A própria Tupperware encontrará servidores adequados para implementar essa intenção, mesmo que o cluster ou serviço seja desativado.

Escalável para suportar todo o sistema global

Historicamente, nossa infraestrutura foi dividida em centenas de pools de servidores dedicados para equipes individuais. Devido à fragmentação e falta de padrões, tínhamos custos operacionais elevados e servidores ociosos eram mais difíceis de serem utilizados novamente. Na conferência do ano passado Sistemas @Escala nós apresentamos infraestrutura como serviço (IaaS), que deve unir nossa infraestrutura em um grande parque de servidores únicos. Mas um único parque de servidores tem suas próprias dificuldades. Deve atender a certos requisitos:

  • Escalabilidade. Nossa infraestrutura cresceu à medida que adicionamos data centers em cada região. Os servidores tornaram-se menores e mais eficientes em termos energéticos, por isso há muito mais deles em cada região. Como resultado, um único agendador por região não consegue lidar com o número de contêineres que podem ser executados em centenas de milhares de servidores em cada região.
  • Confiabilidade. Mesmo que o agendador possa ser ampliado tanto, o grande escopo do agendador significa que há um risco maior de erros e que uma região inteira de contêineres pode se tornar incontrolável.
  • Tolerância ao erro. No caso de uma grande falha na infraestrutura (por exemplo, os servidores que executam o escalonador falham devido a uma falha na rede ou queda de energia), as consequências negativas deverão afetar apenas uma parte dos servidores na região.
  • A comodidade de uso. Pode parecer que você precisa executar vários agendadores independentes para uma região. Mas, do ponto de vista da conveniência, um único ponto de entrada no conjunto partilhado de uma região facilita a gestão da capacidade e dos empregos.

Dividimos o agendador em fragmentos para resolver os problemas de manutenção de um grande pool compartilhado. Cada fragmento do agendador gerencia seu próprio conjunto de trabalhos na região e isso reduz o risco associado ao agendador. À medida que o pool compartilhado cresce, podemos adicionar mais fragmentos do agendador. Para usuários do Tupperware, os shards e os proxies do agendador parecem um painel de controle. Eles não precisam trabalhar com vários fragmentos que orquestram tarefas. Os fragmentos do agendador são fundamentalmente diferentes dos agendadores de cluster que usamos antes, quando o painel de controle era particionado sem dividir estaticamente o conjunto compartilhado de servidores de acordo com a topologia da rede.

Melhore a eficiência de uso com Elastic Computing

Quanto maior for a nossa infra-estrutura, mais importante será utilizar os nossos servidores de forma eficiente para optimizar os custos da infra-estrutura e reduzir a carga. Existem duas maneiras de aumentar a eficiência do uso do servidor:

  • Computação elástica – reduza a escala dos serviços on-line durante horários de silêncio e use servidores liberados para cargas de trabalho off-line, como aprendizado de máquina e trabalhos MapReduce.
  • Sobrecarga – Coloque serviços online e cargas de trabalho em lote nos mesmos servidores para que as cargas de trabalho em lote sejam executadas com baixa prioridade.

O gargalo em nossos data centers é uso de energia. Portanto, preferimos servidores pequenos e com baixo consumo de energia que, juntos, forneçam mais poder de processamento. Infelizmente, em servidores pequenos com pouca CPU e memória, a sobrecarga é menos eficaz. É claro que podemos colocar vários contêineres de pequenos serviços em um pequeno servidor com baixo consumo de energia e consumir poucos recursos do processador e memória, mas serviços grandes terão baixo desempenho nessa situação. Portanto, aconselhamos os desenvolvedores de nossos grandes serviços a otimizá-los para que utilizem todos os servidores.


Basicamente, melhoramos a eficiência de uso usando computação elástica. Muitos dos nossos principais serviços, como o feed de notícias, o recurso de mensagens e a camada web front-end, variam dependendo da hora do dia. Reduzimos intencionalmente os serviços online durante horários de silêncio e usamos servidores liberados para cargas de trabalho offline, como aprendizado de máquina e trabalhos MapReduce.

Tupperware: o assassino do Kubernetes do Facebook?

Sabemos por experiência que é melhor provisionar servidores inteiros como unidades de capacidade elástica porque grandes serviços são grandes doadores e grandes consumidores de capacidade elástica e são otimizados para usar servidores inteiros. Quando o servidor é liberado do serviço online durante horários de silêncio, o corretor de recursos aluga o servidor ao planejador para executar cargas de trabalho offline nele. Se o serviço online sofrer um pico de carga, o corretor de recursos recupera rapidamente o servidor emprestado e, junto com o agendador, o devolve ao serviço online.

Lições aprendidas e planos para o futuro

Nos últimos 8 anos, desenvolvemos a Tupperware para acompanhar o rápido crescimento do Facebook. Compartilhamos o que aprendemos e esperamos que isso ajude outros a gerenciar infraestruturas em rápido crescimento:

  • Configure uma conexão flexível entre o painel de controle e os servidores que ele gerencia. Essa flexibilidade permite que o painel de controle gerencie servidores em diferentes data centers, ajuda a automatizar o descomissionamento e a manutenção de clusters e permite a alocação dinâmica de capacidade usando computação elástica.
  • Com um único painel de controle na região, fica mais conveniente trabalhar com tarefas e mais fácil gerenciar uma grande frota de servidores compartilhados. Observe que o painel de controle mantém um único ponto de entrada, mesmo que sua estrutura interna seja separada por questões de escala ou tolerância a falhas.
  • Usando um modelo de plug-in, o painel de controle pode notificar aplicativos externos sobre as próximas operações do contêiner. Além disso, os serviços com estado podem usar a interface do plugin para personalizar o gerenciamento de contêineres. Com este modelo de plug-in, o painel de controle oferece simplicidade ao mesmo tempo em que atende com eficiência muitos serviços com estado diferentes.
  • Acreditamos que a computação elástica, onde retiramos servidores inteiros de serviços de doadores para trabalhos em lote, aprendizado de máquina e outros serviços não urgentes, é a maneira ideal de melhorar a eficiência de servidores pequenos e com baixo consumo de energia.

Estamos apenas começando a implementar frota única de servidores compartilhados globais. Atualmente cerca de 20% dos nossos servidores estão em um pool compartilhado. Para atingir 100%, muitos problemas precisam ser resolvidos, incluindo a manutenção de um pool de armazenamento compartilhado, a automatização da manutenção, o gerenciamento de requisitos entre locatários, a melhoria da utilização do servidor e o aprimoramento do suporte para cargas de trabalho de aprendizado de máquina. Mal podemos esperar para enfrentar esses desafios e compartilhar nossos sucessos.

Fonte: habr.com

Adicionar um comentário