first commit

This commit is contained in:
Sergey Antropoff
2026-04-17 08:37:27 +03:00
commit 095b276cb3
82 changed files with 5731 additions and 0 deletions

326
Makefile Normal file
View File

@@ -0,0 +1,326 @@
# ═══════════════════════════════════════════════════════════════════════════════
# K3S Ansible Stack — Makefile
# Всё запускается через Docker — Ansible устанавливать не нужно!
#
# Требования: docker, make
# Начало работы: make setup → отредактируй .env и inventory → make install
# ═══════════════════════════════════════════════════════════════════════════════
# ── Конфигурация ──────────────────────────────────────────────────────────────
IMAGE_NAME := k3s-ansible
CONTAINER_NAME := k3s-ansible-runner
# Загружаем .env если существует
-include .env
export
# Цвета терминала
CYAN := \033[0;36m
GREEN := \033[0;32m
YELLOW := \033[1;33m
RED := \033[0;31m
BOLD := \033[1m
NC := \033[0m
# ── Базовая команда запуска контейнера ────────────────────────────────────────
DOCKER_RUN := docker run --rm -it \
--name $(CONTAINER_NAME) \
--network host \
-v $(PWD):/ansible \
-v $(or $(SSH_KEY_PATH),$(HOME)/.ssh):/root/.ssh:ro \
-e VAULT_PASSWORD="$(VAULT_PASSWORD)" \
-e ANSIBLE_VERBOSITY="$(ANSIBLE_VERBOSITY)" \
-e ANSIBLE_TAGS="$(ANSIBLE_TAGS)" \
-e ANSIBLE_SKIP_TAGS="$(ANSIBLE_SKIP_TAGS)" \
-e EXTRA_VARS="$(EXTRA_VARS)" \
-e VERSION="$(VERSION)" \
-e ANSIBLE_FORCE_COLOR=1 \
$(IMAGE_NAME)
.PHONY: help setup build rebuild \
install install-k3s install-cni install-kubevip install-nfs install-ingress \
install-istio install-monitoring \
upgrade uninstall health verify ping \
shell lint check \
molecule-k3s molecule-prometheus molecule-istio molecule-all molecule-lint \
vault-create vault-edit vault-view vault-encrypt-string \
clean clean-all \
_check_env _check_image _check_molecule
# ── DEFAULT ───────────────────────────────────────────────────────────────────
.DEFAULT_GOAL := help
help: ## Показать эту справку
@echo ""
@printf "$(CYAN)$(BOLD)K3S Ansible Stack — управление через Docker$(NC)\n"
@printf "$(CYAN)━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━$(NC)\n"
@echo ""
@printf "$(BOLD)Первый запуск:$(NC)\n"
@echo " 1. make setup — создать .env из шаблона"
@echo " 2. Отредактируй .env и inventory/hosts.ini"
@echo " 3. make build — собрать Docker образ"
@echo " 4. make vault-create — создать vault с токеном"
@echo " 5. make ping — проверить SSH"
@echo " 6. make install — развернуть полный стек"
@echo ""
@printf "$(BOLD)Все команды:$(NC)\n"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) \
| grep -v '^_' \
| awk 'BEGIN {FS = ":.*?## "}; {printf " $(CYAN)%-26s$(NC) %s\n", $$1, $$2}'
@echo ""
@printf "$(BOLD)Переменные (передаются в командной строке):$(NC)\n"
@printf " $(CYAN)VERSION$(NC)=v1.30.0+k3s1 версия K3S для upgrade\n"
@printf " $(CYAN)ANSIBLE_VERBOSITY$(NC)=2 уровень debug вывода (0-4)\n"
@printf " $(CYAN)ANSIBLE_TAGS$(NC)=k3s,kube_vip запустить только теги\n"
@echo ""
# ═══════════════════════════════════════════════════════════════════════════════
# НАСТРОЙКА
# ═══════════════════════════════════════════════════════════════════════════════
setup: ## Первоначальная настройка: создать .env из шаблона
@if [ -f .env ]; then \
printf "$(YELLOW)⚠ .env уже существует, пропускаю$(NC)\n"; \
else \
cp .env.example .env; \
printf "$(GREEN)✓ Создан .env$(NC)\n"; \
fi
@echo ""
@printf "$(BOLD)Следующие шаги:$(NC)\n"
@echo " 1. nano .env — задай VAULT_PASSWORD"
@echo " 2. nano inventory/hosts.ini — укажи IP серверов"
@echo " 3. nano group_vars/all/main.yml — задай kube_vip_address и интерфейс"
@echo " 4. make build — собери Docker образ"
@echo " 5. make vault-create — создай vault"
@echo " 6. make ping — проверь SSH"
@echo " 7. make install — разверни стек"
# ═══════════════════════════════════════════════════════════════════════════════
# DOCKER ОБРАЗ
# ═══════════════════════════════════════════════════════════════════════════════
build: ## Собрать Docker образ ansible-runner
@printf "$(CYAN)Сборка образа $(IMAGE_NAME)...$(NC)\n"
docker build \
--build-arg HELM_VERSION=3.14.4 \
--build-arg KUBECTL_VERSION=v1.29.3 \
-t $(IMAGE_NAME):latest \
-f Dockerfile .
@printf "$(GREEN)✓ Образ $(IMAGE_NAME):latest собран$(NC)\n"
rebuild: ## Пересобрать образ без кэша
@printf "$(CYAN)Пересборка без кэша...$(NC)\n"
docker build --no-cache \
--build-arg HELM_VERSION=3.14.4 \
--build-arg KUBECTL_VERSION=v1.29.3 \
-t $(IMAGE_NAME):latest \
-f Dockerfile .
@printf "$(GREEN)✓ Готово$(NC)\n"
# ═══════════════════════════════════════════════════════════════════════════════
# ПРОВЕРКИ
# ═══════════════════════════════════════════════════════════════════════════════
ping: _check_env _check_image ## Проверить SSH доступность всех нод
@printf "$(CYAN)Проверка SSH...$(NC)\n"
$(DOCKER_RUN) ping
check: _check_env _check_image ## Dry-run: проверить плейбук без изменений
@printf "$(CYAN)Dry-run...$(NC)\n"
$(DOCKER_RUN) ansible-playbook site.yml --check --diff
lint: _check_image ## Проверить синтаксис всех плейбуков
@printf "$(CYAN)Проверка синтаксиса...$(NC)\n"
$(DOCKER_RUN) ansible-playbook site.yml --syntax-check
@printf "$(GREEN)✓ Синтаксис корректен$(NC)\n"
# ═══════════════════════════════════════════════════════════════════════════════
# УСТАНОВКА
# ═══════════════════════════════════════════════════════════════════════════════
install: _check_env _check_image ## Развернуть полный стек (K3S + kube-vip + NFS + ingress)
@printf "$(CYAN)$(BOLD)Разворачиваю полный K3S стек...$(NC)\n"
$(DOCKER_RUN) install
install-k3s: _check_env _check_image ## Установить только K3S кластер
@printf "$(CYAN)Устанавливаю K3S...$(NC)\n"
$(DOCKER_RUN) install-k3s
install-cni: _check_env _check_image ## Установить CNI плагин (задай K3S_CNI=calico|cilium)
@printf "$(CYAN)Устанавливаю CNI ($(or $(K3S_CNI),flannel))...$(NC)\n"
$(DOCKER_RUN) ansible-playbook site.yml --tags cni $(if $(K3S_CNI),-e k3s_cni=$(K3S_CNI),)
install-kubevip: _check_env _check_image ## Установить только kube-vip
@printf "$(CYAN)Устанавливаю kube-vip...$(NC)\n"
$(DOCKER_RUN) install-kubevip
install-nfs: _check_env _check_image ## Установить NFS сервер + CSI Driver
@printf "$(CYAN)Устанавливаю NFS + CSI...$(NC)\n"
$(DOCKER_RUN) install-nfs
install-ingress: _check_env _check_image ## Установить ingress-nginx
@printf "$(CYAN)Устанавливаю ingress-nginx...$(NC)\n"
$(DOCKER_RUN) install-ingress
install-istio: _check_env _check_image ## Установить Istio + Kiali (нужен istio_enabled: true в vars)
@printf "$(CYAN)Устанавливаю Istio + Kiali...$(NC)\n"
$(DOCKER_RUN) ansible-playbook site.yml --tags istio -e istio_enabled=true
install-monitoring: _check_env _check_image ## Установить Prometheus + Grafana (нужен prometheus_stack_enabled: true)
@printf "$(CYAN)Устанавливаю kube-prometheus-stack...$(NC)\n"
$(DOCKER_RUN) ansible-playbook site.yml --tags monitoring -e prometheus_stack_enabled=true
# ═══════════════════════════════════════════════════════════════════════════════
# ОБНОВЛЕНИЕ
# ═══════════════════════════════════════════════════════════════════════════════
upgrade: _check_env _check_image ## Обновить K3S (make upgrade VERSION=v1.30.0+k3s1)
@if [ -z "$(VERSION)" ]; then \
printf "$(RED)✗ Укажи версию: make upgrade VERSION=v1.30.0+k3s1$(NC)\n"; \
exit 1; \
fi
@printf "$(CYAN)Обновляю K3S до $(VERSION)...$(NC)\n"
$(DOCKER_RUN) upgrade
# ═══════════════════════════════════════════════════════════════════════════════
# ДИАГНОСТИКА
# ═══════════════════════════════════════════════════════════════════════════════
health: _check_env _check_image ## Диагностика кластера (сервисы, поды, диск, память)
@printf "$(CYAN)Диагностика...$(NC)\n"
$(DOCKER_RUN) health
verify: _check_env _check_image ## Проверить весь стек (nodes/pods/svc/sc/ingress)
@printf "$(CYAN)Проверка стека...$(NC)\n"
$(DOCKER_RUN) verify
# ═══════════════════════════════════════════════════════════════════════════════
# УДАЛЕНИЕ
# ═══════════════════════════════════════════════════════════════════════════════
uninstall: _check_env _check_image ## ВНИМАНИЕ: удалить весь стек и данные
@printf "$(RED)$(BOLD)ВНИМАНИЕ: Удаление всего стека — данные будут потеряны!$(NC)\n"
@printf "$(YELLOW)Введи 'yes' для подтверждения: $(NC)"; \
read CONFIRM && [ "$$CONFIRM" = "yes" ] || (printf "Отменено.\n" && exit 1)
$(DOCKER_RUN) uninstall
# ═══════════════════════════════════════════════════════════════════════════════
# ANSIBLE VAULT
# ═══════════════════════════════════════════════════════════════════════════════
vault-create: _check_image ## Создать зашифрованный vault (group_vars/all/vault.yml)
@printf "$(CYAN)Создание vault...$(NC)\n"
docker run --rm -it \
-v $(PWD):/ansible \
$(IMAGE_NAME) \
ansible vault create group_vars/all/vault.yml
@printf "$(GREEN)✓ Vault создан$(NC)\n"
vault-edit: _check_image ## Редактировать vault
docker run --rm -it \
-v $(PWD):/ansible \
-e VAULT_PASSWORD="$(VAULT_PASSWORD)" \
$(IMAGE_NAME) \
ansible vault edit group_vars/all/vault.yml
vault-view: _check_image ## Просмотреть vault (расшифрованный вывод)
docker run --rm -it \
-v $(PWD):/ansible \
-e VAULT_PASSWORD="$(VAULT_PASSWORD)" \
$(IMAGE_NAME) \
ansible vault view group_vars/all/vault.yml
vault-encrypt-string: _check_image ## Зашифровать строку: make vault-encrypt-string STR=... NAME=...
@if [ -z "$(STR)" ]; then \
printf "$(RED)✗ Нужна строка: make vault-encrypt-string STR=мой-токен NAME=vault_k3s_token$(NC)\n"; \
exit 1; \
fi
docker run --rm -it \
-v $(PWD):/ansible \
-e VAULT_PASSWORD="$(VAULT_PASSWORD)" \
$(IMAGE_NAME) \
ansible vault encrypt_string '$(STR)' --name '$(or $(NAME),encrypted_var)'
# ═══════════════════════════════════════════════════════════════════════════════
# MOLECULE — ТЕСТИРОВАНИЕ РОЛЕЙ
# Требования: pip install -r requirements-python.txt (molecule, molecule-plugins[docker])
# ═══════════════════════════════════════════════════════════════════════════════
molecule-k3s: _check_molecule ## Тест роли k3s (Docker, ~5 мин)
@printf "$(CYAN)Тестирую роль k3s...$(NC)\n"
cd roles/k3s && molecule test
@printf "$(GREEN)✓ k3s role: OK$(NC)\n"
molecule-prometheus: _check_molecule ## Тест роли prometheus-stack (шаблоны + PVC)
@printf "$(CYAN)Тестирую роль prometheus-stack...$(NC)\n"
cd roles/prometheus-stack && molecule test
@printf "$(GREEN)✓ prometheus-stack role: OK$(NC)\n"
molecule-istio: _check_molecule ## Тест роли istio + kiali (шаблоны)
@printf "$(CYAN)Тестирую роль istio...$(NC)\n"
cd roles/istio && molecule test
@printf "$(GREEN)✓ istio role: OK$(NC)\n"
molecule-all: _check_molecule ## Запустить все Molecule тесты последовательно
@printf "$(CYAN)$(BOLD)Запуск всех Molecule тестов...$(NC)\n"
$(MAKE) molecule-k3s
$(MAKE) molecule-prometheus
$(MAKE) molecule-istio
@printf "$(GREEN)$(BOLD)Все тесты прошли успешно$(NC)\n"
molecule-lint: _check_molecule ## Только линтинг (yamllint + ansible-lint), без Docker
@printf "$(CYAN)Запуск линтинга...$(NC)\n"
yamllint .
ansible-lint
@printf "$(GREEN)✓ Линтинг прошёл$(NC)\n"
# ═══════════════════════════════════════════════════════════════════════════════
# ИНТЕРАКТИВНЫЙ SHELL
# ═══════════════════════════════════════════════════════════════════════════════
shell: _check_image ## Запустить интерактивный bash внутри контейнера
@printf "$(CYAN)Запуск shell (exit для выхода)...$(NC)\n"
docker run --rm -it \
--name $(CONTAINER_NAME)-shell \
--network host \
-v $(PWD):/ansible \
-v $(or $(SSH_KEY_PATH),$(HOME)/.ssh):/root/.ssh:ro \
-e VAULT_PASSWORD="$(VAULT_PASSWORD)" \
-e ANSIBLE_FORCE_COLOR=1 \
$(IMAGE_NAME) shell
# ═══════════════════════════════════════════════════════════════════════════════
# ОЧИСТКА
# ═══════════════════════════════════════════════════════════════════════════════
clean: ## Удалить Docker образ
@printf "$(YELLOW)Удаляю образ $(IMAGE_NAME)...$(NC)\n"
docker rmi $(IMAGE_NAME):latest 2>/dev/null || printf "$(YELLOW)Образ не найден$(NC)\n"
clean-all: clean ## Удалить образ + kubeconfig + кэш Docker
rm -f kubeconfig
docker system prune -f
@printf "$(GREEN)✓ Очистка завершена$(NC)\n"
# ═══════════════════════════════════════════════════════════════════════════════
# ВНУТРЕННИЕ
# ═══════════════════════════════════════════════════════════════════════════════
_check_env:
@if [ ! -f .env ]; then \
printf "$(RED)✗ Файл .env не найден! Запусти: make setup$(NC)\n"; \
exit 1; \
fi
_check_image:
@if ! docker image inspect $(IMAGE_NAME):latest > /dev/null 2>&1; then \
printf "$(YELLOW)⚠ Образ не найден, собираю...$(NC)\n"; \
$(MAKE) build; \
fi
_check_molecule:
@if ! python3 -c "import molecule" 2>/dev/null; then \
printf "$(RED)✗ Molecule не установлен!$(NC)\n"; \
printf "$(YELLOW) Запусти: pip install -r requirements-python.txt$(NC)\n"; \
exit 1; \
fi