Criando uma plataforma Kubernetes no Pinterest

Ao longo dos anos, os 300 milhões de usuários do Pinterest criaram mais de 200 bilhões de pins em mais de 4 bilhões de painéis. Para atender esse exército de usuários e vasta base de conteúdo, o portal desenvolveu milhares de serviços, que vão desde microsserviços que podem ser gerenciados por algumas CPUs, até monólitos gigantes que rodam em uma frota inteira de máquinas virtuais. E então chegou o momento em que os olhos da empresa caíram sobre os k8s. Por que o “cubo” ficou bem no Pinterest? Você aprenderá sobre isso em nossa tradução de um artigo recente de blog Pinterest engenharia.

Criando uma plataforma Kubernetes no Pinterest

Portanto, centenas de milhões de usuários e centenas de bilhões de pins. Para atender esse exército de usuários e essa vasta base de conteúdo, desenvolvemos milhares de serviços, que vão desde microsserviços que podem ser gerenciados por algumas CPUs até monólitos gigantes que são executados em frotas inteiras de máquinas virtuais. Além disso, temos uma variedade de estruturas que também podem exigir acesso à CPU, memória ou E/S.

Ao manter esse zoológico de ferramentas, a equipe de desenvolvimento enfrenta vários desafios:

  • Não existe uma maneira uniforme para os engenheiros administrarem um ambiente de produção. Serviços sem estado, serviços com estado e projetos em desenvolvimento ativo baseiam-se em pilhas de tecnologia completamente diferentes. Isso levou à criação de todo um curso de formação de engenheiros e também complicou seriamente o trabalho da nossa equipe de infraestrutura.
  • Os desenvolvedores com sua própria frota de máquinas virtuais criam uma enorme carga para os administradores internos. Como resultado, operações simples como atualizar o sistema operacional ou a AMI levam semanas e meses. Isso leva ao aumento da carga de trabalho em situações aparentemente cotidianas.
  • Dificuldades em criar ferramentas de gestão de infraestrutura global em cima de soluções existentes. A situação é ainda mais complicada pelo fato de que não é fácil encontrar os proprietários das máquinas virtuais. Ou seja, não sabemos se essa capacidade pode ser extraída com segurança para operar em outras partes da nossa infraestrutura.

Os sistemas de orquestração de contêineres são uma forma de unificar o gerenciamento de cargas de trabalho. Eles abrem as portas para uma maior velocidade de desenvolvimento e simplificam o gerenciamento da infraestrutura, uma vez que todos os recursos envolvidos no projeto são gerenciados por um sistema centralizado.

Criando uma plataforma Kubernetes no Pinterest

Figura 1: Prioridades de infraestrutura (confiabilidade, produtividade e eficiência do desenvolvedor).

A equipe da Cloud Management Platform do Pinterest descobriu o K8s em 2017. No primeiro semestre de 2017, havíamos documentado a maior parte de nossas capacidades de produção, incluindo a API e todos os nossos servidores web. Posteriormente, conduzimos uma avaliação completa de vários sistemas para orquestrar soluções de contêineres, construir clusters e trabalhar com eles. No final de 2017, decidimos usar o Kubernetes. Era bastante flexível e amplamente suportado pela comunidade de desenvolvedores.

Até o momento, construímos nossas próprias ferramentas de inicialização de cluster baseadas em Kops e migramos componentes de infraestrutura existentes, como rede, segurança, métricas, registro em log, gerenciamento de identidade e tráfego para Kubernetes. Também implementamos um sistema de modelagem de carga de trabalho para nosso recurso, cuja complexidade está oculta aos desenvolvedores. Agora estamos focados em garantir a estabilidade do cluster, escalá-lo e conectar novos clientes.

Kubernetes: o jeito do Pinterest

Começar a usar o Kubernetes na escala do Pinterest como uma plataforma que nossos engenheiros adorariam trouxe muitos desafios.

Como uma grande empresa, investimos pesadamente em ferramentas de infraestrutura. Os exemplos incluem ferramentas de segurança que lidam com processamento de certificados e distribuição de chaves, componentes de controle de tráfego, sistemas de descoberta de serviços, componentes de visibilidade e componentes de envio de logs e métricas. Tudo isso foi coletado por um motivo: percorremos o caminho normal de tentativa e erro e, portanto, queríamos integrar todo esse equipamento à nova infraestrutura do Kubernetes, em vez de reinventar a velha roda em uma nova plataforma. Esta abordagem simplificou globalmente a migração, uma vez que todo o suporte da aplicação já existe e não precisa de ser criado do zero.

