更新了编辑阅读选项 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 镜像端做起来也比较容易。