Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I CTRL-C a sleep infinity in docker when it runs as PID 1

Case: we have a docker container that runs a bash script that needs to "block" forever (because it exposes a volume for another container, but there are other reasons why we sometimes want this).

I thought this could work then:

exec sleep infinity;

ps aux then gives "sleep" as PID 1. Great, I thought, then it will receive signals we send it from outside the container. For example:

docker kill -s INT container_name

But that doesn't work, container keeps running (also for SIGTERM). A normal kill does work, but I don't understand why there's a difference (which annoys me greatly):

docker kill container_name

Why can't I kill "sleep" with SIGINT/SIGTERM when it runs as PID 1 in my container? I believe I can kill other things (like bash scripts) with SIGINT/SIGTERM when they run as PID 1 in a container.

like image 329
Otto Avatar asked Oct 18 '22 09:10

Otto


1 Answers

Would this be of any use? https://www.fpcomplete.com/blog/2016/10/docker-demons-pid1-orphans-zombies-signals

Basically the problem is process number 1. Linux/unix kernels are reluctant to signal that process the regular way, as it is supposed to be init. If init process dies, the system issues a panic immediately and reboots. If your process 1 does not have a handler to a signal, the signal just gets dropped. Sleep does not have handlers for any signals but you can build one to bash script.

Basically what you need to do is use exec form in your dockerfile, and split your sleep infinity into a loop as bash traps do not get triggered while shell is executing a command. This sends a signal to the running process 1 and catches it:

Dockerfile:

FROM ubuntu
ADD foo.sh /tmp
RUN ["/tmp/foo.sh"]

foo.sh:

#!/bin/bash

trap "echo signal;exit 0" SIGINT 

while :
do
    sleep 1
done

This will react to docker kill --signal=SIGINT.

like image 184
Hannu Avatar answered Oct 20 '22 11:10

Hannu