微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Docker RUN with keytool import to Java truststore 成功但在映像构建期间同时失败?

如何解决Docker RUN with keytool import to Java truststore 成功但在映像构建期间同时失败?

我必须将自定义根证书添加到 docker 环境中的 Java 信任库。所以我在我的 dockerfile 中添加了以下命令:

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一个非零返回码,所以没有成功
  • 声称不存在的文件实际上存在(会不会是访问问题?)

我检查了什么:

  • %JAVA_HOME 似乎可用,因为错误消息显示了正确的路径
  • 当我在没有上面 RUN 命令的情况下构建映像时,然后在 docker 容器内发出完全相同的命令,它完美运行
  • 我使用 /bin/sh 作为外壳进行了检查,以确保它不是外壳 - 有效
  • 不依赖当前目录,因为所有路径都是绝对路径

现在我没有更多想法如何追踪这个问题。

解决方法

这可能是权限问题,我猜是您使用的基本映像将用户从 root 更改为 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
,

原来是我的错™️

有几件事让我感到困惑:

  1. keytool 显示 Certificate was added to keystore 即使实际上失败了 - 愚蠢
  2. 我检查了该命令是否在 docker 容器中有效,但我错过了我正在以不同方式安装 Java 的另一个版本的映像中进行测试
  3. Java 密钥库并不总是位于同一路径中——它可能是 $JAVA_PATH/lib/security/cacerts,也可能是 $JAVA_PATH/jre/lib/security/cacerts——这显然取决于安装的是 JRE 还是 JDK

所以我的解决方案是编写一个 bash 脚本:

  1. Java 版本是 9 还是更好?然后使用 -cacerts 选项导入,该选项将自动处理密钥库位置
  2. 否则:$JAVA_HOME/jre 目录是否存在?然后使用 -keystore $JAVA_PATH/jre/lib/security/cacerts
  3. 否则:使用-keystore $JAVA_PATH/lib/security/cacerts

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。