Configurar sondas de Liveness y Readiness

KubernetesBeginner
Practicar Ahora

Introducción

Los registros (logs), eventos, la ejecución de comandos y el reenvío de puertos (port-forwarding) te ayudan a inspeccionar una aplicación. Las sondas (probes) permiten que Kubernetes inspeccione la aplicación de forma continua. Una sonda de readiness (disponibilidad) responde a la pregunta: "¿Debería este Pod recibir tráfico?". Una sonda de liveness (actividad) responde a: "¿Debería reiniciarse este contenedor?".

En este laboratorio, configurarás la disponibilidad y la actividad por separado. Primero, crearás una aplicación que solo se marca como "Ready" después de crear un endpoint /ready. Luego, crearás otra aplicación con una sonda de liveness, eliminarás su archivo de salud mediante kubectl exec y observarás cómo Kubernetes reinicia el contenedor.

Preparar un namespace para practicar con sondas

En este paso, prepararás un namespace limpio para practicar con las sondas.

Comienza en /home/labex/project. Mantendrás los manifiestos de las sondas en este directorio.

mkdir -p /home/labex/project
cd /home/labex/project

Verifica que el servidor de la API de Kubernetes sea accesible. Si la máquina virtual acaba de iniciarse y el nodo aún no está listo, espera unos segundos y vuelve a ejecutar el comando.

kubectl get nodes --request-timeout=5s

La salida esperada incluye:

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

Espera hasta que el Pod de red del clúster esté listo. Las sondas y los Services dependen de una red de Pods saludable.

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

Salida esperada:

pod/calico-node-... condition met

Crea un namespace llamado ckad-prep-probes y establécelo como el namespace actual:

kubectl create namespace ckad-prep-probes
kubectl config set-context --current --namespace=ckad-prep-probes

Confirma el namespace actual:

kubectl config view --minify --output 'jsonpath={..namespace}'; echo

Salida esperada:

ckad-prep-probes

Configurar una sonda de Readiness

En este paso, configurarás una sonda de readiness y observarás que el Service solo utiliza Pods que están listos.

El contenedor inicia un servidor HTTP inmediatamente, pero crea /www/ready unos segundos después. La sonda de readiness verifica GET /ready en el puerto 8080. Hasta que esa ruta exista, el Pod puede estar en estado "Running" pero no "Ready", y el Service no debería enviarle tráfico.

Crea readiness-web.yaml:

cat > readiness-web.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: readiness-web
spec:
  replicas: 2
  selector:
    matchLabels:
      app: readiness-web
  template:
    metadata:
      labels:
        app: readiness-web
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: web
        image: busybox:1.36
        command:
        - /bin/sh
        - -c
        - |
          mkdir -p /www
          echo readiness-ok > /www/index.html
          (sleep 12; echo ready > /www/ready) &
          httpd -f -p 8080 -h /www
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 1
          periodSeconds: 2
          failureThreshold: 1
---
apiVersion: v1
kind: Service
metadata:
  name: readiness-web
spec:
  selector:
    app: readiness-web
  ports:
  - port: 80
    targetPort: 8080
EOF

Aplica el manifiesto y observa los Pods poco después de la creación:

kubectl apply -f readiness-web.yaml
sleep 3
kubectl get pods -l app=readiness-web

La salida esperada puede mostrar Pods que están en ejecución (Running) pero aún no listos (Ready):

NAME                             READY   STATUS    RESTARTS   AGE
readiness-web-...                0/1     Running   0          ...

Espera a que el Deployment esté disponible:

kubectl rollout status deployment/readiness-web --timeout=120s

Salida esperada:

deployment "readiness-web" successfully rolled out

Inspecciona los endpoints del Service a través de EndpointSlice. Después de que la sonda de readiness pase, el Service debería tener dos endpoints listos.

kubectl get endpointslice -l kubernetes.io/service-name=readiness-web

La salida esperada incluye:

NAME                ADDRESSTYPE   PORTS   ENDPOINTS
readiness-web-...   IPv4          8080    ... + 1 more...

Crea un Pod cliente y prueba el Service:

kubectl run probe-client --image=busybox:1.36 --restart=Never --command -- sleep 3600
kubectl wait --for=condition=Ready pod/probe-client --timeout=120s
kubectl exec probe-client -- wget -qO- http://readiness-web

