Como usar ganchos do Kubernetes para rastrear os ciclos de vida do contêiner

0
19


As associações de ciclo de vida do contêiner do Kubernetes permitem que você responda às compilações e terminações do contêiner. Você pode manipular eventos executando um comando dentro do contêiner ou fazendo uma solicitação HTTP para um ponto de extremidade que você expõe.

Os ganchos são comumente usados ​​para registrar eventos de contêiner, implementar scripts de limpeza e executar tarefas assíncronas depois que um novo pod se junta ao cluster. Neste artigo, mostraremos como anexar controladores de associação aos seus pods e obter mais controle sobre os ciclos de vida do contêiner.

Ambos os ganchos disponíveis

As versões atuais do Kubernetes são compatíveis com dois ganchos de ciclo de vida do contêiner:

  • PostStart – Os manipuladores neste gancho são chamados imediatamente após a criação de um novo contêiner.
  • PreStop – Esse gancho é invocado imediatamente antes do Kubernetes encerrar um contêiner.

Eles podem ser manipulados por dois mecanismos diferentes:

  • Exec – Execute um comando específico dentro do container.
  • HTTP – Faz uma solicitação HTTP para uma URL dentro do contêiner.

Nenhum dos ganchos fornece argumentos para seus controladores. Cada contêiner suporta apenas um manipulador por gancho; não é possível chamar vários terminais ou combinar um comando exec com uma solicitação HTTP.

Definição de manipuladores de gancho

Você define os manipuladores de gancho para Pods usando seus containers.lifecycle campo manifesto. Dentro deste campo, defina o postStart S preStop propriedades para implementar um ou ambos os ganchos disponíveis.

Aqui está um pod simples que registra uma mensagem quando é iniciado:

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-hooks
spec:
  containers:
    - name: pod-hook-container
      image: nginx:latest
      lifecycle:
        postStart:
          exec:
            command: ["/bin/sh", "-c", "echo STARTED > /startup_message"]

Aplique o pod ao cluster usando o Kubectl:

$ kubectl apply -f pod.yaml

Agora obtenha um shell para o contêiner em execução dentro do Pod:

$ kubectl exec --stdin --tty pod/pod-with-hooks -- sh

Leia o conteúdo do /startup_message processos:

$ cat /startup_message
STARTED

Isso mostra que o link foi chamado com sucesso. Um gancho executivo é considerado bem-sucedido se seu comando sair com um código de status igual a zero.

Manipuladores HTTP

Você pode configurar um manipulador HTTP substituindo o exec campo com httpGet. Somente HTTP GET pedidos são suportados (não httpPost campo).

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-hooks
spec:
  containers:
    - name: pod-hook-container
      image: nginx:latest
      lifecycle:
        postStart:
          httpGet:
            path: /startup
            port: 80

Neste exemplo, o Kubernetes faz um GET solicitação de /startup na porta 80 do contêiner. httpGet campo também aceita scheme S host propriedades para configurar ainda mais a solicitação.

Aqui está um Pod onde /shutdown é chamado por HTTPS antes que ocorra o encerramento do contêiner:

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-hooks
spec:
  containers:
    - name: pod-hook-container
      image: nginx:latest
      lifecycle:
        preStop:
          httpGet:
            path: /startup
            scheme: HTTPS

Os manipuladores de ligação HTTP são considerados bem-sucedidos se o código de resposta HTTP estiver no intervalo 200-299.

Depurando seus drivers

Os controladores de gancho são gerenciados independentemente dos pods aos quais estão conectados. Seus logs não são coletados ou armazenados junto com os logs normais do Pod, então você não verá comandos executivos como echo Started ao correr kubectl logs pod/pod-with-hooks.

Você pode depurar ganchos visualizando o histórico de eventos de um pod. As invocações com falha serão relatadas como FailedPostStartHook S FailedPreStophook eventos. A mensagem de erro inclui uma descrição do que causou o erro.

Tente adicionar este pod ao seu cluster:

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-hooks
spec:
  containers:
    - name: pod-hook-container
      image: nginx:latest
      lifecycle:
        postStart:
          exec:
            command: ["missing-command"]

O link PostStart quebrado fará com que o Pod comece a falhar. Usar kubectl describe para acessar seu histórico de eventos:

