Nossas conclusões após um ano de migração do GitLab.com para Kubernetes

Nota do tradutor.: a adaptação do Kubernetes no GitLab é considerada um dos dois principais fatores que impulsionam o crescimento da empresa. No entanto, até recentemente, a infraestrutura do serviço online GitLab.com estava baseada em máquinas virtuais, e a migração para K8s começou apenas há cerca de um ano, estando ainda em andamento. Temos o prazer de apresentar a tradução de um artigo recente de um engenheiro SRE do GitLab sobre como isso está acontecendo e quais conclusões estão sendo feitas pelos engenheiros envolvidos no projeto.

Nossas conclusões após um ano de migração do GitLab.com para Kubernetes

Já faz cerca de um ano que nosso departamento de infraestrutura está trabalhando na migração de todos os serviços operando no GitLab.com para o Kubernetes. Durante esse tempo, encontramos problemas não apenas relacionados à movimentação dos serviços para o Kubernetes, mas também à gestão de um deployment híbrido durante a transição. Sobre as lições valiosas que aprendemos, falaremos neste artigo.

Desde o início, o GitLab.com operava em nuvem em máquinas virtuais. Essas máquinas virtuais são gerenciadas pelo Chef, e sua instalação é feita através do nosso pacote oficial do Linux. Estratégia de Deployment para o caso de ser necessário atualizar o aplicativo, consiste na simples atualização do parque de servidores de forma coordenada e sequencial através de um pipeline CI. Este método — embora lento e um pouco tedioso — garante que o GitLab.com utiliza os mesmos métodos de instalação e configuração que os usuários das instâncias (self-managed) do GitLab, que utilizam nossos pacotes do Linux para isso.

Utilizamos este método porque é extremamente importante sentir todas as dificuldades e alegrias que os membros da comunidade experimentam ao instalar e configurar suas próprias cópias do GitLab. Esta abordagem funcionou bem por um tempo, no entanto, quando o número de projetos no GitLab ultrapassou 10 milhões, percebemos que ela já não atendia às nossas necessidades de escalabilidade e deployment.

Os primeiros passos rumo ao Kubernetes e ao GitLab cloud-native

Em 2017, foi criado o projeto GitLab Charts para preparar o GitLab para a implantação na nuvem e para permitir que os usuários instalem o GitLab em clusters Kubernetes. Naquela época, sabíamos que a migração do GitLab para o Kubernetes aumentaria as capacidades de escalabilidade da plataforma SaaS, simplificaria as implantações e melhoraria a eficiência do uso dos recursos computacionais. Ao mesmo tempo, muitas funcionalidades de nosso aplicativo dependiam de seções NFS montadas, o que retardava a transição de máquinas virtuais.

A busca por cloud native e Kubernetes permitiu que nossos engenheiros planejassem uma transição gradual, durante a qual abandonamos algumas dependências do aplicativo em relação a armazenamentos de rede, enquanto continuávamos a desenvolver novas funcionalidades. Desde que começamos a planejar a migração no verão de 2019, muitas dessas restrições foram eliminadas, e o processo de migração do GitLab.com para Kubernetes agora está em plena execução!

Recursos do GitLab.com em Kubernetes

Para o GitLab.com, utilizamos um único cluster regional GKE, que processa todo o tráfego do aplicativo. Para minimizar a complexidade (que já é bastante complicada) da migração, focamos em serviços que não dependem de armazenamento local ou NFS. O GitLab.com utiliza predominantemente uma base de código monolítica em Rails, e direcionamos o tráfego dependendo das características da carga de trabalho para diferentes endpoints, isolados em seus próprios pools de nós.

No caso do front-end, esses tipos são divididos em solicitações para web, API, Git SSH/HTTPS e Registry. No caso do back-end, dividimos jobs nas filas com base em várias características dependendo de limites de recursos predefinidos, que nos permitem estabelecer metas de nível de serviço (Service-Level Objectives, SLOs) para diferentes cargas.

Todos esses serviços do GitLab.com estão configurados usando um gráfico Helm não modificado do GitLab. A configuração é feita em subgráficos, que podem ser incluídos seletivamente à medida que migramos gradualmente os serviços para o cluster. Mesmo considerando que foi decidido não incluir na migração alguns dos nossos serviços stateful, como Redis, Postgres, GitLab Pages e Gitaly, o uso do Kubernetes permite reduzir drasticamente o número de VMs que atualmente são gerenciadas pelo Chef.

Transparência e gerenciamento de configuração do Kubernetes

Todas as configurações são geridas pelo próprio GitLab. Para isso, três projetos de configuração baseados em Terraform e Helm são utilizados. Nós nos esforçamos para usar o próprio GitLab para iniciar o GitLab sempre que possível, mas para tarefas operacionais, temos uma instalação separada do GitLab. Isso é necessário para não depender da disponibilidade do GitLab.com durante a implantação e atualizações do GitLab.com.

