2015-01-15 5 views
6

Ich möchte Knoten in einem Andock-Container ausführen können, und dann docker stop <container> ausführen können. Dies sollte den Container auf statt Timing-out stoppen und eine SIGKILL tun. Leider scheint mir etwas zu fehlen, und die Informationen, die ich gefunden habe, scheinen anderen Bits zu widersprechen.Docker-Stopp funktioniert nicht für Node-Prozess

Hier ist ein Test Dockerfile:

FROM ubuntu:14.04 
RUN apt-get update && apt-get install -y curl 
RUN curl -sSL http://nodejs.org/dist/v0.11.14/node-v0.11.14-linux-x64.tar.gz | tar -xzf - 
ADD test.js/
ENTRYPOINT ["/node-v0.11.14-linux-x64/bin/node", "/test.js"] 

Hier ist die test.js im Dockerfile genannt:

var http = require('http'); 

var server = http.createServer(function (req, res) { 
    console.log('exiting'); 
    process.exit(0); 
}).listen(3333, function (err) { 
    console.log('pid is ' + process.pid) 
}); 

Ich baue es etwa so:

$ docker build -t test . 

ich es laufen so:

$ docker run --name test -p 3333:3333 -d test 

Dann laufe ich:

$ docker stop test 

Woraufhin die SIGTERM anscheinend nicht funktioniert, so dass es nach 10 Sekunden Timeout und dann sterben.

Ich habe festgestellt, dass, wenn ich den Knoten Aufgabe durch sh -c dann fange ich es mit ^C von einem interaktiven (-it) Behälter töten kann, aber ich kann immer noch nicht docker stop zu arbeiten. Dies widerspricht den Kommentaren, die ich gelesen habe, dass sh das Signal nicht weitergibt, aber vielleicht mit anderen Kommentaren übereinstimmt, die ich gelesen habe, dass PID 1 nicht SIGTERM bekommt (seit es über sh gestartet wurde, wird es PID sein 2).

Das Endziel ist es, docker start -a ... in einem Upstart-Auftrag ausführen und in der Lage sein, den Dienst zu stoppen, und es tatsächlich den Container verlässt.

Antwort

1

Ok, ich habe selbst einen Workaround gefunden, den ich als Antwort wagen werde, in der Hoffnung, dass es anderen hilft. Es beantwortet nicht vollständig, warum die Signale vorher nicht funktionierten, aber es gibt mir das Verhalten, das ich will.

Mit baseimage-docker scheint das Problem zu lösen. Hier ist, was ich getan habe, um dies mit dem oben genannten minimalen Testbeispiel zu erreichen:

Halten Sie test.js so wie es ist.

Ändern Dockerfile zu wie folgt aussehen:

FROM phusion/baseimage:0.9.15 

# disable SSH 
RUN rm -rf /etc/service/sshd /etc/my_init.d/00_regen_ssh_host_keys.sh 

# install curl and node as before 
RUN apt-get update && apt-get install -y curl 
RUN curl -sSL http://nodejs.org/dist/v0.11.14/node-v0.11.14-linux-x64.tar.gz | tar -xzf - 

# the baseimage init process 
CMD ["/sbin/my_init"] 

# create a directory for the runit script and add it 
RUN mkdir /etc/service/app 
ADD run.sh /etc/service/app/run 

# install the application 
ADD test.js/

baseimage-Docker enthält einen Init-Prozess (/sbin/my_init), die andere Prozesse behandelt beginnen und den Umgang mit zombie processes. Es verwendet runit für die Serviceüberwachung. Die Dockerfile setzt daher den Prozess my_init als den Befehl, der beim Booten ausgeführt werden soll, und fügt ein Skript /etc/service für runit hinzu, um es abzurufen.

Das run.sh Skript ist einfach:

#!/bin/sh 
exec /node-v0.11.14-linux-x64/bin/node /test.js 

Vergessen Sie nicht zu chmod +x run.sh!

Standardmäßig wird runit den Dienst bei einem Ausfall automatisch neu starten.

Nach diesen Schritten (und Build, Ausführen und Stoppen wie zuvor) reagiert der Container ordnungsgemäß auf Anforderungen für das Herunterfahren, zeitnah.

Verwandte Themen