Por outro lado, os modelos de previsão de carga no próprio Kubernetes (como implantações, jobs e conjuntos de Daemon) não são suficientes para o nosso projeto. Esses problemas de usabilidade são enormes barreiras para migrar para o Kubernetes. Por exemplo, ouvimos desenvolvedores de serviços reclamarem de configurações de login ausentes ou incorretas. Também encontramos o uso incorreto de mecanismos de modelo, quando centenas de cópias foram criadas com a mesma especificação e tarefa, o que resultou em problemas de depuração terríveis.

Também foi muito difícil manter versões diferentes no mesmo cluster. Imagine a complexidade do suporte ao cliente se você precisar trabalhar simultaneamente em múltiplas versões do mesmo ambiente de execução, com todos os seus problemas, bugs e atualizações.

Propriedades e controladores do usuário do Pinterest

Para facilitar a implementação do Kubernetes pelos nossos engenheiros e para simplificar e acelerar a nossa infraestrutura, desenvolvemos as nossas próprias definições de recursos personalizados (CRDs).

CRDs fornecem a seguinte funcionalidade:

  1. Combinar diferentes recursos nativos do Kubernetes para que funcionem como uma única carga de trabalho. Por exemplo, o recurso PinterestService inclui uma implantação, um serviço de login e um mapa de configuração. Isso permite que os desenvolvedores não se preocupem em configurar o DNS.
  2. Implemente o suporte de aplicativo necessário. O usuário precisa se concentrar apenas na especificação do contêiner de acordo com sua lógica de negócios, enquanto o controlador CRD implementa todos os contêineres de inicialização, variáveis ​​de ambiente e especificações de pod necessários. Isso fornece um nível de conforto fundamentalmente diferente para os desenvolvedores.
  3. Os controladores CRD também gerenciam o ciclo de vida dos recursos nativos e melhoram a disponibilidade de depuração. Isso inclui reconciliar especificações desejadas e reais, atualizar o status do CRD e manter logs de eventos e muito mais. Sem CRD, os desenvolvedores seriam forçados a gerenciar vários recursos, o que só aumentaria a probabilidade de erro.

Aqui está um exemplo de PinterestService e recurso interno gerenciado por nosso controlador:

Criando uma plataforma Kubernetes no Pinterest

Como você pode ver acima, para oferecer suporte a um contêiner personalizado, precisamos integrar um contêiner init e vários complementos para fornecer segurança, visibilidade e tráfego de rede. Além disso, criamos modelos de mapas de configuração e implementamos suporte para modelos PVC para trabalhos em lote, bem como rastreamento de diversas variáveis ​​de ambiente para rastrear identidade, consumo de recursos e coleta de lixo.

É difícil imaginar que os desenvolvedores queiram escrever esses arquivos de configuração manualmente sem suporte CRD, muito menos manter e depurar ainda mais as configurações.

Fluxo de trabalho de implantação de aplicativos

Criando uma plataforma Kubernetes no Pinterest

A imagem acima mostra como implantar um recurso personalizado do Pinterest em um cluster Kubernetes:

  1. Os desenvolvedores interagem com nosso cluster Kubernetes por meio da CLI e da interface do usuário.
  2. As ferramentas CLI/UI recuperam os arquivos YAML de configuração do fluxo de trabalho e outras propriedades de construção (mesmo ID de versão) do Artifactory e, em seguida, os enviam ao Job Submission Service. Esta etapa garante que apenas versões de produção sejam entregues ao cluster.
  3. JSS é um gateway para diversas plataformas, incluindo Kubernetes. Aqui o usuário é autenticado, as cotas são emitidas e a configuração do nosso CRD é parcialmente verificada.
  4. Após a verificação do CRD do lado JSS, as informações são enviadas para a API da plataforma k8s.
  5. Nosso controlador CRD monitora eventos em todos os recursos do usuário. Ele converte CRs em recursos k8s nativos, adiciona os módulos necessários, define as variáveis ​​de ambiente apropriadas e executa outros trabalhos de suporte para garantir que os aplicativos de usuário em contêineres tenham suporte de infraestrutura suficiente.
  6. O controlador CRD então passa os dados recebidos para a API Kubernetes para que possam ser processados ​​pelo agendador e colocados em produção.

Nota: Este fluxo de trabalho de pré-lançamento da implantação foi criado para os primeiros usuários da nova plataforma k8s. Atualmente, estamos no processo de refinar esse processo para integrá-lo totalmente ao nosso novo CI/CD. Isso significa que não podemos contar tudo relacionado ao Kubernetes. Estamos ansiosos para compartilhar nossa experiência e o progresso da equipe nessa direção em nossa próxima postagem no blog, “Construindo uma plataforma CI/CD para Pinterest”.

