当前位置: 首页 > news >正文

KubeKey离线部署K8s集群,containerd死活拉不了私有镜像?手把手教你搞定证书认证

KubeKey离线部署K8s集群:彻底解决containerd私有镜像拉取认证问题

在离线环境中使用KubeKey部署Kubernetes集群时,containerd运行时无法拉取私有镜像仓库中的镜像是一个常见痛点。特别是当私有仓库使用自签名证书时,反复出现的x509: certificate signed by unknown authority错误会让部署流程陷入停滞。本文将深入解析问题根源,并提供一套完整的解决方案。

1. 问题诊断与根源分析

当执行kk create cluster命令时,如果遇到类似以下的错误日志,表明containerd无法验证私有镜像仓库的TLS证书:

E0528 12:13:49.009936 1166 remote_image.go:180] "PullImage from image service failed" err="rpc error: code = Unknown desc = failed to pull and unpack image \"dockerhub.kubekey.local/kubesphereio/pause:3.9\": failed to resolve reference \"dockerhub.kubekey.local/kubesphereio/pause:3.9\": failed to do request: Head \"https://dockerhub.kubekey.local/v2/kubesphereio/pause/manifests/3.9\": tls: failed to verify certificate: x509: certificate signed by unknown authority"

关键诊断步骤

  1. 手动验证仓库可访问性

    curl -vk https://dockerhub.kubekey.local/v2/

    观察输出中的证书验证结果:

    * SSL certificate verify result: unable to get local issuer certificate (20), continuing anyway.
  2. 检查containerd日志

    sudo journalctl -u containerd -f

    重点关注包含tls: failed to verify certificate的错误条目

  3. 直接使用crictl测试

    sudo crictl pull dockerhub.kubekey.local/kubesphereio/pause:3.9

问题本质:containerd默认要求严格的TLS证书验证,而自签名证书不在系统信任链中。这与Docker的行为不同,Docker可以通过insecure-registries配置更简单地绕过证书验证。

2. containerd证书信任机制详解

containerd处理镜像拉取的证书验证涉及多个配置层级:

配置层级作用域关键参数持久性
全局系统证书所有HTTPS请求/etc/ssl/certs
containerd主配置所有registry请求config.toml中的registry配置
单次命令参数当前命令--plain-http标志

证书查找路径

  1. 首先检查/etc/containerd/certs.d/<registry>/下的CA证书
  2. 然后检查系统默认证书存储(/etc/ssl/certs)
  3. 最后根据config.toml中的insecure_skip_verify设置决定是否跳过验证

注意:containerd v1.5+版本开始,推荐使用config_path替代直接配置,但大多数生产环境仍使用传统配置方式。

3. 完整解决方案:配置containerd信任私有仓库

3.1 方法一:跳过特定仓库的TLS验证(推荐)

这是最常用的解决方案,具体操作步骤如下:

  1. 编辑containerd主配置文件:

    sudo vim /etc/containerd/config.toml
  2. [plugins."io.containerd.grpc.v1.cri".registry]部分添加以下内容:

    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."dockerhub.kubekey.local"] endpoint = ["https://dockerhub.kubekey.local"] [plugins."io.containerd.grpc.v1.cri".registry.configs."dockerhub.kubekey.local".tls] insecure_skip_verify = true
  3. 完全重启containerd服务:

    sudo systemctl stop containerd sudo rm -f /run/containerd/containerd.sock sudo systemctl start containerd
  4. 验证配置是否生效:

    sudo crictl info | jq .config.registry

    应该能看到类似输出:

    { "configs": { "dockerhub.kubekey.local": { "tls": { "insecure_skip_verify": true } } } }

3.2 方法二:添加CA证书到系统信任链(更安全)

如果希望保持TLS验证但信任自签名证书,可以:

  1. 获取私有仓库的CA证书,保存到:

    sudo mkdir -p /etc/containerd/certs.d/dockerhub.kubekey.local sudo cp harbor-ca.crt /etc/containerd/certs.d/dockerhub.kubekey.local/ca.crt
  2. 或者添加到系统证书库:

    sudo cp harbor-ca.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates
  3. 无需设置insecure_skip_verify,直接重启containerd

3.3 方法三:临时解决方案(仅测试用)

对于快速测试,可以使用ctr命令直接跳过验证:

sudo ctr --address /run/containerd/containerd.sock images pull \ --plain-http \ dockerhub.kubekey.local/kubesphereio/pause:3.9

警告:此方法不会持久化配置,仅适用于临时测试,生产环境请使用前两种方法。

4. KubeKey集成与验证

完成containerd配置后,需要确保KubeKey能够正确使用这些设置:

  1. 检查config.yaml中的相关配置:

    registry: privateRegistry: "dockerhub.kubekey.local" insecureRegistries: ["dockerhub.kubekey.local"] skipTLSVerify: true
  2. 重新运行集群部署命令:

    ./kk create cluster -f config-sample.yaml -a kubesphere.tar.gz --with-local-storage
  3. 验证节点上的镜像是否正常拉取:

    sudo crictl images

常见问题排查表

