TL;DR
As três probes respondem perguntas diferentes: a startup pergunta se a aplicação terminou de subir, a liveness se o processo ainda funciona (se não, o container é reiniciado) e a readiness se o pod pode receber tráfego (se não, ele sai do Service, sem reinício). Os padrões são 10 s de intervalo, 1 s de timeout e 3 falhas. Testamos uma aplicação que leva 40 s para subir com liveness a cada 5 s: sem startupProbe, ela é morta aos 15 s e entra em loop de reinícios; com uma startupProbe de até 120 s, ela sobe sem nenhum reinício.
As três probes
| Probe | Pergunta | Quando falha | Serve para |
|---|---|---|---|
| startupProbe | A aplicação terminou de subir? | Enquanto falha, as outras probes não rodam. Se passar do limite, o container é reiniciado. | Aplicação que demora a subir: JVM, migração, cache carregado na partida. |
| livenessProbe | O processo ainda funciona? | Falhou failureThreshold vezes seguidas: o kubelet reinicia o container. | Travamento que só reiniciar resolve: deadlock, loop, conexão presa. |
| readinessProbe | Pode receber tráfego agora? | Falhou: o pod sai dos endpoints do Service, sem reinício. | Pod ocupado, aquecendo ou sem uma dependência que ele não consegue compensar. |
Os valores padrão valem para as três: periodSeconds 10, timeoutSeconds 1, failureThreshold 3, successThreshold 1 e initialDelaySeconds 0 (referência da API do Kubernetes, objeto Probe). A documentação recomenda a startupProbe para proteger containers lentos na subida.
O teste: uma aplicação que leva 40 s para subir
Dois pods iguais: o processo espera 40 s e só então sobe um servidor HTTP que responde em /saude. Os dois têm liveness a cada 5 s com 3 falhas. Só o segundo tem startupProbe, com até 24 tentativas de 5 s (120 s).
# lenta-sem-startup
livenessProbe: { httpGet: { path: /saude, port: 8080 }, periodSeconds: 5, failureThreshold: 3 }
# lenta-com-startup
startupProbe: { httpGet: { path: /saude, port: 8080 }, periodSeconds: 5, failureThreshold: 24 }
livenessProbe: { httpGet: { path: /saude, port: 8080 }, periodSeconds: 5, failureThreshold: 3 } kubectl -n loja get pods lenta-sem-startup lenta-com-startup NAME READY STATUS RESTARTS AGE
lenta-sem-startup 1/1 Running 1 (36s ago) 82s
lenta-com-startup 1/1 Running 0 81s O primeiro aparece como Running e 1/1, mas já foi reiniciado uma vez e vai continuar: a liveness falha três vezes antes dos 40 s, o kubelet o mata, e a subida recomeça do zero. Os eventos contam a história:
kubectl -n loja describe pod lenta-sem-startup | sed -n '/Events:/,$p' Normal Started 37s (x2 over 82s) kubelet Container started
Warning Unhealthy 22s (x6 over 77s) kubelet Liveness probe failed: Get "http://10.42.0.14:8080/saude":
dial tcp 10.42.0.14:8080: connect: connection refused
Normal Killing 22s (x2 over 67s) kubelet Container app failed liveness probe, will be restarted No segundo, as falhas são da startupProbe, e nenhuma delas reinicia nada: são a espera normal da subida.
kubectl -n loja describe pod lenta-com-startup | sed -n '/Events:/,$p' Normal Started 82s kubelet Container started
Warning Unhealthy 42s (x8 over 77s) kubelet Startup probe failed: Get "http://10.42.1.11:8080/saude":
dial tcp 10.42.1.11:8080: connect: connection refused Oito falhas de startup em 40 s, depois nada: a aplicação subiu, a startup passou e a liveness assumiu.
Configuração recomendada
containers:
- name: checkout
ports:
- { name: http, containerPort: 8080 }
startupProbe:
httpGet: { path: /saude, port: http }
periodSeconds: 5
failureThreshold: 24 # até 120 s para subir
livenessProbe:
httpGet: { path: /saude, port: http }
periodSeconds: 10
timeoutSeconds: 3
failureThreshold: 3
readinessProbe:
httpGet: { path: /pronto, port: http }
periodSeconds: 5
timeoutSeconds: 2
failureThreshold: 2 - Startup: teto folgado, medido pela pior subida que você já viu.
- Liveness: só o que reiniciar resolve. Endpoint leve, sem banco e sem API externa.
- Readiness: mais sensível que a liveness; tirar o pod do tráfego por alguns segundos custa pouco.
Os erros de cada probe
Liveness mal configurada aparece como reinícios em sequência e, depois, CrashLoopBackOff; readiness mal configurada aparece como pod Running, 0/1, sem tráfego. Cada um tem página própria, com o diagnóstico passo a passo: Liveness probe failed e Readiness probe failed.
Perguntas frequentes
Quais são os valores padrão das probes?
periodSeconds 10, timeoutSeconds 1, failureThreshold 3, successThreshold 1 e initialDelaySeconds 0, pela referência da API do Kubernetes (objeto Probe). Com eles, uma liveness que para de responder reinicia o container em cerca de 30 s.
Uso initialDelaySeconds ou startupProbe?
startupProbe. O initialDelaySeconds espera um tempo fixo e pronto: se a subida demorar mais num dia de carga, a liveness mata o container do mesmo jeito. A startupProbe espera até a aplicação responder, com um teto (periodSeconds × failureThreshold).
A liveness pode checar o banco de dados?
Não deveria. Se o banco cai, todas as réplicas falham a liveness juntas e são reiniciadas, o que não traz o banco de volta e ainda aumenta a carga quando ele volta. Dependência externa, se for checada, vai na readiness.
Posso usar o mesmo endpoint para as três?
Pode, se ele for leve e responder só se o processo está vivo. O que muda entre elas é a configuração: a startup com teto generoso, a liveness mais tolerante que a readiness.