I can be wrong but it seems to me this is the node
+docker PID1
issue.
Please check very useful Avoid running nodejs as PID 1 under the docker image article that explains what is happening in the details.
It turns out that nodejs cannot receive signals and process them
properly (if it is running with PID 1). Signal refers to SIGTERM,
SIGINT and other kernel signals.
If you run nodejs as PID 1, the following code will not work at all:
process.on('SIGTERM', function onSigterm() {
// do the cleaning job, but it wouldn't
process.exit(0);
});
As a result, you will get a zombie process that will be forced to
terminate by sigkill signal, which means that your “clean up” code
will not be called at all.
Best practices recommend to avoid to run nodejs as PID 1, so running inside docker can cause unexpected behaviors.
Talking about docker
, it is possible to use --init
flag that
will wrap your process with a small init system that will take
advantage of all kernel signals to its subprocesses and ensure that
all orphaned processes are harvested.
For kubernetes you dont have such an option, however there is a trick you can try: you can use dumb-init as entrypoint in your image.
# Runs "/usr/bin/dumb-init -- /my/script --with --args"
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
# or if you use --rewrite or other cli flags
# ENTRYPOINT ["dumb-init", "--rewrite", "2:3", "--"]
CMD ["/my/script", "--with", "--args"]
dumb-init is a simple process supervisor and init system designed to
run as PID 1 inside minimal container environments (such as Docker).
It is deployed as a small, statically-linked binary written in C.
Lightweight containers have popularized the idea of running a single
process or service without normal init systems like systemd or
sysvinit. However, omitting an init system often leads to incorrect
handling of processes and signals, and can result in problems such as
containers which can't be gracefully stopped, or leaking containers
which should have been destroyed.
dumb-init enables you to simply prefix your command with dumb-init. It
acts as PID 1 and immediately spawns your command as a child process,
taking care to properly handle and forward signals as they are
received.