Docker 运行 使用 keytool 导入到 Java truststore 成功但在映像构建期间同时失败?
Docker RUN with keytool import to Java truststore successful but fails at the same time during image build?
我必须将自定义根证书添加到 docker 环境中的 Java 信任库。所以我将以下命令添加到我的 docker 文件中:
RUN $JAVA_HOME/bin/keytool -import -file /opt/custom/certs/mycert.pem -alias mycert -keystore $JAVA_HOME/jre/lib/security/cacerts -trustcacerts -storepass changeit -noprompt
构建 docker 图像时得到以下输出:
Step 10/10 : RUN $JAVA_HOME/bin/keytool -import -file /opt/custom/certs/mycert.pem -alias mycert -keystore $JAVA_HOME/jre/lib/security/cacerts -trustcacerts -storepass changeit -noprompt
---> Running in cbc2a547797e
Certificate was added to keystore
keytool error: java.io.FileNotFoundException: /opt/java/openjdk/jre/lib/security/cacerts (No such file or directory)
The command '/bin/sh -c $JAVA_HOME/bin/keytool -import -file /opt/custom/certs/mycert.pem -alias mycert -keystore $JAVA_HOME/jre/lib/security/cacerts -trustcacerts -storepass changeit -noprompt' returned a non-zero code: 1
我对以下事实感到困惑:
- 输出
Certificate was added to keystore
似乎表明keytool
执行成功
- 同时,我得到
keytool error
和一个非零 return 代码,所以没有成功
- 声称不存在的文件,实际存在(会不会是访问问题?)
我检查过的内容:
%JAVA_HOME
似乎可用,因为错误消息显示正确的路径
- 当我在没有上述
RUN
命令的情况下构建图像时,然后在 docker 容器中发出完全相同的命令,它完美地工作
- 我使用
/bin/sh
作为 shell 检查了相同的内容,以确保它不是 shell - 有效
- 不依赖于当前目录,因为所有路径都是绝对路径
现在我不知道如何追踪这个问题。
这可能是一个权限问题,我猜测是您使用的基本映像将用户从 root 更改为您需要 root 才能访问该文件。
您应该能够执行以下操作:
USER root
RUN $JAVA_HOME/bin/keytool -import -file /opt/custom/certs/mycert.pem -alias mycert -keystore $JAVA_HOME/jre/lib/security/cacerts -trustcacerts -storepass changeit -noprompt
USER originaluser
您可以通过以下方式找到原始用户:
docker history yourbaseimagename:tag
原来是我的错™️
有几件事让我感到困惑:
keytool
显示 Certificate was added to keystore
即使实际上失败了 – 愚蠢
- 我检查了该命令是否在 docker 容器中运行,但我错过了我正在以不同方式 Java 安装的另一个版本的映像中进行测试
- Java 密钥库并不总是位于同一路径 - 它可能是
$JAVA_PATH/lib/security/cacerts
或者可能是 $JAVA_PATH/jre/lib/security/cacerts
- 显然取决于是 JRE 还是 JDK 已安装
所以我的解决方案是写一个 bash 脚本:
- Java 是第 9 版还是更高版本?然后使用
-cacerts
选项导入,该选项将自动处理密钥库位置
- Else:
$JAVA_HOME/jre
目录是否存在?然后使用 -keystore $JAVA_PATH/jre/lib/security/cacerts
- 否则:使用
-keystore $JAVA_PATH/lib/security/cacerts
我正在使用 https://hub.docker.com/r/jenkins/jenkins,在我的情况下,问题是由新的 OpenJDK 11 安装引起的,它从之前使用的路径中删除了 jre。我变了
$JAVA_HOME/jre/lib/security/cacerts
进入
$JAVA_HOME/lib/security/cacerts
我必须将自定义根证书添加到 docker 环境中的 Java 信任库。所以我将以下命令添加到我的 docker 文件中:
RUN $JAVA_HOME/bin/keytool -import -file /opt/custom/certs/mycert.pem -alias mycert -keystore $JAVA_HOME/jre/lib/security/cacerts -trustcacerts -storepass changeit -noprompt
构建 docker 图像时得到以下输出:
Step 10/10 : RUN $JAVA_HOME/bin/keytool -import -file /opt/custom/certs/mycert.pem -alias mycert -keystore $JAVA_HOME/jre/lib/security/cacerts -trustcacerts -storepass changeit -noprompt
---> Running in cbc2a547797e
Certificate was added to keystore
keytool error: java.io.FileNotFoundException: /opt/java/openjdk/jre/lib/security/cacerts (No such file or directory)
The command '/bin/sh -c $JAVA_HOME/bin/keytool -import -file /opt/custom/certs/mycert.pem -alias mycert -keystore $JAVA_HOME/jre/lib/security/cacerts -trustcacerts -storepass changeit -noprompt' returned a non-zero code: 1
我对以下事实感到困惑:
- 输出
Certificate was added to keystore
似乎表明keytool
执行成功
- 同时,我得到
keytool error
和一个非零 return 代码,所以没有成功 - 声称不存在的文件,实际存在(会不会是访问问题?)
我检查过的内容:
%JAVA_HOME
似乎可用,因为错误消息显示正确的路径- 当我在没有上述
RUN
命令的情况下构建图像时,然后在 docker 容器中发出完全相同的命令,它完美地工作 - 我使用
/bin/sh
作为 shell 检查了相同的内容,以确保它不是 shell - 有效 - 不依赖于当前目录,因为所有路径都是绝对路径
现在我不知道如何追踪这个问题。
这可能是一个权限问题,我猜测是您使用的基本映像将用户从 root 更改为您需要 root 才能访问该文件。 您应该能够执行以下操作:
USER root
RUN $JAVA_HOME/bin/keytool -import -file /opt/custom/certs/mycert.pem -alias mycert -keystore $JAVA_HOME/jre/lib/security/cacerts -trustcacerts -storepass changeit -noprompt
USER originaluser
您可以通过以下方式找到原始用户:
docker history yourbaseimagename:tag
原来是我的错™️
有几件事让我感到困惑:
keytool
显示Certificate was added to keystore
即使实际上失败了 – 愚蠢- 我检查了该命令是否在 docker 容器中运行,但我错过了我正在以不同方式 Java 安装的另一个版本的映像中进行测试
- Java 密钥库并不总是位于同一路径 - 它可能是
$JAVA_PATH/lib/security/cacerts
或者可能是$JAVA_PATH/jre/lib/security/cacerts
- 显然取决于是 JRE 还是 JDK 已安装
所以我的解决方案是写一个 bash 脚本:
- Java 是第 9 版还是更高版本?然后使用
-cacerts
选项导入,该选项将自动处理密钥库位置 - Else:
$JAVA_HOME/jre
目录是否存在?然后使用-keystore $JAVA_PATH/jre/lib/security/cacerts
- 否则:使用
-keystore $JAVA_PATH/lib/security/cacerts
我正在使用 https://hub.docker.com/r/jenkins/jenkins,在我的情况下,问题是由新的 OpenJDK 11 安装引起的,它从之前使用的路径中删除了 jre。我变了
$JAVA_HOME/jre/lib/security/cacerts
进入
$JAVA_HOME/lib/security/cacerts