云原生本地开发避坑记:Kind集群NotReady问题

347 阅读2分钟

背景

在云原生开发中,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"]
    }
    

问题现象

  1. 使用kind create cluster创建集群后,节点持续NotReady

  2. 关键错误日志:

    kubectl describe pod -n kube-system -l app=kindnet
    
    Events:
      Warning  Failed     35s   kubelet  Failed to pull image "docker.io/kindest/kindnetd:...": 
      dial tcp xx.xx.xx.xx:443: i/o timeout
    
  3. 矛盾点:手动执行docker pull可以拉取 docker.io/kindest/kindnetd:xxx 镜像


问题定位过程

  1. 初步排查

    • 发现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
    
  2. 深入分析

    # 进入Kind节点检查
    docker exec -it kind-control-plane crictl images
    
    • 发现节点内确实缺失kindnetd镜像
  3. 关键结论

    • Kind的Containerd未继承主机Docker的镜像配置

解决方案

核心思路:由于主机docker pull是能够拉取到正确镜像的,所以考虑绕过网络拉取,直接加载镜像到Kind节点

操作步骤
  1. 导出镜像(在宿主机操作):

    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
    
  2. 导入Kind节点

    kind load image-archive kindnetd.tar --name <cluster-name>
    
  3. 修改DaemonSet配置

    kubectl -n kube-system edit ds kindnet
    
    spec:
      template:
        spec:
          containers:
          - name: kindnet
            image: docker.io/kindest/kindnetd:v20230330-48f316cd # 去掉后面的 sha256 值
            imagePullPolicy: IfNotPresent  # 默认应该就是这个,如果不是修改成这个配置就行了。这个配置表示本次有镜像后就不会去远程拉取
    
  4. 重启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

经验总结

  1. Kind网络架构认知

    • Kind使用容器化节点,每个节点有独立的Containerd
    • 主机Docker配置不会自动继承到集群内

延伸阅读