moby: master process running in container doesn't get SIGTERM on stop with lxc

running:

Linux ubuntu 3.11.0-12-generic #19-Ubuntu SMP Wed Oct 9 16:20:46 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux

(ubuntu latest)

root@ubuntu:/home/sam# lxc-version 
lxc version: 1.0.0.alpha1

run: docker run -i -t ubuntu /bin/bash

attempt to stop the container:

container fails to stop properly and reverts to kill

2013/10/29 16:24:47 error killing container 9d01aa5543a8df028df004c440240e72080b17eada1bf0cd9c5a092ae61139a4 (lxc-kill: failed to get the init pid
, exit status 255)
2013/10/29 16:24:57 Container 9d01aa5543a8df028df004c440240e72080b17eada1bf0cd9c5a092ae61139a4 failed to exit within 10 seconds of lxc SIGKILL - trying direct SIGKILL

About this issue

  • Original URL
  • State: closed
  • Created 11 years ago
  • Comments: 33 (19 by maintainers)

Commits related to this issue

Most upvoted comments

I ran into the same issue with circusd, and I think it has to do with CMD exec form As stated on main docs, CMD can be called in three forms:

CMD ["executable","param1","param2"] (exec form, this is the preferred form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
CMD command param1 param2 (shell form)

if CMD in your Dockerfile is called in shell form, your top process (PID 1) will be /bin/sh/ -c my_cmd And I have seen that my_cmd does not receive the docker stop signal

So I think that’s the solution, change from shell form to exec form. It works for me.

Example: circusd is startef from a script /bin/start.sh, which does some stuff and then execs circusd. https://registry.hub.docker.com/u/apsl/circusbase/dockerfile/

When using default CMD (shell mode):

CMD /bin/start.sh

If you do a ps axu inside container:

root@2ba4910736e4:/# ps axu
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.2  0.0   4444   652 ?        Ss   16:26   0:00 /bin/sh -c /bin/start.sh
root         8  3.5  0.4 195604 17312 ?        Sl   16:26   0:00 /usr/bin/python /usr/local/bin/cir

You can see /bin/start.sh is executed with /bin/sh -c, which has PID 1. Also you can see circusd has PID 8, altrough it was called with exec on start.sh. https://github.com/APSL/docker-circusbase/blob/master/start.sh

But when executed with exec mode:

docker run -d  apsl/circusbase /bin/start.sh

Or changing CMD in your Dockerfile:

CMD ["/bin/start.sh"]

Then ps axu inside container shows cirusd process with PID 1. And now docker stops works well and receives QUIT/TERM signals.

root@b3fdd509c577:/# ps axu
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.9  0.4 195604 17312 ?        Ssl  16:25   0:00 /usr/bin/python /usr/local/bin/cir

Hope this helps.

Hi all,

I’d like to bring this issue up for attention, with a test case (/cc @jpetazzo). As this issue says, it seems like the process running inside the container isn’t getting the SIGTERM sent by Docker.

I have the following Python script:

#!/usr/bin/env python

from __future__ import print_function

import signal
import subprocess
import sys
import time

def handler(signum, frame):
        print('GOT SIGNAL {}'.format(signum))
        sys.exit(1)

signal.signal(signal.SIGTERM, handler)
print('SLEEPING')
time.sleep(1000)
print('DONE')

The expected behavior is SLEEPING, followed by a 1000s pause (a long long time), followed by either one of DONE or GOT SIGNAL 15 if SIGTERM was received.

Running the script outside of any container, we get the correct behavior:

$ python test.py
SLEEPING
^Z
$ kill -TERM %1
$ GOT SIGNAL 15
$

I created an image, available on the public registry as mpetazzoni/sigterm-test, that includes this script and simply executes it when started:

FROM base
RUN apt-get -y install python
ADD test.py /
CMD ["python", "test.py"]

Starting the container, but killing the process manually as a host process, we get the correct behavior:

$ docker run -i -t mpetazzoni/sigterm-test
SLEEPING

> In another term:
> $ sudo kill -TERM <pid of `python test.py`>

GOT SIGNAL 15
$

But using docker stop or docker kill -TERM both result in the incorrect behavior of the process being killed, but without having the chance to catch the SIGTERM signal:

$ docker run -i -t --name=test mpetazzoni/sigterm-test
SLEEPING

> In another term:
> $ docker stop test

$

The Docker daemon log simply shows:

2014/07/17 22:55:30 POST /v1.13/containers/test/stop?t=10
[8912818a] +job stop(test)
[8912818a] -job attach(68976db5bca5f0ea7634b95004625a962a931cc5237e1b28372d2fc3f2170530) = OK (0)
[8912818a] +job release_interface(68976db5bca5f0ea7634b95004625a962a931cc5237e1b28372d2fc3f2170530)
[8912818a] -job release_interface(68976db5bca5f0ea7634b95004625a962a931cc5237e1b28372d2fc3f2170530) = OK (0)
[8912818a] -job stop(test) = OK (0)
2014/07/17 22:55:30 GET /v1.13/containers/68976db5bca5f0ea7634b95004625a962a931cc5237e1b28372d2fc3f2170530/json
[8912818a] +job container_inspect(68976db5bca5f0ea7634b95004625a962a931cc5237e1b28372d2fc3f2170530)
[8912818a] -job container_inspect(68976db5bca5f0ea7634b95004625a962a931cc5237e1b28372d2fc3f2170530) = OK (0)

For reference:

$ docker info
Containers: 25
Images: 298
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Dirs: 348
Execution Driver: lxc-1.0.3
Kernel Version: 3.13.0-29-generic
Username: mpetazzoni
Registry: [https://index.docker.io/v1/]
WARNING: No swap limit support

$ docker version
Client version: 1.1.0
Client API version: 1.13
Go version (client): go1.2.1
Git commit (client): 79812e3
Server version: 1.1.0
Server API version: 1.13
Go version (server): go1.2.1
Git commit (server): 79812000