首页 > 解决方案 > 如何使用 bash/sh shell 从容器内部终止容器进程(PID 1)

问题描述

我有一个场景,我有一个使用crond. 如果该特定脚本失败,我需要退出容器。似乎SIGKILL不适用于 PID 1。

如何使用 bash/sh shell 从容器内部终止容器进程(PID 1)?

最小的例子 -

Dockerfile -

FROM alpine:3.5

ENV LOGS_DIR="/rest/logs/" CRON_LOG_FILE="${LOGS_DIR}/cron.log"

RUN apk add --update python py-pip zip bash && \
    pip install awscli && \
    mkdir -p ${LOGS_DIR} && \
    touch ${CRON_LOG_FILE}

COPY ./lr-s3.sh ./lr-entry.sh ./install_crontab.txt ./files_to_rotate.txt ./

RUN chmod +x /lr-s3.sh /lr-entry.sh && \
    crontab install_crontab.txt

ENTRYPOINT ["/lr-entry.sh"]

入口点 -

#!/bin/bash

LOGS_DIR="${LOGS_DIR:-/rest/logs}"
CRON_LOG_FILE="${LOGS_DIR}/cron.log"

mkdir -p ${LOGS_DIR}
touch ${CRON_LOG_FILE}

ln -sf /proc/1/fd/1 ${CRON_LOG_FILE}

echo "Cron [Starting]"
exec crond -c /var/spool/cron/crontabs -f -L ${CRON_LOG_FILE} "$@"

通过 Cron 运行的脚本 -

aws s3 cp ${LOGS_DIR}/${FL_NAME} s3://${BKTNAME}/${FL_NAME}

if [ "$?" -ne "0" ]; then
    echo "S3 Backup Failed"
    pkill crond
    exit 1
fi

pkill crond在脚本中不起作用,它有 PID 1。

如果容器重新启动或不存在,我们将知道容器或脚本存在问题。

标签: bashdocker

解决方案


如何使用 bash/sh shell 从容器内部终止容器进程(PID 1)?

PID 1 受到保护,所以你不能杀死它,但你可以为它设置一个信号处理程序:

 # somewhere in entrypoint
 trap "exit" SIGINT SIGTERM

之后,exit如果您kill -s SIGINT 1从容器内的另一个进程发送一个,则该进程将。


推荐阅读