feat: добавить поддержку Kubernetes Kind кластеров
Some checks failed
Ansible Testing / lint (push) Has been cancelled
Ansible Testing / test (default) (push) Has been cancelled
Ansible Testing / test (minimal) (push) Has been cancelled
Ansible Testing / test (performance) (push) Has been cancelled
Ansible Testing / deploy-check (push) Has been cancelled

- Создан новый Docker образ k8s для работы с Kind, kubectl, Helm, Istio CLI
- Добавлены команды make k8s: create, destroy, stop, start, status, config, nodes, addon, shell
- Добавлена поддержка пресетов Kubernetes в molecule/presets/k8s/
- Создан скрипт create_k8s_cluster.py для автоматического создания кластеров и установки аддонов
- Добавлена документация docs/kubernetes-kind.md
- Команды kubectl выполняются внутри контейнера k8s, не требуют локальной установки
This commit is contained in:
Сергей Антропов
2025-10-26 03:30:58 +03:00
parent c1655d2674
commit 881502ad69
12 changed files with 1487 additions and 5 deletions

248
Makefile
View File

@@ -25,6 +25,7 @@ VERSION ?= 0.1.0
AUTHOR ?= "Сергей Антропов"
SITE ?= "https://devops.org.ru"
DOCKER_IMAGE ?= inecs/ansible-lab:ansible-controller-latest
DOCKER_K8S_IMAGE ?= inecs/ansible-lab:k8s-latest
DOCKER_DIND_IMAGE ?= docker:27-dind
CONTAINER_NAME ?= ansible-controller
@@ -40,7 +41,7 @@ DOCKER_BUILDX_BUILDER ?= multiarch-builder
# Базовые образы и их теги
BASE_IMAGES := altlinux/p9 astralinux/astra-1.7 redos/redos:9 registry.access.redhat.com/ubi8/ubi centos:7 quay.io/centos/centos:8 quay.io/centos/centos:stream9 almalinux:8 rockylinux:8 ubuntu:20.04 ubuntu:22.04 ubuntu:24.04 debian:9 debian:10 debian:11 debian:bookworm
.PHONY: role vault git docker presets controller help update-playbooks generate-docs setup-cicd list create delete
.PHONY: role vault git docker presets controller k8s help update-playbooks generate-docs setup-cicd list create delete
# =============================================================================
# КОМАНДЫ ДЛЯ РАБОТЫ С РОЛЯМИ
@@ -904,6 +905,8 @@ docker-get-base-tag:
TAG=$$(docker inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
ansible-controller) \
TAG="latest";; \
k8s) \
TAG="latest";; \
*) \
echo "❌ Неизвестный образ: $(IMAGE)"; \
exit 1;; \
@@ -1012,6 +1015,238 @@ controller:
echo " 💡 Удаляет: контейнеры и сети";; \
esac
# =============================================================================
# КОМАНДЫ ДЛЯ РАБОТЫ С KUBERNETES KIND
# =============================================================================
k8s:
@case "$(word 2, $(MAKECMDGOALS))" in \
create) \
echo "☸️ Создание Kind кластера..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$PRESET_ARG" ]; then \
PRESET=k8s-minimal; \
echo "📋 Используется preset по умолчанию: $$PRESET (минимальный без аддонов)"; \
else \
PRESET=$$PRESET_ARG; \
echo "📋 Используется preset: $$PRESET"; \
fi; \
if [ ! -f "molecule/presets/k8s/$$PRESET.yml" ]; then \
echo "❌ Ошибка: Пресет '$$PRESET' не найден!"; \
echo "💡 Доступные пресеты:"; \
ls -1 molecule/presets/k8s/*.yml 2>/dev/null | sed 's|molecule/presets/k8s/||g' | sed 's|\.yml||g' | sed 's/^/ - /' || echo " - k8s-minimal"; \
exit 1; \
fi; \
CONTAINER_NAME=k8s-$$PRESET; \
docker run -d --name $$CONTAINER_NAME --rm \
-v "$(PWD):/workspace" -w /workspace \
-v /var/run/docker.sock:/var/run/docker.sock \
-u root \
-e ANSIBLE_FORCE_COLOR=1 \
-e MOLECULE_PRESET=$$PRESET \
-e MOLECULE_EPHEMERAL_DIRECTORY=/tmp/molecule_workspace \
$(DOCKER_K8S_IMAGE) \
/bin/bash -c 'sleep infinity'; \
echo "🚀 Запуск создания кластера..."; \
docker exec $$CONTAINER_NAME bash -c "cd /workspace && python3 /workspace/scripts/create_k8s_cluster.py molecule/presets/k8s/$$PRESET.yml $$CONTAINER_NAME"; \
echo "✅ Kind кластер создан"; \
echo "💡 Для подключения используйте: make k8s kubeconfig"; \
echo "💡 Для остановки используйте: make k8s stop";; \
destroy) \
echo "🗑️ Удаление Kind кластера..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
PRESET=$${PRESET_ARG:-k8s-minimal}; \
CONTAINER_NAME=k8s-$$PRESET; \
if docker ps | grep -q $$CONTAINER_NAME; then \
docker exec $$CONTAINER_NAME bash -c "kind delete clusters --all" 2>/dev/null || true; \
else \
echo "⚠️ Контейнер $$CONTAINER_NAME не запущен"; \
fi; \
docker rm -f $$CONTAINER_NAME 2>/dev/null || true; \
echo "✅ Kind кластер удален";; \
stop) \
echo "🛑 Остановка Kind кластера..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$PRESET_ARG" ]; then \
echo "❌ Ошибка: Укажите пресет"; \
echo "💡 Пример: make k8s stop kubernetes"; \
exit 1; \
fi; \
CONTAINER_NAME=k8s-$$PRESET_ARG; \
if docker ps | grep -q $$CONTAINER_NAME; then \
docker exec $$CONTAINER_NAME bash -c "kind get clusters | xargs -I {} kind stop cluster --name {}" 2>/dev/null || true; \
echo "✅ Kind кластер остановлен"; \
else \
echo "⚠️ Контейнер $$CONTAINER_NAME не запущен"; \
fi; \
echo "💡 Кластер остановлен, но не удален"; \
echo "💡 Для перезапуска: make k8s start $$PRESET_ARG"; \
echo "💡 Для полного удаления: make k8s destroy $$PRESET_ARG";; \
start) \
echo "🚀 Запуск Kind кластера..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$PRESET_ARG" ]; then \
echo "❌ Ошибка: Укажите пресет"; \
echo "💡 Пример: make k8s start kubernetes"; \
exit 1; \
fi; \
CONTAINER_NAME=k8s-$$PRESET_ARG; \
if ! docker ps | grep -q $$CONTAINER_NAME; then \
echo "❌ Контейнер $$CONTAINER_NAME не запущен"; \
echo "💡 Запустите: make k8s create $$PRESET_ARG"; \
exit 1; \
fi; \
docker exec $$CONTAINER_NAME bash -c "kind get clusters | xargs -I {} kind start cluster --name {}" 2>/dev/null || true; \
echo "✅ Kind кластер запущен";; \
status) \
echo "📊 Статус Kind кластеров:"; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$PRESET_ARG" ]; then \
echo "❌ Ошибка: Укажите пресет"; \
echo "💡 Пример: make k8s status kubernetes"; \
exit 1; \
fi; \
CONTAINER_NAME=k8s-$$PRESET_ARG; \
if docker ps | grep -q $$CONTAINER_NAME; then \
docker exec $$CONTAINER_NAME bash -c "kind get clusters" 2>/dev/null || echo " Нет кластеров"; \
docker exec $$CONTAINER_NAME bash -c "kind get clusters | while read cluster; do echo \"Кластер: \$$cluster\"; kubectl --context kind-\$$cluster get nodes 2>/dev/null || true; done" 2>/dev/null || true; \
else \
echo "⚠️ Контейнер $$CONTAINER_NAME не запущен"; \
echo "💡 Запустите: make k8s create $$PRESET_ARG"; \
fi;; \
config) \
echo "📋 Получение kubeconfig..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$PRESET_ARG" ]; then \
echo "❌ Ошибка: Укажите пресет"; \
echo "💡 Пример: make k8s config kubernetes"; \
exit 1; \
fi; \
CONTAINER_NAME=k8s-$$PRESET_ARG; \
if ! docker ps | grep -q $$CONTAINER_NAME; then \
echo "❌ Контейнер $$CONTAINER_NAME не запущен"; \
echo "💡 Запустите: make k8s create $$PRESET_ARG"; \
exit 1; \
fi; \
KUBECONFIG_FILE="$$(pwd)/kubeconfig"; \
docker exec $$CONTAINER_NAME bash -c "kind get kubeconfig" > $$KUBECONFIG_FILE 2>/dev/null || true; \
if [ -f $$KUBECONFIG_FILE ] && [ -s $$KUBECONFIG_FILE ]; then \
echo "✅ kubeconfig сохранен в: $$KUBECONFIG_FILE"; \
echo ""; \
echo "💡 Для использования:"; \
echo " export KUBECONFIG=$$KUBECONFIG_FILE"; \
echo " kubectl get nodes"; \
echo ""; \
echo "💡 Или для однократного использования:"; \
echo " kubectl --kubeconfig=$$KUBECONFIG_FILE get nodes"; \
else \
echo "❌ Не удалось получить kubeconfig"; \
rm -f $$KUBECONFIG_FILE; \
fi;; \
addon) \
echo "📦 Установка аддона..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
MANIFEST_ARG="$(word 4, $(MAKECMDGOALS))"; \
if [ -z "$$PRESET_ARG" ]; then \
echo "❌ Ошибка: Укажите пресет"; \
echo "💡 Пример: make k8s addon kubernetes https://example.com/manifest.yaml"; \
exit 1; \
fi; \
if [ -z "$$MANIFEST_ARG" ]; then \
echo "❌ Ошибка: Укажите URL манифеста"; \
echo "💡 Пример: make k8s addon kubernetes https://example.com/manifest.yaml"; \
exit 1; \
fi; \
CONTAINER_NAME=k8s-$$PRESET_ARG; \
if ! docker ps | grep -q $$CONTAINER_NAME; then \
echo "❌ Контейнер $$CONTAINER_NAME не запущен"; \
echo "💡 Запустите: make k8s create $$PRESET_ARG"; \
exit 1; \
fi; \
CLUSTER_NAME=$$(docker exec $$CONTAINER_NAME kind get clusters | head -1); \
echo "📥 Установка аддона из $$MANIFEST_ARG..."; \
docker exec $$CONTAINER_NAME bash -c "CLUSTER_NAME=$$CLUSTER_NAME; kubectl --server=https://\$${CLUSTER_NAME}-control-plane:6443 --insecure-skip-tls-verify apply -f $$MANIFEST_ARG"; \
echo "✅ Аддон установлен";; \
nodes) \
echo "🖥️ Просмотр узлов кластера..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$PRESET_ARG" ]; then \
echo "❌ Ошибка: Укажите пресет"; \
echo "💡 Пример: make k8s nodes kubernetes"; \
exit 1; \
fi; \
CONTAINER_NAME=k8s-$$PRESET_ARG; \
if ! docker ps | grep -q $$CONTAINER_NAME; then \
echo "❌ Контейнер $$CONTAINER_NAME не запущен"; \
echo "💡 Запустите: make k8s create $$PRESET_ARG"; \
exit 1; \
fi; \
CLUSTER_NAME=$$(docker exec $$CONTAINER_NAME kind get clusters | head -1); \
docker exec $$CONTAINER_NAME bash -c "CLUSTER_NAME=$$CLUSTER_NAME; kubectl --server=https://\$${CLUSTER_NAME}-control-plane:6443 --insecure-skip-tls-verify get nodes";; \
shell) \
echo "🐚 Открытие shell в контейнере..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$PRESET_ARG" ]; then \
echo "❌ Ошибка: Укажите пресет"; \
echo "💡 Пример: make k8s shell kubernetes"; \
exit 1; \
fi; \
CONTAINER_NAME=k8s-$$PRESET_ARG; \
if docker ps | grep -q $$CONTAINER_NAME; then \
docker exec -it $$CONTAINER_NAME bash; \
else \
echo "❌ Контейнер $$CONTAINER_NAME не запущен"; \
echo "💡 Запустите: make k8s create $$PRESET_ARG"; \
fi;; \
*) \
echo "☸️ Доступные команды:"; \
echo ""; \
echo " make k8s create [preset] - создать Kind кластер"; \
echo " 💡 Без параметра: используется k8s-minimal (без аддонов)"; \
echo " 💡 С параметром: используется указанный пресет"; \
echo " 💡 Кластер НЕ удаляется автоматически"; \
echo ""; \
echo " make k8s destroy [preset] - удалить Kind кластер полностью"; \
echo " 💡 Удалит: кластер и контейнер ansible-controller"; \
echo ""; \
echo " make k8s stop [cluster] - остановить Kind кластер (без удаления)"; \
echo " 💡 Можно указать имя кластера или остановить все"; \
echo " 💡 Для перезапуска: make k8s start"; \
echo ""; \
echo " make k8s start [cluster] - запустить остановленный кластер"; \
echo " 💡 Можно указать имя кластера или запустить все"; \
echo ""; \
echo " make k8s status [cluster] - показать статус кластеров"; \
echo " 💡 Можно указать имя конкретного кластера"; \
echo ""; \
echo " make k8s config [cluster] - получить kubeconfig для подключения"; \
echo " 💡 Сохраняет: kubeconfig в корне проекта"; \
echo " 💡 Можно указать имя конкретного кластера"; \
echo ""; \
echo " make k8s addon [preset] [url] - установить аддон из манифеста"; \
echo " 💡 Требует: пресет и URL манифеста"; \
echo " 💡 Пример: make k8s addon kubernetes https://example.com/manifest.yaml"; \
echo ""; \
echo " make k8s nodes [preset] - показать узлы кластера"; \
echo " 💡 Требует: пресет"; \
echo " 💡 Пример: make k8s nodes kubernetes"; \
echo ""; \
echo " make k8s shell [preset] - открыть shell в контейнере"; \
echo " 💡 Для: ручного управления kubectl/kind"; \
echo " 💡 Пример: make k8s shell kubernetes"; \
echo ""; \
echo "💡 Примеры:"; \
echo " make k8s create # создать минимальный кластер"; \
echo " make k8s create kubernetes # создать кластер с аддонами"; \
echo " make k8s nodes kubernetes # показать узлы кластера"; \
echo " make k8s config kubernetes # получить kubeconfig для кластера"; \
echo " export KUBECONFIG=kubeconfig # использовать конфиг"; \
echo " kubectl get nodes # проверить узлы"; \
echo " make k8s addon kubernetes https://example.com/manifest.yaml # установить аддон"; \
echo " make k8s stop kubernetes # остановить кластер"; \
echo " make k8s start kubernetes # запустить кластер"; \
echo " make k8s destroy kubernetes # удалить кластер с пресетом kubernetes";; \
esac
# =============================================================================
# СПРАВКА
# =============================================================================
@@ -1105,6 +1340,17 @@ help:
@echo " make controller run - запустить ansible-controller"
@echo " make controller stop - остановить ansible-controller"
@echo ""
@echo "☸️ KUBERNETES (Kind кластеры):"
@echo " make k8s create [preset] - создать Kind кластер (по умолчанию: k8s-minimal)"
@echo " make k8s destroy [preset] - удалить Kind кластер"
@echo " make k8s start [preset] - запустить Kind кластер"
@echo " make k8s stop [preset] - остановить Kind кластер"
@echo " make k8s status [preset] - показать статус кластера"
@echo " make k8s nodes [preset] - показать узлы кластера"
@echo " make k8s config [preset] - получить kubeconfig для подключения"
@echo " make k8s addon [preset] [url] - установить аддон из манифеста"
@echo " make k8s shell [preset] - открыть shell в контейнере k8s"
@echo ""
@echo "💡 ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:"
@echo " make presets list # показать все preset'ы"
@echo " make presets test PRESET=etcd-patroni # тест с etcd-patroni"