如何在 docker 入口点之前透明地 运行 脚本?
How to transparently run a script before docker entrypoint?
我正在 cloudformation 模板的 docker 容器中自动部署 java 应用程序。我需要为 java 崩溃日志设置一个环境变量,但我需要保持每个容器的路径唯一。我无法修改 docker 图片或 docker 文件。
为此,我使用了来自 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 注入 在代码中看起来真的很脏,因为我需要检查文件是否存在并且需要更多维护(即以防入口点路径或文件名再次更改) .
有没有更好的方法:
- 使用不同于修改入口点的方法动态设置具有容器名称的路径;或
- 只注入一个 "export" 命令和 运行 原始入口点,无论名称和路径是什么?
如果您想为 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 崩溃日志的文件路径,而不编辑 docker 文件或入口点脚本。如果我是对的,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
被适当的文件名覆盖。
希望这有帮助,让我知道。
我正在 cloudformation 模板的 docker 容器中自动部署 java 应用程序。我需要为 java 崩溃日志设置一个环境变量,但我需要保持每个容器的路径唯一。我无法修改 docker 图片或 docker 文件。
为此,我使用了来自 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 注入 在代码中看起来真的很脏,因为我需要检查文件是否存在并且需要更多维护(即以防入口点路径或文件名再次更改) .
有没有更好的方法:
- 使用不同于修改入口点的方法动态设置具有容器名称的路径;或
- 只注入一个 "export" 命令和 运行 原始入口点,无论名称和路径是什么?
如果您想为 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 崩溃日志的文件路径,而不编辑 docker 文件或入口点脚本。如果我是对的,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
被适当的文件名覆盖。
希望这有帮助,让我知道。