Veröffentlicht am

Exit Code 143: SIGTERM und Graceful Shutdown

Teilen:
Authors

Exit Code 143: SIGTERM, nicht ein Absturz

TL;DR

143 ist 128 plus 15. Der Prozess hat SIGTERM bekommen. Kubernetes schickt das Signal, wenn ein Pod gelöscht wird, ein Rollout das Replica ersetzt oder eine Liveness-Probe den Neustart einleitet. Einmalig beim Deploy ist 143 in Ordnung. Im CrashLoopBackOff alle paar Minuten ist es das nicht.

kubectl describe pod POD

Last State: Exit Code: 143, Reason Error oder Completed. 137 mit OOMKilled ist ein anderes Signal, siehe Exit Code 137.

Wann 143 korrekt ist

Deployment rollt aus, das alte Replica bekommt SIGTERM, wartet bis zu terminationGracePeriodSeconds (Default 30s), dann SIGKILL. In den Logs des alten Pods steht 143, der neue Pod läuft. Das ist der Stopp, den Sie bestellt haben. Dieselbe Zahl sehen Sie nach kubectl delete pod, nach einem Scale-down und nach einem Node-Drain, sobald das Kubelet den Pod beendet.

Kein Fix nötig, solange der neue Pod bereit wird und der alte innerhalb der Grace-Period verschwindet. Hängt der alte minutenlang auf Terminating, liegt es an Finalizern oder einem toten Node: Pod Terminating.

Wann 143 den Loop erzeugt

Die Liveness-Probe schlägt fehl. Das Kubelet schickt SIGTERM, der Prozess beendet sich mit 143, der Restart startet, die Probe schlägt wieder fehl. Von außen sieht das aus wie ein Absturz. describe zeigt in den Events Killing mit dem Hinweis auf die fehlgeschlagene Liveness-Probe. Der Previous-Log ist oft leer oder zeigt nur den Shutdown-Hook, nicht die eigentliche Störung.

Dann die Probe anfassen, nicht den Exit-Handler. startupProbe für den langsamen Start. Liveness nur auf „Prozess tot“, nicht auf eine Datenbank, die gerade langsam ist. periodSeconds mal failureThreshold ist die Zeit, die eine Störung dauern darf, bevor der Kill kommt.

Ein zweites Muster: der Prozess behandelt SIGTERM als Fehler und beendet sich mit einem nicht-null-Code, obwohl er das Signal korrekt bekommen hat. Manche Wrapper machen daraus sichtbar 143. Der Container ist dann beim nächsten Start wieder da, bis das nächste Signal kommt. Quelle des Signals finden, nicht den Code „wegkonfigurieren“.

Grace-Period und preStop

Braucht der Prozess länger als 30 Sekunden, um Verbindungen zu Ende zu schreiben, kommt nach der Grace SIGKILL und oft 137 hinterher. Zwei Stellschrauben:

spec:
  terminationGracePeriodSeconds: 60
  containers:
    - name: app
      lifecycle:
        preStop:
          exec:
            command: ["sh", "-c", "sleep 5"]

preStop läuft vor SIGTERM und zählt in die Grace-Period. Das kurze Sleep gibt dem Endpoint-Controller Zeit, den Pod aus dem Service zu nehmen, bevor der Prozess aufhört zu antworten. Es ist kein Ersatz für einen Handler, der SIGTERM wirklich fängt. Java, nginx und die meisten Application-Server können das. Ein Shell-Skript, das das Signal ignoriert, läuft in den SIGKILL.

Die Period muss größer sein als preStop plus die Zeit, die der Prozess zum Beenden braucht. Sonst killt Kubernetes mitten im Handler.

Quellen

📖 Verwandte Artikel

Weitere interessante Beiträge zu ähnlichen Themen