在本地开发环境中快速搭建一个轻量级的 Kubernetes 集群进行测试和学习,是很多开发者和运维工程师的刚需。传统的 Minikube 或 kubeadm 方案要么资源占用大,要么配置复杂。本文将详细介绍如何在 Ubuntu 系统上安装和使用 kind (Kubernetes IN Docker) ,这是一个使用 Docker 容器作为“节点”来运行 Kubernetes 集群的工具。它启动速度快、资源消耗低,非常适合 CI/CD 流水线、本地功能测试和学习 Kubernetes 核心概念。

通过本文,你将掌握从零开始,在 Ubuntu 上完整部署一个可用的 kind 集群的全过程,包括 Docker 安装、kind 安装、集群创建与管理,以及常见问题的排查思路。无论你是 Kubernetes 新手,还是寻求更高效本地测试方案的老手,都能从中获得可直接复用的实践指南。

1. 背景与核心概念

在深入实操之前,我们有必要理解 kind 是什么,以及它解决了什么问题。

1.1 什么是 kind?

kind 是一个使用 Docker 容器作为“节点”来运行本地 Kubernetes 集群的工具。它的名字来源于 “Kubernetes IN Docker”。你可以把它想象成一个专门为 Kubernetes 定制的、更轻量的 Docker Compose 项目,其“服务”就是 Kubernetes 的各个组件(如 kube-apiserver, kube-controller-manager 等),而每个“节点”(控制平面和工作节点)都运行在一个独立的 Docker 容器中。

1.2 kind 解决了什么问题?

  1. 极致的轻量与快速 :相比于需要启动完整虚拟机的 Minikube,kind 直接利用宿主机的 Docker 运行时,集群的启动和销毁通常在几十秒内完成。
  2. 环境一致性 :由于节点是容器,你可以轻松地指定 Kubernetes 版本、容器运行时(如 containerd)的版本,确保本地测试环境与生产环境高度一致。
  3. CI/CD 友好 :在 CI 流水线中(例如 GitHub Actions, GitLab CI),可以快速创建和销毁一个干净的 Kubernetes 集群来运行集成测试,而无需复杂的虚拟机管理。
  4. 多集群管理 :可以轻松地在同一台机器上运行多个相互隔离的 Kubernetes 集群,用于测试多集群场景或不同版本。
  5. 学习与开发 :对于学习者,它降低了入门 Kubernetes 的门槛;对于开发者,它提供了完美的本地沙箱环境。

1.3 kind 与 Minikube、kubeadm 的对比

特性 kind Minikube kubeadm
节点类型 Docker 容器 虚拟机(默认)、容器 物理机/虚拟机
启动速度 极快 (秒级) 较慢(依赖虚拟机启动) 慢(需初始化系统)
资源占用 很低 (共享宿主机内核) 高(需要分配虚拟机资源) 高(需要完整的操作系统)
集群配置 通过 YAML 配置文件 通过命令行参数或配置文件 通过复杂的配置文件和命令
适用场景 本地开发、CI/CD、快速测试 本地开发、学习(功能更全) 生产环境、自定义集群搭建
网络 使用 Docker 网络,简单 可能需要处理虚拟机网络 需要配置 CNI 网络插件

简单来说,如果你追求的是 快速、轻量、一次性的测试环境 ,kind 是绝佳选择。如果你需要模拟更接近生产环境的特性(如 LoadBalancer 类型的 Service),Minikube 的虚拟机驱动可能更合适。

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 核心依赖:Docker

kind 的核心是 Docker,因此我们必须先安装并正确配置 Docker 环境。

重要提示 :如果你使用 Windows 的 WSL2 来运行 Ubuntu,并且已经安装了 Docker Desktop for Windows 并启用了 WSL2 集成,那么 Docker 环境可能已经就绪。你可以通过在 WSL2 的 Ubuntu 终端中运行 docker version 来验证。如果已安装,可以跳过 2.3 节。

2.3 安装 Docker Engine

我们将使用 Docker 官方提供的便捷脚本来安装最新稳定版的 Docker Engine。

  1. 更新系统包索引并安装必要工具

    sudo apt update
    sudo apt install -y ca-certificates curl gnupg lsb-release
    
  2. 添加 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
    
  3. 设置 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
    
  4. 更新包索引并安装 Docker Engine

    sudo apt update
    sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
    
  5. 验证 Docker 安装 : 安装完成后,运行以下命令检查 Docker 版本并运行一个测试容器:

    docker --version
    sudo docker run hello-world
    

    如果看到 “Hello from Docker!” 等信息,说明 Docker 安装成功。

  6. (可选但推荐)管理 Docker 作为非 root 用户 : 默认情况下,Docker 命令需要 sudo 。为了避免每次输入 sudo ,可以将当前用户加入 docker 组。

    sudo groupadd docker # 如果docker组已存在,会提示,可忽略
    sudo usermod -aG docker $USER
    

    重要 :执行此命令后,你需要 完全注销并重新登录 ,或者重启系统,才能使组更改生效。之后,你就可以直接使用 docker 命令了。 重新登录后,验证:

    docker run hello-world # 应该不再需要sudo
    

