October 8, 2026 路 #22
The process that ignored SIGTERM
Kubernetes deletes the pod and it sits in Terminating until the grace period kills it. Why?
FROM node:22-bookworm-slim
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci --omit=dev && npm cache clean --force
COPY . .
CMD npm start
USER nodeNext puzzle in UTC
One try. The first answer sticks.
How to fix it
CMD npm start is wrapped in sh -c. PID 1 is the shell, which ignores SIGTERM, so the kubelet waits out the grace period and sends SIGKILL.
The shell form of CMD is /bin/sh -c "npm start". In a container, that shell is PID 1. A shell started this way does not forward signals to the child, and PID 1 has extra duties: it is supposed to reap zombies and handle SIGTERM. Kubernetes sends SIGTERM to PID 1, the shell shrugs, and your Node process keeps running until terminationGracePeriodSeconds expires and the kubelet sends SIGKILL. In-flight requests die. Connections reset.
USER after CMD is legal. The user applies at runtime to the command. It does not change the signal problem. The order is still nicer if USER comes first so a reader sees who the process is.
Fix
USER node
CMD ["npm", "start"]
Better, start Node directly so npm is not an extra parent: CMD ["node", "server.js"]. If you need a shell for variable expansion, use exec in an entrypoint script so the app replaces the shell: exec node server.js.