Tipos de recursos especiais

Com base nas necessidades específicas do Pinterest, desenvolvemos os seguintes CRDs para atender a diferentes fluxos de trabalho:

  • PinterestService são serviços sem estado que estão em execução há muito tempo. Muitos de nossos sistemas principais são baseados em um conjunto desses serviços.
  • PinterestJobSet modela trabalhos em lote de ciclo completo. Um cenário comum no Pinterest é que vários trabalhos executem os mesmos contêineres em paralelo, independentemente de outros processos semelhantes.
  • PinterestCronJob é amplamente utilizado em conjunto com pequenas cargas periódicas. Este é um wrapper para trabalho cron nativo com mecanismos de suporte do Pinterest responsáveis ​​pela segurança, tráfego, logs e métricas.
  • PinterestDaemon inclui Daemons de infraestrutura. Esta família continua a crescer à medida que adicionamos mais suporte aos nossos clusters.
  • PinterestTrainingJob se estende aos processos Tensorflow e Pytorch, fornecendo o mesmo nível de suporte de tempo de execução que todos os outros CRDs. Como o Pinterest usa ativamente o Tensorflow e outros sistemas de aprendizado de máquina, tínhamos um motivo para construir um CRD separado em torno deles.

Também estamos trabalhando no PinterestStatefulSet, que em breve será adaptado para data warehouses e outros sistemas com estado.

Suporte de tempo de execução

Quando um pod de aplicativo é executado no Kubernetes, ele recebe automaticamente um certificado para se identificar. Este certificado é usado para acessar o armazenamento secreto ou para se comunicar com outros serviços via mTLS. Enquanto isso, o Container Init Configurator e o Daemon farão o download de todas as dependências necessárias antes de executar o aplicativo em contêiner. Quando tudo estiver pronto, o sidecar de tráfego e o Daemon registrarão o endereço IP do módulo com nosso Zookeeper para que os clientes possam descobri-lo. Tudo isso funcionará porque o módulo de rede foi configurado antes do lançamento do aplicativo.

Os exemplos acima são exemplos típicos de suporte de tempo de execução para cargas de trabalho. Outros tipos de cargas de trabalho podem exigir suporte ligeiramente diferente, mas todos eles vêm na forma de sidecars em nível de pod, daemons em nível de nó ou em nível de máquina virtual. Garantimos que tudo isso seja implantado na infraestrutura de gerenciamento e seja consistente em todos os aplicativos, o que, em última análise, reduz significativamente a carga em termos de trabalho técnico e suporte ao cliente.

Teste e controle de qualidade

Construímos um pipeline de teste ponta a ponta com base na infraestrutura de teste existente do Kubernetes. Esses testes se aplicam a todos os nossos clusters. Nosso pipeline passou por muitas revisões antes de se tornar parte do cluster de produtos.

Além de testar sistemas, possuímos sistemas de monitorização e alerta que monitorizam constantemente o estado dos componentes do sistema, o consumo de recursos e outros indicadores importantes, notificando-nos apenas quando é necessária intervenção humana.

Alternativas

Analisamos algumas alternativas para recursos personalizados, como controladores de acesso de mutação e sistemas de modelo. No entanto, todos eles apresentam desafios operacionais significativos, por isso escolhemos a rota CRD.

Um controlador de admissão mutacional foi usado para introduzir sidecars, variáveis ​​de ambiente e outros suportes de tempo de execução. No entanto, enfrentou vários problemas, tais como vinculação de recursos e gestão do ciclo de vida, onde tais problemas não surgem no CRD.

Nota: Sistemas de modelo, como gráficos Helm, também são amplamente usados ​​para executar aplicativos com configurações semelhantes. No entanto, nossos aplicativos de trabalho são muito diversos para serem gerenciados por meio de modelos. Além disso, durante a implantação contínua, haverá muitos erros ao usar modelos.

Próximos trabalhos

Atualmente, estamos lidando com uma carga mista em todos os nossos clusters. Para dar suporte a tais processos de diversos tipos e portes, atuamos nas seguintes áreas:

  • Uma coleção de clusters distribui grandes aplicativos em diferentes clusters para escalabilidade e estabilidade.
  • Garantir estabilidade, escalabilidade e visibilidade do cluster para criar conectividade de aplicativos e SLAs.
  • Gerenciar recursos e cotas para que os aplicativos não entrem em conflito entre si e a escala do cluster seja controlada de nossa parte.
  • Uma nova plataforma CI/CD para suporte e implantação de aplicativos no Kubernetes.

Fonte: habr.com

Adicionar um comentário