Kubernetes使用自签名证书私有镜像仓库的证书信任异常及非重启修复方案咨询
Kubernetes使用自签名证书私有镜像仓库的证书信任异常及非重启修复方案咨询
您好,我来帮您分析这个问题的核心原因,并提供无需重启机器的修复方案:
问题原因解析
您遇到的问题本质是系统/容器运行时的证书缓存、镜像拉取客户端的状态缓存导致的,具体来说:
- 容器运行时的独立信任体系:像Docker、Containerd这类容器运行时,并不会实时同步系统的信任证书变更——它们要么有自己独立的证书配置目录,要么会缓存已读取的证书信息。第一次未导入CA时的拉取失败记录,会被容器运行时缓存,后续即使系统信任了CA,缓存没清理的话还是会复用旧的失败状态。
- 镜像拉取缓存残留:K8s的kubelet或者容器运行时的镜像拉取组件,会缓存私有仓库的旧证书信息、拉取失败的状态。当您更换新CA后,旧的缓存记录和新CA不匹配,就会触发
x509验证错误。 - 多CA的信任链冲突:更换仓库CA后,机器上可能残留旧CA的信任配置(比如系统证书存储或容器运行时的证书目录里还存在旧CA文件),导致验证新证书时出现信任链冲突,报出
crypto/rsa: verification error。
无需重启的修复方案
根据您使用的容器运行时(Docker/Containerd),可以执行以下针对性操作:
情况一:使用Docker作为容器运行时
- 配置Docker专属信任证书
容器运行时不会自动读取系统CA,需要把CA证书放到Docker的私有仓库专属证书目录:# 替换成你的私有仓库域名和端口 REGISTRY="your-registry-domain:5000" mkdir -p /etc/docker/certs.d/${REGISTRY} # 把新CA证书复制到该目录 cp /path/to/your-new-ca.crt /etc/docker/certs.d/${REGISTRY}/ca.crt - 清理Docker缓存
清除之前拉取失败的镜像缓存和运行时缓存:# 清理未使用的镜像、容器、缓存 docker system prune -f # 如果知道拉取失败的镜像标签,也可以单独删除 docker rmi ${REGISTRY}/your-image:tag - 重载kubelet配置
让K8s节点的kubelet重新读取Docker的信任配置:systemctl reload kubelet
情况二:使用Containerd作为容器运行时
- 更新系统证书存储
先确保系统CA已经正确导入并生效:# Debian/Ubuntu系统 update-ca-certificates # RHEL/CentOS系统 update-ca-trust extract - 清理Containerd缓存
清除镜像拉取的缓存和元数据:# 清理所有未使用的镜像(不会删除正在使用的镜像) crictl rmi --prune # 清理Containerd的内容缓存(如果需要彻底清理,注意:会删除所有本地镜像,按需执行) rm -rf /var/lib/containerd/io.containerd.content.v1.content/blobs/sha256/* - 重载Containerd和kubelet
让组件重新读取最新的证书配置:systemctl reload containerd systemctl reload kubelet
通用收尾操作
- 删除之前拉取失败的Pod:让K8s重新创建Pod,触发全新的镜像拉取请求:
kubectl delete pod <failed-pod-name> -n <your-namespace> - 验证证书信任是否生效:用curl测试私有仓库的证书是否被信任:
如果返回curl -v https://your-registry-domain:5000/v2/200 OK(无需认证)或401 Unauthorized(需要认证),说明证书信任已经正常工作。
为什么重启机器会生效?
重启会彻底清空系统、容器运行时、kubelet的所有缓存,让所有组件重新读取最新的证书配置,但这显然不是生产环境的最优解——上面的步骤可以在不重启机器的前提下解决问题,避免丢失已有的镜像和节点配置。
备注:内容来源于stack exchange,提问作者Astin Gengo
相关产品推荐
相关产品推荐

