[英]DockerFile : RUN Pass arguments
我们需要更改 docker 镜像中 Keystore 的 JKS 密码。
DockerFile 中的以下命令有效
1. RUN [\
2. "/usr/lib/jvm/java-11-openjdk-amd64/bin/keytool",\
3. "-storepasswd",\
4. "-storepass",\
5. "changeit",\
6. "-new",\
7. "NEW_JKS_PASSWORD",\
8. "-cacerts"\
9. ]
但是,更改后的密码(第 7 行)仍然是一个硬编码字符串。 我们想从环境中读取它并在命令中设置。 如何使用环境变量来实现相同的目标?
您可以使用ARG
,然后使用RUN
命令的 shell 形式:
ARG jks_password
RUN "/usr/lib/jvm/java-11-openjdk-amd64/bin/keytool -storepasswd -storepass …"
然后,在构建时使用docker build --build-arg jks_password=XYZ .
但这种带有一个警告,请参阅泊坞文档的警告:
警告:不建议使用构建时变量来传递秘密,如 github 密钥、用户凭据等。使用 docker history 命令的图像的任何用户都可以看到构建时变量值。 请参阅“使用 BuildKit 构建镜像”部分,了解在构建镜像时使用机密的安全方法。
相反,应该使用--secret
标志:
RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret
以及相应的--secret id=mysecret,src=mysecret.txt .
构建参数: --secret id=mysecret,src=mysecret.txt .
将 Dockerfile 视为应用程序的 Java 源代码,将构建的映像视为 jar 文件。 当你运行容器时,你在RUN
命令中所做的任何事情都会被修复,就像一个 jar 文件一样,如果你知道如何很好地使用主机工具,那么很容易提取图像的内容(在这种情况下,相应的秘密)。
这里最简单的方法是删除这个RUN
指令。 相反,在主机系统上运行keytool
命令,然后在docker run -v
使用docker run -v
bind mount 选项将文件注入容器。
# Get the existing cacerts file out of the image
docker run --rm yourimage \
cat /usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts \
> cacerts
# Change its password
keytool \
-keystore cacerts \
-storepass changeit \
-storepasswd -new NEW_JKS_PASSWD
# Run the container, replacing the cacerts file with the local one
docker run \
-v $PWD/cacerts:/usr/lib/jvm/java-11-openjdk-amd64/lib/security/cacerts \
...
yourimage
如果你真的想在容器中这样做,你需要使用一个入口点脚本来更改密码。 将ENTRYPOINT
和CMD
一起使用的典型模式是让ENTRYPOINT
成为执行一些必需的首次设置的包装脚本,然后运行 shell exec "$@"
命令来运行CMD
(其余的命令行参数) 作为主容器进程。
在这种情况下,请记住,任何拥有 Docker 访问权限的人都可以docker inspect
容器以查找其启动时使用的环境变量和其他选项,并且任何对系统具有 root 访问权限的人都可以找到任何进程的环境变量,因此有以这种方式传递密码的安全风险并非微不足道。
入口点脚本如下所示:
#!/bin/sh
# Set the password if it's provided
if [ -n "$NEW_JKS_PASSWORD" ]; then
/usr/lib/jvm/java-11-openjdk-amd64/bin/keytool \
-storepasswd \
-storepass changeit \
-new "$NEW_JKS_PASSWORD" \
-cacerts
# Prevent the password from leaking into the main process
# (`docker inspect` _etc._ will still show it)
unset NEW_JKS_PASSWORD
fi
# Run the main container process
exec "$@"
在您的 Dockerfile 中,您可以将此脚本作为入口点,并且运行应用程序的任何java
命令都是该命令:
FROM openjdk:11
COPY target/app.jar entrypoint.sh /
# MUST be JSON-array form
ENTRYPOINT ["/entrypoint.sh"]
# Can be either shell or JSON-array form
CMD ["java", "-jar", "/app.jar"]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.