Como as prioridades de pod no Kubernetes causaram tempo de inatividade no Grafana Labs

Observação. trad.: Apresentamos a sua atenção detalhes técnicos sobre os motivos da recente indisponibilidade do serviço em nuvem mantido pelos criadores do Grafana. Este é um exemplo clássico de como um recurso novo e aparentemente extremamente útil, projetado para melhorar a qualidade da infraestrutura... pode causar danos se você não considerar as inúmeras nuances de sua aplicação na realidade da produção. É ótimo quando aparecem materiais como esse que permitem que você aprenda não apenas com seus erros. Os detalhes estão na tradução deste texto do vice-presidente de produto do Grafana Labs.

Como as prioridades de pod no Kubernetes causaram tempo de inatividade no Grafana Labs

Na sexta-feira, 19 de julho, o serviço Hosted Prometheus no Grafana Cloud parou de funcionar por aproximadamente 30 minutos. Peço desculpas a todos os clientes afetados pela interrupção. Nosso trabalho é fornecer as ferramentas de monitoramento que você precisa e entendemos que não tê-las disponíveis pode dificultar sua vida. Levamos este incidente extremamente a sério. Esta nota explica o que aconteceu, como respondemos e o que estamos fazendo para garantir que isso não aconteça novamente.

Pré-história

O serviço Grafana Cloud Hosted Prometheus é baseado em Córtex — Projeto CNCF para criar um serviço Prometheus multilocatário, horizontalmente escalonável e altamente disponível. A arquitetura Cortex consiste em um conjunto de microsserviços individuais, cada um executando sua própria função: replicação, armazenamento, consultas, etc. Cortex está em desenvolvimento ativo e constantemente adicionando novos recursos e melhorando o desempenho. Implantamos regularmente novas versões do Cortex em clusters para que os clientes possam aproveitar esses recursos – felizmente, o Cortex pode ser atualizado sem tempo de inatividade.

Para atualizações contínuas, o serviço Ingester Cortex requer uma réplica adicional do Ingester durante o processo de atualização. (Observação. trad.: Ingerir - o componente básico do Córtex. Seu trabalho é coletar um fluxo constante de amostras, agrupá-las em pedaços do Prometheus e armazená-las em um banco de dados como DynamoDB, BigTable ou Cassandra.) Isso permite que os Ingesters antigos encaminhem os dados atuais para os novos Ingesters. É importante notar que os Ingesters exigem recursos. Para que funcionem, você precisa ter 4 núcleos e 15 GB de memória por pod, ou seja, 25% do poder de processamento e memória da máquina base no caso dos nossos clusters Kubernetes. Em geral, normalmente temos muito mais recursos não utilizados no cluster do que 4 núcleos e 15 GB de memória, portanto, podemos facilmente ativar esses ingesters adicionais durante as atualizações.

No entanto, muitas vezes acontece que durante a operação normal nenhuma das máquinas possui esses 25% de recursos não utilizados. Sim, nem nos esforçamos: CPU e memória sempre serão úteis para outros processos. Para resolver este problema, decidimos usar Prioridades do pod do Kubernetes. A ideia é dar aos Ingesters uma prioridade mais alta do que outros microsserviços (sem estado). Quando precisamos executar um Ingester (N+1) adicional, deslocamos temporariamente outros pods menores. Esses pods são transferidos para recursos livres em outras máquinas, deixando um “buraco” grande o suficiente para executar um Ingester adicional.

Na quinta-feira, 18 de julho, lançamos quatro novos níveis de prioridade para nossos clusters: crítico, alto, média и baixo. Eles foram testados em um cluster interno sem tráfego de clientes por cerca de uma semana. Por padrão, os pods sem uma prioridade especificada são recebidos média prioridade, foi definida turma para Ingesters com alta prioridade. Crítico foi reservado para monitoramento (Prometheus, Alertmanager, node-exporter, kube-state-metrics, etc.). Nossa configuração está aberta e você pode ver o PR aqui.

Acidente

Na sexta-feira, 19 de julho, um dos engenheiros lançou um novo cluster Cortex dedicado para um grande cliente. A configuração deste cluster não incluía novas prioridades de pod, portanto, todos os novos pods receberam uma prioridade padrão - média.

