DockerコンテナでPID 1を使用してプロセスを終了することはできません。

DockerコンテナでPID 1を使用してプロセスを終了することはできません。

powerdnsイテレータを含むコンテナを作成するための次のDockerfileがあります。

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"]

私のrecursor.conf外観は次のとおりです。

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が無効になっています。

問題は、dockerがコンテナを正しく停止できないことですdocker stop recursor。しばらくすると、OOMKillerはプログラムを終了し、次のメッセージを提供します。

Exited (137) 2 seconds ago

128信号+ 9=は、RAMが十分ではないことをオンラインで検索しましたが、137そうではありません。コンテナ内でPID 1()を実行しdocker exec -it recursor /bin/bashて終了しようとすると、何も起こりません。サービスは何も起こらなかったかのように実行され続けます。kill -9 -- 1

また、デーモンモードで再帰プログラムを始めてみました。結果は同じでした。

なぜこれが起こるのか知っている人がいますか?

答え1

PID 1のプロセスはinitプロセスです。これはpidネームスペースやコンテナ内でも適用されます。このpid 1は信号ハンドラが定義されていSIGKILLないため終了できません。KILLどのその他のユーザーモードプロセス。

本当に殺したい場合は殺すべきです。ホストから。ホストコンピュータで実行します(十分な権限、おそらくrootを使用)。

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

PID 1 を削除するとコンテナが停止するため、コンテナ全体が終了します。私は質問のタイトルに答えましたが、基本的な質問であるOOMの原因には答えませんでした。

更新:使いやすくすることができます。docker kill、デフォルトはKILLシグナルです。それは次のとおりです。

docker kill containername

アップデート2:PID 1が終了できないことを確認してくださいSIGKILL(別名-9)。でもコンテナで(この例ではユーザーの名前空間を有効にする必要があります。そうしないと、unshare --mount-proc --fork --pidルートのみが使用されます)。

最初の端末:

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

効果なし

2番目のターミナルで:

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

最初の端末:

# Killed
$ 

関連情報