现象可能原因解决方案
配置修改后仍报证书错误配置未生效彻底重启containerd并删除旧socket
部分节点可以拉取,部分不行配置未同步到所有节点确保所有节点containerd配置一致
能拉取镜像但无法创建Pod镜像路径不正确检查privateRegistrynamespaceOverride配置

5. 高级配置与最佳实践

5.1 多仓库配置示例

对于需要访问多个私有仓库的环境,config.toml可以这样配置:

[plugins."io.containerd.grpc.v1.cri".registry] config_path = "" [plugins."io.containerd.grpc.v1.cri".registry.mirrors] [plugins."io.containerd.grpc.v1.cri".registry.mirrors."dockerhub.kubekey.local"] endpoint = ["https://dockerhub.kubekey.local"] [plugins."io.containerd.grpc.v1.cri".registry.mirrors."internal.registry.com"] endpoint = ["https://internal.registry.com"] [plugins."io.containerd.grpc.v1.cri".registry.configs] [plugins."io.containerd.grpc.v1.cri".registry.configs."dockerhub.kubekey.local".tls] insecure_skip_verify = true [plugins."io.containerd.grpc.v1.cri".registry.configs."internal.registry.com".auth] username = "admin" password = "Harbor12345"

5.2 配置持久化技巧

为避免升级或重置后配置丢失,建议:

  1. 备份原始配置:

    sudo cp /etc/containerd/config.toml /etc/containerd/config.toml.bak
  2. 创建配置片段:

    sudo mkdir -p /etc/containerd/conf.d sudo vim /etc/containerd/conf.d/registry.conf
  3. 在主配置中添加:

    imports = ["/etc/containerd/conf.d/*.conf"]

5.3 性能优化建议

对于大型离线环境:

  1. 配置本地镜像缓存:

    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."dockerhub.kubekey.local"] endpoint = ["https://dockerhub.kubekey.local", "http://localhost:5000"]
  2. 调整并行下载数:

    [plugins."io.containerd.grpc.v1.cri"] max_concurrent_downloads = 5

在实际项目中,我发现最稳妥的做法是在部署前先在所有节点上预加载必要的镜像,这可以避免部署过程中的网络问题。使用ctr images import命令可以批量导入离线镜像包,比依赖集群部署时的拉取更可靠。

http://www.jsqmd.com/news/529622/

相关文章:

  • 避开FPGA时序约束的坑:Vivado Check_timing报告中那些‘High’级别警告都意味着什么?
  • 基于Comsol的SOFC单通道非绝热燃料电池模型:包括气体扩散层与实际SEM扫描结果的电极扩...
  • ESP32-S3开发板避坑指南:从SD卡挂载到LVGL屏幕异常的5个实战解决方案
  • Windows Server域环境下共享文件夹容量配额管理实战:从配置到验证的完整流程
  • 揭秘MCP Sampling接口底层调用栈:基于eBPF实时追踪syscall→gRPC stream→采样率动态熔断阈值触发全过程(含火焰图)
  • AcFun视频下载神器:3步轻松保存A站所有精彩内容!
  • 告别S32DS内置编辑器:用VSCode写代码,搭配J-Link在S32DS中调试S32K144的完整流程
  • MCP vs REST API:20万QPS压测数据曝光,为什么头部大厂已悄悄切换协议栈?
  • Vue-Flow-Editor 流程可视化:7个提效技巧助力业务流程设计
  • 别再只会用OpenCV的resize了!手把手教你用Python实现三种经典图像放大算法(附完整代码)
  • CellphoneDB统计分析实战:单细胞通讯中的配体-受体互作解析
  • 告别纯GPS:手把手教你为Pixhawk无人车配置视觉惯性导航(VIO)与MAVROS融合定位
  • 终极黑苹果安装指南:如何在普通PC上运行macOS系统
  • 效率直接起飞 9个降AIGC工具:毕业论文全流程降AI率测评与推荐
  • Display Driver Uninstaller终极使用指南:彻底解决显卡驱动残留问题
  • 内网开发必备:Maven本地仓库jar包失效的终极解决方案(附一键清理脚本)
  • 从内存访问模式到缓存优化:实战解析Perf的PEBS数据地址剖析功能
  • 【从零开始学Java | 第十八篇】BigInteger
  • C30混凝土实体群桩与边坡稳定性的数值计算模拟及监测研究
  • SUNFLOWER MATCH LAB 科研工具链:Matlab数据预处理与模型调用接口
  • 基于Luminex技术的药效评估方法研究与应用
  • fastMRI技术竞赛实战指南:从数据挑战到算法突破的完整路径
  • 手把手教你为CST8XX触摸屏编写设备树(DTS):基于Hynitron芯片的完整配置指南
  • NSudo:Windows系统权限管理的终极解决方案与完全指南
  • Dify平台上的ViT模型应用:无需编码构建图像分类服务
  • GTE文本向量模型效果展示:多语言文本相似度计算案例
  • Arrow:高效可视化游戏叙事设计工具,让复杂剧情创作变得简单
  • 如何用猫抓插件下载网页视频和音频?浏览器资源嗅探工具完整指南
  • 基于MATLAB的DTW算法在特定人孤立词语音识别系统中的应用——16页试验文档
  • 从Full-band到Sub-band:自适应滤波器演进史与SAF在WebRTC等现代语音引擎中的角色