Um ponto importante na operação de sistemas distribuídos é o tratamento de falhas. O Kubernetes ajuda nisso usando controladores que monitoram a integridade do seu sistema e reiniciam serviços que pararam de funcionar. No entanto, o Kubernetes pode interromper seus aplicativos à força para garantir a integridade geral do sistema. Nesta série, veremos como você pode ajudar o Kubernetes a fazer seu trabalho com mais eficiência e reduzir o tempo de inatividade do aplicativo.
Antes dos contêineres, a maioria dos aplicativos era executada em máquinas virtuais ou físicas. Se o aplicativo travasse ou travasse, demorava muito para cancelar a tarefa em andamento e recarregar o programa. Na pior das hipóteses, alguém teria que resolver este problema manualmente à noite, nas horas mais inoportunas. Se apenas 1 ou 2 máquinas em funcionamento estivessem realizando uma tarefa importante, tal interrupção seria completamente inaceitável.
Portanto, em vez de reinicializações manuais, eles começaram a usar o monitoramento em nível de processo para reiniciar automaticamente o aplicativo no caso de um encerramento anormal. Se o programa falhar, o processo de monitoramento captura o código de saída e reinicializa o servidor. Com o advento de sistemas como o Kubernetes, esse tipo de resposta às falhas do sistema foi simplesmente integrada à infraestrutura.
O Kubernetes usa um loop de eventos de observação de diferença e ação para garantir que os recursos permaneçam íntegros enquanto viajam dos contêineres para os próprios nós.
Isso significa que você não precisa mais executar manualmente o monitoramento de processos. Se um recurso falhar na verificação de integridade, o Kubernetes simplesmente fornecerá um substituto automaticamente. No entanto, o Kubernetes faz muito mais do que apenas monitorar falhas em seu aplicativo. Ele pode criar mais cópias do aplicativo para execução em diversas máquinas, atualizar o aplicativo ou executar diversas versões do seu aplicativo simultaneamente.
Portanto, há muitos motivos pelos quais o Kubernetes pode encerrar um contêiner perfeitamente íntegro. Por exemplo, se você atualizar sua implantação, o Kubernetes interromperá lentamente os pods antigos enquanto inicia novos. Se você encerrar um nó, o Kubernetes interromperá a execução de todos os pods nesse nó. Finalmente, se um nó ficar sem recursos, o Kubernetes encerrará todos os pods para liberar esses recursos.
Portanto, é fundamental que seu aplicativo seja encerrado com impacto mínimo para o usuário final e tempo de recuperação mínimo. Isso significa que antes de desligar, ele deve salvar todos os dados que precisam ser salvos, fechar todas as conexões de rede, concluir o trabalho restante e gerenciar outras tarefas urgentes.
Na prática, isso significa que seu aplicativo deve ser capaz de lidar com a mensagem SIGTERM, o sinal de encerramento do processo que é o sinal padrão para o utilitário kill em sistemas operacionais Unix. Ao receber esta mensagem, o aplicativo deverá ser encerrado.
Depois que o Kubernetes decide encerrar um pod, vários eventos ocorrem. Vejamos cada etapa que o Kubernetes executa ao encerrar um contêiner ou pod.
Digamos que queremos encerrar um dos pods. Neste ponto, ele irá parar de receber novo tráfego – os contêineres em execução no pod não serão afetados, mas todo o novo tráfego será bloqueado.
Vejamos o gancho preStop, que é um comando especial ou solicitação HTTP enviado a contêineres em um pod. Se a sua aplicação não desligar corretamente ao receber o SIGTERM, você poderá usar o preStop para desligar corretamente.
A maioria dos programas sairá normalmente quando receber um sinal SIGTERM, mas se você estiver usando código de terceiros ou algum sistema que você não controla totalmente, o gancho preStop é uma ótima maneira de forçar um desligamento normal sem alterar o aplicativo.
Após executar esse gancho, o Kubernetes enviará um sinal SIGTERM aos contêineres do pod, informando que em breve serão desconectados. Ao receber este sinal, seu código prosseguirá para o processo de desligamento. Esse processo pode incluir interromper qualquer conexão de longa duração, como uma conexão de banco de dados ou fluxo WebSocket, salvar o estado atual e assim por diante.
Mesmo se você usar um gancho preStop, é muito importante verificar o que exatamente acontece com seu aplicativo quando você envia um sinal SIGTERM e como ele se comporta, para que eventos ou alterações na operação do sistema causadas por um desligamento do pod não ocorram como uma surpresa para você.
Neste ponto, o Kubernetes aguardará um período de tempo especificado, chamado terminaçãoGracePeriodSecond, ou o período para encerrar normalmente quando receber um sinal SIGTERM, antes de tomar outras medidas.
Por padrão, esse período é de 30 segundos. É importante notar que ele funciona em paralelo com o gancho preStop e o sinal SIGTERM. O Kubernetes não esperará que o gancho preStop e o SIGTERM terminem – se o seu aplicativo for encerrado antes do término do TerminationGracePeriod, o Kubernetes passará imediatamente para a próxima etapa. Portanto, verifique se o valor desse período em segundos não é menor que o tempo necessário para desligar corretamente o pod e, caso ultrapasse 30s, aumente o período para o valor desejado em YAML. No exemplo dado, são 60 anos.
E, finalmente, a última etapa é se os contêineres ainda estiverem em execução após o términoGracePeriod, eles enviarão um sinal SIGKILL e serão excluídos à força. Neste ponto, o Kubernetes também limpará todos os outros objetos do pod.
O Kubernetes encerra pods por vários motivos, portanto, certifique-se de que seu aplicativo termine normalmente para garantir um serviço estável.
Alguns anúncios 🙂
Obrigado por ficar com a gente. Gostou dos nossos artigos? Quer ver mais conteúdos interessantes? Apoie-nos fazendo um pedido ou recomendando a amigos,
Dell R730xd 2x mais barato no data center Equinix Tier IV em Amsterdã? Só aqui
Fonte: habr.com