Durante o ciclo de vida de uma aplicação, há várias razões pelas quais os pods podem ser encerrados, seja porque o usuário digitou o comando "kubectl delete" ou por uma atualização de versão, entre outras. Nesses casos, o Kubernetes permite que os contêineres em execução no pod sejam encerrados de forma "graciosa" com algumas configurações. Mas primeiro, vamos entender como a operação de exclusão/encerramento acontece.
Assim que o usuário digita o comando "kubectl delete", ele é passado para o servidor API e, a partir daí, os endpoints são removidos do objeto de endpoints. Os endpoints são importantes para fornecer qualquer serviço. Eles são removidos diretamente do plano de controle, o que aciona eventos para o kube-proxy, o controlador de ingress, o DNS e outros componentes.
Com isso, todos esses componentes atualizam suas referências e deixam de servir tráfego para o endereço IP do POD. Essa operação pode ser rápida. No entanto, é possível que os componentes estejam ocupados realizando outras operações, o que pode causar algum atraso na atualização das referências.
Ao mesmo tempo, o status do pod no etcd é alterado para "Terminating" (encerrando) e o Kubelet é notificado, iniciando os processos de desmontagem de quaisquer volumes do contêiner (CSI), desanexação do contêiner da rede e liberação do endereço IP (CNI) e destruição do contêiner para o Container Runtime (CRI).
O processo de exclusão de pods pode ser problemático, pois enquanto na criação do pod o Kubernetes aguarda a atualização do Kubelet para informar os detalhes do IP e atualizar os endpoints, quando o pod é excluído, o endpoint é removido e o Kubelet é atualizado simultaneamente. Isso pode ser um problema, pois às vezes os componentes levam tempo para atualizar os endpoints, e se o pod for excluído antes que essas atualizações sejam propagadas, enfrentaremos um tempo de inatividade. O tráfego ainda será encaminhado para o pod removido, pois não houve atualização do ingress ou de quaisquer serviços de alto nível.
Para evitar cenários de tempo de inatividade do aplicativo, é importante garantir que o pod não seja excluído antes que o endpoint seja atualizado. Uma maneira de fazer isso é usar o terminationGracePeriodSeconds.
Quando um comando delete é dado ao pod, ele recebe o sinal SIGTERM e por padrão, o Kubernetes espera 30 segundos antes de forçar a interrupção do processo. Durante esse tempo, o container pode processar tráfego, fechar conexões de back-end e encerrar o processo. No entanto, se a aplicação precisar de mais tempo para encerrar, o valor de terminationGracePeriodSeconds pode ser incluído ou alterado na definição do pod. Além disso, é possível incluir um script para aguardar um tempo e, em seguida, encerrar. O Kubernetes expõe um 'preStop hook' no pod antes do acionamento do SIGTERM, que pode ser utilizado para essa finalidade.
Para evitar possíveis tempos de inatividade do aplicativo, é importante garantir que o pod não seja excluído antes que o endpoint, seja atualizado. Uma solução para isso é utilizar a opção terminationGracePeriodSeconds na definição do pod.
Ao enviar o sinal SIGTERM para um pod, o Kubernetes aguarda 30 segundos antes de interromper o processo. Durante esse período, o container pode processar o tráfego, encerrar conexões de back-end e finalizar o processo. Caso a aplicação necessite de mais tempo para encerrar, é possível incluir ou alterar o valor de terminationGracePeriodSeconds.
Além disso, l utilizar um "preStop hook" no pod, que permite incluir um script para aguardar um tempo antes de encerrar. Dessa forma, é possível garantir que o pod não seja excluído antes que o endpoint, seja atualizado.
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- name: nginx
image: nginx
ports:
- name: nginx
containerPort: 80
lifecycle:
preStop:
exec:
command: ["sleep", "10"]
terminationGracePeriodSeconds: 45
Essa configuração pode ajudar a aplicação a processar todas as requisições e fechar as conexões, evitando o encerramento forçado.
Além disso, é possível alterar o tempo padrão de espera, que é de 30 segundos, ao excluir manualmente um recurso usando o comando kubectl delete, adicionando o parâmetro --grace-period=SEGUNDOS.
# kubectl delete deployment test --grace-period=60
Em conclusão, a remoção dos endpoints e a atualização das referências podem levar algum tempo, o que pode resultar em tempos de inatividade se o pod for excluído antes que essas atualizações sejam propagadas.
Ao personalizar o tempo de término e adotar estratégias adequadas, é possível minimizar os tempos de inatividade e garantir um processo de exclusão mais suave e controlado dos pods no Kubernetes. Isso contribui para a disponibilidade contínua dos serviços e a satisfação dos usuários.