在我的10台机器裸机Kubernetes集群中,一个服务需要调用另一个使用自签名证书的基于https的服务。但是,由于此自签名证书未添加到pod的受信任根ca中,调用失败,无法验证x.509证书。
所有的pod都是基于ubuntu docker镜像的,但是在ubuntu上添加ca证书到信任列表的方法(使用dpkg-reconfigure ca证书)在这个pod上不再起作用了,当然,即使我成功地在一个pod上添加了ca证书到信任根目录,当另一个pod被踢的时候,它也会消失。
我搜索了Kubernetes文档,惊讶地发现除了配置证书与API服务对话之外没有任何其他内容,这不是我要找的。如果Pod之间需要任何安全通道,这应该是很常见的场景。
3条答案
按热度按时间jhiyze9q1#
如果你想在构建时把证书保存起来,编辑你的Docker文件,添加命令从构建上下文复制证书并更新信任。你甚至可以把它作为一个层添加到Docker hub等的东西中。
如果你试图在运行时更新信任,事情会变得更加复杂,我自己还没有这样做,但是你可以创建一个包含证书的
configMap
,将它安装到容器中的上述路径,然后使用一个入口点脚本在主进程之前运行update-ca-certificates
。lmyy7pcs2#
更新编辑读取选项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.)将证书添加到配置Map:假设你的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/ as file中安装卷中,以一对一文件关系安装配置Map文件
所以我相信这里的想法是/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密钥,他们有一个dns 01挑战,可用于证明您拥有该证书,这意味着您应该能够利用该解决方案,即使没有入口/即使群集仅用于专用网络。)
编辑:选项3。)(在获得更多Kubernetes实践经验后)
我相信switchboard.op的答案可能是最好的/应该是公认的答案。这个“可以”在运行时完成,但我认为它永远不应该在运行时完成,在运行时完成它是超级黑客和充满边缘案例/没有一个通用的解决方案。
而且,我的选项1只对了一半。在pod上单独安装ca.crt是不够的。在pod上安装该文件后,您需要运行一个命令来信任它。这意味着您可能需要覆盖pod启动命令。例如,您无法执行连接到数据库之类的操作(默认的启动命令),然后更新受信任的CA证书的命令。你必须覆盖启动文件,使之成为一只手卡住,覆盖默认的启动脚本,更新受信任的CA证书,连接到数据库。而问题是Ubuntu,RHEL,Alpine,和其他主机具有不同的位置,您必须在这些位置装载CA证书,有时使用不同的命令来信任CA证书,因此,您可以在运行时将通用解决方案应用于群集中的所有Pod以更新其ca.cert,这并非不可能,但是将需要大量的if语句和变化的webhook/复杂性。(手工制作的每个吊舱解决方案是非常可能的,虽然如果你只需要能够动态更新它的一个吊舱。)
op的答案是如果我必须这么做的话我会这么做。构建一个新的自定义docker映像,并将您的自定义ca.cert信任地烘焙到映像中。这是一个通用的解决方案,并且极大地简化了YAML方面。而且在docker映像方面做起来相对容易。
zkure5ic3#
出于好奇,这里有一个使用init容器方法的manifest示例。
其用途为:
注:
的确,它有点丑陋和可怕,但至少它确实有效,并且是概念验证。简单ConfigMap的解决方案不起作用,因为curl读取ca-certificates.crt,而在该方法中没有修改它。