无法在Docker入口点脚本中捕获信号

IPlato

我有一个docker entrypoint脚本,该脚本应该捕获发送到容器中进程的信号。主要应用程序是tomcat-嵌入到docker-entrypoint.sh中的Java进程,该进程被传递给dumb-init。容器中的进程映射如下所示:

root@mycontainer:/usr/local/tomcat/webapps/datarouter-example# ps -ef
    UID        PID  PPID  C STIME TTY          TIME CMD
    root         1     0  0 05:21 ?        00:00:00 dumb-init -- /docker-entrypoint.sh
    root         6     1  0 05:21 ?        00:00:00 bash /docker-entrypoint.sh
    root        14     6  1 05:21 ?        00:08:57 /jdk-13.0.1/bin/java -Djava.util.logging.config.file=....

Dockerfile:

FROM maven:3.6.3-jdk-13 as maven_builder

WORKDIR /app
COPY . /app
RUN ["mvn","clean","install","-T","2C","-DskipTests=true"]


FROM tomcat:9.0.31-jdk13-openjdk-buster

ARG dumbInitVersion='1.2.2'

# install dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
        sudo \
        wget \
        dpkg-dev \
    && rm -rf /var/lib/apt/lists/*

ARG webappDir
WORKDIR $CATALINA_HOME/webapps/$webappDir/
ENV CATALINA_OUT $CATALINA_HOME/logs/catalina.out
ENV CATALINA_PID $CATALINA_HOME/catalina.pid
COPY docker-entrypoint.sh /
COPY --from=maven_builder /app/target/datarouter-example $CATALINA_HOME/webapps/$webappDir/

RUN wget https://github.com/Yelp/dumb-init/releases/download/v"$dumbInitVersion"/dumb-init_"$dumbInitVersion"_amd64.deb; \
    dpkg -i dumb-init_*.deb; \
    rm dumb-init_*.deb

EXPOSE 8080
ENTRYPOINT ["dumb-init", "--", "/docker-entrypoint.sh"]

这是简化的docker-entrypoint.sh:

        #!/usr/bin/env bash

        start(){
                echo "$(date +'%F %T,%3N') Starting tomcat..." >> "$CATALINA_OUT"
                catalina.sh start && tail -f "$CATALINA_OUT"
        }

        stop(){
                echo "$(date +'%F %T,%3N') starting stop" >> "$CATALINA_OUT"

   # some fancy shutdown logic, e.g. calling our application's shutdown endpoint to cleanup (does not stop tomcat)

                echo "$(date +'%F %T,%3N') Stopping tomcat..." >> "$CATALINA_OUT"
                catalina.sh stop  >> "$CATALINA_OUT"

                wait $(cat "${CATALINA_PID}")

                tailId=$(pgrep tail)
                if [[ -n "$tailId" ]]; then
                        kill "$tailId"
                fi
                exit
        }

        trap stop SIGINT SIGQUIT SIGHUP SIGTERM

    start

现在的问题。每次从容器内部发出docker stop命令或a时kill 1,都会向Java应用程序发送信号,并在stop功能到达第一行之前首先开始关闭我确定是因为Terminated日志:

Terminated
++ stop
+++ date '+%F %T,%3N'
++ echo '2020-03-13 14:34:54,480 starting stop'

并在catalina.out中:

2020-03-12 04:08:27.079 INFO [Thread-13] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-apr-8080"]
2020-03-12 04:08:27,079 starting stop
2020-03-12 04:08:27.085 INFO [Thread-13] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-apr-8081"]
2020-03-12 04:08:27.090 INFO [Thread-13] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["https-openssl-apr-8443"]
2020-03-12 04:08:27.096 INFO [Thread-13] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
......

我真的很困惑为什么会发生这种情况以及如何解决此问题以便catalina.sh stop执行。

IPlato

在尝试了一些更改之后,以下脚本将捕获SIGTERM并执行预期的步骤。

对原始docker-entrypoint Dockerfile的更改:

  • 从dumb-init切换为tini,只是尝试一下。
  • 从Catalina开始切换为Catalina运行,自己将其置于后台并等待
  • 删除了尾巴过程

我认为尾巴是造成最初描述的行为的原因。新入口点脚本的最大缺点是,我在运行时丢失了容器日志docker logs ...由于我们绑定了安装日志目录,因此我们仍然能够获取日志,但是将进行进一步调查以获取日志docker logs ...

如果有人有建议或其他解决方案,我仍在寻找更好的解决方案。

#!/usr/bin/env bash

trap stop SIGTERM SIGINT SIGQUIT SIGHUP ERR

start(){
   local catalinaPid

   touch "${CATALINA_PID}"
   catalina.sh run >> ${CATALINA_OUT} 2>&1 &
   catalinaPid=$!
   echo "$catalinaPid" > "${CATALINA_PID}"

   wait "$catalinaPid"
}

stop(){
   echo "$(date +'%F %T,%3N') starting stop" >> "$CATALINA_OUT"

   # some fancy shutdown logic, e.g. calling our application's shutdown endpoint to cleanup (does not stop tomcat)

   echo "$(date +'%F %T,%3N') Stopping tomcat..." >> "$CATALINA_OUT"
   catalina.sh stop 20 >> "$CATALINA_OUT"

   wait $(cat "${CATALINA_PID}")

   exit
}

start

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

docker入口点脚本无法运行

来自分类Dev

了解Docker入口点脚本

来自分类Dev

了解Docker入口点脚本

来自分类Dev

即使在Flask和Flask Migrate中也无法在Docker中运行入口点脚本

来自分类Dev

Docker Couchbase:无法使用入口点脚本中的curl连接到端口8091

来自分类Dev

为什么Docker入口点脚本无法启动?

来自分类Dev

Docker运行中的Dockerfile入口点脚本参数

来自分类Dev

执行不替换Docker入口点脚本中的bash shell

来自分类Dev

入口点脚本中的Docker exec命令失败

来自分类Dev

找不到Docker映像入口点脚本

来自分类Dev

找不到Docker映像入口点脚本

来自分类Dev

docker-compose与Dokerfile入口点脚本冲突

来自分类Dev

获取setuputils包中的入口点脚本文件位置?

来自分类Dev

无法从“docker stop”捕获 TERM 信号

来自分类Dev

Docker-compose应该运行一次我的入口点脚本然后退出两次

来自分类Dev

Grafana Docker入口点脚本以“没有这样的文件或目录”停止,但文件在那里

来自分类Dev

python setuptools入口点脚本找不到模块

来自分类Dev

在bash中捕获来自“ docker stop”的信号

来自分类Dev

AWS KCL 在 docker 中捕获关闭信号

来自分类Dev

从节点脚本中运行节点脚本

来自分类Dev

从节点脚本中运行节点脚本

来自分类Dev

在Ubuntu中无法捕获SIGPIPE信号

来自分类Dev

在Ubuntu中无法捕获SIGPIPE信号

来自分类Dev

如何在Shell脚本中捕获退出1信号?

来自分类Dev

我可以在bash脚本中捕获时钟信号吗?

来自分类Dev

^节点脚本参数中的字符

来自分类Dev

在gulp中执行任意节点脚本

来自分类Dev

在 Java 中删除跨站点脚本

来自分类Dev

timer_create()无法在处理程序函数中捕获信号

Related 相关文章

热门标签

归档