Como solucionar problemas de sonda de disponibilidade e prontidão com meus clusters do Amazon EKS?

7 minuto de leitura
0

Quero solucionar problemas relacionados a sondas de atividade e prontidão no meu cluster do Amazon Elastic Kubernetes Service (Amazon EKS).

Breve descrição

Os kubelets que estão sendo executados nos nós de processamento usam sondas para verificar periodicamente o status dos pods. Atualmente, o Kubernetes oferece suporte a três estados em sondas: sucesso, falha e desconhecido. O kubelet considera o pod bem-sucedido ou íntegro nas seguintes condições:

  • A aplicação em execução dentro do contêiner está pronta.
  • A aplicação aceita tráfego e responde às sondas definidas no manifesto do pod.

O Kubelet considera que um pod de aplicação falhou ou não está íntegro quando a sonda não responde. O Kubelet então marca esse pod como não íntegro e envia SIGTERM ao pod. Uma das seguintes situações ocorre com base na política de ciclo de vida e na restartPolicy definidas na implantação:

  • O pod é encerrado imediatamente.
  • O pod é desligado normalmente depois de parar para aceitar tráfego.

Exemplo:

spec:
 containers:
 - name: "example-container"
  image: "example-image"
  lifecycle:
   preStop:
    exec:
     command: ["sh", "-c", "sleep 10"]

Neste exemplo, se o contêiner de exemplo executado dentro do pod de exemplo deixar de ser íntegro por não responder às sondas, o pod deixará de aceitar tráfego em 10 segundos. Em seguida, o kubelet desligará o pod normalmente. Se o pod não for encerrado mesmo após 30 segundos, o kubelet o removerá à força. O kubelet considera o pod da aplicação desconhecido quando não consegue determinar o status desse pod usando sondas definidas no manifesto de implantação. Nesse caso, o kubelet executa verificações adicionais para determinar o status do pod.

O Kubernetes fornece verificações de sonda em sonda de atividade, sonda de prontidão e sonda de inicialização.

  • O Kubelet usa sondas de atividade para saber o estado da aplicação que está sendo executada dentro do seu pod.
  • O Kubelet usa sondas de prontidão para saber quando sua aplicação está pronta para começar a servir o tráfego de entrada.
  • O Kubelet usa sondas de inicialização para iniciar lentamente as aplicações dentro do pod. Quando uma sonda de inicialização é configurada, as sondas de atividade e prontidão não verificam o pod até que a inicialização seja considerada bem-sucedida.

Se nenhuma dessas sondas estiver definida no manifesto do pod, o kubelet marcará os pods indefinidamente como bem-sucedidos ou íntegros. Você pode configurar uma das seguintes sondas para verificar a integridade do pod:

  • Sonda HTTP
  • Sonda de comando
  • Sonda de soquete TCP
  • Sonda gRPC

Resolução

Erros de falha na verificação de integridade da aplicação devido a tempos limite do cliente

Quando suas sondas de atividade ou prontidão falham, você recebe as seguintes mensagens de erro:

Liveness probe failed: Get "http://podIP:8080/health ": context deadline exceeded (Client.Timeout exceeded while awaiting headers)

Readiness probe failed: Get "http://podIP:8080/health ": context deadline exceeded (Client.Timeout exceeded while awaiting headers)

Para solucionar esses erros, faça o seguinte:

Verifique se você configurou corretamente as sondas de atividade e prontidão dos pods da aplicação.

Se estiver usando a Amazon Virtual Private Cloud (Amazon VPC) CNI versão 1.11.0 ou posterior, certifique-se de que POD_SECURITY_GROUP_ENFORCING_MODE esteja definido como standard em aws-node DaemonSet. Se essa configuração estiver incorreta, execute o seguinte comando:

kubectl set env daemonset aws-node -n kube-system POD_SECURITY_GROUP_ENFORCING_MODE=standard

Certifique-se de definir DISABLE_TCP_EARLY_DEMUX como true para amazon-k8s-cni-init que é o contêiner em initcontainers quando as seguintes condições forem verdadeiras:

  • Você está usando uma versão CNI do Amazon VPC anterior à versão 1.11.0.
  • Seus pods estão configurados com grupos de segurança.
  • ENABLE_POD_ENI está definido como true.
kubectl patch daemonset aws-node -n kube-system \
-p '{"spec": {"template": {"spec": {"initContainers": [{"env":[{"name":"DISABLE_TCP_EARLY_DEMUX","value":"true"}],"name":"aws-vpc-cni-init"}]}}}}'

Erros de falha do Amazon VPC CNI

Seu aws-node DaemonSet pode falhar com os seguintes erros:

Liveness probe failed: OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: read init-p: connection reset by peer: unknown
Warning  Unhealthy  11m (x3 over 12m)    kubelet            Liveness probe failed:
Normal   Killing    11m                  kubelet            Container aws-node failed liveness probe, will be restarted

