给kubernetes1.28集群配置网络,使用Flannel。但是运行相应kube-flannel.yml无法拉去镜像,导致flannel配置失败。
使用
kubectl describe pod kube-flannel-ds-f8gxl -n kube-flannel
查看pod信息,结果如下:
kube-flannel.yml来源:GitHub - flannel-io/flannel: flannel is a network fabric for containers, designed for Kubernetes
原因自然是国内无法直接连接国外镜像源,直接下载。
解决思路
找到国内对应的镜像源,替换yml文件的镜像地址。或者是找到相应的镜像离线压缩包资源,导入集群镜像仓库。因为我找了好久都没找到国内的镜像地址(如果有找到的,可以教教我,评论区告诉我-_-)。所以我使用的是第二种方式,找到相应的镜像离线压缩包。
解决方法一:
通过DockerHub离线下载网网址(网址若是失效,可以查看本人的资源列表,压缩包已经上传),下载下面两个包:
flannel/flannel:v0.25.1
flannel/flannel-cni-plugin:v1.4.0-flannel1
得到这两个tar.gz文件。将文件上传到master节点。接着进行如下操作:
1.1使用docker工具,将两者导入为本地镜像
docker load --input /path/to/tar
但是,在1.24之后的版本之后kubelet 彻底移除了dockershim,改为默认使用Containerd。在本地有docker镜像,yml修改为本地配置镜像地址,也无法使用这一镜像。还需要继续操作。
1.2将docker镜像save为tar(因为ctr无法直接import这两个镜像压缩包,只好借助docker转一手)
#docker -o tar压缩包名要保存的路径 本地镜像
docker save -o flannel-flannel-cni-plugin-v1.4.1-flannel1-amd64.tar flannel/flannel-cni-plugin:v1.4.1-flannel1
docker save -o flannel-flannel-v0.25.1-amd64.tar flannel/flannel:v0.25.1
操作成功,在当前文件夹下能看到这两个tar文件。
1.3将tar镜像压缩包,导入到containerd的k8s.io命名空间中
#-n后面加命名空间名称
ctr -n k8s.io images import flannel-flannel-v0.25.1-amd64.tar
ctr -n k8s.io images import flannel-flannel-cni-plugin-v1.4.1-flannel1-amd64.tar
操作成功,显示如下:
查看k8s.io下面是否有flannel的镜像文件
注:Kubernetes 下使用的 containerd 默认命名空间是k8s.io,只有导入这个命名空间,kubelet才能从本地拉取这个镜像文件。本文kubernetes集群是1.28的,所以不再是默认地从本地docker镜像里获取镜像,而是从containerd的本地镜像里面获取。如果是1.24之前的版本,默认仍是docker,那么1.2以及1.3的操作是不需要的,kubelet能直接拉取本地docker镜像。
1.4修改kube-flanne.yml
将开头提及的kube-flannel.yml下载到本地后,修改所有image键值对,并添加镜像拉取策略。修改内容如下:
(vim进入后,:set number)
:wq保存退出。
1.5在每一个工作节点也需要将tar上传,并导入到containerd的本地镜像,不然分派到工作节点的pod无法获得初始化的镜像
1.6删除集群内的相关资源,重新运行kube-flannel.yml文件
#删除资源
kubectl delete -f kube-flannel.yml
#重新运行
kubectl apply -f kube-flannel.yml
发现pod能够正常拉取镜像
弊端:这种方法虽然能够解决问题,但是针对每一个节点,都需要导入本地镜像十分麻烦,个人建议为k8s集群搭建相应的私人镜像仓库,将镜像文件上传到镜像仓库,kubelet从镜像仓库拉取更为合理,见解决办法二。
解决办法二:k8s1.28,为集群配置harbor镜像仓库,上传镜像,从仓库拉取相关镜像
针对1.24之前的版本,网上有许多配置harbor镜像仓库的办法,重点是/etc/docker/daemon.json文件,这里不再赘述。
1.24之后 kubelet 彻底移除dockershim,改为默认Containerd。containerd 不能像docker一样 “docker login 私人镜像仓库地址” 登录到镜像仓库,即便是本地docker登录harbor ,集群仍是无法从harbor拉取到镜像。这里需要修改配置文件。
本文的containerd为1.6,按照网上常规的修改/etc/containerd/config.toml文件的方式不再被推荐。
参考官方文档——containerd/docs/cri/config.md at main · containerd/containerd · GitHub
配置相应的hosts.toml,为集群设置Harbor镜像仓库
步骤如下(2.1-2.4操作每一台机器都要进行!!!):
2.1修改/etc/containerd/config.toml
2.2自定义证书
绕过TLS验证(containerd/docs/hosts.md at main · containerd/containerd · GitHub)
#创建文件目录 IP和端口替换为你的私人镜像仓库的IP以及对外开放的端口
mkdir -p /etc/containerd/certs.d/192.168.12.34:5000
#创建-打开hosts.toml
vi /etc/containerd/certs.d/192.168.12.34:5000/hosts.toml
#想hosts.toml中写入以下内容 IP和端口和前面一样进行替换
server = "http://192.168.12.34:5000"
[host."192.168.12.34:5000"]
capabilities = ["pull", "resolve", "push"]
skip_verify = true
2.3重新启动containerd
systemctl daemon-reload
systemctl restart containerd
2.4完成上述操作,可能crictl以及集群yml文件仍然无法正常从私人镜像仓库拉取镜像
可能报错如下:
解决操作:
vim /etc/crictl.yaml
将runtime以及image endpoint均替换为"unix:///run/containerd/containerd.sock"
:wq保存退出
2.5测试将镜像推送至harbor
使用docker上传(传统操作)
docker tag flannel/flannel-cni-plugin:v1.4.1-flannel1 IP:PORT/flannel/flannel-cni-plugin:v1.4.1-flannel1
docker push IP:PORT/flannel/flannel-cni-plugin:v1.4.1-flannel1
另一个镜像也是相同操作(如果报错,可能是需要先在harbor上创建一个flannel的project)。
2.6修改kube-flannel.yml文件
:wq保存退出。重新删除并运行kube-flannel.yml发现成功拉取镜像(可以通过kubectl describe详查pod)。
总结
方法二比方法一更为正式,毕竟配置集群总该要配置私人镜像,省去了每一个节点导入镜像的操作。要是还未配置私人镜像仓库,使用方法一也可行。
其余知识点:/etc/containerd/config.toml配置文件对ctr不生效,这个配置文件由CRI使用,即对crictl生效。
如果你的ctr images pull总是报错: http: server gave HTTP response to HTTPS client。可能这并不是你的配置出错,而是你需要在后面pull操作后加上--plain-http参数。表示你当前client与镜像仓库之间接受http形式的通信。或者是使用自定义的hosts-dir来指定配置文件。
ctr images pull IP:PORT/library/service:v1.0.0 --plain-http
ctr images pull IP:PORT/library/service:v1.0.0 --hosts-dir "/etc/containerd/certs.d"
参考
containerd/docs/hosts.md at main · containerd/containerd · GitHub
containerd/docs/cri/config.md at main · containerd/containerd · GitHub