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.


