Kubernetes-кластер на ноутбуке — задача нередкая: CI/CD, эксперименты с операторами, проверка манифестов без нагрузки на prod. minikube тянет виртуалку, k3s просит отдельный host, а kind поднимает управляющую плоскость в Docker-контейнерах. Развернули, поработали, удалили — без побочных эффектов.
Зачем kind
kind создает кластер из Docker-контейнеров: control-plane и worker-ноды — это образы kindest/node. Основной use-case — локальная разработка и CI. В GitHub Actions есть официальный action create-kind, что делает пайплайны с тестами поверх K8s тривиальными.
От minikube отличается отсутствием гипервизора и нативной поддержкой multi-node топологий. От k3d — тем, что не требует Rancher и работает с CRI/containerd напрямую.
Установка
macOS, Linux и Windows (через WSL2) — бинарник из GitHub Releases.
# macOS
brew install kind
# Linux
curl -Lo /usr/local/bin/kind https://kind.sigs.k8s.io/dl/v0.22.0/kind-linux-amd64
chmod +x /usr/local/bin/kind
# Проверка
kind version
# kind v0.22.0 go1.21.8 linux/amd64
Понадобится Docker (или Podman с kind use docker driver). Убедись, что в Docker выставлен минимум 4 GB памяти для всех контейнеров.
Первый кластер одной командой
kind create cluster
# Creating cluster "kind" ...
# ✓ Ensuring node image (kindest/node:v1.29.0) ✓
# ✓ Preparing nodes ✓
# ✓ Writing configuration ✓
# ✓ Starting control-plane ✓
# ✓ Installing CNI ✓
# ✓ Installing StorageClass ✓
# ✓ Waiting for node readiness ✓
# Successfully created cluster "kind"!
kind создал кластер с именем kind, записал kubeconfig в ~/.kube/config. Проверяем:
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# kind-control-plane Ready control-plane 2m v1.29.0
kubectl get pods -A
# NAMESPACE NAME READY
# kube-system coredns-... 1/1
# local-path-storage local-path-provisioner-... 1/1
Готово. Single-node кластер поднят за минуту.
Конфиг: multi-node и runtime
Для кластера с несколькими worker-нодами используется YAML-конфиг. Создадим три worker-ноды:
# kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 80
hostPort: 8080
protocol: TCP
- role: worker
- role: worker
- role: worker
kind create cluster --name multi --config kind-config.yaml
Флаги создания кластера:
| Флаг | Назначение | Пример |
|---|---|---|
--name | Имя кластера | kind create cluster --name prod |
--config | Путь к YAML | --config ./kind.yaml |
--image | Кастомный образ node | --image kindest/node:v1.28.0 |
--wait | Таймаут readiness | --wait 5m |
--kubeconfig | Альтернативный kubeconfig | --kubeconfig ~/.kube/dev |
Вместо флага --image можно указать node.internalImage в конфиге — полезно для air-gapped окружений.
Загрузка образов в кластер
kind использует отдельный container runtime внутри ноды. Образы из локального Docker daemon не видны. Для загрузки:
# Сборка образа
docker build -t myapp:v1.0 ./myapp
# Загрузка в kind-ноды
kind load docker-image myapp:v1.0 --name multi
# Для всех нод сразу
kind load docker-image myapp:v1.1 --name multi --nodes kind-worker,kind-worker2
Для CI часто используют образ из tar-архива:
docker save myapp:v1.0 > myapp.tar
kind load image-archive myapp.tar --name multi
После загрузки образ доступен в кластере без registry.
kind с kubeconfig
По умолчанию kind мержит контекст в ~/.kube/config. Для изоляции:
# Отдельный kubeconfig
KUBECONFIG=~/.kube/kind-config kind create cluster --name isolated
# Или экспорт после создания
kind get kubeconfig --name multi > ./kubeconfig
export KUBECONFIG=./kubeconfig
kubectl get nodes
Управление несколькими кластерами:
kind get clusters
# kind
# multi
# isolated
# Удалить конкретный
kind delete cluster --name isolated
Очистка
kind delete cluster --name multi
# Deleting cluster "multi" ...
Без --name удаляется кластер по умолчанию (kind). Все ресурсы Docker удаляются вместе с нодами. Если Docker был остановлен при работающем кластере — ноды остаются в статусе NotReady при следующем запуске. Лечится пересозданием кластера.
Gotchas
containerd внутри ноды. kubectl работает с containerd напрямую. Привычные docker ps и docker exec не покажут поды — они живут внутри kind-ноды. Для отладки:
docker exec -it multi-control-plane crictl ps
docker exec -it multi-control-plane crictl logs <container-id>
HostNetworking и PortMappings. Для доступа извне к подам нужен extraPortMappings в конфиге. Без него hostPort не работает — pod Networking в kind изолирован.
PersistentVolumes. kind создает StorageClass kind-node на основе local-path-provisioner. Данные хранятся на хосте в /var/local-path-provisioner. Для чистого окружения — просто удали кластер.
Cgroups v2. В новых дистрибутивах (Ubuntu 22.04+, Fedora) Docker может требовать настройки:
docker info | grep cgroup
# Cgroup Driver: systemd
# Cgroup Version: 2
kind работает с обоими версиями, но в редких случаях с cgroups v2 на Arch Linux возникают проблемы с лимитами памяти. Решение — передать в конфиг:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
"MemoryManager": true
runtimeConfig:
"memorymanager.k8s.io/v1alpha1": true
Версии. kind отстает от upstream Kubernetes на 1-2 минорные версии. Актуальную матрицу совместимости смотри в README проекта перед поднятием prod-подобного окружения.
kind — быстрый способ поднять Kubernetes на машине разработчика или в CI без виртуализации. Основной цикл: kind create cluster, работа, kind delete cluster. Для air-gapped или многонодовых сценариев — YAML-конфиг и kind load docker-image. Ограничения известны: нет GPU, нет реального сетевого стека, производительность ниже bare metal. Для остального — сойдет.