Readiness probe failed: OCI runtime exec failed: exec failed: container_linux.go:380: starting container process caused: process_linux.go:99: starting setns process caused: fork/exec /proc/self/exe: resource temporarily unavailable: unknown
Warning  Unhealthy  11m (x9 over 13m)    kubelet            Readiness probe failed:

Você pode resolver esses erros aumentando o valor de timeoutSeconds para 60 segundos no aws-node DaemonSet.

Para visualizar os valores atuais dos campos na VPC CNI, execute o seguinte comando:

$kubectl get daemonset aws-node -n kube-system -o yaml

A saída é semelhante à seguinte:

"livenessProbe":
          exec:
            command:
            - /app/grpc-health-probe
            -addr=:50051
            -connect-timeout=5s
            -rpc-timeout=5s
          failureThreshold: 3
          initialDelaySeconds: 60
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 60

Erros de conexão da aplicação

Quando você executar o comando describe em pods de aplicação personalizados, receberá os seguintes erros se esses pods falharem nas verificações das sondas de atividade e prontidão:

2m 25s Warning  Unhealthy  Liveness probe failed: Get "http://podIP:8081/health ": dial tcp 192.168.187.28: 8081: connect: connection refused

2m 25s Warning  Unhealthy   Readiness probe failed: Get "http:// podIP:8081/health": dial tcp 192.168.187.28:8081: connect: connection refused

Warning  Unhealthy  39s (x4 over 2m19s)  kubelet            Liveness probe failed: HTTP probe failed with statuscode: 500

Warning  Unhealthy  29s (x5 over 2m19s)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 500

Para solucionar esse erro, siga estas etapas:

1.    Execute curl manualmente no caminho de verificação de integridade definido no manifesto do pod a partir do nó de processamento.

[ec2-user@ip-10-0-0-11 ~]$ curl -ikv podIP:8081/health

2.    Execute-o no pod da aplicação que falha nas sondas de atividade ou prontidão. Em seguida, execute curl no caminho de verificação de integridade definido no manifesto do pod:

local@bastion-host ~ % kubectl exec <pod-name> -- curl  -ikv "http://localhost:8081/_cluster/health?"

3.    Verifique se há erros nos logs do kubelet do nó de processamento em que o pod está sendo executado:

[ec2-user@ip-10-0-0-11 ~]$ journalctl -u kubelet //optionally 'grep' with pod name

4.    Execute o comando describe pod no pod e verifique o status atual dos contêineres que estão sendo executados no pod. Além disso, verifique os logs do pod:

$ kubectl describe pod <pod name> -n <namespace>

$ kubectl logs <pod name>

5.    Se você ainda não tiver informações sobre o erro, considere aumentar o detalhamento do kubelet subjacente que está sendo executado no nó de processamento:

$ sudo systemctl status kubelet
$ vi /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf 
   [Service]
   Environment='KUBELET_ARGS=--node-ip=192.168.31.211 --pod-infra-container-image=602401143452.dkr.ecr.us-east-2.amazonaws.com/eks/pause:3.5 --v=2'

No arquivo de configuração, altere --v=2 para --v=9 e salve o arquivo.

Reinicie o kubelet para que as alterações entrem em vigor:

$ sudo systemctl daemon-reload && sudo systemctl restart kubelet && sudo systemctl enable kubelet

Execute o comando a seguir para verificar o detalhamento do kubelet:

$ systemctl status kubelet -l

A saída deve ter a seguinte aparência:

CGroup: /system.slice/kubelet.service 
       └─5909 /usr/bin/kubelet --cloud-provider aws --config /etc/kubernetes/kubelet/kubelet-config.json --kubeconfig /var/lib/kubelet/kubeconfig --container-runtime docker --network-plugin cni --node-ip=10.0.0.11 --pod-infra-container-image=602401143452.dkr.ecr.us-east-1.amazonaws.com/eks/pause:3.1-eksbuild.1 --v=9

Reinicie o pod que falha com as verificações de atividade ou prontidão. Em seguida, certifique-se de que esse pod esteja sendo implantado no nó de processamento do Amazon EKS onde as alterações anteriores foram feitas. Você pode verificar os logs do kubelet executando o seguinte comando:

$ journalctl -u kubelet //optionally 'grep' with pod name

6.    Execute a mesma imagem de contêiner no bastion host e verifique se você consegue executar curl no caminho de verificação de integridade definido nas sondas no manifesto. Além disso, verifique os logs do contêiner.

7.    Para sondas HTTP, verifique se o cabeçalho http personalizado está configurado corretamente. O kubelet usa o código golang equivalente ao curl para testar seu pod em HTTP.

Exemplo:

"livenessProbe":
   httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3

8.    Se você estiver usando uma sonda exec, verifique se o pod está configurado corretamente. No exemplo a seguir, o pod passa por 30 segundos e depois falha:

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: registry.k8s.io/busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

AWS OFICIAL
AWS OFICIALAtualizada há um ano