3. 安装 kind

安装好 Docker 后,安装 kind 就非常简单了。kind 是一个单独的二进制文件,我们可以通过多种方式获取。

3.1 使用 curl 下载二进制文件(推荐)

这是最直接的方法,从 kind 的 GitHub 发布页下载最新版本。

  1. 下载最新的 kind 二进制文件 : 访问 kind 官方 GitHub Releases 查看最新版本号(例如 v0.23.0 )。然后执行以下命令,请将 {KIND_VERSION} 替换为实际版本号。

    # 例如,下载 v0.23.0
    KIND_VERSION="v0.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

  2. 赋予执行权限并移动到 PATH

    chmod +x ./kind
    sudo mv ./kind /usr/local/bin/
    
  3. 验证安装

    kind version
    

    输出应类似: kind v0.23.0 go1.20.5 linux/amd64

3.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! 👋

这条命令完成了以下几件事:

  1. 创建了一个名为 kind 的集群(默认名称)。
  2. 拉取了 Kubernetes 节点镜像 kindest/node:v1.29.2 (版本可能不同)。
  3. 启动了一个 Docker 容器作为 Kubernetes 控制平面节点。
  4. 自动配置了 kubectl 的上下文(context)指向这个新集群。

4.2 验证集群状态

使用 kubectl 与集群交互。如果你的系统没有 kubectl ,需要先安装。

  1. 安装 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
    
  2. 检查集群节点

    kubectl get nodes
    

    输出应类似:

    NAME                 STATUS   ROLES           AGE   VERSION
    kind-control-plane   Ready    control-plane   95s   v1.29.2
    

    可以看到一个名为 kind-control-plane 的节点已经处于 Ready 状态。

  3. 查看集群信息

    kubectl cluster-info
    

4.3 使用配置文件创建自定义集群

默认创建的是单节点集群。kind 的强大之处在于可以通过 YAML 配置文件定义复杂的集群拓扑。

  1. 创建一个配置文件 ,例如 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。

  2. 使用配置文件创建集群

    kind create cluster --name multi-node-cluster --config kind-config.yaml
    

    这里我们通过 --name 指定了集群名称,通过 --config 指定了配置文件。

  3. 验证多节点集群

    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.0
    

5. kind 集群的日常操作与管理

创建集群后,你需要知道如何与之交互。

5.1 切换集群上下文

如果你有多个 kind 集群(或其他 Kubernetes 集群), kubectl 需要通过上下文来知道操作哪个集群。

  • 列出所有上下文

    kubectl config get-contexts
    
  • 切换到指定的 kind 集群

    kubectl config use-context kind-multi-node-cluster # 使用你的集群名
    
  • 查看当前上下文

    kubectl config current-context
    

5.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.yaml

kind: 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 “label=io.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.log

5.5 删除集群

当测试完成,可以轻松删除集群以释放资源。

# 删除指定集群
kind delete cluster --name multi-node-cluster

# 删除默认集群(名为 kind)
kind delete cluster

删除操作会停止并移除所有相关的 Docker 容器、网络和存储卷。

6. 完整实战案例:在 kind 集群中部署一个 Nginx 应用

让我们通过一个完整的例子,巩固对 kind 的使用。目标:在 kind 集群中部署 Nginx,并通过 NodePort 在宿主机访问。

6.1 创建带有端口映射的集群

首先,创建一个允许从宿主机访问的集群。

  1. 创建 nginx-kind-cluster.yaml

    kind: 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
    
  2. 创建集群:

    kind create cluster --name nginx-demo --config nginx-kind-cluster.yaml
    

6.2 部署 Nginx Deployment 和 Service

  1. 创建一个名为 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 一致
    
  2. 应用这个配置:

    kubectl apply -f nginx-deployment.yaml
    
  3. 查看资源状态:

    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-demo

7. 常见问题与排查思路

在使用 kind 的过程中,你可能会遇到一些问题。以下是常见问题的排查指南。

7.1 Docker 环境问题

问题现象 可能原因 解决思路
docker: command not found Docker 未安装或未在 PATH 中。 按照本文第 2.3 节重新安装 Docker。
Cannot connect to the Docker daemon... Docker 服务未运行,或当前用户不在 docker 组。 1. 启动服务: sudo systemctl start docker
2. 确保用户已加入 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 显示 NotReady CNI 网络插件(通常是 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 refused kubectl 上下文配置错误或 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-ready=true"
      extraMounts: # 挂载本地目录到节点,便于开发
        - hostPath: /path/to/code
          containerPath: /code
    

8.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 工具链深度集成,打造极致的云原生本地开发体验。

更多推荐