Embora nossos pipelines para o cluster Kubernetes funcionem em uma instalação separada do GitLab, os repositórios de código têm espelhos, disponíveis publicamente nos seguintes endereços:

  • k8s-workloads/gitlab-com — wrapper de configuração do GitLab.com para o Helm chart do GitLab;
  • k8s-workloads/gitlab-helmfiles — contém configurações para serviços que não estão diretamente relacionados ao aplicativo GitLab. Isso inclui configurações para gerenciamento de logs e monitoramento do cluster, bem como para ferramentas integradas como PlantUML;
  • Gitlab-com-infrastructure — configuração Terraform para Kubernetes e antiga infraestrutura de VM (legacy). Aqui, todos os recursos necessários para iniciar o cluster são configurados, incluindo o próprio cluster, pools de nós, contas de serviços e reserva de endereços IP.

Nossas conclusões após um ano de migração do GitLab.com para Kubernetes
Ao fazer alterações, é exibido um resumo público com um link para um diff detalhado que a SRE analisa antes de fazer alterações no cluster.

Para SRE, o link leva a um diff detalhado na instalação do GitLab que é usada para operações e à qual o acesso é restrito. Isso permite que funcionários e a comunidade sem acesso ao projeto operacional (que é aberto apenas para SRE) visualizem as mudanças propostas na configuração. Combinando uma instância pública do GitLab para código com uma instância privada para pipelines de CI, mantemos um fluxo de trabalho unificado, garantindo ao mesmo tempo independência do GitLab.com durante as atualizações da configuração.

O que aprendemos durante a migração

Durante a transição, adquirimos experiências que aplicamos a novas migrações e implantações no Kubernetes.

1. Aumento de custos devido ao tráfego entre zonas de disponibilidade

Nossas conclusões após um ano de migração do GitLab.com para Kubernetes
Estatísticas de egress diária (bytes por dia) do conjunto de repositórios Git no GitLab.com

O Google divide sua rede em regiões. Essas, por sua vez, são divididas em zonas de disponibilidade (AZ). O hosting de Git está associado a grandes volumes de dados, então é importante para nós controlar o egress da rede. No caso de tráfego interno, o egress é gratuito apenas se permanecer dentro dos limites de uma única zona de disponibilidade. No momento da redação deste artigo, estamos transferindo cerca de 100 TB de dados em um dia normal de trabalho (e isso é apenas para repositórios Git). Os serviços que, em nossa antiga topologia baseada em VM, estavam na mesma máquina virtual, agora operam em diferentes pods do Kubernetes. Isso significa que parte do tráfego que anteriormente era local para a VM pode potencialmente sair das zonas de disponibilidade.

Os clusters regionais GKE permitem abranger várias zonas de disponibilidade para redundância. Estamos considerando a possibilidade de dividir o cluster regional GKE em clusters de uma única zona para serviços que geram grandes volumes de tráfego. Isso permitirá reduzir os custos de egress enquanto mantém a redundância a nível de cluster.

2. Limites, solicitações de recursos e escalabilidade

Nossas conclusões após um ano de migração do GitLab.com para Kubernetes
Número de réplicas processando o tráfego de produção em registry.gitlab.com. O tráfego atinge seu pico por volta das 15:00 UTC.

Nossa história de migração começou em agosto de 2019, quando migramos o primeiro serviço — o registro de contêineres GitLab (GitLab Container Registry) — para o Kubernetes. Esse serviço crítico de alto tráfego foi ideal para a primeira migração, pois é um aplicativo stateless com poucas dependências externas. O primeiro problema que enfrentamos foi o alto número de pods expulsos devido à falta de memória nos nós. Por causa disso, tivemos que ajustar as solicitações e limites.

Foi descoberto que, no caso de um aplicativo cujo consumo de memória aumenta com o tempo, valores baixos para as solicitações (reservando memória para cada pod) combinados com um limite "generoso" de uso resultavam na saturação (saturação) dos nós e em altos níveis de expulsões. Para lidar com esse problema, foi decidido aumentar as solicitações e diminuir os limites.. Isso aliviou a pressão sobre os nós e proporcionou um ciclo de vida dos pods que não exerceu pressão excessiva sobre o nó. Agora começamos as migrações com valores generosos (e praticamente idênticos) de requisições e limites, ajustando-os conforme necessário.

3. Métricas e Logs

Nossas conclusões após um ano de migração do GitLab.com para Kubernetes
A unidade de infraestrutura foca nas latências, na porcentagem de erros e na saturação com metas estabelecidas de nível de serviço (SLO), ligadas a disponibilidade geral do nosso sistema.

