• containerd拉取私库镜像失败(kubelet)


    最近在跟着高塔老师的教程用二进制的方式搭建k8s

    kubernetes v1.20.0     我没有使用最新的版本,是因为内部网络问题。

    containerd  v1.5.2        之前并没有使用过,但对docker比较熟悉

    我所处的环境是一个内网环境,无法连接互联网,更无法连接国际互联网,

    内网环境下部署了Harbor(private registry),用作镜像仓库来使用,是以http形式来进行服务的,即 insecure registry,ip地址为192.168.1.8

    还有6台虚拟机节点,分为 3台主节点(master)和3台工作节点(worker),而192.168.1.1为网关路由器地址,所以从2开始,2-4为master,5-7为worker

    192.168.1.2/192.168.1.3/192.168.1.4/192.168.1.5/192.168.1.6/192.168.1.7

    第12步骤部署CoreDNS部分出现了containerd无法拉取私库里面的镜像的问题。

    首先我在自己的私库Harbor是存在沙箱镜像pause:3.2 ,我使用docker能正常拉取,说明我的Harbor是没有问题的。docker是由/etc/docker/daemon.json  insecure-registries :["192.168.1.8"]进行配置的。

    当我安装高塔老师的步骤执行到:

    $ kubectl get pods -l k8s-app=kube-dns -n kube-system --kubeconfig=admin.kubeconfig

    一直会出现容器正在创建的状态,于是通过describe看一下具体问题。

    执行如下命令后,具体错误为:

    $ kubectl describe pod coredns-xxxx-xxx  -n kube-system --kubeconfig=admin.kubeconfig

    第一个问题: 出现了kubelet去k8s.gcr.io/pause:3.5拉取镜像了,并没有去私库拉取镜像,导致沙箱镜像无法下载,也就是无法运行coreDNS镜像。

    而我在内网的harbor pause镜像地址为: 192.168.1.8/kubernetes/pause:3.2

    那如何解决这个问题呢? 

    我一开始以为是出现的错误是由于kubelet的配置所在,所以重新找到高塔老师的文档,又看了一遍,没有发现蛛丝马迹。

    然后又找到了containerd的官方文档,发现在默认生成的/etc/containerd/config.toml中包含了要拉取sandbox_image地址,也就是说containerd告诉kubelet去gcr.io拉取镜像,我们通过修改这个地址来让kubelet去我们的私库拉取镜像。

    $ containerd config default > /etc/containerd/config.toml
    1. [plugins]
    2. [plugins."io.containerd.grpc.v1.cri"]
    3. sandbox_image="k8s.gcr.io/pause:3.5"

    下面是修改后的配置,然后重启三个worker节点的containerd

    1. [plugins]
    2. [plugins."io.containerd.grpc.v1.cri"]
    3. sandbox_image="192.168.1.8/kubernetes/pause:3.2"
    $ systemctl restart containerd

    第二个问题:我继续通过kubectl descirbe命令来查看情况,这次的结果是地址确实变化了,但是还是没有从私库上拉取下来。

    我找了很多文档,包括github的issues和discussions有不少人都遇到了这个问题,但是都没有一个详细的解决办法,尤其是看了这篇手册https://github.com/containerd/containerd/blob/release/1.5/docs/cri/registry.md,按照手册配置了半天,没有任何效果,有点浪费时间。

    总结一下:无外乎就是修改config.toml里面的 insecure_skip_verify及在[plugins."io.containerd.grpc.v1.cri".registry]新增mirrors、auths或configs,但结果都是无效的。

    并且issues的人 说ctr无法使用cri的config,也就是说config.toml是cri的配置,可以通过:

    $ ctr images pull --plain-http  192.168.1.8/kubernetes/pause:3.2

    进行拉取,但是kubelet并不认识ctr,是因为ctr没有实现cri接口,具体表现为:

    1. $ ctr images pull --plain-http 192.168.1.8/kubernetes/pause:3.2
    2. $ ctr images ls //我们发现就有了这个镜像,但是当我们执行
    3. $ crictl images //并没有发现刚刚拉取下来的pause:3.2镜像

    也就是还是无法让kubelet从私库拉取pause:3.2镜像的问题都是如下错误:

    Failed CreatePodSandBox 7s(x22 over 4m42s) kubelet Failed to create pod sandbox: rpc error: code=Unknown desc = failed to get sandbox image "192.168.1.8/kubernetes/pause:3.2" :failed to pull image "192.168.1.8/kubernetes/pause:3.2": failed to pull and unpack image "192.168.1.8/kubernetes/pause:3.2": failed to resolve reference "192.168.1.8/kubernetes/pause:3.2": failed to do request: Head "https://192.168.1.8/v2/kubernetes/pause/manifests/3.2": dial tcp 192.168.1.8:443: connect:connection refused 

    我重新又找文档,又鏖战了一天的时间,发现在containerd:配置hosts 中有一个Bypass TLS Verification Example,我按照教程立刻配了一下,问题立刻解决。

    解决方法为:

    1. $ tree /etc/containerd/certs.d
    2. /etc/containerd/certs.d
    3. └── docker.io
    4. └── hosts.toml
    1. $ cat /etc/containerd/certs.d/docker.io/hosts.toml
    2. server = "https://docker.io"
    3. [host."http://192.168.1.8:80"]
    4. capabilities = ["pull", "resolve","push"]
    5. skip_verify = true

    还有就是修改你的config.toml中的192.168.1.8为docker.io ,对,你没看错,一定要修改这里。

    1. [plugins]
    2. [plugins."io.containerd.grpc.v1.cri"]
    3. sandbox_image="docker.io/kubernetes/pause:3.2"

    这是因为containerd已经设置了hosts,你可以理解为拦截器,将访问docker.io的链接替换为上面咱们hosts.toml里面设置的私库地址。

    以后你的所有的私库中的镜像地址都不是 192.168.1.8/repo/image:version ,而是docker.io/repo/image:version 

    也就是说更改的是你的yaml文件里面image镜像地址,改为docker.io/repo/image:version  ,但是harbor不用任何更改。

    $ systemctl restart containerd

    别忘重启所有worker节点。

    参考链接:

    1.高塔老师:kubernetes the hard way 

    GitHub - kelseyhightower/kubernetes-the-hard-way: Bootstrap Kubernetes the hard way on Google Cloud Platform. No scripts.

    2.containerd: 配置registry 

    https://github.com/containerd/containerd/blob/release/1.5/docs/cri/registry.md 

    3.containerd:配置hosts

     https://github.com/containerd/containerd/blob/release/1.5/docs/hosts.md

  • 相关阅读:
    基于操作系统讨论Java线程与进程、浅谈Go的线程与管程
    DRF中的模型序列化是什么
    C语言程序编译全流程,从源代码到二进制
    SQL Alias 别名
    mac安装mysql教程(docker版本)(sql 小虚竹)
    leetcode解题思路分析(一百三十一)1103 - 1109 题
    Three.js相机模拟
    Spring IOC核心功能快速入门
    ​力扣解法汇总1374-生成每种字符都是奇数个的字符串
    Taurus.MVC WebAPI 入门开发教程1:框架下载环境配置与运行(含系列目录)。
  • 原文地址:https://blog.csdn.net/u010566813/article/details/125990298