【问题标题】:How to transparently run a script before docker entrypoint?如何在 docker 入口点之前透明地运行脚本?
【发布时间】:2019-06-19 10:59:20
【问题描述】:

我在 cloudformation 模板中的 docker 容器中自动部署 java 应用程序。我需要为 java 崩溃日志设置一个 env 变量,但我需要保持每个容器的路径唯一。我无法修改 docker 镜像或 dockerfile。

为此,我使用了来自 docker 容器的 $HOSTNAME,它足够独特。问题是我不能像往常一样使用 docker 环境变量,因为它是在容器启动后设置的。解决方法是通过设置 env 变量来更改入口点,然后启动原始入口点。

EntryPoint: 
            - /bin/sh
            - -c
            - export JAVA_OPTS="$JAVA_OPTS -XX:HeapDumpPath=/mnt/crashdumps/java_$HOSTNAME.hprof" 
&& ./entrypoint.sh

(它是 AWS::ECS::TaskDefinition 的 cloudformation YAML 模板,但同样的东西可以在 docker cli 中表达)

在 Java 容器提供程序更改入口点 shell 脚本的位置之前,它一直运行良好。现在 shell 注入 在代码中看起来真的很脏,因为我需要检查文件是否存在并且需要更多维护(即,以防入口点路径或文件名再次更改)。

有没有更好的方法:

  1. 使用不同于修改入口点的方法动态设置具有容器名称的路径;或
  2. 只注入一个“导出”命令并运行原始入口点,无论名称和路径是什么?

【问题讨论】:

    标签: java amazon-web-services docker amazon-cloudformation docker-entrypoint


    【解决方案1】:

    如果您想要为您的 java 崩溃日志动态生成路径,我建议您在 docker 入口点脚本本身中动态生成唯一名称。

    就像这个,我测试过并且工作正常。

    #!/bin/sh
    
    # Create some random file in /tmp
    filename=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo '')
    touch /tmp/$filename
    cat /tmp/$filename
    export filename=$filename
    

    每次我运行此脚本时,都会在您生成多个容器时发生。它将在/tmp 中生成具有随机名称的文件。

    $ ls /tmp/
    DzJXInMvJAgvN  f0rgIMIt115h7  sSgVDXj2zvRTh  x4dBEciezQnix
    

    因此,在这种情况下,入口点将在每次调用期间生成一个唯一名称,因此无需在 docker entrypoint 之前调用任何内容。

    希望这会有所帮助。

    更新

    到目前为止,我了解到您想要覆盖 java 崩溃日志的文件路径,而不编辑 dockerfile 或入口点脚本。 JAVA_OPTS-XX:HeapDumpPath 选项如果我是对的。

    你可以试试这个

    $ docker run -itd --env JAVA_OPTS="$JAVA_OPTS -XX:HeapDumpPath=/mnt/crashdumps/java_$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 13 ; echo '').hprof" alpine sh
    $ docker exec -it 75f062ff8906 env
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    HOSTNAME=75f062ff8906
    TERM=xterm
    JAVA_OPTS= -XX:HeapDumpPath=/mnt/crashdumps/java_MyRZcSKxFtZaF.hprof
    HOME=/root
    

    如您所见,JAVA_OPTS 被适当的文件名覆盖。 希望这会有所帮助,请告诉我。

    【讨论】:

    • 感谢您的回答!问题是我无法修改 dockerfile 或入口点脚本,因为在部署阶段它是不可见的。我只下载图像并运行它。如果有一种聪明的方法可以将此代码添加到现有的入口点 shell 脚本中,那将是可行的。
    • 哦,我明白了。让我检查一下。
    • 但是您仍然可以在您的docker run 命令中添加-XX:HeapDumpPath 选项,对吗?如果是这样,那么您能否将您的docker run 命令提供给我。
    • 无法仅添加“运行”命令,因为正在从 cloudformation TaskDefinition 模板设置集群。我们最终通过确保 docker 容器使用 exec 启动应用程序来解决这个问题,这解决了变量。感谢您的建议,他们帮助我们更好地理解了这个问题!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多