web-dev-qa-db-fra.com

Impossible de tuer le processus avec PID 1 dans le conteneur Docker

J'ai le Dockerfile suivant pour créer un conteneur avec un récurseur powerdns:

FROM debian:stretch-slim
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update && \
    apt-get install --no-install-recommends -y \
    pdns-recursor && \
    rm -rf /var/lib/apt/lists/* && \
    apt-get clean
COPY ./configuration/recursor.conf /etc/powerdns/recursor.conf
RUN chown -R :pdns /etc/powerdns/ && \
    chmod 0750 /etc/powerdns/ && \
    chmod 0640 /etc/powerdns/recursor.conf
EXPOSE 8699
ENTRYPOINT ["/usr/sbin/pdns_recursor", "--daemon=no"]

Ma recursor.conf ressemble à ça:

config-dir=/etc/powerdns
forward-zones=resolver1.opendns.com=208.67.222.222
hint-file=/usr/share/dns/root.hints
local-address=0.0.0.0
local-port=8699
quiet=yes
security-poll-suffix=
setgid=pdns
setuid=pdns

IPv6 est désactivé sur l'hyperviseur.

Le problème est que docker n'est pas en mesure d'arrêter correctement le conteneur avec docker stop recursor. Après un certain temps, OOMKiller termine le programme avec les informations suivantes:

Exited (137) 2 seconds ago

J'ai cherché sur le web et les signaux 128 + 9 = 137 signifie que je n'ai pas assez de RAM, ce qui n'est tout simplement pas le cas. Lorsque j'exécute docker exec -it recursor /bin/bash et essayez de tuer le PID 1 (kill -9 -- 1) dans le conteneur, je ne reçois aucune réaction - le service continue simplement de fonctionner comme si de rien n'était.

J'ai également essayé de démarrer le récurseur en mode démon - même résultat.

Quelqu'un a-t-il une idée de la raison?

9
manifestor

Le processus avec PID 1 est le processus d'initialisation. Cela reste vrai dans un espace de noms pid ou un conteneur: ce pid 1 ne peut pas être tué avec SIGKILL car il n'a pas de gestionnaire de signal KILL défini, contrairement à any autre processus de l'espace utilisateur.

Si vous voulez vraiment le tuer, vous devez le tuer depuis l'hôte . En cours d'exécution sur l'hôte (avec suffisamment de privilèges, probablement root):

kill -KILL $(docker inspect --format '{{.State.Pid}}' containername)

Cela fera tomber le conteneur entier, car retirer son PID 1 signifie arrêter le conteneur. Veuillez noter que j'ai répondu au titre de la question, mais pas au problème sous-jacent: quelle est la cause du MOO.

MISE À JOUR: probablement plus simple à utiliser docker kill , qui est par défaut le signal KILL. Ce serait:

docker kill containername

UPDATE2: convaincre que le PID 1 ne peut pas être tué avec SIGKILL (aka -9), même dans un conteneur (l'exemple nécessite un espace de noms utilisateur activé sinon utilisez simplement unshare --mount-proc --fork --pid en tant que root).

premier terminal:

$ unshare --map-root-user --mount-proc --fork --pid
# echo $$
1
# pstree -p
bash(1)---pstree(88)
# kill -9 1
#

aucun effet

Sur un deuxième terminal:

$ pstree -p $(pidof unshare)
unshare(2023)───bash(2024)
$ kill -9 2024

premier terminal:

# Killed
$ 
15
A.B