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行(仍然是一个硬编码字符串。我们想从环境中读取它,并在命令中设置。如何使用环境变量来实现相同的效果?

将Dockerfile想象成应用程序的Java源代码,将构建的映像想象成jar文件。当您运行容器时,您在RUN命令中所做的任何操作都将被修复,就像jar文件一样,如果您知道如何很好地使用主机工具,那么提取图像的内容(在这种情况下,提取相应的秘密(是非常容易的。

这里最简单的方法是删除这个RUN指令。相反,在主机系统上运行keytool命令,然后在运行时使用docker run -v绑定装载选项将文件注入容器。

# 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

如果您真的想在容器中执行此操作,则需要使用入口点脚本来更改密码。将ENTRYPOINTCMD一起使用的典型模式是,将ENTRYPOINT作为一个包装脚本,进行一些所需的首次安装,然后运行shellexec "$@"命令,以运行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"]

您可以使用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 .

但是这附带了一个警告,请参阅Docker文档中的警告:

警告:不建议使用构建时间变量来传递github密钥、用户凭据等机密。使用docker history命令的图像的任何用户都可以看到构建时间变量值。请参阅"使用BuildKit构建图像"部分,了解构建图像时使用机密的安全方法。

相反,应该使用--secret标志:

RUN --mount=type=secret,id=mysecret cat /run/secrets/mysecret

以及相应的docker构建参数:--secret id=mysecret,src=mysecret.txt .

相关内容

  • 没有找到相关文章

最新更新