【问题标题】:How to use docker ENTRYPOINT to exec java and then exec touch once java process completesjava进程完成后如何使用docker ENTRYPOINT执行java然后执行touch
【发布时间】:2021-06-17 22:44:39
【问题描述】:

我正在尝试运行一个带有 2 个容器的 pod。主容器执行一个运行 cron 作业的 docker java 映像,另一个 sidecar(logstash) 容器读取日志并将其发送到 Kibana 服务器。当 cron 作业完成后,主容器完成,但边车容器继续运行,因为它没有正常关闭。我尝试了https://github.com/karlkfi/kubexit 和 preStop 容器生命周期挂钩,但没有奏效。 现在,我想尝试使用 dockerfile 停止 sidecar 容器。 Docker ENTRYPOINT exec java image jar,一旦 java 进程完成,我想在主容器内创建/触摸一个文件,我的另一个 sidecar 容器会查找该文件。

这是我当前的 dockerfile

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

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

【问题讨论】:

    标签: java docker kubernetes dockerfile kubernetes-pod


    【解决方案1】:

    您可以通过进程 PID 等待进程完成。 bash 解释器有一个名为 wait 的内置命令,如果使用子 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 
    

    【讨论】:

      【解决方案2】:

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

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

      一旦检测到,sidecar 容器确实退出 0;

      这有点hacky,但应该可以完成工作。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-05-12
        • 2018-08-25
        • 2021-07-23
        • 2022-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多