【问题标题】:Kubernetes add ca certificate to pods' trust rootKubernetes 将 ca 证书添加到 pod 的信任根
【发布时间】:2016-12-22 10:41:59
【问题描述】:

在我的 10 台机器裸机 Kubernetes 集群中,一个服务需要调用另一个使用自签名证书的基于 https 的服务。 但是,由于此自签名证书未添加到 pod 的受信任根 ca 中,因此调用失败说无法验证 x.509 证书。

所有 pod 都基于 ubuntu docker 镜像。但是,将 ca cert 添加到 ubuntu 上的信任列表的方法(使用 dpkg-reconfigure ca-certificates)不再适用于该 pod。当然,即使我在一个 pod 上成功添加了 ca 证书以信任 root,但当另一个 pod 被踢时,它就消失了。

我搜索了 Kubernetes 文档,但惊讶地发现除了配置证书以与 API 服务对话之外没有找到任何其他文档,这不是我想要的。如果 pod 之间需要任何安全通道,这应该是很常见的情况。有什么想法吗?

【问题讨论】:

    标签: ssl docker certificate kubernetes


    【解决方案1】:

    如果您想在构建时烘焙证书,请编辑 Dockerfile 添加命令以从构建上下文复制证书并更新信任。你甚至可以将它作为一个层添加到 docker hub 等中。

    COPY my-cert.crt /usr/local/share/ca-certificates/
    RUN update-ca-certificates
    

    如果您尝试在运行时更新信任,事情会变得更加复杂。我自己没有这样做,但您可以创建一个包含证书的configMap,将其安装到上述路径的容器中,然后使用入口点脚本在您的主进程之前运行update-ca-certificates

    【讨论】:

      【解决方案2】:

      更新了编辑阅读选项 3:

      如果我遇到您的情况,我可以想出 3 个选项来解决您的问题:
      选项 1。)(我能提供的唯一完整解决方案,不幸的是,我的其他解决方案是一半解决方案,感谢 Paras Patidar/以下网站:)
      https://medium.com/@paraspatidar/add-ssl-tls-certificate-or-pem-file-to-kubernetes-pod-s-trusted-root-ca-store-7bed5cd683d

      1.) 将证书添加到配置映射: 假设您的 pem 文件是 my-cert.pem
      kubectl -n <namespace-for-config-map-optional> create configmap ca-pemstore — from-file=my-cert.pem

      2.) 将 configmap 作为卷挂载到容器的退出 CA 根位置: 将该配置映射的文件作为一对一的文件关系挂载在目录 /etc/ssl/certs/ 中的卷挂载中作为文件例如

      apiVersion: v1 
      kind: Pod
      metadata:
        name: cacheconnectsample
      spec:
            containers:
            - name: cacheconnectsample
              image: cacheconnectsample:v1
              volumeMounts:
              - name: ca-pemstore
                mountPath: /etc/ssl/certs/my-cert.pem
                subPath: my-cert.pem
                readOnly: false
              ports:
              - containerPort: 80
              command: [ "dotnet" ]
              args: [ "cacheconnectsample.dll" ]
            volumes:
            - name: ca-pemstore
              configMap:
                name: ca-pemstore
      

      所以我相信这里的想法是 /etc/ssl/certs/ 是 pod 信任的 tls 证书的位置,并且 subPath 方法允许您添加文件而不清除文件夹的内容,这将包含 k8s 的秘密。
      如果所有 pod 共享这个 mountPath,那么您也许可以将 pod present 和 configmap 添加到每个命名空间,但这还处于 alpha 阶段,仅对静态命名空间有用。 (但如果这是真的,那么您所有的 pod 都会信任该证书。)


      选项 2。)(一半解决方案/想法 + 不能完全回答您的问题,但可以解决您的问题,我相当有信心在理论上会起作用,这需要您进行研究,但我认为您'会发现这是最好的选择:)
      从理论上讲,您应该能够利用 cert-manager + external-dns + Lets Encrypt Free + 公共域名将自签名证书替换为公共证书。
      (cert-manager 的最终结果是在您的集群中自动生成由 Lets Encrypt Free 签名的 k8s tls 机密,他们有一个 dns01 挑战,可用于证明您拥有证书,这意味着您应该能够利用它即使没有入口/即使集群仅用于专用网络的解决方案。)

      编辑:选项 3。)(在获得更多 Kubernetes 实践经验后)
      我相信 switchboard.op 的答案可能是最好的/应该是公认的答案。这个“可以”在运行时完成,但我认为它永远不应该在运行时完成,在运行时这样做是超级hacky并且充满了边缘情况/没有通用的解决方案。

      事实证明,我这样做的选项 1 只正确了一半。 仅将 ca.crt 安装在 pod 上是不够的。将该文件安装在 pod 上后,您需要运行命令来信任它。这意味着您可能需要覆盖 pods 启动命令。例如,您不能执行诸如连接到数据库(默认启动命令)然后更新受信任的 CA 证书命令之类的操作。您必须覆盖启动文件以防卡住,覆盖默认启动脚本,更新受信任的 CA 证书,连接到数据库。问题是 Ubuntu、RHEL、Alpine 和其他有不同的位置,您必须在其中挂载 CA 证书,有时还有不同的命令来信任 CA 证书,因此这是一个通用的运行时解决方案,您可以将其应用于集群中的所有 pod 以进行更新他们的 ca.cert 并非不可能,但需要大量的 if 语句和变异的 webhook/复杂性。 (如果您只需要能够为单个 pod 动态更新它,则非常有可能手工制作每个 pod 的解决方案。)

      switchboard.op 的答案是如果我必须这样做,我会这样做。构建一个新的自定义 docker 镜像,并将您的自定义 ca.cert 信任烘焙到镜像中。这是一个通用的解决方案,并且极大地简化了 YAML 端。而且在 docker 镜像端做起来也比较容易。

      【讨论】:

      • 方法 1 帮助了我。感谢那。我使用Secret 而不是ConfigMap 来部署根CA 证书。
      猜你喜欢
      • 2011-05-17
      • 1970-01-01
      • 2021-01-17
      • 2012-03-19
      • 2011-02-24
      • 2022-10-03
      • 2021-08-28
      • 2017-02-19
      • 2016-08-30
      相关资源
      最近更新 更多