用Docker容器运行本地Kubernetes集群
kind(Kubernetes IN Docker)把每个 Kubernetes 节点都跑成一个 Docker 容器,从而在单机上拉起多节点的真实集群。它最初是 Kubernetes 官方为自身 e2e 测试而开发的工具,如今是 CI 流水线与本地验证的事实标准之一。
与 minikube 的区别:
| 对比项 | kind | minikube |
|---|---|---|
| 节点实现 | 每个节点是一个 Docker 容器 | 默认单节点容器/虚拟机 |
| 多节点 | 原生支持,配置驱动 | 支持,但资源开销更大 |
| 启动速度 | 快,适合频繁创建销毁 | 相对较慢 |
| 插件生态 | 无内置插件,需自行部署 | 内置 Dashboard/Ingress 等插件 |
| 定位 | CI、e2e 测试、精确复现 | 本地开发体验 |
kind 的节点镜像(kindest/node)里已经预装好 kubelet、containerd 与 kubeadm,集群通过 kubeadm 在容器内初始化,因此它跑的是货真价实的 Kubernetes,而不是精简模拟。
# macOS / Linux (Homebrew)
brew install kind
# Go 安装(可指定版本)
go install sigs.k8s.io/kind@v0.24.0
# 下载二进制(Linux)
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.24.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
# macOS 二进制
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.24.0/kind-darwin-arm64
chmod +x ./kind && sudo mv ./kind /usr/local/bin/kind
# Windows
choco install kind
kind version
前置条件:宿主机需安装 Docker(或 Podman),且当前用户有权限访问 Docker 守护进程。
kind [command]
kind create cluster 创建集群
kind delete cluster 删除集群
kind get clusters 列出集群
kind get nodes 列出集群节点(容器名)
kind get kubeconfig 输出集群的 kubeconfig
kind export kubeconfig 导出并合并 kubeconfig
kind export logs 导出节点日志,排障必备
kind load docker-image 把宿主机镜像加载进集群
kind load image-archive 把镜像归档文件加载进集群
kind build node-image 自行构建节点镜像
kind completion 生成 shell 自动补全
kind version 查看版本
# 最简创建(集群名默认为 kind)
kind create cluster
# 指定名称与节点镜像版本
kind create cluster --name dev --image kindest/node:v1.31.0
# 使用配置文件
kind create cluster --config kind-config.yaml
# 创建后保留节点容器,便于事后调试
kind create cluster --name debug --retain
# 把 kubeconfig 写到独立文件,避免污染默认上下文
kind create cluster --name dev --kubeconfig ./dev-kubeconfig
# 等待创建完成
kind create cluster --name dev --wait 120s
多节点 + 端口映射 + 节点标签的典型配置:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: dev
networking:
apiServerAddress: "127.0.0.1"
apiServerPort: 6443
podSubnet: "10.244.0.0/16"
serviceSubnet: "10.96.0.0/12"
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
# 把节点容器端口映射到宿主机,创建后不可修改
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
- role: worker
- role: worker
启用特性门控与运行时配置:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
DynamicResourceAllocation: true
runtimeConfig:
api/alpha: "true"
# 查看与切换
kind get clusters
kubectl config get-contexts
kubectl config use-context kind-dev
# 节点与 kubeconfig
kind get nodes --name dev
kind get kubeconfig --name dev
kind export kubeconfig --name dev --kubeconfig ./dev-config
# 节点本身就是容器,可以直接用 docker 查看
docker ps --filter "label=io.x-k8s.kind.cluster=dev"
docker exec -it dev-control-plane bash
# 删除
kind delete cluster --name dev
kind delete clusters --all
# 导出日志(集群异常时的第一手资料)
kind export logs --name dev ./kind-logs
# 直接加载宿主机 Docker 中的镜像
kind load docker-image my-app:latest --name dev
# 从归档文件加载
docker save my-app:latest -o my-app.tar
kind load image-archive my-app.tar --name dev
# 多节点集群会加载到所有节点
kind load docker-image my-app:latest --name dev --nodes dev-worker,dev-worker2
配套的 Pod 必须设置拉取策略,否则 kubelet 仍会去远程仓库找同名镜像:
spec:
containers:
- name: app
image: my-app:latest
imagePullPolicy: IfNotPresent # 或 Never
# 1. 用带 extraPortMappings 的配置创建集群(见上文)
# 2. 部署适配 kind 的 ingress-nginx
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
# 3. 等待就绪
kubectl wait --namespace ingress-nginx \
--for=condition=ready pod \
--selector=app.kubernetes.io/component=controller \
--timeout=90s
# 4. 现在可以通过 http://localhost 访问 Ingress
# LoadBalancer 类型 Service 需要额外组件
# 方案一:MetalLB
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.14.8/config/manifests/metallb-native.yaml
# 方案二:cloud-provider-kind(为 kind 提供云控制器)
# 创建 -> 加载镜像 -> 部署 -> 测试 -> 销毁
kind create cluster --name ci --config kind-config.yaml
kind load docker-image my-app:${GIT_SHA} --name ci
kubectl apply -k overlays/test
kubectl rollout status deployment/my-app --timeout=120s
kubectl get pods -o wide
kind delete cluster --name ci
kindest/node 镜像的版本要与 kind 版本匹配。每个 kind 版本都有对应的默认节点镜像,跨版本乱用可能初始化失败;不确定时省略 --image 用默认值。extraPortMappings 只在创建集群时生效,创建后无法修改。要改端口必须删除集群重建,这是最常见的返工点。kind load docker-image 加载的镜像必须配合 imagePullPolicy: IfNotPresent 或 Never。默认的 Always 会让 kubelet 无视本地镜像去远程拉取,直接 ImagePullBackOff。--kubeconfig 指定独立文件,或用 kind export kubeconfig 后再手工合并。kubectl get nodes 看到的节点名对应一个 Docker 容器,容器重启等同于节点重启,集群数据可能丢失。<pending>。kind delete cluster 会一并删除节点容器和集群数据,--retain 创建的节点容器不会被自动清理,需手工 docker rm。kubeadm 或托管 Kubernetes 服务。kubectl — Kubernetes集群管理工具minikube — 本地Kubernetes开发环境kubeadm — Kubernetes集群安装工具k9s — 终端下的 Kubernetes 管理 UI