Ubuntu 上使用 kind 快速搭建轻量级 Kubernetes 本地测试环境
在本地开发环境中快速搭建一个轻量级的 Kubernetes 集群进行测试和学习是很多开发者和运维工程师的刚需。传统的 Minikube 或 kubeadm 方案要么资源占用大要么配置复杂。本文将详细介绍如何在 Ubuntu 系统上安装和使用kind (Kubernetes IN Docker)这是一个使用 Docker 容器作为“节点”来运行 Kubernetes 集群的工具。它启动速度快、资源消耗低非常适合 CI/CD 流水线、本地功能测试和学习 Kubernetes 核心概念。通过本文你将掌握从零开始在 Ubuntu 上完整部署一个可用的 kind 集群的全过程包括 Docker 安装、kind 安装、集群创建与管理以及常见问题的排查思路。无论你是 Kubernetes 新手还是寻求更高效本地测试方案的老手都能从中获得可直接复用的实践指南。1. 背景与核心概念在深入实操之前我们有必要理解 kind 是什么以及它解决了什么问题。1.1 什么是 kindkind是一个使用 Docker 容器作为“节点”来运行本地 Kubernetes 集群的工具。它的名字来源于 “Kubernetes IN Docker”。你可以把它想象成一个专门为 Kubernetes 定制的、更轻量的 Docker Compose 项目其“服务”就是 Kubernetes 的各个组件如 kube-apiserver, kube-controller-manager 等而每个“节点”控制平面和工作节点都运行在一个独立的 Docker 容器中。1.2 kind 解决了什么问题极致的轻量与快速相比于需要启动完整虚拟机的 Minikubekind 直接利用宿主机的 Docker 运行时集群的启动和销毁通常在几十秒内完成。环境一致性由于节点是容器你可以轻松地指定 Kubernetes 版本、容器运行时如 containerd的版本确保本地测试环境与生产环境高度一致。CI/CD 友好在 CI 流水线中例如 GitHub Actions, GitLab CI可以快速创建和销毁一个干净的 Kubernetes 集群来运行集成测试而无需复杂的虚拟机管理。多集群管理可以轻松地在同一台机器上运行多个相互隔离的 Kubernetes 集群用于测试多集群场景或不同版本。学习与开发对于学习者它降低了入门 Kubernetes 的门槛对于开发者它提供了完美的本地沙箱环境。1.3 kind 与 Minikube、kubeadm 的对比特性kindMinikubekubeadm节点类型Docker 容器虚拟机默认、容器物理机/虚拟机启动速度极快秒级较慢依赖虚拟机启动慢需初始化系统资源占用很低共享宿主机内核高需要分配虚拟机资源高需要完整的操作系统集群配置通过 YAML 配置文件通过命令行参数或配置文件通过复杂的配置文件和命令适用场景本地开发、CI/CD、快速测试本地开发、学习功能更全生产环境、自定义集群搭建网络使用 Docker 网络简单可能需要处理虚拟机网络需要配置 CNI 网络插件简单来说如果你追求的是快速、轻量、一次性的测试环境kind 是绝佳选择。如果你需要模拟更接近生产环境的特性如 LoadBalancer 类型的 ServiceMinikube 的虚拟机驱动可能更合适。2. 环境准备与版本说明在开始安装 kind 之前我们需要确保基础环境就绪。本文以Ubuntu 22.04 LTS为例其他版本 Ubuntu 或 Debian 系发行版步骤类似。2.1 系统要求操作系统Ubuntu 20.04 / 22.04 / 24.04 或更高版本本文使用 Ubuntu 22.04 LTS。架构x86_64 / amd64 或 arm64。内核建议使用较新的稳定内核。权限需要sudo权限来安装软件包。2.2 核心依赖Dockerkind 的核心是 Docker因此我们必须先安装并正确配置 Docker 环境。重要提示如果你使用 Windows 的 WSL2 来运行 Ubuntu并且已经安装了 Docker Desktop for Windows 并启用了 WSL2 集成那么 Docker 环境可能已经就绪。你可以通过在 WSL2 的 Ubuntu 终端中运行docker version来验证。如果已安装可以跳过 2.3 节。2.3 安装 Docker Engine我们将使用 Docker 官方提供的便捷脚本来安装最新稳定版的 Docker Engine。更新系统包索引并安装必要工具sudo apt update sudo apt install -y ca-certificates curl gnupg lsb-release添加 Docker 的官方 GPG 密钥sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg设置 Docker 的稳定版仓库echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null更新包索引并安装 Docker Enginesudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin验证 Docker 安装 安装完成后运行以下命令检查 Docker 版本并运行一个测试容器docker --version sudo docker run hello-world如果看到 “Hello from Docker!” 等信息说明 Docker 安装成功。可选但推荐管理 Docker 作为非 root 用户 默认情况下Docker 命令需要sudo。为了避免每次输入sudo可以将当前用户加入docker组。sudo groupadd docker # 如果docker组已存在会提示可忽略 sudo usermod -aG docker $USER重要执行此命令后你需要完全注销并重新登录或者重启系统才能使组更改生效。之后你就可以直接使用docker命令了。 重新登录后验证docker run hello-world # 应该不再需要sudo3. 安装 kind安装好 Docker 后安装 kind 就非常简单了。kind 是一个单独的二进制文件我们可以通过多种方式获取。3.1 使用 curl 下载二进制文件推荐这是最直接的方法从 kind 的 GitHub 发布页下载最新版本。下载最新的 kind 二进制文件 访问 kind 官方 GitHub Releases 查看最新版本号例如v0.23.0。然后执行以下命令请将{KIND_VERSION}替换为实际版本号。# 例如下载 v0.23.0 KIND_VERSIONv0.23.0 curl -Lo ./kind https://kind.sigs.k8s.io/dl/${KIND_VERSION}/kind-linux-amd64对于 ARM64 架构如 Apple Silicon Mac 或 Raspberry Pi使用kind-linux-arm64。赋予执行权限并移动到 PATHchmod x ./kind sudo mv ./kind /usr/local/bin/验证安装kind version输出应类似kind v0.23.0 go1.20.5 linux/amd643.2 使用包管理器安装你也可以使用系统的包管理器但仓库中的版本可能不是最新的。使用 Homebrew (Linux/macOS)brew install kind使用 Chocolatey (Windows)choco install kind对于 Ubuntu官方并未提供 APT 仓库因此推荐使用上述的 curl 方法。4. 创建你的第一个 kind 集群安装完成后创建一个单节点集群包含一个控制平面节点只需要一条命令。4.1 创建默认集群运行以下命令kind 会自动下载所需的节点镜像并创建集群。kind create cluster输出解析Creating cluster kind ... ✓ Ensuring node image (kindest/node:v1.29.2) ✓ Preparing nodes ✓ Writing configuration ✓ Starting control-plane ️ ✓ Installing CNI ✓ Installing StorageClass Set kubectl context to kind-kind You can now use your cluster with: kubectl cluster-info --context kind-kind kubectl get nodes Have a nice day! 这条命令完成了以下几件事创建了一个名为kind的集群默认名称。拉取了 Kubernetes 节点镜像kindest/node:v1.29.2版本可能不同。启动了一个 Docker 容器作为 Kubernetes 控制平面节点。自动配置了kubectl的上下文context指向这个新集群。4.2 验证集群状态使用kubectl与集群交互。如果你的系统没有kubectl需要先安装。安装 kubectl如果未安装# 下载最新稳定版 curl -LO https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl # 赋予权限并移动 chmod x kubectl sudo mv kubectl /usr/local/bin/ # 验证 kubectl version --client检查集群节点kubectl get nodes输出应类似NAME STATUS ROLES AGE VERSION kind-control-plane Ready control-plane 95s v1.29.2可以看到一个名为kind-control-plane的节点已经处于Ready状态。查看集群信息kubectl cluster-info4.3 使用配置文件创建自定义集群默认创建的是单节点集群。kind 的强大之处在于可以通过 YAML 配置文件定义复杂的集群拓扑。创建一个配置文件例如kind-config.yaml# kind-config.yaml kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 # 指定 Kubernetes 版本需确保 kind 有对应的节点镜像 nodes: - role: control-plane image: kindest/node:v1.28.0 # 指定节点镜像版本 - role: worker image: kindest/node:v1.28.0 - role: worker image: kindest/node:v1.28.0这个配置定义了一个包含 1 个控制平面节点和 2 个工作节点的集群并指定使用 Kubernetes v1.28.0。使用配置文件创建集群kind create cluster --name multi-node-cluster --config kind-config.yaml这里我们通过--name指定了集群名称通过--config指定了配置文件。验证多节点集群kubectl get nodes --context kind-multi-node-cluster输出应显示三个节点NAME STATUS ROLES AGE VERSION multi-node-cluster-control-plane Ready control-plane 2m v1.28.0 multi-node-cluster-worker Ready none 2m v1.28.0 multi-node-cluster-worker2 Ready none 2m v1.28.05. kind 集群的日常操作与管理创建集群后你需要知道如何与之交互。5.1 切换集群上下文如果你有多个 kind 集群或其他 Kubernetes 集群kubectl需要通过上下文来知道操作哪个集群。列出所有上下文kubectl config get-contexts切换到指定的 kind 集群kubectl config use-context kind-multi-node-cluster # 使用你的集群名查看当前上下文kubectl config current-context5.2 将本地镜像加载到 kind 集群在本地开发时你经常需要将自己构建的 Docker 镜像用于测试。由于 kind 的节点是独立的容器你需要将镜像从本地 Docker 守护进程“加载”到 kind 集群的节点中。假设你本地有一个名为my-app:latest的镜像。# 语法kind load docker-image image-name --name cluster-name kind load docker-image my-app:latest --name kind这条命令会将本地的my-app:latest镜像加载到名为kind的集群的所有节点中。之后在集群的 Pod 配置中就可以直接使用image: my-app:latest了。5.3 访问集群服务端口映射在 kind 中如果需要从宿主机访问集群内 Service 的 NodePort 或者需要将服务暴露到宿主机可以在配置文件中设置extraPortMappings。修改kind-config.yamlkind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane image: kindest/node:v1.28.0 # 端口映射配置 extraPortMappings: - containerPort: 80 # 容器节点内的端口 hostPort: 8080 # 宿主机上的端口 listenAddress: 0.0.0.0 # 可选绑定到所有接口 protocol: tcp # 可选tcp 或 udp创建集群后在集群内创建一个 NodePort 类型 Service其 nodePort 为 80那么你就可以通过宿主机的localhost:8080访问该服务。5.4 查看集群日志如果需要排查集群组件的问题可以查看具体节点的日志。首先找到节点对应的容器名。# 列出所有 kind 相关的容器 docker ps --filter “labelio.x-k8s.kind.cluster” --format “table {{.Names}}” # 进入控制平面节点容器查看 kube-apiserver 日志 docker exec -it kind-control-plane bash # 在容器内 journalctl -u kube-apiserver -f # 或者直接查看日志文件 tail -f /var/log/kubernetes/kube-apiserver.log5.5 删除集群当测试完成可以轻松删除集群以释放资源。# 删除指定集群 kind delete cluster --name multi-node-cluster # 删除默认集群名为 kind kind delete cluster删除操作会停止并移除所有相关的 Docker 容器、网络和存储卷。6. 完整实战案例在 kind 集群中部署一个 Nginx 应用让我们通过一个完整的例子巩固对 kind 的使用。目标在 kind 集群中部署 Nginx并通过 NodePort 在宿主机访问。6.1 创建带有端口映射的集群首先创建一个允许从宿主机访问的集群。创建nginx-kind-cluster.yamlkind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane image: kindest/node:v1.29.2 extraPortMappings: - containerPort: 30080 # 我们将把 Service 的 nodePort 设为此值 hostPort: 8080 protocol: tcp创建集群kind create cluster --name nginx-demo --config nginx-kind-cluster.yaml6.2 部署 Nginx Deployment 和 Service创建一个名为nginx-deployment.yaml的文件apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.25-alpine # 使用一个轻量级版本 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-service spec: type: NodePort selector: app: nginx ports: - protocol: TCP port: 80 # Service 的端口 targetPort: 80 # Pod 容器的端口 nodePort: 30080 # 映射到宿主机的端口必须与 kind 配置的 containerPort 一致应用这个配置kubectl apply -f nginx-deployment.yaml查看资源状态kubectl get pods,deploy,svc输出应显示两个 Nginx Pod 在运行以及一个nginx-service其PORT(S)列应包含80:30080/TCP。6.3 从宿主机访问应用现在你可以在宿主机上打开浏览器访问http://localhost:8080或者使用curl命令curl http://localhost:8080你应该能看到 Nginx 的欢迎页面。这证明了流量通过hostPort: 8080-nodePort: 30080-Service Port: 80-Pod Port: 80的路径成功到达了应用。6.4 清理实战环境# 删除 Kubernetes 资源 kubectl delete -f nginx-deployment.yaml # 或者直接删除整个集群 kind delete cluster --name nginx-demo7. 常见问题与排查思路在使用 kind 的过程中你可能会遇到一些问题。以下是常见问题的排查指南。7.1 Docker 环境问题问题现象可能原因解决思路docker: command not foundDocker 未安装或未在 PATH 中。按照本文第 2.3 节重新安装 Docker。Cannot connect to the Docker daemon...Docker 服务未运行或当前用户不在docker组。1. 启动服务sudo systemctl start docker2. 确保用户已加入docker组并已重新登录。3. 检查服务状态sudo systemctl status docker。WSL2中 Docker 命令报错Docker Desktop 的 WSL2 集成未正确启用。1. 确保 Docker Desktop 设置中 “Use the WSL 2 based engine” 和 “Enable integration with my default WSL distro” 已勾选。2. 在 WSL2 中确保$PATH包含 Docker 的路径。7.2 kind 集群创建失败问题现象可能原因解决思路ERROR: failed to create cluster: failed to pull image网络问题无法拉取kindest/node镜像。1. 检查网络连接。2. 尝试手动拉取docker pull kindest/node:v1.29.2替换为所需版本。3. 使用国内镜像源如果存在。ERROR: failed to create cluster: node(s) already exist for a cluster with the name已存在同名的集群或容器。1. 删除已存在的集群kind delete cluster --name cluster-name。2. 或者使用不同的集群名称创建。集群创建卡在Starting control-plane资源不足内存/CPU或内核参数问题。1. 检查 Docker 资源限制在 Docker Desktop 设置中调整。2. 确保系统满足最低资源要求。3. 查看具体日志docker logs control-plane-container-id。kubectl get nodes显示NotReadyCNI 网络插件通常是 kindnet安装失败。1. 等待几分钟网络插件可能正在初始化。2. 查看 Pod 状态kubectl get pods -n kube-system。3. 查看具体 Pod 日志kubectl logs -n kube-system cni-pod-name。4. 尝试重新创建集群。7.3 镜像加载与访问问题问题现象可能原因解决思路kind load后 Pod 仍显示ImagePullBackOff镜像未成功加载到所有节点或镜像名称/标签不匹配。1. 确认加载命令指定了正确的集群名kind load docker-image my-img:tag --name cluster-name。2. 确认 Deployment/Pod 中image字段与加载的镜像名完全一致包括标签。3. 登录到节点容器内检查docker exec -it node-name crictl images。宿主机无法通过hostPort访问服务extraPortMappings配置错误或 Service 的nodePort不匹配。1. 确认kind配置中containerPort与 Service 的nodePort数值相同。2. 确认 Service 类型为NodePort。3. 检查宿主机防火墙是否阻止了该端口。kubectl命令报The connection to the server was refusedkubectl上下文配置错误或 API 服务器未运行。1. 确认当前上下文kubectl config current-context应为kind-cluster-name。2. 检查控制平面容器是否运行docker ps | grep control-plane。3. 重启集群kind delete cluster然后kind create cluster。8. 最佳实践与工程建议将 kind 有效地集成到你的开发工作流中需要遵循一些最佳实践。8.1 集群配置管理版本化配置文件始终将你的kind-config.yaml文件纳入版本控制如 Git。这确保了团队所有成员和 CI/CD 流水线都能创建完全一致的集群环境。明确指定镜像版本在配置文件的image字段中始终使用完整的镜像标签如kindest/node:v1.28.0避免使用latest标签以保证环境可重现性。按需配置资源根据测试需求调整节点资源。虽然 kind 本身轻量但你可以在配置中限制节点的 CPU/内存防止影响宿主机其他工作。nodes: - role: control-plane image: kindest/node:v1.28.0 kubeadmConfigPatches: - | kind: InitConfiguration nodeRegistration: kubeletExtraArgs: node-labels: ingress-readytrue extraMounts: # 挂载本地目录到节点便于开发 - hostPath: /path/to/code containerPath: /code8.2 开发与测试流程作为一次性环境使用将 kind 集群视为临时环境。测试完成后立即删除。这鼓励了基础设施即代码IaC的实践所有应用部署都应通过 YAML 文件或 Helm Chart 来描述。集成到 CI/CD在.gitlab-ci.yml或 GitHub Actions 工作流中将kind create cluster作为测试任务的第一步。确保流水线脚本能处理集群创建失败的情况。预加载常用镜像如果 CI 环境中网络不稳定可以预先将基础镜像如nginx,busybox,redis加载到 kind 节点或者使用本地私有镜像仓库。8.3 性能与稳定性清理无用镜像和容器定期运行docker system prune -a -f和kind delete cluster来清理磁盘空间。注意这会删除所有未使用的 Docker 资源和所有 kind 集群。避免在节点容器内直接修改Kind 节点容器是临时的。任何对节点的手动修改如安装软件在集群删除后都会丢失。所有定制化都应通过 Kubernetes 资源DaemonSet, 初始化容器等或 kind 的配置补丁kubeadmConfigPatches来完成。监控资源使用在长时间运行的测试中使用docker stats或kubectl top nodes/pods监控集群的资源消耗。8.4 进阶使用场景测试 Ingress 控制器Kind 非常适合测试 Ingress。你可以安装 Nginx Ingress Controller 或 Contour并利用extraPortMappings将 80/443 端口映射到宿主机。多集群联邦测试通过创建多个 kind 集群可以模拟和测试 Kubernetes 集群联邦Federation或服务网格的多集群场景。验证 Kubernetes 版本升级快速创建一个低版本集群然后按照升级流程操作验证升级脚本的兼容性。通过遵循上述步骤和建议你可以在 Ubuntu 上高效地利用 kind 搭建一个功能完善的本地 Kubernetes 沙箱环境。它不仅简化了学习和实验过程更能成为你日常开发和自动化测试中不可或缺的利器。当你熟悉了基本操作后可以进一步探索如何将 kind 与你的 IDE、本地 CI 工具链深度集成打造极致的云原生本地开发体验。