尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Ubuntu 上使用 kind 快速搭建本地 Kubernetes 开发集群

Ubuntu 上使用 kind 快速搭建本地 Kubernetes 开发集群 如果你正在学习 Kubernetes或者需要在本地快速搭建一个用于开发测试的集群那么你一定遇到过资源消耗大、环境配置复杂、清理困难等问题。在虚拟机里跑 Minikube 太笨重用云服务又太贵有没有一种轻量、快速、用完即抛的方案答案是肯定的这就是kind (Kubernetes in Docker)。它不是一个图形处理软件而是一个使用 Docker 容器作为“节点”来运行 Kubernetes 集群的工具。听起来有点绕简单说它能在你的一台机器上用几个 Docker 容器瞬间“变”出一个功能完整的 K8s 集群。这对于开发者、CI/CD 流水线、或者只是想快速验证一个 K8s 概念的你来说简直是“神器”。但别急着去官网复制命令。在 Ubuntu 上安装 kind远不止curl和chmod那么简单。很多人卡在 Docker 环境、权限问题或者网络配置上最终得到一个无法启动的集群。这篇文章的目的就是帮你绕过这些坑从零开始在 Ubuntu 上搭建一个稳定可用的 kind 集群。我们不仅会完成安装还会深入理解其工作原理并给出生产级的最佳实践建议让你真正掌握这个高效的本地 K8s 开发工具。1. 为什么选择 kind重新定义本地 K8s 开发体验在深入安装步骤之前我们必须先搞清楚 kind 到底解决了什么痛点以及它和 Minikube、k3s、Docker Desktop 内置 K8s 等方案的本质区别。这决定了它是否适合你的场景。传统本地 K8s 方案的三大痛点资源消耗大无论是 Minikube 启动一个虚拟机还是 k3s 运行一堆系统服务都会占用可观的 CPU 和内存。环境隔离差很多工具会直接修改你的主机网络、系统服务容易造成环境污染清理不彻底。启动速度慢从启动虚拟机到拉取镜像再到初始化集群动辄几分钟打断了开发的流畅性。kind 的颠覆性思路容器即节点。kind 的核心思想非常巧妙既然 Docker 容器本身就是一个轻量级的隔离环境那为什么不直接用容器来模拟 K8s 的节点Node呢一个kind集群由两个或多个 Docker 容器组成一个容器作为控制平面Control Plane运行kube-apiserver、kube-scheduler、kube-controller-manager等核心组件。一个或多个容器作为工作节点Worker Node运行kubelet和containerd或 Docker来托管你的业务 Pod。所有这些都是跑在你自己主机 Docker 守护进程里的容器。这意味着极致轻量节点本身就是一个容器资源开销极小。完美隔离整个集群生命周期被封装在 Docker 中kind delete cluster即可彻底清理不留任何系统级残留。秒级启动基于现有的 Docker 镜像集群创建通常在 30 秒到 2 分钟内完成。高度一致集群组件以容器镜像形式分发确保了环境的一致性非常适合 CI/CD。那么谁最适合使用 kindKubernetes 学习者快速搭建实验环境反复创建销毁无压力。应用开发者在本地验证 Helm Chart、Operator 或自定义资源定义CRD。CI/CD 工程师在流水线中集成一个临时的、干净的 K8s 集群进行集成测试。项目贡献者为 Kubernetes 上游项目如 SIG Testing贡献代码kind 是官方推荐的本地测试环境。如果你的需求是在一台 Ubuntu 开发机上获得一个最接近生产环境架构多节点、且管理成本最低的 K8s 沙盒那么 kind 几乎是当前的最优解。2. 核心概念与架构解析理解 kind 如何工作要玩转一个工具不能只停留在命令层面。理解 kind 的架构能帮助你在出问题时快速定位。2.1 kind 的三层架构我们可以把 kind 的架构分为三层kind 命令行工具这是你直接交互的客户端。它负责根据配置文件创建 Docker 容器节点并在容器内部部署和配置 Kubernetes 组件。Docker 容器节点每个容器都运行一个特制的 Linux 发行版镜像通常是kindest/node里面预装了systemd、containerd、kubeadm、kubelet等必要组件。控制平面节点容器会额外运行etcd和核心控制面组件。Kubernetes 集群运行在上述容器内部对外提供完整的 K8s API。kubectl通过一个kind生成的 kubeconfig 文件来连接这个集群。2.2 关键组件交互流程当你执行kind create cluster时kind工具拉取kindest/node镜像如果本地没有。根据配置启动一个或多个容器并为它们配置独立的网络和存储。在控制平面容器内使用kubeadm初始化一个 Kubernetes 集群。将生成的 admin kubeconfig 从容器内提取到主机并更新本地~/.kube/config文件。如果需要部署 CoreDNS、CNI 网络插件默认使用kindnet一种简单的基于ptp的 CNI等插件。2.3 与 Docker Desktop Kubernetes 的对比很多人分不清 kind 和 Docker Desktop 自带的 Kubernetes。它们有本质区别Docker Desktop K8s是一个单节点的、高度集成的、黑盒式的 K8s 环境。它方便但不可配置节点数且与 Docker Desktop 深度绑定。kind是一个创建和管理多节点 K8s 集群的工具。它更灵活你可以定义多个控制平面和工作节点模拟更复杂的拓扑结构并且完全独立于任何桌面环境。理解了这些你就知道 kind 不是一个“玩具”而是一个用于创建标准化、可移植 K8s 集群的基础设施工具。3. 环境准备确保你的 Ubuntu 系统就绪安装 kind 本身很简单难点在于确保其依赖环境正确。请严格按照以下步骤检查你的 Ubuntu 系统。3.1 系统要求操作系统Ubuntu 18.04 LTS, 20.04 LTS, 22.04 LTS 或更高版本。本文以Ubuntu 22.04 LTS为例。架构x86_64 (amd64) 或 arm64。确保你的 CPU 支持虚拟化对于 Docker 运行容器是必要的。权限你需要拥有sudo权限来安装软件包。3.2 安装并配置 Docker最关键的一步kind 完全依赖 Docker 运行时。如果你的 Docker 安装有问题kind 绝对无法工作。# 1. 卸载旧版本 Docker如果存在 sudo apt-get remove docker docker-engine docker.io containerd runc # 2. 更新 apt 包索引并安装依赖包 sudo apt-get update sudo apt-get install -y \ ca-certificates \ curl \ gnupg \ lsb-release # 3. 添加 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 # 4. 设置 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 # 5. 安装 Docker Engine sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin # 6. 验证 Docker 安装 sudo docker run hello-world如果看到 “Hello from Docker!” 的信息说明 Docker 安装成功。3.3 将当前用户加入 docker 组避免每次使用 sudo默认情况下运行docker命令需要sudo权限。为了方便将你的用户加入docker组。# 将当前用户加入 docker 组 sudo usermod -aG docker $USER # 重要注销并重新登录或者执行以下命令使组更改生效 newgrp docker # 验证无需 sudo 即可运行 docker docker run hello-world注意newgrp命令只对当前 shell 会话生效。最可靠的方法是完全注销系统再重新登录。3.4 检查 Docker 服务状态与 cgroup 驱动Kubernetes 推荐使用systemd作为 cgroup 驱动。我们需要确保 Docker 也使用systemd。# 检查 Docker 服务状态 sudo systemctl status docker --no-pager -l # 创建或修改 Docker 的 daemon.json 配置文件 sudo tee /etc/docker/daemon.json /dev/null EOF { exec-opts: [native.cgroupdriversystemd], log-driver: json-file, log-opts: { max-size: 100m }, storage-driver: overlay2 } EOF # 重启 Docker 服务使配置生效 sudo systemctl daemon-reload sudo systemctl restart docker # 验证 cgroup 驱动 docker info | grep -i cgroup输出中应包含Cgroup Driver: systemd。至此一个为运行 Kubernetes 优化过的 Docker 环境已经准备就绪。这是 kind 能成功运行的基石。4. 安装 kind 命令行工具有了健康的 Docker 环境安装 kind 本身就像喝水一样简单。kind 是一个单独的 Go 二进制文件我们直接下载即可。4.1 使用 curl 下载最新稳定版推荐访问 kind 官方 GitHub Releases 页面找到最新版本的 Linux amd64 二进制文件。以下命令会自动获取最新版本号并下载。# 下载最新的 kind 二进制文件 curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64 # 或者指定一个具体版本例如 v0.20.0 # curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.20.0/kind-linux-amd64 # 赋予执行权限 chmod x ./kind # 将 kind 移动到系统 PATH 目录例如 /usr/local/bin sudo mv ./kind /usr/local/bin/ # 验证安装 kind version你应该能看到类似kind v0.20.0 go1.20.4 linux/amd64的输出。4.2 备选使用包管理器安装如果你更喜欢使用包管理器也可以通过snap安装但版本可能不是最新的。# 使用 snap 安装 sudo snap install kind --classic # 验证安装 kind version4.3 安装 kubectlKubernetes 命令行工具kind 创建集群后你需要kubectl来管理它。# 下载最新稳定版 kubectl curl -LO https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl # 赋予执行权限并移动到 PATH chmod x kubectl sudo mv kubectl /usr/local/bin/ # 验证安装 kubectl version --client --outputyaml现在kind和kubectl都已就位。5. 创建你的第一个 kind 集群现在进入最激动人心的环节。我们将用最简单的命令创建一个集群然后逐步深入高级配置。5.1 基础创建单控制平面集群这是最常用的场景创建一个包含一个控制平面节点和一个工作节点的集群。# 使用默认配置创建集群集群名称默认为 “kind” kind create cluster # 或者显式指定集群名称 kind create cluster --name my-cluster这个命令会执行以下操作在后台拉取kindest/node镜像约 500MB。启动两个 Docker 容器一个作为控制平面一个作为工作节点。在容器内初始化 Kubernetes 集群并配置网络。生成 kubeconfig 文件并合并到你的~/.kube/config中。将当前kubectl的上下文切换到新创建的集群。整个过程大约需要 1-2 分钟。完成后你会看到类似Creating cluster “my-cluster” ... ✓的成功信息。5.2 验证集群状态创建完成后立即验证集群是否健康。# 查看集群节点状态 kubectl get nodes # 查看所有命名空间下的 Pod 状态 kubectl get pods --all-namespaces # 查看 kind 创建的 Docker 容器 docker pskubectl get nodes的输出应该显示两个节点状态都是Ready。docker ps会显示两个名为my-cluster-control-plane和my-cluster-worker的容器在运行。5.3 理解 kind 的 kubeconfigkind 不会覆盖你原有的~/.kube/config文件而是将新集群的配置作为一个新的上下文context添加进去。# 查看当前的 kubeconfig 上下文 kubectl config get-contexts # 查看当前正在使用的上下文 kubectl config current-context # 切换回其他集群的上下文如果你有多个 kubectl config use-context your-other-contextkind创建的上下文名称通常是kind-my-cluster格式。这种设计让你可以轻松在多个集群本地 kind、Minikube、远程 EKS/AKS之间切换。6. 高级配置使用 kind 配置文件默认配置适合快速上手但真实场景往往需要定制指定 Kubernetes 版本、配置多节点、映射本地端口、预加载镜像等。这就需要使用kind 配置文件一个 YAML 文件。6.1 配置文件基础结构创建一个名为kind-config.yaml的文件# kind-config.yaml kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 # 配置集群的网络 networking: # API Server 的监听地址设置为 0.0.0.0 允许从主机外部访问谨慎使用 apiServerAddress: 127.0.0.1 # API Server 端口默认为 6443 apiServerPort: 6443 # 节点配置 nodes: # 控制平面节点 - role: control-plane # 将主机端口 80 映射到容器的 80 端口便于访问 Ingress 服务 extraPortMappings: - containerPort: 80 hostPort: 80 protocol: TCP - containerPort: 443 hostPort: 443 protocol: TCP # 工作节点 - role: worker - role: worker这个配置定义了一个 1 个控制平面 2 个工作节点的集群并将宿主机的 80 和 443 端口映射到了控制平面节点。6.2 使用配置文件创建集群# 使用配置文件创建集群 kind create cluster --name multi-node-cluster --config kind-config.yaml # 验证节点数量 kubectl get nodes现在你应该能看到三个节点。6.3 关键配置项详解指定 Kubernetes 版本通过node的镜像标签指定。nodes: - role: control-plane image: kindest/node:v1.27.3sha256:... # 使用特定版本镜像注意镜像标签必须使用完整的镜像摘要SHA256你可以在 kind 发布说明 中找到对应版本的正确镜像名。预加载本地 Docker 镜像到集群在 CI/CD 中避免从远程仓库拉取镜像可以极大加速部署。nodes: - role: control-plane - role: worker # 这个配置段告诉 kind在创建节点时将主机上的指定镜像加载到节点容器中 containerdConfigPatches: - |- [plugins.io.containerd.grpc.v1.cri.registry.mirrors.localhost:5000] endpoint [http://kind-registry:5000]但更常用的方法是使用kind load docker-image命令# 假设你本地构建了一个镜像 my-app:v1 docker build -t my-app:v1 . # 将该镜像加载到名为 multi-node-cluster 的集群的所有节点中 kind load docker-image my-app:v1 --name multi-node-cluster # 之后在集群中部署时Pod 会直接使用节点本地已加载的镜像无需拉取。配置持久化存储默认情况下节点容器内的数据在容器删除后会丢失。你可以将主机目录挂载到节点容器内。nodes: - role: worker extraMounts: - hostPath: /path/on/host/data containerPath: /data # readOnly: true # 可选默认为 false (读写)7. 在 kind 集群中部署应用实战理论说再多不如动手跑一个应用。我们来部署一个经典的 Nginx 服务并通过 NodePort 和 Ingress 两种方式访问它。7.1 部署 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: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 80 type: NodePort # 使用 NodePort 类型K8s 会分配一个主机端口# 应用配置 kubectl apply -f nginx-deployment.yaml # 查看部署状态 kubectl get deployments kubectl get pods kubectl get svc nginx-service查看nginx-service时你会看到类似80:3xxxx/TCP的输出其中3xxxx是随机分配的 NodePort。7.2 通过 NodePort 访问由于 kind 节点是 Docker 容器你需要访问宿主机的 IP 和 NodePort。但注意NodePort 是在容器内部暴露的你需要将其映射到宿主机。这就是前面配置文件中extraPortMappings的用处。如果你创建集群时没有映射端口可以临时使用kubectl port-forward# 将本地的 8080 端口转发到 nginx-service 的 80 端口 kubectl port-forward service/nginx-service 8080:80然后在浏览器访问http://localhost:8080。7.3 部署 Ingress Controller 并配置 Ingress更生产化的方式NodePort 不适合生产。我们部署一个 Ingress Controller如 NGINX Ingress Controller并利用之前映射的宿主机 80/443 端口。# 使用官方 Manifest 部署 NGINX Ingress Controller kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml # 等待 Ingress Controller 的 Pod 变为 Ready kubectl wait --namespace ingress-nginx \ --forconditionready pod \ --selectorapp.kubernetes.io/componentcontroller \ --timeout90s创建 Ingress 资源# nginx-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-ingress spec: ingressClassName: nginx rules: - host: myapp.local http: paths: - pathType: Prefix path: / backend: service: name: nginx-service port: number: 80kubectl apply -f nginx-ingress.yaml由于我们在kind-config.yaml中将宿主机的 80 端口映射到了控制平面节点并且 Ingress Controller 监听节点的 80 端口现在你可以在宿主机上编辑/etc/hosts文件添加一行127.0.0.1 myapp.local然后在浏览器访问http://myapp.local就能看到 Nginx 欢迎页面了。这完全模拟了生产环境通过域名访问服务的流程。8. 集群管理与故障排查8.1 日常管理命令# 列出所有 kind 集群 kind get clusters # 获取指定集群的 kubeconfig kind get kubeconfig --name my-cluster # 导出 kubeconfig 到文件 kind get kubeconfig --name my-cluster my-cluster-kubeconfig.yaml # 删除集群彻底清理所有相关容器和资源 kind delete cluster --name my-cluster # 删除所有 kind 集群 kind delete clusters --all8.2 常见问题与排查思路问题现象可能原因排查方式解决方案kind create cluster卡在Ensuring node image ...网络问题无法拉取kindest/node镜像。1. 检查网络连接。2.docker pull kindest/node:v1.27.3手动拉取。使用代理或更换镜像源。手动拉取后重试。ERROR: failed to create cluster: docker run errorDocker 守护进程未运行或权限不足。1.systemctl status docker。2.docker ps测试。启动 Docker 服务 (sudo systemctl start docker)。确保用户已在docker组并重新登录。kubectl get nodes显示NotReadyCNI 网络插件未成功安装或 Pod 网络有问题。1.kubectl get pods -n kube-system查看coredns是否 Running。2.docker logs control-plane-container-id查看节点日志。通常等待几分钟会自动恢复。可尝试kubectl delete pod -n kube-system -l k8s-appkube-dns重启 CoreDNS。无法从宿主机访问 NodePort 服务NodePort 在容器网络内未映射到宿主机。检查服务类型是否为NodePort以及分配的端口。1. 使用kubectl port-forward临时转发。2. 在kind配置文件中使用extraPortMappings永久映射。kind load docker-image失败集群名称错误或集群未运行。kind get clusters确认集群状态。确保集群正在运行并使用正确的--name参数。节点磁盘空间不足容器内日志或镜像占满空间。docker exec node-container df -h进入容器查看。1. 清理无用镜像docker system prune。2. 扩展 Docker 根目录大小。8.3 深入节点容器内部调试有时需要进入节点容器内部查看情况。# 获取控制平面节点的容器 ID docker ps --filter namemy-cluster-control-plane --format {{.ID}} # 进入容器内部的 shell docker exec -it control-plane-container-id /bin/bash # 在容器内你可以像在普通 Linux 系统一样操作 # 查看 kubelet 日志 journalctl -u kubelet -f # 查看容器运行时 (containerd) 状态 crictl ps9. 生产级最佳实践与进阶指南将 kind 用于本地开发很方便但遵循一些最佳实践能让体验更顺畅甚至可以在 CI 中发挥更大作用。9.1 镜像管理与加速预加载镜像在 CI 流水线中先使用kind load docker-image将构建好的镜像加载到集群再运行测试。这比每次从仓库拉取快得多。使用本地镜像仓库可以部署一个registry:2容器作为本地仓库并在 kind 配置中配置镜像仓库镜像。# 创建本地仓库容器 docker run -d -p 5000:5000 --restartalways --name kind-registry registry:2 # 连接仓库到 kind 网络如果集群已创建 docker network connect kind kind-registry然后在配置文件中添加containerdConfigPatches来配置镜像仓库。9.2 配置管理版本化配置文件将你的kind-config.yaml纳入 Git 版本控制确保团队环境和 CI 环境一致。多集群配置为不同的项目或测试目的创建不同的配置文件如kind-config-dev.yaml,kind-config-integration.yaml。9.3 集成到 CI/CD例如 GitHub Actionskind 是 CI 中运行 Kubernetes 集成测试的绝佳选择。以下是一个简化的 GitHub Actions 工作流步骤# .github/workflows/k8s-test.yaml 片段 jobs: integration-test: runs-on: ubuntu-latest steps: - uses: actions/checkoutv4 - name: Set up Docker uses: docker/setup-buildx-actionv3 - name: Set up kind uses: helm/kind-actionv1.8.0 # 使用社区 Action 安装 kind - name: Create kind cluster run: | kind create cluster --config ./kind-config-ci.yaml kubectl cluster-info --context kind-kind - name: Build and load image run: | docker build -t my-app:ci-${{ github.sha }} . kind load docker-image my-app:ci-${{ github.sha }} - name: Run tests run: | kubectl apply -f ./k8s/manifests/ # 运行你的测试脚本例如使用 kubectl 或 helm test9.4 性能与资源限制默认情况下kind 节点容器没有资源限制。在资源有限的机器上你可以通过 Docker 在创建集群前设置资源限制但这需要修改 Docker 的启动配置或使用docker run的参数而 kind 本身不直接支持。更常见的做法是调整集群规模使用单节点集群只有控制平面也是工作节点来节省资源。# 单节点集群配置 (控制平面节点也承担工作) kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane # 此节点也将运行工作负载9.5 清理策略养成随手清理的习惯避免残留容器占用磁盘。# 定期清理未使用的 Docker 资源 docker system prune -af # 删除所有不再需要的 kind 集群 kind delete clusters --all通过以上步骤你不仅能在 Ubuntu 上顺利安装和使用 kind更能理解其设计哲学掌握定制化配置、应用部署和故障排查的完整技能链。kind 将本地 Kubernetes 体验提升到了一个全新的高度——快速、轻量、可重复且与生产环境高度相似。无论是用于日常开发、学习验证还是集成到自动化流水线中它都是一个值得你放入工具箱的强力伙伴。建议你将本文中的配置文件和命令保存下来作为日后搭建本地 K8s 环境的快速参考。
返回列表