$ kubectl describe pod/pod-with-hooks
...
Events:
  Type     Reason               Age                From               Message
  ----     ------               ----               ----               -------
  Normal   Scheduled            30s                default-scheduler  Successfully assigned pod-with-hooks...
  Normal   Created              10s (x2 over 11s)  kubelet            Created container pod-hook-container
  Normal   Started              10s (x2 over 11s)  kubelet            Started container pod-hook-container
  Warning  FailedPostStartHook  10s (x2 over 11s)  kubelet            Exec lifecycle hook ([missing-command]) for Container "pod-hook-container" in Pod "pod-with-hooks" failed - error: command 'missing-command' exited with 126: , message: "OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: exec: "missing-command": executable file not found in $PATH: unknownrn"
  Normal   Killing              10s (x2 over 11s)  kubelet            FailedPostStartHook
  Warning  BackOff              5s (x2 over 6s)    kubelet            Back-off restarting failed container

a FailedPostStartHook evento revela que o controlador falhou porque missing-command não é um executável válido dentro do contêiner. Isso fez com que o contêiner fosse fechado e reiniciado em um loop de retorno. Ele ficará preso assim perpetuamente como missing-command nunca será executável.

Pegadinhas para ficar de olho

Hook Summons tem alguns recursos que podem surpreendê-lo. Manter isso em mente pode ajudar a evitar comportamentos estranhos e falhas inesperadas.

  • Hooks podem ser chamados mais de uma vez. Kubernetes garante sua PostStart S PreStop manipuladores serão chamados “pelo menos” uma vez para cada contêiner. Em algumas situações, um link pode ser invocado várias vezes. Seus controladores devem ser idempotentes para que possam suportar essa possibilidade.
  • Ganchos com falha matam seu contêiner. Como o exemplo de depuração acima ilustra, ganchos com falha matam imediatamente seu contêiner. Você deve garantir que seus comandos e endpoints HTTP estejam livres de erros para evitar problemas inesperados de inicialização do pod. Os manipuladores de gancho devem ser leves e livres de dependências. Não tente acessar um recurso que pode não estar disponível imediatamente após o início do contêiner.
  • PostStart os ganchos competem com o recipiente ENTRYPOINT. PostStart é acionado aproximadamente ao mesmo tempo em que o contêiner é criado. No entanto, o Kubernetes não espera o gancho: ele será chamado de forma assíncrona junto com o contêiner. ENTRYPOINT, que pode ser concluído antes que o manipulador de gancho seja chamado. Isso significa que o script de ponto de entrada do seu contêiner Vai comece a executar mesmo que seu controlador relate um erro e acabe matando o contêiner.
  • PreStop os ganchos bloquearão a extremidade do recipiente. O Kubernetes garante que seus contêineres não serão encerrados até que seu PreStop ganchos foram concluídos, até um tempo máximo definido pelo período de carência de encerramento do pod. O contêiner será eliminado independentemente de o gancho ainda estar em execução quando o período de carência terminar.
  • PreStop ganchos não são necessários finalizado vagens Este pode ser particularmente impactante dependendo do seu caso de uso. A implementação atual de PreStop só dispara quando há um pod finalizado devido à exclusão, esgotamento de recursos, falha de investigação ou um evento semelhante. O gancho não será chamado para contêineres que param naturalmente porque seu processo termina sua tarefa e sai com um código de erro zero.

Os ganchos afetam diretamente a progressão do ciclo de vida dos seus pods. Os pods não podem ser marcados como Running até PostStart gancho completo; da mesma forma, um Pod ficará preso Terminating Até que PreStop acabou

conclusão

Os eventos do ciclo de vida do Kubernetes são uma maneira de notificar os contêineres sobre sua própria criação e exclusão iminente. Ao fornecer comandos de API ou endpoints em seu contêiner, você pode rastrear estágios críticos do ciclo de vida e relatá-los a outros componentes de sua infraestrutura.

Os eventos de ciclo de vida são fáceis de configurar, mas também apresentam algumas armadilhas comuns. Você pode usar mecanismos adjacentes, como testes de inicialização e configuração, se precisar de uma chamada mais confiável. Essa é a melhor opção para scripts essenciais ao configurar um novo ambiente de contêiner.