将自签名证书导入 Docker 的 JRE cacert 无法被服务识别

  • Java 服务在 Docker 容器内运行,该容器访问外部 HTTPS URL,其自签名证书对 service/JRE cacert 密钥库不可用,因此连接失败。
  • 因此,将 HTTPS 外部 URL 的自签名证书导入到 Docker 容器的 JRE cacert 密钥库中。(检查环境变量后)$JAVA_HOME
  • 已重新启动 Docker 容器(使用命令),希望服务也重新启动,并从 JRE cacert 中选取更改。但这并没有发生,Java服务仍然无法访问外部HTTPS URL。docker restart

任何想法在 Docker 容器内运行的 Java 服务如何选择 JRE cacert 随着新证书导入而变化?


答案 1

因此,将 HTTPS 外部 URL 的自签名证书导入到 Docker 容器的 JRE cacert 密钥库中。

否:需要将其导入到运行容器的 Docker 映像中。

将其导入容器只会创建一个临时可写数据层,当您重新启动容器时,该层将被丢弃。

这样回答

USER root
COPY ldap.cer $JAVA_HOME/jre/lib/security
RUN \
    cd $JAVA_HOME/jre/lib/security \
    && keytool -keystore cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias ldapcert -file ldap.cer

答案 2

对于使用已经配置的基于java的容器,如jenkinssonarqubenexus(例如,如果您运行自己的构建服务器),我发现使用docker run的参数将合适的-file安装到这些容器中会更方便。cacerts

我使用openjdk中的文件作为基础:cacerts

  1. 使用临时容器从 openjdk 映像中提取:cacerts
docker pull openjdk:latest
docker run --rm --entrypoint cat openjdk:latest /etc/ssl/certs/java/cacerts > cacerts
  1. 使用从同一文件夹启动的临时容器将证书添加到提取的证书,该文件夹还包含:cacertsldap.cer
docker run --rm -v `pwd`:/tmp/certs openjdk:latest bash -c 'cd /tmp/certs && keytool -keystore cacerts -storepass changeit -noprompt -trustcacerts -importcert -alias buenting-root -file ldap.cer'
  1. 运行目标 Docker 容器,使用 run 参数挂载提取的,例如:cacertssonarqube
docker run ... -v /path/to/your/prepared/cacerts:/etc/ssl/certs/java/cacerts:ro ... sonarqube:lts

如果有新版本的 openjdk,您可以使用 1 中的命令更新主机上的 -file。和 2.cacerts

要更新目标映像(例如 ),您不需要使用 和 创建自己的映像。sonarqubeDockerfiledocker build