背景
在云原生开发中,Kind(Kubernetes in Docker)是本地测试集群的热门工具。但在国内网络环境下,由于镜像拉取问题(特别是kindnet网络组件),经常导致节点长期处于NotReady状态。本文将记录一次典型的问题解决过程。
环境信息
-
主机:腾讯云CVM
-
工具版本:
- Kind v0.18.0
- Kubernetes v1.26.3
- Containerd 1.6.19
- Docker 20.10.21
-
网络环境:
- 已配置腾讯云Docker镜像加速源
{ "registry-mirrors":["https://mirror.ccs.tencentyun.com"] }
问题现象
-
使用
kind create cluster创建集群后,节点持续NotReady -
关键错误日志:
kubectl describe pod -n kube-system -l app=kindnetEvents: Warning Failed 35s kubelet Failed to pull image "docker.io/kindest/kindnetd:...": dial tcp xx.xx.xx.xx:443: i/o timeout -
矛盾点:手动执行
docker pull可以拉取 docker.io/kindest/kindnetd:xxx 镜像
问题定位过程
-
初步排查:
- 发现Kind使用独立Containerd实例
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME xxx-control-plane NotReady control-plane 37m v1.26.3 172.18.0.2 <none> Ubuntu 22.04.2 LTS 5.4.0-139-generic containerd://1.6.19-46-g941215f49 -
深入分析:
# 进入Kind节点检查 docker exec -it kind-control-plane crictl images- 发现节点内确实缺失
kindnetd镜像
- 发现节点内确实缺失
-
关键结论:
- Kind的Containerd未继承主机Docker的镜像配置
解决方案
核心思路:由于主机docker pull是能够拉取到正确镜像的,所以考虑绕过网络拉取,直接加载镜像到Kind节点
操作步骤
-
导出镜像(在宿主机操作):
docker pull kindest/kindnetd:v20230330-48f316cd # 这里如果没有v20230330-48f316cd版本的镜像,需要使用docker tag先给拉取的kindnetd镜像新增一个tag。使用 docker tag <imageId> kindest/kindnetd:v20230330-48f316cd docker save kindest/kindnetd:v20230330-48f316cd > kindnetd.tar -
导入Kind节点:
kind load image-archive kindnetd.tar --name <cluster-name> -
修改DaemonSet配置:
kubectl -n kube-system edit ds kindnetspec: template: spec: containers: - name: kindnet image: docker.io/kindest/kindnetd:v20230330-48f316cd # 去掉后面的 sha256 值 imagePullPolicy: IfNotPresent # 默认应该就是这个,如果不是修改成这个配置就行了。这个配置表示本次有镜像后就不会去远程拉取 -
重启Pod:
kubectl -n kube-system delete pod -l app=kindnet
结果验证
kubectl get nodes
NAME STATUS ROLES AGE VERSION
kind-control-plane Ready control-plane 5m v1.26.3
经验总结
-
Kind网络架构认知:
- Kind使用容器化节点,每个节点有独立的Containerd
- 主机Docker配置不会自动继承到集群内