首页 > 解决方案 > 如何将 PEM 证书从 ConfigMap 动态添加到 OpenShift 中的 Java cacerts?

问题描述

我们正在尝试构建一组相同的服务,这些服务连接到不同的 MQTT 代理和不同的 3rd 方系统。每个服务都需要有自己的证书才能连接到自己的 MQTT 代理。

为此,我们使用了一个 Jenkins 管道,它将新构建的 Docker 镜像推送到 OpenShift 中的多个目标项目。每个项目都有自己的 ConfigMap 以及连接/配置详细信息。

现在的问题是我们想对 PEM 证书做同样的事情。最简单且有效的方法是将证书保存在存储库中,并将其导入 dockerfile。当我们想在 OpenShift 中添加更多具有相同服务但配置不同的 POD 时,它工作正常,但并没有扩大。

为了动态地做到这一点,我们考虑了initContainers。这将允许我们动态发送证书。

initContainers:
  - name: inject-pem-to-cacerts
    image: <imageName>
    env:
      - name: MQTT_CERT_PEM
        value: home/fromMount/cert.pem
     - name: CACERTS
       value: $JAVA_HOME/jre/lib/security/cacerts 
    command: ['/bin/bash']
    args: ['-c', "keytool -import -noprompt -keystore $CACERTS -file $MQTT_CERT_PEM -storepass changeit -alias service-$MQTT_CERT_PEM"]

在这种情况下,我们在该特定路径上收到PermissionDenied 。就我们测试而言,这里不是 Sudo 选项。也许这是 YAML 中的安全上下文问题,但不知道应该设置什么。

如果有其他方法可以做得更好,我很乐意倾听。

标签: dockerkubernetesopenshift

解决方案


您面临的问题源于 Init-Containers不是这里的正确工具。Init-Containers在 Pod 容器之前启动,因此您在此处配置的信任库将位于 Init-Container 而不是应用程序容器上。为了实现你想要做的事情,我推荐PostStart Container Lifecycle Handler

  containers:
    - name: my-container
      lifecycle:
        postStart:
          exec: ['-c', "keytool -import -noprompt -keystore $CACERTS -file $MQTT_CERT_PEM -storepass changeit -alias service-$MQTT_CERT_PEM"]

退后一步,我想知道另一种解决方案。如果我理解正确,您需要为各种 MQTT 代理的服务器证书安装 cacerts。所以,既然 cacerts不是机密的,为什么不使用一个安装了所有 cacerts的单一 Docker 映像。这将消除 K8s 的很多复杂性。


推荐阅读