Что выбрать:
Для локальной разработки есть два проверенных инструмента. Minikube создает кластер в контейнере или виртуалке и тащит с собой удобную обвязку: аддоны, дашборд, проброс портов одной командой. Kind (Kubernetes in Docker) запускает каждую ноду кластера как обычный Docker-контейнер. Он легче, стартует за секунды и отлично подходит для CI, где кластер создается и убивается на каждый прогон тестов.
Новичку проще с minikube, его и возьмем за основу в курсе. Kind пригодится, когда нужны быстрые пересоздания, тот же CI. Мультинодовый кластер, кстати, умеют оба: у kind это конфиг-файл, у minikube флаг --nodes, покажу ниже. Оба инструмента спокойно живут на одной машине параллельно.
Из требований: установленный и запущенный Docker, минимум 2 CPU и 4 ГБ свободной памяти. Комфортная планка 4 CPU и 8 ГБ, тогда останется запас под сами приложения.
Запускаем minikube:
Код: Выделить всё
# macOS: brew install minikube
# Linux:
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
minikube start --driver=docker --cpus=4 --memory=8192
kubectl get nodes
minikube status # жив ли кластер
minikube dashboard # веб-интерфейс в браузере
minikube stop # выключить, состояние сохранится
minikube delete # снести кластер целиком
Первый запуск скачает базовый образ ноды, это около гигабайта, наберитесь терпения. Дальше старт занимает меньше минуты. Команда kubectl get nodes должна показать одну ноду в статусе Ready. Если kubectl еще не установлен, временно выручит встроенный вызов minikube kubectl -- get nodes (обратите внимание на разделитель --, без него minikube попытается разобрать флаги сам и вы получите ошибку). Но лучше поставить бинарник отдельно, он понадобится на каждом шагу:
Код: Выделить всё
# macOS: brew install kubectl
# Linux:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install kubectl /usr/local/bin/kubectl
kubectl version --client
Запускаем kind:
Код: Выделить всё
# macOS: brew install kind
# Linux, готовый бинарник со страницы релизов:
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.30.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
kind create cluster --name dev
kubectl cluster-info --context kind-dev
kind delete cluster --name dev # снести кластер, симметрично minikube delete
Кластер готов секунд за двадцать. Многонодовая конфигурация описывается отдельным файлом:
Код: Выделить всё
# kind-multi.yaml
# создание: kind create cluster --name dev --config kind-multi.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
Локальные Docker-образы ни один из кластеров не видит автоматически: у нод свой внутренний рантайм, ему ваш хостовый Docker не указ. Собрали свой образ, загрузите его внутрь кластера явно:
Код: Выделить всё
docker build -t myapp:dev .
kind load docker-image myapp:dev --name dev # для kind
minikube image load myapp:dev # для minikube
Типичные грабли:
Docker не запущен. Обе утилиты при старте честно ругаются, но текст ошибки длинный, и суть в нем теряется. Проверяйте docker ps перед стартом кластера.
Не хватает памяти. Поды повисают в Pending, а kubectl describe pod показывает Insufficient memory. Лечится пересозданием: minikube delete, затем minikube start с большим значением memory.
Перепутанные контексты. Когда подняты и minikube, и kind, kubectl смотрит в тот кластер, который стартовал последним. Смотрите kubectl config get-contexts и переключайтесь через kubectl config use-context minikube. Половина загадочных "у меня под пропал" объясняется именно этим.
Docker Hub отдает 403 или тянет образы еле-еле. Знакомая история для РФ. Тут важно понимать, кто что качает. Зеркало в /etc/docker/daemon.json (секция registry-mirrors) настраивает только хостовый демон, то есть помогает скачать образ самой ноды (kicbase у minikube, kindest/node у kind) и собрать образ через docker build. А вот образы подов тянет рантайм внутри нод, и хостовая настройка туда не доезжает. Для minikube зеркало передается флагом при старте: minikube start --registry-mirror=https://адрес-зеркала. Для kind зеркала настраиваются через containerdConfigPatches в конфиге кластера плюс файлы hosts.toml внутри нод, готовый рецепт есть в документации kind на странице Local Registry (kind.sigs.k8s.io/docs/user/local-registry/). Есть и путь попроще: скачать нужный образ хостовым докером (он ваше зеркало уже использует) и закинуть в кластер через kind load docker-image или minikube image load.
Образ загружен в kind, а под все равно падает с ErrImagePull. Проверьте imagePullPolicy: с тегом latest политика по умолчанию Always, и кластер лезет в реестр вместо локального образа. Используйте осмысленные теги вроде myapp:dev или ставьте imagePullPolicy: IfNotPresent.
Что усвоили:
У вас есть локальный кластер, вы умеете его поднимать, останавливать и сносить, а заодно переключаться между несколькими кластерами через контексты. В следующей главе запустим в нем первые поды и разберем, как Kubernetes описывает контейнеры в манифестах.