如何使用 docker ENTRYPOINT 执行 java 然后在 java 过程完成后执行触摸
How to use docker ENTRYPOINT to exec java and then exec touch once java process completes
我正在尝试 运行 一个带有 2 个容器的容器。主容器执行 docker java 图像,其中 运行 是 cron 作业,另一个 sidecar(logstash)容器读取日志并将其发送到 Kibana 服务器。当 cron 作业完成后主容器完成,但边车容器保持 运行ning 因为它没有正常关闭。我尝试了 https://github.com/karlkfi/kubexit 和 preStop 容器生命周期挂钩,但没有用。
现在,我想尝试使用 dockerfile 停止 sidecar 容器。 Docker ENTRYPOINT exec java 图像 jar 并且一旦 java 过程完成,我想在主容器中创建/触摸一个文件,我的其他 sidecar 容器寻找那个触摸的文件。
这是我当前的docker文件
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 容器中。
entrypoint.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
您可以在主容器和边车容器中挂载一个 emptyDir。
主容器在给定位置写入一个文件,这个 emptydir 在它退出之前作为入口点的最后一条语句挂载,并且 sidecar 有一个循环检查是否存在这个相同的文件。
一旦检测到,sidecar 容器就会退出 0;
有点老套,但应该可以。
附带说明一下,Docker 和 Kubernetes 在如何处理日志方面有一些默认设置。他们从每个容器的 STDOUT 收集它们,并将输出存储在节点 运行 容器 (/var/lib/docker/containers) 上的文件中。 Logstah 可以在这些节点中的每一个上设置为守护程序集 运行,并将容器日志位置安装为 hostPath 并跟踪上述文件。这样你的容器就不需要任何 sodecar,在我看来简化了整体设置,让 logstash 负责做任何需要日志记录的事情。
我正在尝试 运行 一个带有 2 个容器的容器。主容器执行 docker java 图像,其中 运行 是 cron 作业,另一个 sidecar(logstash)容器读取日志并将其发送到 Kibana 服务器。当 cron 作业完成后主容器完成,但边车容器保持 运行ning 因为它没有正常关闭。我尝试了 https://github.com/karlkfi/kubexit 和 preStop 容器生命周期挂钩,但没有用。 现在,我想尝试使用 dockerfile 停止 sidecar 容器。 Docker ENTRYPOINT exec java 图像 jar 并且一旦 java 过程完成,我想在主容器中创建/触摸一个文件,我的其他 sidecar 容器寻找那个触摸的文件。
这是我当前的docker文件
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 容器中。
entrypoint.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
您可以在主容器和边车容器中挂载一个 emptyDir。
主容器在给定位置写入一个文件,这个 emptydir 在它退出之前作为入口点的最后一条语句挂载,并且 sidecar 有一个循环检查是否存在这个相同的文件。
一旦检测到,sidecar 容器就会退出 0;
有点老套,但应该可以。
附带说明一下,Docker 和 Kubernetes 在如何处理日志方面有一些默认设置。他们从每个容器的 STDOUT 收集它们,并将输出存储在节点 运行 容器 (/var/lib/docker/containers) 上的文件中。 Logstah 可以在这些节点中的每一个上设置为守护程序集 运行,并将容器日志位置安装为 hostPath 并跟踪上述文件。这样你的容器就不需要任何 sodecar,在我看来简化了整体设置,让 logstash 负责做任何需要日志记录的事情。