无法终止 docker 容器中 PID 1 的进程

无法终止 docker 容器中 PID 1 的进程

我有以下 Dockerfile 用于创建其中包含 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"]

我的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=137意味着我没有足够的 RAM,但事实并非如此。当我执行docker exec -it recursor /bin/bash并尝试终止kill -9 -- 1容器内的 PID 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

UPDATE2:确信 PID 1 不能被杀死SIGKILL(又名-9),甚至在容器中(该示例需要启用用户命名空间,否则仅使用unshare --mount-proc --fork --pidroot 身份)。

第一个终端:

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

没有效果

在第二个终端上:

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

第一个终端:

# Killed
$ 

相关内容