Salida esperada:

readiness-ok

Configurar una sonda de Liveness

En este paso, configurarás una sonda de liveness que verifica un archivo de salud.

Una sonda de liveness decide si Kubernetes debe reiniciar un contenedor. Este ejemplo utiliza una sonda de tipo exec que ejecuta test -f /tmp/healthy dentro del contenedor. El contenedor crea ese archivo al iniciarse, por lo que comienza en un estado saludable.

Crea liveness-web.yaml:

cat > liveness-web.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: liveness-web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: liveness-web
  template:
    metadata:
      labels:
        app: liveness-web
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: web
        image: busybox:1.36
        command:
        - /bin/sh
        - -c
        - |
          touch /tmp/healthy
          mkdir -p /www
          echo liveness-ok > /www/index.html
          httpd -f -p 8080 -h /www
        ports:
        - containerPort: 8080
        livenessProbe:
          exec:
            command:
            - test
            - -f
            - /tmp/healthy
          initialDelaySeconds: 3
          periodSeconds: 3
          failureThreshold: 1
EOF

Aplica el manifiesto y espera al Deployment:

kubectl apply -f liveness-web.yaml
kubectl rollout status deployment/liveness-web --timeout=120s

La salida esperada incluye:

deployment.apps/liveness-web created
deployment "liveness-web" successfully rolled out

Almacena el nombre del Pod y confirma que el archivo de salud existe:

LIVE_POD="$(kubectl get pods -l app=liveness-web -o jsonpath='{.items[0].metadata.name}')"
echo "$LIVE_POD"
kubectl exec "$LIVE_POD" -- test -f /tmp/healthy
echo "health file exists"

La salida esperada incluye el nombre del Pod y:

health file exists

Describe el Pod y busca la configuración de la sonda de liveness:

kubectl describe pod "$LIVE_POD" | grep -A3 'Liveness:'

La salida esperada incluye:

Liveness:  exec [test -f /tmp/healthy] delay=3s timeout=1s period=3s

Provocar un reinicio por Liveness

En este paso, eliminarás el archivo de salud y observarás cómo la sonda de liveness reinicia el contenedor.

El objeto Pod puede permanecer igual mientras el contenedor en su interior se reinicia. Por eso observarás el contador de reinicios del contenedor en lugar de esperar un nuevo nombre de Pod.

Almacena el nombre del Pod actual:

LIVE_POD="$(kubectl get pods -l app=liveness-web -o jsonpath='{.items[0].metadata.name}')"
echo "$LIVE_POD"

Elimina el archivo de salud desde dentro del contenedor:

kubectl exec "$LIVE_POD" -- rm /tmp/healthy

Observa el contador de reinicios hasta que sea mayor que cero. La sonda de liveness se ejecuta cada tres segundos, por lo que esto puede tomar un momento.

for i in $(seq 1 20); do
  RESTARTS="$(kubectl get pod "$LIVE_POD" -o jsonpath='{.status.containerStatuses[0].restartCount}')"
  echo "restart-count=$RESTARTS"
  if [ "$RESTARTS" != "0" ]; then
    break
  fi
  sleep 3
done

La salida esperada eventualmente incluye:

restart-count=1

Después de que el contenedor se reinicia, el comando de inicio crea /tmp/healthy nuevamente. Confirma que el archivo ha vuelto:

kubectl exec "$LIVE_POD" -- test -f /tmp/healthy
echo "health file recreated"

Salida esperada:

health file recreated

Lee los eventos del Pod y busca el fallo de la sonda de liveness:

kubectl describe pod "$LIVE_POD" | sed -n '/Events:/,$p'

La salida esperada incluye:

Warning  Unhealthy  ...  Liveness probe failed
Normal   Killing    ...  Container web failed liveness probe

Resumen

Has configurado ambas sondas principales de la aplicación. La sonda de readiness controló cuándo los Pods se unían a los endpoints del Service, mientras que la sonda de liveness reinició un contenedor después de que su archivo de salud fuera eliminado. También inspeccionaste EndpointSlices, descripciones de Pods, contadores de reinicios y eventos para conectar la configuración de las sondas con el comportamiento visible de Kubernetes.