Configurar Probes de Liveness e Readiness

KubernetesBeginner
Pratique Agora

Introdução

Logs, eventos, exec e port-forwarding ajudam você a inspecionar uma aplicação. As probes permitem que o Kubernetes inspecione a aplicação continuamente. Uma probe de readiness (prontidão) responde à pergunta: "Este Pod deve receber tráfego?". Uma probe de liveness (vivacidade) responde à pergunta: "Este container deve ser reiniciado?".

Neste laboratório, você configurará o readiness e o liveness separadamente. Primeiro, você criará uma aplicação que só se torna "Ready" após criar um endpoint /ready. Em seguida, você criará outra aplicação com uma probe de liveness, removerá seu arquivo de saúde com kubectl exec e observará o Kubernetes reiniciar o container.

Preparar um Namespace para Prática de Probes

Nesta etapa, você preparará um namespace limpo para praticar as probes.

Comece em /home/labex/project. Você manterá os manifestos das probes neste diretório.

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

Verifique se o servidor da API do Kubernetes está acessível. Se a VM acabou de iniciar e o nó ainda não está pronto, aguarde alguns segundos e execute o comando novamente.

kubectl get nodes --request-timeout=5s

A saída esperada inclui:

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

Aguarde até que o Pod de rede do cluster esteja pronto (Ready). Probes e Services dependem de uma rede de Pods saudável.

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

Saída esperada:

pod/calico-node-... condition met

Crie um namespace chamado ckad-prep-probes e defina-o como o namespace atual:

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

Confirme o namespace atual:

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

Saída esperada:

ckad-prep-probes

Configurar uma Probe de Readiness

Nesta etapa, você configurará uma probe de readiness e observará que o Service utiliza apenas Pods que estejam prontos.

O container inicia um servidor HTTP imediatamente, mas cria o arquivo /www/ready alguns segundos depois. A probe de readiness verifica GET /ready na porta 8080. Até que esse caminho exista, o Pod pode estar "Running", mas não "Ready", e o Service não deve enviar tráfego para ele.

Crie o arquivo 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

Aplique o manifesto e observe os Pods logo após a criação:

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

A saída esperada pode mostrar Pods que estão "Running", mas ainda não "Ready":

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

Aguarde até que o Deployment esteja disponível:

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

Saída esperada:

deployment "readiness-web" successfully rolled out

Inspecione os endpoints do Service através do EndpointSlice. Após a probe de readiness passar, o Service deve ter dois endpoints prontos.

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

A saída esperada inclui:

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

Crie um Pod cliente e teste o 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

Saída esperada:

readiness-ok

Configurar uma Probe de Liveness

Nesta etapa, você configurará uma probe de liveness que verifica um arquivo de saúde.

Uma probe de liveness decide se o Kubernetes deve reiniciar um container. Este exemplo utiliza uma probe do tipo exec que executa test -f /tmp/healthy dentro do container. O container cria esse arquivo quando inicia, portanto, ele começa saudável.

Crie o arquivo 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

Aplique o manifesto e aguarde o Deployment:

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

A saída esperada inclui:

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

Armazene o nome do Pod e confirme se o arquivo de saúde 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"

A saída esperada inclui o nome do Pod e:

health file exists

Descreva o Pod e procure pela configuração da probe de liveness:

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

A saída esperada inclui:

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

Disparar uma Reinicialização de Liveness

Nesta etapa, você removerá o arquivo de saúde e observará a probe de liveness reiniciar o container.

O objeto Pod pode permanecer o mesmo enquanto o container dentro dele é reiniciado. É por isso que você observará a contagem de reinicializações do container em vez de esperar por um novo nome de Pod.

Armazene o nome do Pod atual:

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

Remova o arquivo de saúde de dentro do container:

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

Observe a contagem de reinicializações até que ela se torne maior que zero. A probe de liveness é executada a cada três segundos, então isso pode levar um breve 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

A saída esperada eventualmente inclui:

restart-count=1

Após o container reiniciar, o comando de inicialização cria o /tmp/healthy novamente. Confirme se o arquivo voltou:

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

Saída esperada:

health file recreated

Leia os eventos do Pod e procure pela falha de liveness:

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

A saída esperada inclui:

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

Resumo

Você configurou as duas principais probes de aplicação. A probe de readiness controlou quando os Pods entravam nos endpoints do Service, enquanto a probe de liveness reiniciou um container após a remoção do seu arquivo de saúde. Você também inspecionou EndpointSlices, descrições de Pods, contagens de reinicialização e eventos para conectar a configuração das probes ao comportamento visível do Kubernetes.