No último ano, um dos eventos-chave da unidade de infraestrutura foram as melhorias na monitoração e no trabalho com SLO. Os SLO nos permitiram estabelecer metas para serviços individuais, que monitoramos de perto durante a migração. Mas mesmo com essa visibilidade aprimorada, nem sempre conseguimos detectar problemas rapidamente, utilizando métricas e alertas. Por exemplo, ao focar nas latências e na porcentagem de erros, não abrangemos completamente todos os cenários de uso do serviço em migração.

Esse problema foi identificado quase imediatamente após a transferência de parte das cargas de trabalho para o cluster. Ele se destacou especialmente ao verificar funções cujo número de requisições é pequeno, mas que possuem dependências de configuração muito específicas. Uma das lições-chave após a migração foi a necessidade de considerar na monitoração não apenas métricas, mas também logs e o 'long tail' (refere-se à distribuição delas em um gráfico — nota do tradutor) de erros. Agora, para cada migração, incluímos uma lista detalhada de requisições aos logs (log queries) e planejamos procedimentos claros de rollback, que podem ser transmitidos de uma equipe para outra em caso de problemas.

O atendimento paralelo das mesmas requisições na antiga infraestrutura de VM e na nova, baseada em Kubernetes, representou um desafio único. Ao contrário da migração do tipo lift-and-shift (transferência rápida de aplicações 'como estão' para a nova infraestrutura; mais detalhes podem ser lidos, por exemplo, aqui — nota do tradutor.), o trabalho paralelo em "máquinas virtuais antigas" e Kubernetes requer que as ferramentas de monitoramento sejam compatíveis com ambos os ambientes e consigam consolidar métricas em uma única visão. É importante que usemos os mesmos dashboards e consultas de logs para alcançar uma observabilidade consistente durante o período de transição.

4. Mudando o tráfego para o novo cluster

Para o GitLab.com, parte dos servidores é destinada à fase canário (canary). O parque canário atende nossos projetos internos e também pode ser acionado por usuários. Mas, principalmente, é destinado à verificação de mudanças feitas na infraestrutura e no aplicativo. O primeiro serviço migrado começou recebendo um volume limitado de tráfego interno, e continuamos usando esse método para garantir que os SLO estejam sendo cumpridos antes de direcionar todo o tráfego para o cluster.

No caso da migração, isso significa que inicialmente as solicitações para projetos internos são direcionadas ao Kubernetes, e então, gradualmente, redirecionamos o restante do tráfego para o cluster alterando o peso do backend através do HAProxy. Durante a transição de VM para Kubernetes, ficou claro que era muito vantajoso ter um método simples de redirecionamento de tráfego entre a infraestrutura antiga e a nova e, consequentemente, manter a infraestrutura antiga pronta para um rollback nos primeiros dias após a migração.

5. Capacidade de reserva dos pods e seu uso

Quase imediatamente, o seguinte problema foi identificado: os pods para o serviço Registry iniciaram rapidamente, no entanto, o início dos pods para o Sidekiq levou até dois minutos. O longo tempo de inicialização dos pods para o Sidekiq se tornou um problema quando começamos a migração das cargas de trabalho do Kubernetes para os trabalhadores, que precisam processar jobs rapidamente e escalar rapidamente.

Neste caso, a lição foi que, embora o Horizontal Pod Autoscaler (HPA) no Kubernetes lide bem com o aumento do tráfego, é importante considerar as características das cargas de trabalho e alocar capacidade de reserva para os pods (especialmente em condições de demanda desigual). No nosso caso, houve um aumento repentino nos jobs, resultando em uma escalabilidade rápida que levou à saturação dos recursos de CPU antes que conseguíssemos escalar o pool de nós.

Sempre há a tentação de extrair o máximo do cluster, no entanto, após inicialmente enfrentarmos problemas de desempenho, agora começamos com um orçamento generoso de pod e o reduzimos posteriormente, monitorando atentamente o SLO. A inicialização dos pods para o serviço Sidekiq acelerou consideravelmente e agora leva em média cerca de 40 segundos. Do tempo de inicialização reduzido dos pods tanto o GitLab.com quanto nossos usuários de instalações self-managed que trabalham com o chart Helm oficial do GitLab se beneficiaram.

Conclusão

Após a migração de cada serviço, celebramos as vantagens de usar Kubernetes em produção: deploys mais rápidos e seguros, escalabilidade e uma distribuição de recursos mais eficaz. Além disso, os benefícios da migração vão além do serviço GitLab.com. Cada melhoria no chart Helm oficial traz vantagens também para seus usuários.

Espero que você tenha gostado da história sobre nossas aventuras na migração para Kubernetes. Continuamos a migrar novos serviços para o cluster. Mais informações podem ser encontradas nas seguintes publicações:

P.S. do tradutor

Confira também em nosso blog:

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster