解决 Kubernetes 使用自签名 Docker Registry 证书的问题

90次阅读
没有评论

问题描述

在尝试从私有 Docker Registry 拉取镜像到 Kubernetes 集群时,遇到了以下错误信息:

Type     Reason     Age                From               Message  
----     ------     ----               ----               -------  
Normal   Scheduled  104s               default-scheduler  Successfully assigned namespace/service-8599c54df8-592wm to fat2  
Normal   Pulling    67s                kubelet            Pulling image "192.168.100.178:5000/service:ds-1.2"  
Warning  Failed     67s                kubelet            Error: ErrImagePull  
Warning  Failed     67s                kubelet            Failed to pull image "192.168.100.178:5000/service:ds-1.2": rpc error: code = Unknown desc = failed to pull and unpack image "192.168.100.178:5000/service:ds-1.2": failed to resolve reference "192.168.100.178:5000/service:ds-1.2": failed to do request: Head "https://192.168.100.178:5000/v2/service/manifests/ds-1.2": x509: certificate signed by unknown authority (possibly because of "x509: invalid signature: parent certificate cannot sign this kind of certificate" while trying to verify candidate authority certificate "192.168.100.174: hostname")  
Warning  Failed     65s (x2 over 66s)  kubelet            Error: ImagePullBackOff  
Normal   BackOff    65s (x2 over 66s)  kubelet            Back-off pulling image "192.168.100.178:5000/service:ds-1.2"

用户已经将 Docker Registry 的证书复制到了 /etc/docker/certs.d/192.168.100.178:5000/ 目录,并且还复制了另一个可以正常从 Docker Registry 拉取镜像的集群中的 Secret。用户还验证了可以成功执行 docker login

尽管已经采取了上述操作,但新的 Kubernetes 集群似乎不信任签署 Docker Registry 证书的 CA。用户已经尝试了多种方法,但问题仍然没有解决。用户在此请求帮助解决这个问题。

解决方案

请注意以下操作可能涉及版本差异,请在实施前做好备份。

步骤1:安装根证书

首先,需要将用于创建 Docker Registry 证书的根证书安装到 Kubernetes 节点上。这个根证书被用于签署 Docker Registry 证书。

  1. 将根证书拷贝到 Kubernetes 节点的 /etc/ssl/tls/certs 目录。假设根证书文件名为 registry-ca.crt
  2. 更新 Kubernetes 节点上的 CA 证书存储。执行以下命令来更新 CA 证书存储:
    bash
    sudo update-ca-certificates

    这会将根证书添加到系统的 CA 存储中,使 Kubernetes 节点信任该根证书。

步骤2:验证修改

  1. 确保根证书已经成功添加到 Kubernetes 节点的 CA 存储。
  2. 重新尝试从私有 Docker Registry 拉取镜像到 Kubernetes 集群,查看是否解决了问题。

如果仍然遇到问题,可以尝试以下补充方案:

补充方案:使用额外的工具

在某些情况下,手动控制容器的启动顺序可能会更加灵活。你可以使用脚本或工具来确保 Docker Registry 的容器已经启动后再启动 Kubernetes 中的容器。以下是一个简单的 Bash 脚本示例,用于在容器 A 启动后启动容器 B:

#!/bin/bash
# 启动容器 A
docker run -d --name container_a your_image_a
# 等待容器 A 完全启动
while ! docker exec container_a echo "Container A is ready"; do
  sleep 1
done
# 启动容器 B
docker run -d --name container_b your_image_b

请将上面的示例脚本保存为文件,并根据实际情况修改容器的名称和镜像。

这是一个备选方案,如果上述安装根证书的方法无效,你可以尝试使用此方法来确保 Docker Registry 的容器已经准备就绪,然后再启动 Kubernetes 中的容器。

希望这些解决方案能够帮助你解决问题。如果问题仍然存在,建议仔细检查证书和配置是否正确,并确保 Docker Registry 和 Kubernetes 之间的网络连接正常。

正文完