¿Cómo soluciono los problemas en los sondeos de disponibilidad y preparación con mis clústeres de Amazon EKS?

8 minutos de lectura
0

Quiero solucionar problemas relacionados con los sondeos de disponibilidad y preparación en mi clúster de Amazon Elastic Kubernetes Service (Amazon EKS).

Descripción breve

Los kubelets que se ejecutan en los nodos de trabajo utilizan sondeos para comprobar el estado del pod periódicamente. Actualmente, Kubernetes admite tres estados en los sondeos: correcto, error y desconocido. Kubelet considera que el pod es correcto o está en buen estado si se dan las siguientes condiciones:

  • La aplicación que se ejecuta dentro del contenedor está lista.
  • La aplicación acepta el tráfico y responde a los sondeos que se definen en el manifiesto del pod.

Kubelet considera que se ha producido un error en un pod de aplicación o que no está en buen estado cuando el sondeo no responde. A continuación, Kubelet marca este pod como incorrecto y envía SIGTERM al pod. Se produce una de las siguientes situaciones en función de la política de ciclo de vida y la política de reinicio que se definen en la implementación:

  • El pod se cierra inmediatamente.
  • El pod se cierra correctamente una vez que se detiene para aceptar tráfico.

Ejemplo:

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

En este ejemplo, si el contenedor de ejemplo que se ejecuta dentro del pod de ejemplo se queda en estado incorrecto al no responder a los sondeos, el pod deja de aceptar tráfico en 10 segundos. Luego, kubelet cierra el pod de manera sencilla. Si el pod no se cierra incluso después de 30 segundos, kubelet lo elimina por la fuerza. Kubelet considera que el pod de la aplicación es desconocido cuando no puede determinar el estado del pod mediante los sondeos que se definen en el manifiesto de implementación. En este caso, kubelet realiza comprobaciones adicionales para determinar el estado del pod.

Kubernetes proporciona las comprobaciones de sondeo sobre el sondeo de disponibilidad, el sondeo de preparación y el sondeo de inicio.

  • Kubelet usa sondeos de disponibilidad para conocer el estado de la aplicación que se ejecuta dentro del pod.
  • Kubelet utiliza sondeos de disponibilidad para saber cuándo la aplicación está lista para empezar a atender el tráfico entrante.
  • Kubelet usa sondeos de inicio para las aplicaciones de inicio lento dentro del pod. Cuando se configura un sondeo de inicio, los sondeos de disponibilidad y preparación no comprueban el pod hasta que se considere que el inicio se ha realizado correctamente.

Si ninguno de estos sondeos está definido en el manifiesto del pod, kubelet marca los pods indefinidamente como correctos o en buen estado. Puede configurar uno de los siguientes sondeos para comprobar el estado del pod:

  • Sondeo HTTP
  • Sondeo de comando
  • Sondeo de socket TCP
  • Sondeo gRPC

Resolución

Errores de comprobación del estado de la aplicación debido a los tiempos de espera del cliente

Cuando se produce un error en los sondeos de disponibilidad o preparación, aparecen los siguientes mensajes de error:

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 estos errores, haga lo siguiente:

Compruebe si ha configurado correctamente los sondeos de disponibilidad y preparación de los pods de la aplicación.

Si utiliza la versión 1.11.0 o posterior del CNI de Amazon Virtual Private Cloud (Amazon VPC), asegúrese de que POD_SECURITY_GROUP_ENFORCING_MODE esté configurado como estándar en el DaemonSet aws-node. Si esta configuración es incorrecta, ejecute el siguiente comando:

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

Asegúrese de configurar DISABLE_TCP_EARLY_DEMUX en true para amazon-k8s-cni-init, que es el contenedor de initcontainers, cuando se cumplan las siguientes condiciones:

  • Está utilizando una versión del CNI de Amazon VPC anterior a la versión 1.11.0.
  • Sus pods están configurados con grupos de seguridad.
  • ENABLE_POD_ENI se ha establecido en 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"}]}}}}'

Errores del CNI de Amazon VPC

Es posible que el DaemonSet aws-node produzca un error con los siguientes errores:

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:

Para resolver estos errores, aumente el valor de timeoutSeconds a 60 segundos en el DaemonSet aws-node.

Para ver los valores actuales de los campos del CNI de VPC, ejecute el siguiente comando:

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

El resultado es similar al siguiente:

"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

Errores de conexión a la aplicación

Al ejecutar el comando describe en los pods de aplicaciones personalizados, aparecen los siguientes errores si los pods no superan las comprobaciones del sondeo de disponibilidad y preparación:

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 este error, haga lo siguiente:

1.    Aplique curl manualmente en la ruta de la comprobación de estado que está definida en el manifiesto del pod desde el nodo de trabajo.

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

2.    Ejecute en el pod de la aplicación en el que se produzca un error en los sondeos de disponibilidad o preparación. A continuación, aplique curl en la ruta de la comprobación de estado que está definida en el manifiesto del pod:

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

3.    Compruebe si hay errores en los registros de kubelet del nodo de trabajo en el que se ejecuta el pod:

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

4.    Ejecute el comando describe pod en el pod y compruebe el estado actual de los contenedores que se ejecutan en el pod. Asimismo, compruebe los registros del pod:

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

$ kubectl logs <pod name>

5.    Si aún no tiene información sobre el error, considere la posibilidad de aumentar el nivel de detalle del kubelet subyacente que se ejecuta en el nodo de trabajo:

$ 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'

En el archivo de configuración, cambie --v=2 por --v=9 y, a continuación, guarde el archivo.

Reinicie el kubelet para que los cambios surtan efecto:

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

Ejecute el siguiente comando para comprobar el nivel de detalle del kubelet:

$ systemctl status kubelet -l

El resultado debe tener el siguiente aspecto:

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 el pod en el que se produzca un error en las comprobaciones de disponibilidad o preparación. A continuación, asegúrese de que este pod se esté implementando en el nodo de trabajo de Amazon EKS donde se realizaron los cambios anteriores. Para comprobar el estado de los registros de kubelet, ejecute el siguiente comando:

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

6.    Ejecute la misma imagen del contenedor en el host bastión y compruebe si puede aplicar curl en la ruta de la comprobación de estado que está definida en los sondeos del manifiesto. Además, compruebe los registros del contenedor.

7.    Para los sondeos HTTP, compruebe que el encabezado HTTP personalizado esté configurado correctamente. Kubelet usa el código golang, que equivale a curl, para realizar una comprobación de HTTP en el pod.

Ejemplo:

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

8.    Si utiliza un sondeo de ejecución, compruebe que el pod esté configurado correctamente. En el siguiente ejemplo, el pod durante 30 segundos y, a continuación, se produce un error:

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

OFICIAL DE AWS
OFICIAL DE AWSActualizada hace un año