kind集群需自定义配置启用containerd socket、显式指定kubeconfig路径、预装适配ci的cni;ci中应缓存kind二进制与node镜像,按github_run_id命名集群并确保跨job镜像加载一致性。

用 kind create cluster 启动最小可用集群
Kind 本质是把 K8s 组件跑在 Docker 容器里,所以它不依赖虚拟机或外部云,适合 CI 中快速启停。但默认命令 kind create cluster 创建的集群没开 containerd socket 挂载、没暴露 kubeconfig 路径、也不带预装 CNI,CI 里直接用会卡在 Pod 无法 Ready。
- CI 中务必加
--config指定自定义配置,至少声明containerdConfigPatches和nodes.role - 别信默认
~/.kube/config—— CI 环境常多用户/无家目录,必须用--kubeconfig显式输出路径,比如--kubeconfig /tmp/kind-config - Go 测试若需访问集群,得在
os.Setenv("KUBECONFIG", "/tmp/kind-config")后再初始化 clientset,否则rest.InClusterConfig()会失败
Go 单元测试里加载 kind 集群要绕过权限和延迟问题
本地开发时 kind 启动快,但 CI(尤其是 GitHub Actions)上 Docker daemon 响应慢、kubectl wait 容易超时、非 root 用户还可能被拒绝挂载 /var/run/docker.sock。
- 用
kind export kubeconfig --name my-cluster --kubeconfig /tmp/kind-kubeconfig替代反复调kind get kubeconfig,避免权限抖动 - 等待 control-plane Ready 不要用
kubectl wait --for=condition=Ready node --all,改用kind get nodes | grep control-plane | grep -q "Ready"更轻量 - Go 测试中别在
TestMain里同步拉起集群 —— 失败时没清理逻辑;建议提前在 CI step 里建好,测试只负责读 config 和发请求
kind 配置里 containerd 和 CNI 的关键字段不能省
Go 应用若用 client-go 创建 DaemonSet 或使用 hostNetwork,没配对 containerd 和 CNI 就会卡在 ContainerCreating,错误日志里常见 failed to get sandbox IP address 或 cni plugin not initialized。
- 必须在 kind config YAML 中显式写
containerdConfigPatches,补上[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]避免镜像拉取失败 - CNI 插件不能只靠 kind 默认的
kindnetd—— CI 容器环境常禁用 IPv6,得加extraMounts把宿主机/etc/resolv.conf挂进去,否则 Pod DNS 解析失败 - Go 构建镜像若用
FROM golang:alpine,得在 kind node image 里提前apk add ca-certificates,否则 client-go 访问 apiserver 会报x509: certificate signed by unknown authority
GitHub Actions 中复用 kind 集群提升 Go CI 速度
每次跑测试都 kind create + kind delete,光启动就占 40 秒以上,Go 模块又常有多个子测试并行跑,实际浪费大量资源。
立即学习“go语言免费学习笔记(深入)”;
- 用
actions/cache缓存kind二进制和 base node image(如kindest/node:v1.28.0),跳过重复下载 - 集群名按
GITHUB_RUN_ID命名,配合if: ${{ !cancelled() }}在 job 结尾执行kind delete cluster --name ${{ github.run_id }},避免残留 - Go 测试前用
kubectl apply -f ./test-manifests预装 CRD 或 Secret,比在每个 test 里用dynamicclient创建更快更稳
真正麻烦的是跨 job 共享集群状态 —— 比如 build job 生成镜像后,test job 要拉它,得用 kind load docker-image 并确保两个 job 运行在同一 runner 上,这点很容易被忽略