O cluster Kubernetes não tinha recursos suficientes para o novo cluster Cortex, e o cluster Cortex de produção existente não foi atualizado (os Ingesters ficaram sem alta prioridade). Como os Ingesters do novo cluster, por padrão, tinham média prioridade, e os pods existentes em produção funcionaram sem prioridade alguma, os Ingesters do novo cluster substituíram os Ingesters do cluster de produção Cortex existente.

O ReplicaSet do Ingester despejado no cluster de produção detectou o pod despejado e criou um novo para manter o número especificado de cópias. O novo pod foi atribuído por padrão média prioridade, e outro Ingester “antigo” em produção perdeu seus recursos. O resultado foi processo de avalanche, o que levou ao deslocamento de todos os pods do Ingester para clusters de produção do Cortex.

Os ingesters têm estado e armazenam dados das 12 horas anteriores. Isso nos permite compactá-los com mais eficiência antes de gravá-los no armazenamento de longo prazo. Para conseguir isso, o Cortex fragmenta dados entre séries usando uma tabela de hash distribuída (DHT) e replica cada série em três Ingesters usando consistência de quorum no estilo Dynamo. O Cortex não grava dados em Ingesters desabilitados. Assim, quando um grande número de Ingesters sai do DHT, o Cortex não consegue fornecer replicação suficiente das entradas e eles travam.

Detecção e Remediação

Novas notificações do Prometheus baseadas em "orçamento de erro" (baseado em erro orçamentário — os detalhes aparecerão em um artigo futuro) começou a soar o alarme 4 minutos após o início do desligamento. Nos próximos cinco minutos, executamos alguns diagnósticos e ampliamos o cluster Kubernetes subjacente para hospedar os clusters de produção novos e existentes.

Depois de mais cinco minutos, os Ingesters antigos gravaram seus dados com sucesso, os novos foram iniciados e os clusters Cortex ficaram disponíveis novamente.

Outros 10 minutos foram gastos diagnosticando e corrigindo erros de falta de memória (OOM) de proxies reversos de autenticação localizados na frente do Cortex. Os erros de OOM foram causados ​​​​por um aumento de dez vezes no QPS (acreditamos que seja devido a solicitações excessivamente agressivas dos servidores Prometheus do cliente).

Resultado

O tempo de inatividade total foi de 26 minutos. Nenhum dado foi perdido. Os ingeridores carregaram com sucesso todos os dados da memória para armazenamento de longo prazo. Durante o desligamento, os servidores Prometheus do cliente foram excluídos em buffer (controlo remoto) gravações usando nova API remote_write baseado em WAL (de autoria de Callum Styan do Grafana Labs) e repetiu as gravações com falha após a falha.

Como as prioridades de pod no Kubernetes causaram tempo de inatividade no Grafana Labs
Operações de gravação de cluster de produção

Descobertas

É importante aprender com este incidente e tomar as medidas necessárias para evitar a sua recorrência.

Em retrospectiva, não deveríamos ter definido o padrão média prioridade até que todos os Ingesters em produção tenham recebido alto uma prioridade. Além disso, era preciso cuidar deles com antecedência alta prioridade. Tudo está consertado agora. Esperamos que nossa experiência ajude outras organizações que estão considerando o uso de prioridades de pod no Kubernetes.

Adicionaremos um nível adicional de controle sobre a implantação de quaisquer objetos adicionais cujas configurações sejam globais para o cluster. A partir de agora, tais mudanças serão avaliadasоmais pessoas. Além disso, a modificação que causou a falha foi considerada muito pequena para um documento de projeto separado – ela só foi discutida em uma edição do GitHub. A partir de agora, todas essas alterações nas configurações serão acompanhadas pela documentação apropriada do projeto.

Por fim, automatizaremos o redimensionamento do proxy reverso de autenticação para evitar a sobrecarga de OOM que testemunhamos e revisaremos as configurações padrão do Prometheus relacionadas ao fallback e escalonamento para evitar problemas semelhantes no futuro.

A falha também teve algumas consequências positivas: tendo recebido os recursos necessários, o Cortex se recuperou automaticamente sem intervenção adicional. Também adquirimos uma valiosa experiência trabalhando com Grafana Loki - nosso novo sistema de agregação de logs - que ajudou a garantir que todos os Ingesters se comportassem adequadamente durante e após a falha.

PS do tradutor

Leia também em nosso blog:

Fonte: habr.com

Adicionar um comentário