Перейти к содержимому

kind: локальный Kubernetes в Docker

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. Для остального — сойдет.