如何使用docker ENTRYPOINT执行java,然后在java进程完成后执行触摸



我正在尝试运行一个包含2个容器的pod。主容器执行一个dockerjava映像,该映像运行cron作业,另一个sidecar(logstash(容器读取日志并将其发送到Kibana服务器。一旦cron作业完成,主容器就会完成,但sidecar容器会继续运行,因为它不会正常关闭。我试过了https://github.com/karlkfi/kubexit和preStop容器生命周期挂钩,但不起作用。现在,我想尝试停止sidecar容器使用dockerfile。Docker ENTRYPOINT执行java镜像jar,一旦java进程完成,我就想在主容器中创建/触摸一个文件,我的另一个sidecar容器会在其中查找被触摸的文件。

这是我目前的档案

FROM mcr.microsoft.com/java/jre:11-zulu-alpine
ARG projectVersion
WORKDIR /opt/example/apps/sync
COPY /target/sync-app-${projectVersion}.jar app.jar
ENTRYPOINT exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar app.jar

我想在java进程执行完成后添加以下内容

echo "Going to kill sync-app container..."
trap 'touch /opt/example/apps/sync/container/done' EXIT

我真的很想知道一旦ENTRYPOINT执行完成,是否可以执行上述命令?(可以将这些命令添加到脚本中,并将该脚本传递给ENTRYPOINT(。但是,我不确定添加这些命令需要什么才能正确执行它。

我拥有的logstash容器的代码将查找文件(由第一个容器创建(

- args:
- |
dockerd-entrypoint.sh &
while ! test -f /opt/example/apps/sync/container/done; do
echo "Waiting for sync-app to finish..."
sleep 5
done
echo "sync-app finished, exiting"
exit 0
command:
- /bin/sh
- -c

如果需要更多信息,请告诉我。感谢您提前提供的帮助!

您可以通过进程PID等待进程完成。bash解释器有一个名为wait的内置命令,如果使用子PID作为参数进行调用,它将等待子PID完成。

因此,您可以创建以下entrypoint.sh并将其添加到java容器中。

入口点.sh

#!/bin/bash
echo "Cleaning the file signal and running the entrypoint"
rm -rf /opt/example/apps/sync/container/done
exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar app.jar &
child_pid=$!
echo "Process started, waiting for the exit"
wait $child_pid
echo "Entrypoint exited, signaling the file"
touch /opt/example/apps/sync/container/done 

您可以在主容器和sidecar容器中安装emptyDir。

主容器在一个给定的位置写入一个文件,这个emptydir在它退出之前作为入口点中的最后一条语句被挂载,sidecar有一个循环来检查是否存在这个相同的文件。

一旦检测到,sidecar容器就会退出0;

这有点古怪,但应该做得好。

顺便说一句,Docker和Kubernetes在如何处理日志方面有一些默认设置。它们从每个容器的STDOUT中收集它们,并将输出存储在运行容器的节点上的一个文件中(/var/lib/docker/containers(。Logstah可以设置为在每个节点上运行的守护进程集,容器日志位置安装为hostPath并跟踪上面提到的文件。这样,您的容器就不需要任何sodecar,并且在我看来简化了整个设置,让logstash负责执行日志记录所需的任何操作。

最新更新