Compare commits
15 Commits
podman
...
d6bc3f1f31
| Author | SHA1 | Date | |
|---|---|---|---|
| d6bc3f1f31 | |||
| a875a874e9 | |||
| e6287769d6 | |||
| 51c76fb859 | |||
| dc255d006a | |||
| 26a09cd637 | |||
| df97e9d3d4 | |||
| 09ca55539f | |||
| 9c55c8f615 | |||
| f2a0f46813 | |||
| 8071fba25f | |||
| d32ca54f7b | |||
| b1bae8af9f | |||
| 33ada54c12 | |||
| b4881da7c5 |
@@ -5,3 +5,7 @@ skip_list:
|
|||||||
- yaml[line-length]
|
- yaml[line-length]
|
||||||
- var-naming[no-role-prefix]
|
- var-naming[no-role-prefix]
|
||||||
- 'ignore-errors'
|
- 'ignore-errors'
|
||||||
|
|
||||||
|
exclude_paths:
|
||||||
|
- molecule/universal/
|
||||||
|
- files/playbooks/
|
||||||
842
Makefile
842
Makefile
@@ -1,157 +1,713 @@
|
|||||||
# Глобальные переменные
|
# =============================================================================
|
||||||
IMAGE ?= ansible
|
# Ansible Template - Универсальная лаборатория для тестирования Ansible ролей
|
||||||
TAG ?= 0.1
|
# Автор: Сергей Антропов
|
||||||
REGISTRY ?= inecs/ansible
|
# Сайт: https://devops.org.ru
|
||||||
# По умолчанию используем docker. Для локальной разработки используйте docker-compose
|
# =============================================================================
|
||||||
RUN_MODE ?= docker
|
|
||||||
|
|
||||||
# Определение команды RUN в зависимости от RUN_MODE
|
# =============================================================================
|
||||||
ifeq ($(RUN_MODE), docker-compose)
|
# ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
|
||||||
RUN = docker compose run --rm $(IMAGE)
|
# =============================================================================
|
||||||
else ifeq ($(RUN_MODE), docker)
|
|
||||||
RUN = docker run -it --rm \
|
|
||||||
--name $(IMAGE) \
|
|
||||||
-v $(PWD):/ansible \
|
|
||||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
|
||||||
-v ~/.ssh/id_rsa:/root/.ssh/id_rsa:ro \
|
|
||||||
-e ANSIBLE_VAULT_PASSWORD_FILE=/ansible/vault-password.txt \
|
|
||||||
--privileged \
|
|
||||||
--workdir /ansible \
|
|
||||||
$(REGISTRY)/$(IMAGE)
|
|
||||||
else
|
|
||||||
$(error Invalid RUN_MODE. Use "docker-compose" or "docker")
|
|
||||||
endif
|
|
||||||
|
|
||||||
view create edit show delete test lint deploy new init build rebuild prune release images push pull shell:
|
# Основные переменные
|
||||||
@true
|
PROJECT_NAME ?= ansible-template
|
||||||
|
VERSION ?= 0.1.0
|
||||||
|
AUTHOR ?= "Сергей Антропов"
|
||||||
|
SITE ?= "https://devops.org.ru"
|
||||||
|
|
||||||
####################################################################################################
|
# Docker переменные
|
||||||
# Инициализация новой роли
|
DOCKER_IMAGE ?= quay.io/ansible/creator-ee:latest
|
||||||
####################################################################################################
|
DOCKER_COMPOSE ?= docker compose
|
||||||
init:
|
DOCKER_NETWORK ?= labnet
|
||||||
@echo "Шаг 1: Создание Docker-образа..."
|
|
||||||
@make docker build
|
|
||||||
@echo "Шаг 2: Создание Docker-образов для запуска Molecule..."
|
|
||||||
@make docker images
|
|
||||||
@echo "Шаг 3: Создание нового vault-файла с паролем..."
|
|
||||||
@read -p "Введите пароль для vault: " VAULT_PASSWORD; \
|
|
||||||
echo "$$VAULT_PASSWORD" > vault-password.txt; \
|
|
||||||
make vault create
|
|
||||||
@echo "Шаг 4: Создание нового брэнча в гите..."
|
|
||||||
@make git new
|
|
||||||
@echo "Шаг 5: Создание новой роли..."
|
|
||||||
@make role new
|
|
||||||
|
|
||||||
####################################################################################################
|
# Molecule переменные
|
||||||
# Управление контейнерами с помощью docker compose или docker run
|
SCENARIO ?= universal
|
||||||
####################################################################################################
|
LAB_SPEC ?= molecule/presets/minimal.yml
|
||||||
docker:
|
MOLECULE_EPHEMERAL_DIRECTORY ?= /tmp/molecule
|
||||||
|
|
||||||
|
# Kubernetes переменные
|
||||||
|
KUBE_CONTEXT ?= kind-lab
|
||||||
|
ISTIO_VERSION ?= 1.22.1
|
||||||
|
KIND_VERSION ?= v0.23.0
|
||||||
|
|
||||||
|
# Переменные окружения
|
||||||
|
ENV_FILE ?= .env
|
||||||
|
ROLES_DIR ?= ./roles
|
||||||
|
VAULT_PASSWORD_FILE ?= vault/.vault
|
||||||
|
|
||||||
|
# Цвета для вывода
|
||||||
|
RED := \033[0;31m
|
||||||
|
GREEN := \033[0;32m
|
||||||
|
YELLOW := \033[0;33m
|
||||||
|
BLUE := \033[0;34m
|
||||||
|
PURPLE := \033[0;35m
|
||||||
|
CYAN := \033[0;36m
|
||||||
|
WHITE := \033[0;37m
|
||||||
|
RESET := \033[0m
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# ОСНОВНЫЕ КОМАНДЫ
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
.PHONY: help
|
||||||
|
help: ## Показать справку по всем командам
|
||||||
|
@echo "$(CYAN)Ansible Template - Универсальная лаборатория$(RESET)"
|
||||||
|
@echo "$(YELLOW)Автор: $(AUTHOR)$(RESET)"
|
||||||
|
@echo "$(YELLOW)Сайт: $(SITE)$(RESET)"
|
||||||
|
@echo ""
|
||||||
|
@echo "$(GREEN)Основные команды:$(RESET)"
|
||||||
|
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " $(CYAN)%-20s$(RESET) %s\n", $$1, $$2}' $(MAKEFILE_LIST) | grep -E "^(init|setup|clean|help)"
|
||||||
|
@echo ""
|
||||||
|
@echo "$(GREEN)Лаборатория:$(RESET)"
|
||||||
|
@awk 'BEGIN {FS = ":.*?## "} /^lab-[a-zA-Z_-]+:.*?## / {printf " $(CYAN)%-20s$(RESET) %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||||
|
@echo ""
|
||||||
|
@echo "$(GREEN)Kubernetes:$(RESET)"
|
||||||
|
@awk 'BEGIN {FS = ":.*?## "} /^kube-[a-zA-Z_-]+:.*?## / {printf " $(CYAN)%-20s$(RESET) %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||||
|
@echo ""
|
||||||
|
@echo "$(GREEN)Отчеты и мониторинг:$(RESET)"
|
||||||
|
@awk 'BEGIN {FS = ":.*?## "} /^(report|kubeconfigs|open-report|full-test):.*?## / {printf " $(CYAN)%-20s$(RESET) %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||||
|
@echo ""
|
||||||
|
@echo "$(GREEN)Пресеты:$(RESET)"
|
||||||
|
@awk 'BEGIN {FS = ":.*?## "} /^preset-[a-zA-Z_-]+:.*?## / {printf " $(CYAN)%-20s$(RESET) %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||||
|
@echo ""
|
||||||
|
@echo "$(GREEN)Роли:$(RESET)"
|
||||||
|
@awk 'BEGIN {FS = ":.*?## "} /^role-[a-zA-Z_-]+:.*?## / {printf " $(CYAN)%-20s$(RESET) %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||||
|
@echo ""
|
||||||
|
@echo "$(GREEN)Утилиты:$(RESET)"
|
||||||
|
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " $(CYAN)%-20s$(RESET) %s\n", $$1, $$2}' $(MAKEFILE_LIST) | grep -E "^(lint|env|vault|git|docker|report|snapshot|cleanup|chaos|check-secrets|idempotence)"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# ИНИЦИАЛИЗАЦИЯ И НАСТРОЙКА
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
.PHONY: init
|
||||||
|
init: setup-env setup-vault setup-roles setup-precommit ## Полная инициализация проекта
|
||||||
|
@echo "$(GREEN)✅ Проект успешно инициализирован!$(RESET)"
|
||||||
|
@echo "$(YELLOW)📖 Документация: $(SITE)$(RESET)"
|
||||||
|
@echo "$(YELLOW)🚀 Быстрый старт: make lab up$(RESET)"
|
||||||
|
|
||||||
|
.PHONY: setup-env
|
||||||
|
setup-env: ## Создать .env файл с настройками
|
||||||
|
@if [ ! -f $(ENV_FILE) ]; then \
|
||||||
|
echo "$(YELLOW)Создание .env файла...$(RESET)"; \
|
||||||
|
echo "# Ansible Template Environment" > $(ENV_FILE); \
|
||||||
|
echo "PROJECT_NAME=$(PROJECT_NAME)" >> $(ENV_FILE); \
|
||||||
|
echo "VERSION=$(VERSION)" >> $(ENV_FILE); \
|
||||||
|
echo "AUTHOR=$(AUTHOR)" >> $(ENV_FILE); \
|
||||||
|
echo "SITE=$(SITE)" >> $(ENV_FILE); \
|
||||||
|
echo "" >> $(ENV_FILE); \
|
||||||
|
echo "# Docker settings" >> $(ENV_FILE); \
|
||||||
|
echo "DOCKER_IMAGE=$(DOCKER_IMAGE)" >> $(ENV_FILE); \
|
||||||
|
echo "DOCKER_NETWORK=$(DOCKER_NETWORK)" >> $(ENV_FILE); \
|
||||||
|
echo "" >> $(ENV_FILE); \
|
||||||
|
echo "# Molecule settings" >> $(ENV_FILE); \
|
||||||
|
echo "SCENARIO=$(SCENARIO)" >> $(ENV_FILE); \
|
||||||
|
echo "LAB_SPEC=$(LAB_SPEC)" >> $(ENV_FILE); \
|
||||||
|
echo "" >> $(ENV_FILE); \
|
||||||
|
echo "# Kubernetes settings" >> $(ENV_FILE); \
|
||||||
|
echo "KUBE_CONTEXT=$(KUBE_CONTEXT)" >> $(ENV_FILE); \
|
||||||
|
echo "ISTIO_VERSION=$(ISTIO_VERSION)" >> $(ENV_FILE); \
|
||||||
|
echo "KIND_VERSION=$(KIND_VERSION)" >> $(ENV_FILE); \
|
||||||
|
echo "" >> $(ENV_FILE); \
|
||||||
|
echo "# Paths" >> $(ENV_FILE); \
|
||||||
|
echo "ROLES_DIR=$(ROLES_DIR)" >> $(ENV_FILE); \
|
||||||
|
echo "VAULT_PASSWORD_FILE=$(VAULT_PASSWORD_FILE)" >> $(ENV_FILE); \
|
||||||
|
echo "$(GREEN)✅ .env файл создан$(RESET)"; \
|
||||||
|
else \
|
||||||
|
echo "$(YELLOW)⚠️ .env файл уже существует$(RESET)"; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
.PHONY: setup-vault
|
||||||
|
setup-vault: ## Создать vault-password.txt
|
||||||
|
@if [ ! -f $(VAULT_PASSWORD_FILE) ]; then \
|
||||||
|
echo "$(YELLOW)Создание vault-password.txt...$(RESET)"; \
|
||||||
|
echo "ansible-vault-password" > $(VAULT_PASSWORD_FILE); \
|
||||||
|
echo "$(GREEN)✅ vault-password.txt создан$(RESET)"; \
|
||||||
|
else \
|
||||||
|
echo "$(YELLOW)⚠️ vault-password.txt уже существует$(RESET)"; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
.PHONY: setup-roles
|
||||||
|
setup-roles: ## Создать директорию для ролей
|
||||||
|
@mkdir -p $(ROLES_DIR)
|
||||||
|
@echo "$(GREEN)✅ Директория ролей создана: $(ROLES_DIR)$(RESET)"
|
||||||
|
|
||||||
|
.PHONY: setup-precommit
|
||||||
|
setup-precommit: ## Установить pre-commit хуки
|
||||||
|
@if command -v pre-commit >/dev/null 2>&1; then \
|
||||||
|
pre-commit install; \
|
||||||
|
echo "$(GREEN)✅ Pre-commit хуки установлены$(RESET)"; \
|
||||||
|
else \
|
||||||
|
echo "$(YELLOW)⚠️ pre-commit не установлен. Установите: pip install pre-commit$(RESET)"; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# УПРАВЛЕНИЕ ЛАБОРАТОРИЕЙ
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
.PHONY: lab
|
||||||
|
lab: ## Управление лабораторией (up|down|sh|test|create|converge|verify|destroy|reset)
|
||||||
|
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||||
|
up) \
|
||||||
|
echo "$(GREEN)🚀 Поднимаем контроллер...$(RESET)"; \
|
||||||
|
$(DOCKER_COMPOSE) up -d; \
|
||||||
|
echo "$(GREEN)✅ Контроллер запущен$(RESET)";; \
|
||||||
|
down) \
|
||||||
|
echo "$(YELLOW)🛑 Останавливаем контроллер...$(RESET)"; \
|
||||||
|
$(DOCKER_COMPOSE) down -v; \
|
||||||
|
echo "$(GREEN)✅ Контроллер остановлен$(RESET)";; \
|
||||||
|
sh) \
|
||||||
|
echo "$(BLUE)🐚 Входим в контроллер...$(RESET)"; \
|
||||||
|
docker exec -it ansible-controller bash;; \
|
||||||
|
test) \
|
||||||
|
echo "$(PURPLE)🧪 Запускаем полный цикл тестирования...$(RESET)"; \
|
||||||
|
$(MAKE) lab up; \
|
||||||
|
docker exec -e MOLECULE_EPHEMERAL_DIRECTORY=$(MOLECULE_EPHEMERAL_DIRECTORY) ansible-controller \
|
||||||
|
bash -lc 'cd /ansible && molecule test -s $(SCENARIO)'; \
|
||||||
|
echo "$(GREEN)✅ Тестирование завершено$(RESET)";; \
|
||||||
|
create) \
|
||||||
|
echo "$(BLUE)🏗️ Создаем инфраструктуру...$(RESET)"; \
|
||||||
|
$(MAKE) lab up; \
|
||||||
|
docker exec -e MOLECULE_EPHEMERAL_DIRECTORY=$(MOLECULE_EPHEMERAL_DIRECTORY) ansible-controller \
|
||||||
|
bash -lc 'cd /ansible && molecule create -s $(SCENARIO)'; \
|
||||||
|
echo "$(GREEN)✅ Инфраструктура создана$(RESET)";; \
|
||||||
|
converge) \
|
||||||
|
echo "$(YELLOW)⚙️ Запускаем роли...$(RESET)"; \
|
||||||
|
docker exec -e MOLECULE_EPHEMERAL_DIRECTORY=$(MOLECULE_EPHEMERAL_DIRECTORY) ansible-controller \
|
||||||
|
bash -lc 'cd /ansible && molecule converge -s $(SCENARIO)'; \
|
||||||
|
echo "$(GREEN)✅ Роли выполнены$(RESET)";; \
|
||||||
|
verify) \
|
||||||
|
echo "$(CYAN)🔍 Проверяем работу лаборатории...$(RESET)"; \
|
||||||
|
docker exec -e MOLECULE_EPHEMERAL_DIRECTORY=$(MOLECULE_EPHEMERAL_DIRECTORY) ansible-controller \
|
||||||
|
bash -lc 'cd /ansible && molecule verify -s $(SCENARIO)'; \
|
||||||
|
echo "$(GREEN)✅ Проверка завершена$(RESET)";; \
|
||||||
|
destroy) \
|
||||||
|
echo "$(RED)💥 Уничтожаем инфраструктуру...$(RESET)"; \
|
||||||
|
docker exec -e MOLECULE_EPHEMERAL_DIRECTORY=$(MOLECULE_EPHEMERAL_DIRECTORY) ansible-controller \
|
||||||
|
bash -lc 'cd /ansible && molecule destroy -s $(SCENARIO)'; \
|
||||||
|
echo "$(GREEN)✅ Инфраструктура уничтожена$(RESET)";; \
|
||||||
|
reset) \
|
||||||
|
echo "$(PURPLE)🔄 Полный сброс лаборатории...$(RESET)"; \
|
||||||
|
$(MAKE) lab destroy; \
|
||||||
|
$(MAKE) lab down; \
|
||||||
|
$(MAKE) lab up; \
|
||||||
|
echo "$(GREEN)✅ Лаборатория сброшена$(RESET)";; \
|
||||||
|
*) \
|
||||||
|
echo "$(RED)❌ Неизвестная команда. Доступные: up, down, sh, test, create, converge, verify, destroy, reset$(RESET)";; \
|
||||||
|
esac
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# УПРАВЛЕНИЕ KUBERNETES
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
.PHONY: kube
|
||||||
|
kube: ## Управление Kubernetes (sh|cmd|enter|kiali|istio|grafana|prom|pf-stop)
|
||||||
|
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||||
|
sh) \
|
||||||
|
echo "$(BLUE)🐚 Входим в контейнер с kubectl...$(RESET)"; \
|
||||||
|
docker exec -it ansible-controller bash;; \
|
||||||
|
cmd) \
|
||||||
|
if [ -z "$(CLUSTER)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make kube cmd CLUSTER=lab CMD=\"get pods -A\"$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(CYAN)🔧 Выполняем kubectl команду...$(RESET)"; \
|
||||||
|
docker exec -it ansible-controller bash -lc 'kubectl --context kind-$(CLUSTER) $(CMD)';; \
|
||||||
|
enter) \
|
||||||
|
if [ -z "$(CLUSTER)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make kube enter CLUSTER=lab$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(BLUE)🚪 Входим в кластер...$(RESET)"; \
|
||||||
|
docker exec -it ansible-controller bash -lc '\
|
||||||
|
POD=$$(kubectl --context kind-$(CLUSTER) -n lab-demo get pod -l app=toolbox -o jsonpath="{.items[0].metadata.name}"); \
|
||||||
|
[ -n "$$POD" ] || { echo "toolbox pod not found"; exit 1; }; \
|
||||||
|
kubectl --context kind-$(CLUSTER) -n lab-demo exec -it $$POD -- /bin/sh';; \
|
||||||
|
kiali) \
|
||||||
|
if [ -z "$(CLUSTER)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make kube kiali CLUSTER=lab$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(PURPLE)🔮 Port-forward Kiali...$(RESET)"; \
|
||||||
|
docker exec -d ansible-controller bash -lc 'kubectl --context kind-$(CLUSTER) -n istio-system port-forward svc/kiali 20001:20001'; \
|
||||||
|
echo "$(GREEN)✅ Kiali: http://localhost:20001$(RESET)";; \
|
||||||
|
istio) \
|
||||||
|
if [ -z "$(CLUSTER)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make kube istio CLUSTER=lab$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(PURPLE)🌐 Port-forward Istio Gateway...$(RESET)"; \
|
||||||
|
docker exec -d ansible-controller bash -lc 'kubectl --context kind-$(CLUSTER) -n istio-system port-forward svc/istio-ingressgateway 8082:80 8444:443'; \
|
||||||
|
echo "$(GREEN)✅ Istio GW: http://localhost:8082 https://localhost:8444$(RESET)";; \
|
||||||
|
grafana) \
|
||||||
|
if [ -z "$(CLUSTER)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make kube grafana CLUSTER=lab$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(BLUE)📊 Port-forward Grafana...$(RESET)"; \
|
||||||
|
docker exec -d ansible-controller bash -lc 'kubectl --context kind-$(CLUSTER) -n monitoring port-forward svc/monitoring-grafana 3000:80'; \
|
||||||
|
echo "$(GREEN)✅ Grafana: http://localhost:3000 (admin/admin)$(RESET)";; \
|
||||||
|
prom) \
|
||||||
|
if [ -z "$(CLUSTER)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make kube prom CLUSTER=lab$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(YELLOW)📈 Port-forward Prometheus...$(RESET)"; \
|
||||||
|
docker exec -d ansible-controller bash -lc 'kubectl --context kind-$(CLUSTER) -n monitoring port-forward svc/monitoring-kube-prometheus-prometheus 9090:9090'; \
|
||||||
|
echo "$(GREEN)✅ Prometheus: http://localhost:9090$(RESET)";; \
|
||||||
|
pf-stop) \
|
||||||
|
echo "$(RED)🛑 Останавливаем все port-forward...$(RESET)"; \
|
||||||
|
docker exec -it ansible-controller bash -lc 'pkill -f "kubectl .* port-forward" || true'; \
|
||||||
|
echo "$(GREEN)✅ Port-forward остановлены$(RESET)";; \
|
||||||
|
kubeconfig) \
|
||||||
|
if [ -z "$(CLUSTER)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make kube kubeconfig CLUSTER=lab$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(BLUE)📋 Получаем kubeconfig для кластера $(CLUSTER)...$(RESET)"; \
|
||||||
|
mkdir -p reports/kubeconfigs; \
|
||||||
|
docker exec ansible-controller bash -lc 'kubectl --context kind-$(CLUSTER) config view --raw' > reports/kubeconfigs/kubeconfig-$(CLUSTER).yaml; \
|
||||||
|
echo "$(GREEN)✅ Kubeconfig сохранен: reports/kubeconfigs/kubeconfig-$(CLUSTER).yaml$(RESET)";; \
|
||||||
|
*) \
|
||||||
|
echo "$(RED)❌ Неизвестная команда. Доступные: sh, cmd, enter, kiali, istio, grafana, prom, pf-stop, kubeconfig$(RESET)";; \
|
||||||
|
esac
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# УПРАВЛЕНИЕ ПРЕСЕТАМИ
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
.PHONY: preset
|
||||||
|
preset: ## Управление пресетами (list|create|edit|test|copy)
|
||||||
|
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||||
|
list) \
|
||||||
|
echo "$(CYAN)📋 Доступные пресеты:$(RESET)"; \
|
||||||
|
echo ""; \
|
||||||
|
echo "$(GREEN)Классические пресеты:$(RESET)"; \
|
||||||
|
echo " minimal.yml - Минимальная лаборатория (1-3 машины)"; \
|
||||||
|
echo " webapp.yml - Веб-приложение (3-5 машин)"; \
|
||||||
|
echo " microservices.yml - Микросервисы (5-8 машин)"; \
|
||||||
|
echo " ha.yml - Высокая доступность (6-10 машин)"; \
|
||||||
|
echo " k8s-cluster.yml - Kubernetes кластер (8-12 машин)"; \
|
||||||
|
echo " cicd.yml - CI/CD пайплайн (10-15 машин)"; \
|
||||||
|
echo " bigdata.yml - Big Data кластер (12-18 машин)"; \
|
||||||
|
echo " servicemesh.yml - Service Mesh (15-20 машин)"; \
|
||||||
|
echo " enterprise.yml - Enterprise (18-20 машин)"; \
|
||||||
|
echo " maximum.yml - Максимальный (20 машин)"; \
|
||||||
|
echo ""; \
|
||||||
|
echo "$(GREEN)Kubernetes пресеты:$(RESET)"; \
|
||||||
|
echo " k8s-single.yml - Kubernetes Single Node"; \
|
||||||
|
echo " k8s-multi.yml - Kubernetes Multi-Cluster"; \
|
||||||
|
echo " k8s-istio-full.yml - Kubernetes + Istio Full Stack"; \
|
||||||
|
echo ""; \
|
||||||
|
echo "$(GREEN)DinD пресеты:$(RESET)"; \
|
||||||
|
echo " dind-simple.yml - DinD Simple"; \
|
||||||
|
echo " dind-swarm.yml - DinD Swarm"; \
|
||||||
|
echo " dind-compose.yml - DinD Compose"; \
|
||||||
|
echo ""; \
|
||||||
|
echo "$(GREEN)DOoD пресеты:$(RESET)"; \
|
||||||
|
echo " dood-simple.yml - DOoD Simple"; \
|
||||||
|
echo " dood-mixed.yml - DOoD Mixed"; \
|
||||||
|
echo ""; \
|
||||||
|
echo "$(GREEN)Смешанные пресеты:$(RESET)"; \
|
||||||
|
echo " mixed-k8s-dind.yml - Mixed Kubernetes + DinD"; \
|
||||||
|
echo " mixed-k8s-dood.yml - Mixed Kubernetes + DOoD"; \
|
||||||
|
echo " mixed-full.yml - Mixed Full Stack";; \
|
||||||
|
create) \
|
||||||
|
if [ -z "$(NAME)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make preset create NAME=my-preset$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(YELLOW)📝 Создаем пресет: $(NAME).yml$(RESET)"; \
|
||||||
|
$(MAKE) preset copy SOURCE=minimal.yml TARGET=$(NAME).yml; \
|
||||||
|
echo "$(GREEN)✅ Пресет создан: molecule/presets/$(NAME).yml$(RESET)";; \
|
||||||
|
edit) \
|
||||||
|
if [ -z "$(NAME)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make preset edit NAME=my-preset$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(BLUE)✏️ Редактируем пресет: $(NAME).yml$(RESET)"; \
|
||||||
|
$${EDITOR:-vim} molecule/presets/$(NAME).yml;; \
|
||||||
|
test) \
|
||||||
|
if [ -z "$(NAME)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make preset test NAME=my-preset$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(PURPLE)🧪 Тестируем пресет: $(NAME).yml$(RESET)"; \
|
||||||
|
$(MAKE) lab test LAB_SPEC=molecule/presets/$(NAME).yml;; \
|
||||||
|
copy) \
|
||||||
|
if [ -z "$(SOURCE)" ] || [ -z "$(TARGET)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make preset copy SOURCE=minimal.yml TARGET=my-preset.yml$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(YELLOW)📋 Копируем пресет: $(SOURCE) -> $(TARGET)$(RESET)"; \
|
||||||
|
cp molecule/presets/$(SOURCE) molecule/presets/$(TARGET); \
|
||||||
|
echo "$(GREEN)✅ Пресет скопирован$(RESET)";; \
|
||||||
|
*) \
|
||||||
|
echo "$(RED)❌ Неизвестная команда. Доступные: list, create, edit, test, copy$(RESET)";; \
|
||||||
|
esac
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# УПРАВЛЕНИЕ РОЛЯМИ
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
.PHONY: role
|
||||||
|
role: ## Управление ролями (list|create|edit|test|lint|deploy)
|
||||||
|
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||||
|
list) \
|
||||||
|
echo "$(CYAN)📋 Доступные роли:$(RESET)"; \
|
||||||
|
if [ -d "$(ROLES_DIR)" ]; then \
|
||||||
|
ls -la $(ROLES_DIR)/ | grep "^d" | awk '{print " " $$9}' | grep -v "^\.$\|^\.\.$"; \
|
||||||
|
else \
|
||||||
|
echo " $(YELLOW)Директория ролей не найдена$(RESET)"; \
|
||||||
|
fi;; \
|
||||||
|
create) \
|
||||||
|
if [ -z "$(NAME)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make role create NAME=my-role$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(YELLOW)📝 Создаем роль: $(NAME)$(RESET)"; \
|
||||||
|
mkdir -p $(ROLES_DIR)/$(NAME)/{tasks,handlers,templates,files,vars,defaults,meta,tests}; \
|
||||||
|
echo "---" > $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo "# Основные задачи роли $(NAME)" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo "" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo "- name: $(NAME) placeholder" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo " debug:" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo " msg: \"Роль $(NAME) готова для настройки\"" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo "" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo "- name: Install $(NAME) package" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo " package:" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo " name: \"{{ $(NAME)_package | default('$(NAME)') }}\"" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo " state: present" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo "" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo "- name: Start $(NAME) service" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo " systemd:" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo " name: \"{{ $(NAME)_service | default('$(NAME)') }}\"" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo " state: started" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo " enabled: true" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo " when: $(NAME)_service is defined" >> $(ROLES_DIR)/$(NAME)/tasks/main.yml; \
|
||||||
|
echo "---" > $(ROLES_DIR)/$(NAME)/defaults/main.yml; \
|
||||||
|
echo "# Переменные по умолчанию для роли $(NAME)" >> $(ROLES_DIR)/$(NAME)/defaults/main.yml; \
|
||||||
|
echo "$(NAME)_enabled: true" >> $(ROLES_DIR)/$(NAME)/defaults/main.yml; \
|
||||||
|
echo "$(NAME)_package: $(NAME)" >> $(ROLES_DIR)/$(NAME)/defaults/main.yml; \
|
||||||
|
echo "$(NAME)_service: $(NAME)" >> $(ROLES_DIR)/$(NAME)/defaults/main.yml; \
|
||||||
|
echo "---" > $(ROLES_DIR)/$(NAME)/meta/main.yml; \
|
||||||
|
echo "galaxy_info:" >> $(ROLES_DIR)/$(NAME)/meta/main.yml; \
|
||||||
|
echo " author: $(AUTHOR)" >> $(ROLES_DIR)/$(NAME)/meta/main.yml; \
|
||||||
|
echo " description: Роль $(NAME)" >> $(ROLES_DIR)/$(NAME)/meta/main.yml; \
|
||||||
|
echo " company: $(SITE)" >> $(ROLES_DIR)/$(NAME)/meta/main.yml; \
|
||||||
|
echo " license: MIT" >> $(ROLES_DIR)/$(NAME)/meta/main.yml; \
|
||||||
|
echo " min_ansible_version: 2.9" >> $(ROLES_DIR)/$(NAME)/meta/main.yml; \
|
||||||
|
echo "dependencies: []" >> $(ROLES_DIR)/$(NAME)/meta/main.yml; \
|
||||||
|
echo "---" > $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "# Роль $(NAME)" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "Описание роли $(NAME)." >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "## Переменные" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "| Переменная | По умолчанию | Описание |" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "|------------|--------------|----------|" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "| \`$(NAME)_enabled\` | \`true\` | Включить роль |" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "| \`$(NAME)_package\` | \`$(NAME)\` | Имя пакета |" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "| \`$(NAME)_service\` | \`$(NAME)\` | Имя сервиса |" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "## Использование" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "\`\`\`yaml" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "- hosts: all" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo " roles:" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo " - role: $(NAME)" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "\`\`\`" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "## Автор" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "$(AUTHOR)" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "Сайт: $(SITE)" >> $(ROLES_DIR)/$(NAME)/README.md; \
|
||||||
|
echo "$(GREEN)✅ Роль $(NAME) создана$(RESET)";; \
|
||||||
|
edit) \
|
||||||
|
if [ -z "$(NAME)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make role edit NAME=my-role$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(BLUE)✏️ Редактируем роль: $(NAME)$(RESET)"; \
|
||||||
|
$${EDITOR:-vim} $(ROLES_DIR)/$(NAME)/tasks/main.yml;; \
|
||||||
|
test) \
|
||||||
|
if [ -z "$(NAME)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make role test NAME=my-role$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(PURPLE)🧪 Тестируем роль: $(NAME)$(RESET)"; \
|
||||||
|
$(MAKE) lab test LAB_SPEC=molecule/presets/minimal.yml;; \
|
||||||
|
lint) \
|
||||||
|
echo "$(YELLOW)🔍 Проверяем роли...$(RESET)"; \
|
||||||
|
docker exec ansible-controller bash -lc 'ansible-lint --config-file /ansible/.ansible-lint $(ROLES_DIR)/*'; \
|
||||||
|
echo "$(GREEN)✅ Проверка завершена$(RESET)";; \
|
||||||
|
deploy) \
|
||||||
|
echo "$(PURPLE)🚀 Развертываем роли...$(RESET)"; \
|
||||||
|
docker exec ansible-controller bash -lc 'ansible-playbook -i /tmp/molecule/inventory/hosts.yml files/playbooks/site.yml'; \
|
||||||
|
echo "$(GREEN)✅ Развертывание завершено$(RESET)";; \
|
||||||
|
info) \
|
||||||
|
if [ -z "$(NAME)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make role info NAME=my-role$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(BLUE)📋 Информация о роли: $(NAME)$(RESET)"; \
|
||||||
|
docker exec ansible-controller bash -lc 'cat /ansible/roles/$(NAME)/README.md';; \
|
||||||
|
*) \
|
||||||
|
echo "$(RED)❌ Неизвестная команда. Доступные: list, create, edit, test, lint, deploy, info$(RESET)";; \
|
||||||
|
esac
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# УПРАВЛЕНИЕ VAULT
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
.PHONY: vault
|
||||||
|
vault: ## Управление Ansible Vault (show|create|edit|delete|rekey|decrypt|encrypt)
|
||||||
|
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||||
|
show) \
|
||||||
|
echo "$(BLUE)🔍 Показываем содержимое vault...$(RESET)"; \
|
||||||
|
docker exec ansible-controller bash -lc 'ansible-vault view --vault-password-file $(VAULT_PASSWORD_FILE) vault/secrets.yml';; \
|
||||||
|
create) \
|
||||||
|
echo "$(YELLOW)📝 Создаем vault файл...$(RESET)"; \
|
||||||
|
docker exec ansible-controller bash -lc 'echo "---" > vault/secrets.yml && ansible-vault encrypt --encrypt-vault-id default --vault-password-file $(VAULT_PASSWORD_FILE) vault/secrets.yml';; \
|
||||||
|
edit) \
|
||||||
|
echo "$(BLUE)✏️ Редактируем vault файл...$(RESET)"; \
|
||||||
|
docker exec ansible-controller bash -lc 'ansible-vault edit --vault-password-file $(VAULT_PASSWORD_FILE) vault/secrets.yml';; \
|
||||||
|
delete) \
|
||||||
|
echo "$(RED)🗑️ Удаляем vault файл...$(RESET)"; \
|
||||||
|
docker exec ansible-controller bash -lc 'rm vault/secrets.yml';; \
|
||||||
|
rekey) \
|
||||||
|
echo "$(YELLOW)🔑 Изменяем пароль vault...$(RESET)"; \
|
||||||
|
docker exec ansible-controller bash -lc 'ansible-vault rekey --vault-password-file $(VAULT_PASSWORD_FILE) vault/secrets.yml';; \
|
||||||
|
decrypt) \
|
||||||
|
echo "$(GREEN)🔓 Расшифровываем vault файл...$(RESET)"; \
|
||||||
|
docker exec ansible-controller bash -lc 'ansible-vault decrypt --vault-password-file $(VAULT_PASSWORD_FILE) vault/secrets.yml';; \
|
||||||
|
encrypt) \
|
||||||
|
echo "$(RED)🔒 Шифруем vault файл...$(RESET)"; \
|
||||||
|
docker exec ansible-controller bash -lc 'ansible-vault encrypt --encrypt-vault-id default --vault-password-file $(VAULT_PASSWORD_FILE) vault/secrets.yml';; \
|
||||||
|
*) \
|
||||||
|
echo "$(RED)❌ Неизвестная команда. Доступные: show, create, edit, delete, rekey, decrypt, encrypt$(RESET)";; \
|
||||||
|
esac
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# УПРАВЛЕНИЕ GIT
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
.PHONY: git
|
||||||
|
git: ## Управление Git (status|add|commit|push|pull|branch|merge)
|
||||||
|
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||||
|
status) \
|
||||||
|
echo "$(CYAN)📊 Статус Git репозитория:$(RESET)"; \
|
||||||
|
git status;; \
|
||||||
|
add) \
|
||||||
|
echo "$(GREEN)➕ Добавляем файлы в Git...$(RESET)"; \
|
||||||
|
git add .;; \
|
||||||
|
commit) \
|
||||||
|
if [ -z "$(MESSAGE)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make git commit MESSAGE=\"your commit message\"$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(YELLOW)💾 Создаем коммит...$(RESET)"; \
|
||||||
|
git commit -m "$(MESSAGE)";; \
|
||||||
|
push) \
|
||||||
|
echo "$(BLUE)🚀 Отправляем изменения...$(RESET)"; \
|
||||||
|
git push;; \
|
||||||
|
pull) \
|
||||||
|
echo "$(GREEN)📥 Получаем изменения...$(RESET)"; \
|
||||||
|
git pull;; \
|
||||||
|
branch) \
|
||||||
|
if [ -z "$(NAME)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make git branch NAME=my-branch$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(PURPLE)🌿 Создаем ветку: $(NAME)$(RESET)"; \
|
||||||
|
git checkout -b $(NAME);; \
|
||||||
|
merge) \
|
||||||
|
if [ -z "$(BRANCH)" ]; then \
|
||||||
|
echo "$(RED)❌ Использование: make git merge BRANCH=my-branch$(RESET)"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo "$(YELLOW)🔀 Сливаем ветку: $(BRANCH)$(RESET)"; \
|
||||||
|
git merge $(BRANCH);; \
|
||||||
|
*) \
|
||||||
|
echo "$(RED)❌ Неизвестная команда. Доступные: status, add, commit, push, pull, branch, merge$(RESET)";; \
|
||||||
|
esac
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# УПРАВЛЕНИЕ DOCKER
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
.PHONY: docker
|
||||||
|
docker: ## Управление Docker (build|rebuild|prune|shell|logs|stop|start)
|
||||||
@case "$(word 2, $(MAKECMDGOALS))" in \
|
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||||
build) \
|
build) \
|
||||||
docker buildx create --use --name multiarch-builder --driver docker-container; \
|
echo "$(YELLOW)🔨 Собираем Docker образы...$(RESET)"; \
|
||||||
if [ "$(RUN_MODE)" = "docker-compose" ]; then \
|
$(DOCKER_COMPOSE) build;; \
|
||||||
docker compose build $(c); \
|
|
||||||
else \
|
|
||||||
docker build -t $(REGISTRY)/$(IMAGE) .; \
|
|
||||||
fi;; \
|
|
||||||
rebuild) \
|
rebuild) \
|
||||||
docker buildx create --use --name multiarch-builder --driver docker-container; \
|
echo "$(YELLOW)🔨 Пересобираем Docker образы...$(RESET)"; \
|
||||||
if [ "$(RUN_MODE)" = "docker-compose" ]; then \
|
$(DOCKER_COMPOSE) build --no-cache;; \
|
||||||
docker compose build --no-cache $(c); \
|
|
||||||
else \
|
|
||||||
docker build --no-cache -t $(REGISTRY)/$(IMAGE) .; \
|
|
||||||
fi;; \
|
|
||||||
prune) \
|
prune) \
|
||||||
|
echo "$(RED)🧹 Очищаем Docker...$(RESET)"; \
|
||||||
docker system prune -af;; \
|
docker system prune -af;; \
|
||||||
shell) \
|
shell) \
|
||||||
clear; \
|
echo "$(BLUE)🐚 Входим в Docker контейнер...$(RESET)"; \
|
||||||
echo "Entering to Ansible container shell..."; \
|
docker exec -it ansible-controller bash;; \
|
||||||
$(RUN) bash ;; \
|
logs) \
|
||||||
release) \
|
echo "$(CYAN)📋 Показываем логи...$(RESET)"; \
|
||||||
docker buildx create --use --name multiarch-builder --driver docker-container; \
|
$(DOCKER_COMPOSE) logs -f;; \
|
||||||
docker login $(REGISTRY); \
|
stop) \
|
||||||
docker buildx build -t $(REGISTRY)/$(IMAGE):$(TAG) -t $(REGISTRY)/$(IMAGE):latest --platform linux/amd64,linux/arm64 --push .;; \
|
echo "$(RED)🛑 Останавливаем контейнеры...$(RESET)"; \
|
||||||
images) \
|
$(DOCKER_COMPOSE) stop;; \
|
||||||
docker buildx create --use --name multiarch-builder --driver docker-container; \
|
start) \
|
||||||
echo "Логинимся в Docker Hub..."; \
|
echo "$(GREEN)▶️ Запускаем контейнеры...$(RESET)"; \
|
||||||
docker login; \
|
$(DOCKER_COMPOSE) start;; \
|
||||||
echo "Собираем и пушим основной Ansible образ..."; \
|
*) \
|
||||||
docker buildx build -t $(REGISTRY)/$(IMAGE):$(TAG) -t $(REGISTRY)/$(IMAGE):latest --platform linux/amd64,linux/arm64 --push .; \
|
echo "$(RED)❌ Неизвестная команда. Доступные: build, rebuild, prune, shell, logs, stop, start$(RESET)";; \
|
||||||
echo "Собираем и пушим образ CentOS..."; \
|
|
||||||
docker buildx build -t $(REGISTRY):centos --platform linux/amd64,linux/arm64 --push -f Dockerfile-CentOS .; \
|
|
||||||
echo "Собираем и пушим образ Ubuntu..."; \
|
|
||||||
docker buildx build -t $(REGISTRY):ubuntu --platform linux/amd64,linux/arm64 --push -f Dockerfile-Ubuntu .; \
|
|
||||||
echo "Образы успешно опубликованы в Docker Hub: $(REGISTRY)";; \
|
|
||||||
*) echo "Unknown action. Available actions: build, rebuild, prune, release";; \
|
|
||||||
esac
|
esac
|
||||||
|
|
||||||
####################################################################################################
|
# =============================================================================
|
||||||
# Работа с ролью
|
# ОТЧЕТЫ И МОНИТОРИНГ
|
||||||
####################################################################################################
|
# =============================================================================
|
||||||
vault:
|
|
||||||
@case "$(word 2, $(MAKECMDGOALS))" in \
|
|
||||||
show) $(RUN) bash -c "ansible-vault view --vault-password-file vault-password.txt vars/secrets.yml";; \
|
|
||||||
create) $(RUN) bash -c "ansible-vault create --encrypt-vault-id default --vault-password-file vault-password.txt vars/secrets.yml";; \
|
|
||||||
edit) $(RUN) bash -c "ansible-vault edit --vault-password-file vault-password.txt vars/secrets.yml";; \
|
|
||||||
delete) $(RUN) bash -c "rm vars/secrets.yml";; \
|
|
||||||
rekey) $(RUN) bash -c "ansible-vault rekey --vault-password-file vault-password.txt vars/secrets.yml";; \
|
|
||||||
decrypt) $(RUN) bash -c "ansible-vault decrypt --vault-password-file vault-password.txt vars/secrets.yml";; \
|
|
||||||
encrypt) $(RUN) bash -c "ansible-vault encrypt --encrypt-vault-id default --vault-password-file vault-password.txt vars/secrets.yml";; \
|
|
||||||
*) echo "Unknown action";; \
|
|
||||||
esac
|
|
||||||
|
|
||||||
role:
|
.PHONY: report
|
||||||
@case "$(word 2, $(MAKECMDGOALS))" in \
|
report: ## Сгенерировать HTML отчет
|
||||||
new) \
|
@echo "$(PURPLE)📊 Генерируем HTML отчет...$(RESET)"
|
||||||
clear; \
|
@mkdir -p reports
|
||||||
echo "Введите название новой роли на английском:"; \
|
@docker exec ansible-controller bash -lc 'python3 /ansible/scripts/report_html.py /ansible/reports/lab-health.json /ansible/reports/lab-report.html'
|
||||||
read ROLE_NAME; \
|
@echo "$(GREEN)✅ HTML отчет: reports/lab-report.html$(RESET)"
|
||||||
echo "Введите описание роли:"; \
|
@echo "$(YELLOW)📖 Откройте отчет в браузере:$(RESET)"
|
||||||
read ROLE_DESC; \
|
@echo " $(BLUE)file://$(PWD)/reports/lab-report.html$(RESET)"
|
||||||
cp -r default/ "roles/$${ROLE_NAME}"; \
|
|
||||||
printf "\n- name: $${ROLE_DESC}" >> roles/deploy.yaml; \
|
|
||||||
printf "\n import_playbook: $${ROLE_NAME}/deploy.yaml" >> roles/deploy.yaml; \
|
|
||||||
printf '\n - ../../roles/%s' "$$ROLE_NAME" >> molecule/default/converge.yml; \
|
|
||||||
printf "\n - $${ROLE_NAME}" >> roles/$$ROLE_NAME/deploy.yaml;; \
|
|
||||||
lint) \
|
|
||||||
clear; \
|
|
||||||
echo "Check your role..."; \
|
|
||||||
$(RUN) bash -c "ansible-vault decrypt --vault-password-file vault-password.txt vars/secrets.yml"; \
|
|
||||||
$(RUN) bash -c "ansible-lint roles/*"; \
|
|
||||||
$(RUN) bash -c "ansible-vault encrypt vars/secrets.yml --encrypt-vault-id default --vault-password-file vault-password.txt";; \
|
|
||||||
test) \
|
|
||||||
clear; \
|
|
||||||
echo "Running test roles..."; \
|
|
||||||
$(RUN) bash -c "ansible-vault decrypt --vault-password-file vault-password.txt vars/secrets.yml"; \
|
|
||||||
$(RUN) bash -c "docker login $(REGISTRY) && molecule test --parallel --destroy=always"; \
|
|
||||||
$(RUN) bash -c "ansible-vault encrypt vars/secrets.yml --encrypt-vault-id default --vault-password-file vault-password.txt";; \
|
|
||||||
deploy) \
|
|
||||||
clear; \
|
|
||||||
echo "Deploying roles to production..."; \
|
|
||||||
$(RUN) bash -c "ansible-playbook roles/deploy.yaml";; \
|
|
||||||
*) echo "Unknown action";; \
|
|
||||||
esac
|
|
||||||
|
|
||||||
####################################################################################################
|
.PHONY: kubeconfigs
|
||||||
# Работа с Git
|
kubeconfigs: ## Получить все kubeconfig файлы
|
||||||
####################################################################################################
|
@echo "$(BLUE)📋 Получаем все kubeconfig файлы...$(RESET)"
|
||||||
git:
|
@mkdir -p reports/kubeconfigs
|
||||||
@case "$(word 2, $(MAKECMDGOALS))" in \
|
@docker exec ansible-controller bash -lc 'for cluster in $$(kind get clusters 2>/dev/null || echo ""); do \
|
||||||
push) \
|
if [ -n "$$cluster" ]; then \
|
||||||
git branch; \
|
echo "Получаем kubeconfig для $$cluster..."; \
|
||||||
read -p "Выберите ветку для пуша: " BRANCH; \
|
kubectl --context kind-$$cluster config view --raw > /ansible/reports/kubeconfigs/kubeconfig-$$cluster.yaml; \
|
||||||
read -p "Введите описание коммита: " COMMIT; \
|
fi; \
|
||||||
commitname=$$COMMIT; \
|
done'
|
||||||
git add . ; \
|
@echo "$(GREEN)✅ Kubeconfig файлы сохранены в reports/kubeconfigs/$(RESET)"
|
||||||
git commit -m "$$commitname"; \
|
@if [ -d "reports/kubeconfigs" ] && [ -n "$$(ls reports/kubeconfigs/ 2>/dev/null)" ]; then \
|
||||||
git push -u origin $$BRANCH; \
|
echo "$(YELLOW)📁 Найденные kubeconfig файлы:$(RESET)"; \
|
||||||
echo "Изменения внесены в Git";; \
|
ls -la reports/kubeconfigs/ | grep -v "^total" | awk '{print " " $$9}'; \
|
||||||
pull) \
|
fi
|
||||||
git pull;; \
|
|
||||||
new) \
|
.PHONY: open-report
|
||||||
read -p "Введите имя новой ветки: " BRANCH_NAME; \
|
open-report: ## Открыть HTML отчет в браузере
|
||||||
NEW_BRANCH="$$BRANCH_NAME"; \
|
@if [ -f "reports/lab-report.html" ]; then \
|
||||||
git checkout -b $$NEW_BRANCH; \
|
echo "$(BLUE)🌐 Открываем отчет в браузере...$(RESET)"; \
|
||||||
echo "Создана и переключена на новую ветку: $$NEW_BRANCH";; \
|
if command -v open >/dev/null 2>&1; then \
|
||||||
*) echo "Unknown action. Available actions: push, pull, cluster-branch";; \
|
open reports/lab-report.html; \
|
||||||
esac
|
elif command -v xdg-open >/dev/null 2>&1; then \
|
||||||
|
xdg-open reports/lab-report.html; \
|
||||||
|
else \
|
||||||
|
echo "$(YELLOW)⚠️ Откройте отчет вручную: file://$(PWD)/reports/lab-report.html$(RESET)"; \
|
||||||
|
fi; \
|
||||||
|
echo "$(GREEN)✅ Отчет открыт$(RESET)"; \
|
||||||
|
else \
|
||||||
|
echo "$(RED)❌ Отчет не найден. Сначала выполните: make report$(RESET)"; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
.PHONY: full-test
|
||||||
|
full-test: ## Полный цикл тестирования с отчетом и kubeconfig
|
||||||
|
@echo "$(PURPLE)🚀 Запускаем полный цикл тестирования...$(RESET)"
|
||||||
|
@$(MAKE) lab test
|
||||||
|
@echo "$(BLUE)📊 Генерируем отчеты...$(RESET)"
|
||||||
|
@$(MAKE) report
|
||||||
|
@$(MAKE) kubeconfigs
|
||||||
|
@echo "$(GREEN)✅ Полный цикл завершен!$(RESET)"
|
||||||
|
@echo "$(YELLOW)📁 Результаты:$(RESET)"
|
||||||
|
@echo " $(BLUE)📊 HTML отчет: reports/lab-report.html$(RESET)"
|
||||||
|
@echo " $(BLUE)📋 Kubeconfig файлы: reports/kubeconfigs/$(RESET)"
|
||||||
|
@echo "$(YELLOW)🌐 Открыть отчет: make open-report$(RESET)"
|
||||||
|
|
||||||
|
.PHONY: chaos
|
||||||
|
chaos: ## Запустить Chaos Engineering тесты
|
||||||
|
@echo "$(RED)🧨 Запускаем Chaos Engineering...$(RESET)"
|
||||||
|
@docker exec ansible-controller bash -lc 'ansible-playbook -i /tmp/molecule/inventory/hosts.yml /ansible/files/playbooks/chaos.yml'
|
||||||
|
@echo "$(GREEN)✅ Chaos Engineering завершен$(RESET)"
|
||||||
|
|
||||||
|
.PHONY: check-secrets
|
||||||
|
check-secrets: ## Проверить безопасность секретов
|
||||||
|
@echo "$(YELLOW)🔍 Проверяем безопасность секретов...$(RESET)"
|
||||||
|
@docker exec ansible-controller bash -lc 'bash /ansible/scripts/secret_scan.sh'
|
||||||
|
@echo "$(GREEN)✅ Проверка секретов завершена$(RESET)"
|
||||||
|
|
||||||
|
.PHONY: idempotence
|
||||||
|
idempotence: ## Проверить идемпотентность
|
||||||
|
@echo "$(BLUE)🔄 Проверяем идемпотентность...$(RESET)"
|
||||||
|
@docker exec ansible-controller bash -lc 'ansible-playbook -i /tmp/molecule/inventory/hosts.yml /ansible/files/playbooks/site.yml --check'
|
||||||
|
@echo "$(GREEN)✅ Идемпотентность проверена$(RESET)"
|
||||||
|
|
||||||
|
.PHONY: snapshot
|
||||||
|
snapshot: ## Сохранить снапшот лаборатории
|
||||||
|
@echo "$(YELLOW)📸 Создаем снапшот...$(RESET)"
|
||||||
|
@docker exec ansible-controller bash -lc 'bash /ansible/scripts/snapshot.sh'
|
||||||
|
@echo "$(GREEN)✅ Снапшот сохранен$(RESET)"
|
||||||
|
|
||||||
|
.PHONY: restore
|
||||||
|
restore: ## Восстановить из снапшота
|
||||||
|
@echo "$(BLUE)🔄 Восстанавливаем из снапшота...$(RESET)"
|
||||||
|
@docker exec ansible-controller bash -lc 'bash /ansible/scripts/restore.sh'
|
||||||
|
@echo "$(GREEN)✅ Снапшот восстановлен$(RESET)"
|
||||||
|
|
||||||
|
.PHONY: cleanup
|
||||||
|
cleanup: ## Очистить лабораторию
|
||||||
|
@echo "$(RED)🧹 Очищаем лабораторию...$(RESET)"
|
||||||
|
@docker exec ansible-controller bash -lc 'bash /ansible/scripts/cleanup.sh'
|
||||||
|
@echo "$(GREEN)✅ Лаборатория очищена$(RESET)"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# УТИЛИТЫ
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
.PHONY: lint
|
||||||
|
lint: ## Проверить весь проект на ошибки
|
||||||
|
@echo "$(YELLOW)🔍 Проверяем весь проект...$(RESET)"
|
||||||
|
@docker exec ansible-controller bash -lc 'ansible-lint --config-file /ansible/.ansible-lint molecule/universal/'
|
||||||
|
@docker exec ansible-controller bash -lc 'ansible-lint --config-file /ansible/.ansible-lint files/playbooks/'
|
||||||
|
@if [ -d "$(ROLES_DIR)" ] && [ -n "$$(ls $(ROLES_DIR)/ 2>/dev/null)" ]; then \
|
||||||
|
docker exec ansible-controller bash -lc 'ansible-lint --config-file /ansible/.ansible-lint $(ROLES_DIR)/*'; \
|
||||||
|
fi
|
||||||
|
@echo "$(GREEN)✅ Проверка завершена$(RESET)"
|
||||||
|
|
||||||
|
.PHONY: env
|
||||||
|
env: ## Показать переменные окружения
|
||||||
|
@echo "$(CYAN)🔧 Переменные окружения:$(RESET)"
|
||||||
|
@echo "PROJECT_NAME: $(PROJECT_NAME)"
|
||||||
|
@echo "VERSION: $(VERSION)"
|
||||||
|
@echo "AUTHOR: $(AUTHOR)"
|
||||||
|
@echo "SITE: $(SITE)"
|
||||||
|
@echo "DOCKER_IMAGE: $(DOCKER_IMAGE)"
|
||||||
|
@echo "DOCKER_NETWORK: $(DOCKER_NETWORK)"
|
||||||
|
@echo "SCENARIO: $(SCENARIO)"
|
||||||
|
@echo "LAB_SPEC: $(LAB_SPEC)"
|
||||||
|
@echo "KUBE_CONTEXT: $(KUBE_CONTEXT)"
|
||||||
|
@echo "ROLES_DIR: $(ROLES_DIR)"
|
||||||
|
@echo "VAULT_PASSWORD_FILE: $(VAULT_PASSWORD_FILE)"
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean: cleanup ## Полная очистка проекта
|
||||||
|
@echo "$(RED)🧹 Полная очистка проекта...$(RESET)"
|
||||||
|
@rm -rf .env
|
||||||
|
@rm -rf vault/
|
||||||
|
@rm -rf reports/
|
||||||
|
@rm -rf snapshots/
|
||||||
|
@echo "$(GREEN)✅ Проект очищен$(RESET)"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# ЗАГЛУШКИ ДЛЯ ПАРАМЕТРОВ
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
%:
|
||||||
|
@:
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# ЗАГРУЗКА ПЕРЕМЕННЫХ ИЗ .env
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
ifneq (,$(wildcard .env))
|
||||||
|
include .env
|
||||||
|
export
|
||||||
|
endif
|
||||||
532
README.md
532
README.md
@@ -1,62 +1,496 @@
|
|||||||
# AnsibleTemplate
|
# Ansible Template - Универсальная лаборатория для тестирования Ansible ролей
|
||||||
|
|
||||||
Темплейт для создания, проверки и тестирование ролей Ansible с помощью контейнеров Docker.
|
[](https://opensource.org/licenses/MIT)
|
||||||
|
[](https://www.ansible.com/)
|
||||||
|
[](https://molecule.readthedocs.io/)
|
||||||
|
[](https://www.docker.com/)
|
||||||
|
|
||||||
### С чего начать?
|
## 📋 Описание
|
||||||
|
|
||||||
На вашей машине вам необходимо сбилдить образ, где будут запускаться все роли через docker-compose.
|
**Ansible Template** - это универсальная лаборатория для тестирования Ansible ролей в различных конфигурациях. Проект предоставляет гибкую и мощную среду для тестирования Ansible ролей, включая Docker-in-Docker (DinD), Docker-outside-of-Docker (DOoD), кластеры Kubernetes (Kind), Istio, Kiali, Prometheus и Grafana.
|
||||||
|
|
||||||
Это можно сделать самостоятельно:
|
### 🎯 Основные возможности
|
||||||
|
|
||||||
- **make docker build** - создание контейнера
|
- **Динамическое создание инфраструктуры** - автоматическое развертывание Docker контейнеров и Kind кластеров
|
||||||
- **make docker rebuild** - пересоздание контейнера, если были внесены изменения в Dockerfile
|
- **Поддержка различных ОС** - тестирование ролей на Debian и RHEL-подобных системах
|
||||||
- **make docker prune** - очистить систему от лишних образов
|
- **Docker-in-Docker (DinD)** - изолированные Docker-среды внутри контейнеров
|
||||||
- **make docker shell** - войти в контейнер Shell
|
- **Docker-outside-of-Docker (DOoD)** - использование Docker-демона хоста из контейнера
|
||||||
- **make docker release** - собирает образ контейнера и пушит его в докер реджистри
|
- **Kubernetes кластеры** - полноценные Kind кластеры с аддонами
|
||||||
- **make docker images** - собрать образы контейнеров с systemd, для удобного тестирования ролей
|
- **Service Mesh** - Istio с Kiali для визуализации
|
||||||
- **make images** - собрать и запушить все образы (основной Ansible, CentOS, Ubuntu) в Docker Hub (inecs/ansible)
|
- **Мониторинг** - Prometheus, Grafana, Jaeger для полной наблюдаемости
|
||||||
|
- **21 готовый пресет** - от простых до экстремально сложных сценариев
|
||||||
|
- **HTML отчеты** - красивые отчеты о результатах тестирования
|
||||||
|
- **Снапшоты** - сохранение и восстановление состояния лаборатории
|
||||||
|
|
||||||
Или ввести команду:
|
## 🚀 Быстрый старт
|
||||||
|
|
||||||
- **make init** - которая создаст файл секретов с паролем. Сбилдит образ. И создаст новую роль.
|
### Предварительные требования
|
||||||
|
|
||||||
### Работа с ролью
|
- Docker 20.0+
|
||||||
- **make role new** - создать новую роль из шаблона. Название роли пишется на английском, описание роли на любом языке
|
- Docker Compose 2.0+
|
||||||
- **make role lint** - проверяет все роли в папке roles/* на наличие ошибок
|
- Make
|
||||||
- **make role test** - позволяет тестировать роль, указанную в molecule/default/converge.yml
|
- Git
|
||||||
сразу на двух контейнерах (RedHat и Ubuntu)
|
|
||||||
- **make role deploy** - запускает роль в продакшен. Все хосты берет из файла inventory/hosts
|
|
||||||
|
|
||||||
### Работа с файлом переменных
|
### Установка
|
||||||
|
|
||||||
Все переменные защищены через **Ansible-Vault** и находятся в папке vars/secrets.yml
|
```bash
|
||||||
|
# Клонировать репозиторий
|
||||||
|
git clone https://github.com/your-username/ansible-template.git
|
||||||
|
cd ansible-template
|
||||||
|
|
||||||
Для смены пароля измените его в файле **./vault-password.txt**
|
# Создать необходимые файлы
|
||||||
|
echo "your-vault-password" > vault-password.txt
|
||||||
|
mkdir -p roles
|
||||||
|
mkdir -p files/playbooks
|
||||||
|
|
||||||
- **make vault create** - создать новый файл с учетом пароля в файле **./vault-password.txt**
|
# Установить pre-commit хуки (опционально)
|
||||||
- **make vault delete** - удалить файл с переменными
|
make pre-commit-install
|
||||||
- **make vault edit** - отредактировать файл переменных
|
|
||||||
- **make vault show** - показать содержимое файла переменных
|
|
||||||
- **make vault rekey** - сменить пароль шифрования
|
|
||||||
- **make vault encrypt** - зашифровать файл секретов
|
|
||||||
- **make vault decrypt** - расшифровать файл секретов
|
|
||||||
|
|
||||||
### Работа с Git
|
|
||||||
|
|
||||||
- **make git push** - запушить изменения. С выбором ветки и вводом коммита.
|
|
||||||
- **make git pull** - получить изменения из репы
|
|
||||||
- **make git new** - создание нового брэнча имя cluster-branch_name для IaC подхода.
|
|
||||||
|
|
||||||
### Добавить свой образ контейнера для тестов
|
|
||||||
|
|
||||||
Что бы добавить или изменить докер-образы для тестирования ролей измените файл настроек молекулы
|
|
||||||
molecule/default/molecule.yml
|
|
||||||
```yaml
|
|
||||||
- name: ubuntu-instance
|
|
||||||
image: "your.docker-registry.com/your-image:latest"
|
|
||||||
privileged: true
|
|
||||||
pre_build_image: true
|
|
||||||
volumes:
|
|
||||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
|
||||||
```
|
```
|
||||||
Помните, что образ обязательно должен содержать python не ниже версии 3.12 и systemd для нормального тестирования ролей.
|
|
||||||
|
### Первый запуск
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Инициализация проекта
|
||||||
|
make init
|
||||||
|
|
||||||
|
# Поднять контроллер
|
||||||
|
make lab up
|
||||||
|
|
||||||
|
# Запустить минимальную лабораторию
|
||||||
|
make lab test
|
||||||
|
|
||||||
|
# Посмотреть отчет
|
||||||
|
make report
|
||||||
|
```
|
||||||
|
|
||||||
|
### Основные команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Показать справку
|
||||||
|
make help
|
||||||
|
|
||||||
|
# Управление лабораторией
|
||||||
|
make lab up # Поднять контроллер
|
||||||
|
make lab down # Остановить контроллер
|
||||||
|
make lab test # Полный цикл тестирования
|
||||||
|
make lab create # Создать инфраструктуру
|
||||||
|
make lab converge # Запустить роли
|
||||||
|
make lab verify # Проверить работу
|
||||||
|
make lab destroy # Уничтожить инфраструктуру
|
||||||
|
make lab reset # Полный сброс
|
||||||
|
|
||||||
|
# Управление Kubernetes
|
||||||
|
make kube sh # Войти в контейнер
|
||||||
|
make kube cmd CLUSTER=lab CMD="get pods -A"
|
||||||
|
make kube kiali CLUSTER=lab
|
||||||
|
make kube istio CLUSTER=lab
|
||||||
|
make kube grafana CLUSTER=lab
|
||||||
|
make kube prom CLUSTER=lab
|
||||||
|
make kube kubeconfig CLUSTER=lab # Получить kubeconfig
|
||||||
|
|
||||||
|
# Управление пресетами
|
||||||
|
make preset list # Список пресетов
|
||||||
|
make preset create NAME=my-preset
|
||||||
|
make preset test NAME=my-preset
|
||||||
|
make preset edit NAME=my-preset
|
||||||
|
|
||||||
|
# Управление ролями
|
||||||
|
make role list # Список ролей
|
||||||
|
make role create NAME=my-role
|
||||||
|
make role test NAME=my-role
|
||||||
|
make role lint # Проверка ролей
|
||||||
|
make role deploy # Развертывание ролей
|
||||||
|
make role info NAME=my-role # Информация о роли
|
||||||
|
|
||||||
|
# Проверка всего проекта
|
||||||
|
make lint # Проверить весь проект на ошибки
|
||||||
|
make check-secrets # Проверить безопасность секретов
|
||||||
|
make idempotence # Проверить идемпотентность
|
||||||
|
make chaos # Запустить Chaos Engineering тесты
|
||||||
|
|
||||||
|
# Управление Vault
|
||||||
|
make vault show # Показать содержимое
|
||||||
|
make vault create # Создать vault файл
|
||||||
|
make vault edit # Редактировать vault файл
|
||||||
|
|
||||||
|
# Управление Git
|
||||||
|
make git status # Статус репозитория
|
||||||
|
make git add # Добавить файлы
|
||||||
|
make git commit MESSAGE="your message"
|
||||||
|
make git push # Отправить изменения
|
||||||
|
|
||||||
|
# Отчеты и мониторинг
|
||||||
|
make report # HTML отчет
|
||||||
|
make kubeconfigs # Получить все kubeconfig файлы
|
||||||
|
make open-report # Открыть отчет в браузере
|
||||||
|
make full-test # Полный цикл с отчетом и kubeconfig
|
||||||
|
make snapshot # Создать снапшот
|
||||||
|
make restore # Восстановить снапшот
|
||||||
|
make cleanup # Очистить лабораторию
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📚 Документация
|
||||||
|
|
||||||
|
### Основные разделы
|
||||||
|
|
||||||
|
- **[Универсальная лаборатория](docs/universal-lab.md)** - полное руководство по работе с лабораторией
|
||||||
|
- **[Пресеты](docs/presets.md)** - описание всех 21 готового пресета
|
||||||
|
- **[Роли](docs/roles.md)** - структура и создание Ansible ролей
|
||||||
|
- **[CI/CD](ci-cd/README.md)** - настройка CI/CD для Ansible ролей
|
||||||
|
|
||||||
|
### Дополнительные материалы
|
||||||
|
|
||||||
|
- **[Примеры использования](docs/examples.md)** - практические примеры
|
||||||
|
- **[Troubleshooting](docs/troubleshooting.md)** - решение проблем
|
||||||
|
- **[API Reference](docs/api.md)** - справочник по API
|
||||||
|
|
||||||
|
## 🎛️ Пресеты
|
||||||
|
|
||||||
|
### Классические пресеты (systemd контейнеры)
|
||||||
|
|
||||||
|
| Пресет | Машины | Описание | Команда |
|
||||||
|
|--------|--------|----------|---------|
|
||||||
|
| `minimal.yml` | 1-3 | Базовая конфигурация | `make lab-test LAB_SPEC=molecule/presets/minimal.yml` |
|
||||||
|
| `webapp.yml` | 3-5 | Веб-приложение | `make lab-test LAB_SPEC=molecule/presets/webapp.yml` |
|
||||||
|
| `microservices.yml` | 5-8 | Микросервисы | `make lab-test LAB_SPEC=molecule/presets/microservices.yml` |
|
||||||
|
| `ha.yml` | 6-10 | Высокая доступность | `make lab-test LAB_SPEC=molecule/presets/ha.yml` |
|
||||||
|
| `k8s-cluster.yml` | 8-12 | Kubernetes кластер | `make lab-test LAB_SPEC=molecule/presets/k8s-cluster.yml` |
|
||||||
|
| `cicd.yml` | 10-15 | CI/CD пайплайн | `make lab-test LAB_SPEC=molecule/presets/cicd.yml` |
|
||||||
|
| `bigdata.yml` | 12-18 | Big Data кластер | `make lab-test LAB_SPEC=molecule/presets/bigdata.yml` |
|
||||||
|
| `servicemesh.yml` | 15-20 | Service Mesh | `make lab-test LAB_SPEC=molecule/presets/servicemesh.yml` |
|
||||||
|
| `enterprise.yml` | 18-20 | Enterprise | `make lab-test LAB_SPEC=molecule/presets/enterprise.yml` |
|
||||||
|
| `maximum.yml` | 20 | Максимальный | `make lab-test LAB_SPEC=molecule/presets/maximum.yml` |
|
||||||
|
|
||||||
|
### Kubernetes пресеты
|
||||||
|
|
||||||
|
| Пресет | Описание | Команда |
|
||||||
|
|--------|----------|---------|
|
||||||
|
| `k8s-single.yml` | Одиночный Kind кластер | `make lab-test LAB_SPEC=molecule/presets/k8s-single.yml` |
|
||||||
|
| `k8s-multi.yml` | Мульти-кластер (dev/staging/prod) | `make lab-test LAB_SPEC=molecule/presets/k8s-multi.yml` |
|
||||||
|
| `k8s-istio-full.yml` | Полный стек Istio | `make lab-test LAB_SPEC=molecule/presets/k8s-istio-full.yml` |
|
||||||
|
|
||||||
|
### Docker пресеты
|
||||||
|
|
||||||
|
| Пресет | Тип | Описание | Команда |
|
||||||
|
|--------|-----|----------|---------|
|
||||||
|
| `dind-simple.yml` | DinD | 3 изолированных Docker среды | `make lab-test LAB_SPEC=molecule/presets/dind-simple.yml` |
|
||||||
|
| `dind-swarm.yml` | DinD | Docker Swarm кластер | `make lab-test LAB_SPEC=molecule/presets/dind-swarm.yml` |
|
||||||
|
| `dind-compose.yml` | DinD | Docker Compose стеки | `make lab-test LAB_SPEC=molecule/presets/dind-compose.yml` |
|
||||||
|
| `dood-simple.yml` | DOoD | 3 DOoD контейнера | `make lab-test LAB_SPEC=molecule/presets/dood-simple.yml` |
|
||||||
|
| `dood-mixed.yml` | DOoD | Смешанная конфигурация | `make lab-test LAB_SPEC=molecule/presets/dood-mixed.yml` |
|
||||||
|
|
||||||
|
### Смешанные пресеты
|
||||||
|
|
||||||
|
| Пресет | Описание | Команда |
|
||||||
|
|--------|----------|---------|
|
||||||
|
| `mixed-k8s-dind.yml` | Kubernetes + DinD | `make lab-test LAB_SPEC=molecule/presets/mixed-k8s-dind.yml` |
|
||||||
|
| `mixed-k8s-dood.yml` | Kubernetes + DOoD | `make lab-test LAB_SPEC=molecule/presets/mixed-k8s-dood.yml` |
|
||||||
|
| `mixed-full.yml` | Полная гибридная конфигурация | `make lab-test LAB_SPEC=molecule/presets/mixed-full.yml` |
|
||||||
|
|
||||||
|
## 🛠️ Основные команды
|
||||||
|
|
||||||
|
### Управление лабораторией
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Поднять контроллер
|
||||||
|
make lab-up
|
||||||
|
|
||||||
|
# Погасить контроллер
|
||||||
|
make lab-down
|
||||||
|
|
||||||
|
# Полный цикл тестирования
|
||||||
|
make lab-test
|
||||||
|
|
||||||
|
# Создать инфраструктуру
|
||||||
|
make lab-create
|
||||||
|
|
||||||
|
# Запустить роли
|
||||||
|
make lab-converge
|
||||||
|
|
||||||
|
# Проверить работу
|
||||||
|
make lab-verify
|
||||||
|
|
||||||
|
# Уничтожить инфраструктуру
|
||||||
|
make lab-destroy
|
||||||
|
|
||||||
|
# Полный сброс
|
||||||
|
make lab-reset
|
||||||
|
```
|
||||||
|
|
||||||
|
### Снапшоты и восстановление
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Сохранить снапшот
|
||||||
|
make lab-snapshot
|
||||||
|
|
||||||
|
# Восстановить из снапшота
|
||||||
|
make lab-restore
|
||||||
|
|
||||||
|
# Очистить лабораторию
|
||||||
|
make lab-cleanup
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kubernetes команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Войти в контейнер с kubectl
|
||||||
|
make kube-sh
|
||||||
|
|
||||||
|
# Выполнить kubectl команду
|
||||||
|
make kube-cmd CLUSTER=lab CMD="get pods -A"
|
||||||
|
|
||||||
|
# Войти в кластер
|
||||||
|
make kube-enter CLUSTER=lab
|
||||||
|
|
||||||
|
# Port-forward Kiali
|
||||||
|
make kiali-port-forward CLUSTER=lab
|
||||||
|
|
||||||
|
# Port-forward Istio Gateway
|
||||||
|
make istio-gw-port-forward CLUSTER=lab
|
||||||
|
|
||||||
|
# Port-forward Grafana
|
||||||
|
make grafana-port-forward CLUSTER=lab
|
||||||
|
|
||||||
|
# Port-forward Prometheus
|
||||||
|
make prom-port-forward CLUSTER=lab
|
||||||
|
|
||||||
|
# Остановить все port-forward
|
||||||
|
make kube-pf-stop
|
||||||
|
```
|
||||||
|
|
||||||
|
### Отчеты и мониторинг
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Сгенерировать HTML отчет
|
||||||
|
make lab-report
|
||||||
|
|
||||||
|
# Открыть Grafana
|
||||||
|
make grafana-open
|
||||||
|
|
||||||
|
# Получить URL Bookinfo
|
||||||
|
make bookinfo-url
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Создание собственных пресетов
|
||||||
|
|
||||||
|
### Структура пресета
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
# ПРЕСЕТ: Название (количество машин)
|
||||||
|
#
|
||||||
|
# Описание: Подробное описание пресета
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/your-preset.yml
|
||||||
|
#
|
||||||
|
# Автор: Ваше имя
|
||||||
|
# Сайт: https://your-site.com
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
# Kind кластеры (опционально)
|
||||||
|
kind_clusters:
|
||||||
|
- name: your-cluster
|
||||||
|
workers: 2
|
||||||
|
api_port: 6443
|
||||||
|
addons:
|
||||||
|
ingress_nginx: true
|
||||||
|
metrics_server: true
|
||||||
|
istio: true
|
||||||
|
kiali: true
|
||||||
|
prometheus_stack: true
|
||||||
|
ingress_host_http_port: 8081
|
||||||
|
ingress_host_https_port: 8443
|
||||||
|
|
||||||
|
# Образы для разных семейств ОС
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
# Настройки по умолчанию для systemd контейнеров
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
# Определение хостов лаборатории
|
||||||
|
hosts:
|
||||||
|
- name: host1
|
||||||
|
family: debian
|
||||||
|
group: webservers
|
||||||
|
publish:
|
||||||
|
- "8080:80"
|
||||||
|
|
||||||
|
- name: host2
|
||||||
|
type: dind
|
||||||
|
group: dind
|
||||||
|
publish:
|
||||||
|
- "2375:2375"
|
||||||
|
|
||||||
|
- name: host3
|
||||||
|
type: dood
|
||||||
|
family: rhel
|
||||||
|
group: dood
|
||||||
|
publish:
|
||||||
|
- "8081:80"
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Типы хостов
|
||||||
|
|
||||||
|
- **systemd** - обычные контейнеры с systemd (по умолчанию)
|
||||||
|
- **dind** - Docker-in-Docker контейнеры
|
||||||
|
- **dood** - Docker-outside-of-Docker контейнеры
|
||||||
|
|
||||||
|
### Семейства ОС
|
||||||
|
|
||||||
|
- **debian** - Debian/Ubuntu системы
|
||||||
|
- **rhel** - RHEL/CentOS системы
|
||||||
|
|
||||||
|
### Группы хостов
|
||||||
|
|
||||||
|
Можно создавать любые группы для организации хостов:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
hosts:
|
||||||
|
- name: web1
|
||||||
|
group: webservers
|
||||||
|
- name: db1
|
||||||
|
group: databases
|
||||||
|
- name: cache1
|
||||||
|
group: caches
|
||||||
|
```
|
||||||
|
|
||||||
|
### Публикация портов
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
publish:
|
||||||
|
- "8080:80" # HTTP
|
||||||
|
- "8443:443" # HTTPS
|
||||||
|
- "3306:3306" # MySQL
|
||||||
|
- "5432:5432" # PostgreSQL
|
||||||
|
```
|
||||||
|
|
||||||
|
### Переменные окружения
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
|
DATABASE_URL: "postgresql://user:pass@db:5432/mydb"
|
||||||
|
DEBUG: "true"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📁 Структура проекта
|
||||||
|
|
||||||
|
```
|
||||||
|
ansible-template/
|
||||||
|
├── README.md # Основная документация
|
||||||
|
├── Makefile # Команды управления
|
||||||
|
├── docker-compose.yaml # Docker Compose конфигурация
|
||||||
|
├── vault-password.txt # Пароль для Ansible Vault
|
||||||
|
├── docs/ # Документация
|
||||||
|
│ ├── universal-lab.md # Руководство по лаборатории
|
||||||
|
│ ├── presets.md # Описание пресетов
|
||||||
|
│ ├── roles.md # Структура ролей
|
||||||
|
│ ├── examples.md # Примеры использования
|
||||||
|
│ ├── troubleshooting.md # Решение проблем
|
||||||
|
│ └── api.md # API Reference
|
||||||
|
├── ci-cd/ # CI/CD конфигурация
|
||||||
|
│ ├── README.md # Документация CI/CD
|
||||||
|
│ ├── .gitlab-ci.yml # GitLab CI/CD
|
||||||
|
│ ├── gitlab/ # GitLab Runner
|
||||||
|
│ └── dockerfiles/ # Dockerfile'ы для разных ОС
|
||||||
|
├── molecule/ # Molecule конфигурация
|
||||||
|
│ ├── universal/ # Универсальный сценарий
|
||||||
|
│ │ ├── molecule.yml # Конфигурация Molecule
|
||||||
|
│ │ ├── vars.yml # Переменные по умолчанию
|
||||||
|
│ │ ├── create.yml # Создание инфраструктуры
|
||||||
|
│ │ └── verify.yml # Проверка работы
|
||||||
|
│ └── presets/ # Готовые пресеты
|
||||||
|
│ ├── minimal.yml # Минимальная лаборатория
|
||||||
|
│ ├── webapp.yml # Веб-приложение
|
||||||
|
│ ├── k8s-single.yml # Kubernetes single
|
||||||
|
│ ├── dind-simple.yml # DinD simple
|
||||||
|
│ ├── dood-simple.yml # DOoD simple
|
||||||
|
│ └── ... # Другие пресеты
|
||||||
|
├── files/ # Файлы для ролей
|
||||||
|
│ ├── playbooks/ # Ansible playbooks
|
||||||
|
│ ├── k8s/ # Kubernetes манифесты
|
||||||
|
│ ├── grafana/ # Grafana дашборды
|
||||||
|
│ └── requirements.yml # Ansible коллекции
|
||||||
|
├── roles/ # Ansible роли
|
||||||
|
│ └── your_role/ # Ваши роли
|
||||||
|
├── scripts/ # Скрипты (запускаются через Docker)
|
||||||
|
│ ├── report_html.py # Генератор HTML отчетов
|
||||||
|
│ ├── snapshot.sh # Создание снапшотов
|
||||||
|
│ ├── restore.sh # Восстановление снапшотов
|
||||||
|
│ └── cleanup.sh # Очистка лаборатории
|
||||||
|
├── vault/ # Секреты и пароли
|
||||||
|
│ ├── .vault # Пароль для Ansible Vault
|
||||||
|
│ └── secrets.yml # Зашифрованные секреты
|
||||||
|
└── .pre-commit-config.yaml # Pre-commit конфигурация
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🤝 Участие в разработке
|
||||||
|
|
||||||
|
### Установка для разработки
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Клонировать репозиторий
|
||||||
|
git clone https://github.com/your-username/ansible-template.git
|
||||||
|
cd ansible-template
|
||||||
|
|
||||||
|
# Установить pre-commit хуки
|
||||||
|
make pre-commit-install
|
||||||
|
|
||||||
|
# Запустить тесты
|
||||||
|
make lab-test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Создание нового пресета
|
||||||
|
|
||||||
|
1. Создать файл в `molecule/presets/your-preset.yml`
|
||||||
|
2. Добавить описание в `docs/presets.md`
|
||||||
|
3. Протестировать: `make lab-test LAB_SPEC=molecule/presets/your-preset.yml`
|
||||||
|
4. Создать Pull Request
|
||||||
|
|
||||||
|
### Создание новой роли
|
||||||
|
|
||||||
|
1. Создать структуру роли в `roles/your-role/`
|
||||||
|
2. Добавить описание в `docs/roles.md`
|
||||||
|
3. Протестировать с подходящим пресетом
|
||||||
|
4. Создать Pull Request
|
||||||
|
|
||||||
|
## 📄 Лицензия
|
||||||
|
|
||||||
|
Этот проект распространяется под лицензией MIT. См. файл [LICENSE](LICENSE) для подробностей.
|
||||||
|
|
||||||
|
## 👥 Авторы
|
||||||
|
|
||||||
|
- **Сергей Антропов** - *Основной разработчик* - [devops.org.ru](https://devops.org.ru)
|
||||||
|
|
||||||
|
## 🙏 Благодарности
|
||||||
|
|
||||||
|
- [Ansible](https://www.ansible.com/) - за отличный инструмент автоматизации
|
||||||
|
- [Molecule](https://molecule.readthedocs.io/) - за фреймворк тестирования
|
||||||
|
- [Docker](https://www.docker.com/) - за контейнеризацию
|
||||||
|
- [Kubernetes](https://kubernetes.io/) - за оркестрацию
|
||||||
|
- [Istio](https://istio.io/) - за service mesh
|
||||||
|
|
||||||
|
## 📞 Поддержка
|
||||||
|
|
||||||
|
- **Документация**: [docs/](docs/)
|
||||||
|
- **Issues**: [GitHub Issues](https://github.com/your-username/ansible-template/issues)
|
||||||
|
- **Discussions**: [GitHub Discussions](https://github.com/your-username/ansible-template/discussions)
|
||||||
|
- **Сайт**: [devops.org.ru](https://devops.org.ru)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Сделано с ❤️ для сообщества DevOps**
|
||||||
123
ci-cd/README.md
Normal file
123
ci-cd/README.md
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
# CI/CD для Ansible ролей
|
||||||
|
|
||||||
|
Этот раздел содержит примеры настройки CI/CD для Ansible ролей с использованием GitLab CI/CD.
|
||||||
|
|
||||||
|
## Структура
|
||||||
|
|
||||||
|
```
|
||||||
|
ci-cd/
|
||||||
|
├── README.md # Эта документация
|
||||||
|
├── .gitlab-ci.yml # GitLab CI/CD конфигурация
|
||||||
|
├── gitlab/ # GitLab Runner конфигурация
|
||||||
|
│ ├── config.json # Docker registry конфигурация
|
||||||
|
│ ├── docker-compose.yaml # GitLab Runner в Docker
|
||||||
|
│ └── runner/
|
||||||
|
│ └── config.toml # Runner конфигурация
|
||||||
|
└── dockerfiles/ # Dockerfile'ы для разных ОС
|
||||||
|
├── Dockerfile # Базовый Dockerfile
|
||||||
|
├── Dockerfile-CentOS # Dockerfile для CentOS
|
||||||
|
└── Dockerfile-Ubuntu # Dockerfile для Ubuntu
|
||||||
|
```
|
||||||
|
|
||||||
|
## GitLab CI/CD
|
||||||
|
|
||||||
|
### Основные этапы
|
||||||
|
|
||||||
|
1. **Lint** - проверка синтаксиса Ansible
|
||||||
|
2. **Test** - запуск тестов через Molecule
|
||||||
|
3. **Deploy** - развертывание в продакшн
|
||||||
|
4. **Notify** - уведомления о результатах
|
||||||
|
|
||||||
|
### Настройка
|
||||||
|
|
||||||
|
1. **Переменные окружения:**
|
||||||
|
- `CI_REGISTRY_USER` - пользователь Docker registry
|
||||||
|
- `CI_REGISTRY_PASSWORD` - пароль Docker registry
|
||||||
|
- `SSH_PRIVATE_KEY` - SSH ключ для доступа к серверам
|
||||||
|
- `TELEGRAM_BOT_TOKEN` - токен Telegram бота
|
||||||
|
- `TELEGRAM_CHAT_ID` - ID чата для уведомлений
|
||||||
|
|
||||||
|
2. **Docker Registry:**
|
||||||
|
- Настроен доступ к `hub.cism-ms.ru`
|
||||||
|
- Используется образ `hub.cism-ms.ru/ansible/ansible:latest`
|
||||||
|
|
||||||
|
3. **Vault:**
|
||||||
|
- Автоматическое расшифрование/шифрование секретов
|
||||||
|
- Используется `vault-password.txt` для доступа
|
||||||
|
|
||||||
|
## GitLab Runner
|
||||||
|
|
||||||
|
### Конфигурация
|
||||||
|
|
||||||
|
- **Executor:** Docker
|
||||||
|
- **Image:** `hub.cism-ms.ru/ansible/ansible:latest`
|
||||||
|
- **Privileged:** true
|
||||||
|
- **Volumes:** Docker socket для DinD
|
||||||
|
|
||||||
|
### Настройка Runner
|
||||||
|
|
||||||
|
1. Зарегистрировать Runner:
|
||||||
|
```bash
|
||||||
|
docker-compose -f ci-cd/gitlab/docker-compose.yaml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Настроить переменные в `ci-cd/gitlab/runner/config.toml`
|
||||||
|
|
||||||
|
## Dockerfile'ы
|
||||||
|
|
||||||
|
### Базовый Dockerfile
|
||||||
|
- Основан на Ubuntu
|
||||||
|
- Установлены Ansible, Molecule, Docker
|
||||||
|
- Настроен systemd для тестирования
|
||||||
|
|
||||||
|
### Dockerfile-CentOS
|
||||||
|
- Основан на CentOS
|
||||||
|
- Адаптирован для RHEL-семейства
|
||||||
|
- Установлены необходимые пакеты
|
||||||
|
|
||||||
|
### Dockerfile-Ubuntu
|
||||||
|
- Основан на Ubuntu
|
||||||
|
- Оптимизирован для Debian-семейства
|
||||||
|
- Включены дополнительные инструменты
|
||||||
|
|
||||||
|
## Использование
|
||||||
|
|
||||||
|
### Локальная разработка
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Создать роль
|
||||||
|
make role create NAME=my-role
|
||||||
|
|
||||||
|
# Тестировать роль
|
||||||
|
make role test NAME=my-role
|
||||||
|
|
||||||
|
# Проверить синтаксис
|
||||||
|
make role lint
|
||||||
|
```
|
||||||
|
|
||||||
|
### CI/CD Pipeline
|
||||||
|
|
||||||
|
1. **Автоматический запуск** при push в ветки
|
||||||
|
2. **Lint проверка** всех ролей
|
||||||
|
3. **Molecule тесты** для каждой роли
|
||||||
|
4. **Deploy** в продакшн (ручной запуск)
|
||||||
|
5. **Уведомления** в Telegram
|
||||||
|
|
||||||
|
### Настройка для своего проекта
|
||||||
|
|
||||||
|
1. Скопировать `.gitlab-ci.yml` в корень проекта
|
||||||
|
2. Настроить переменные в GitLab
|
||||||
|
3. Обновить Docker registry URL
|
||||||
|
4. Настроить SSH ключи для деплоя
|
||||||
|
|
||||||
|
## Безопасность
|
||||||
|
|
||||||
|
- Все секреты хранятся в Ansible Vault
|
||||||
|
- SSH ключи используются только для деплоя
|
||||||
|
- Docker registry требует аутентификации
|
||||||
|
- Vault файлы автоматически шифруются после использования
|
||||||
|
|
||||||
|
## Автор
|
||||||
|
|
||||||
|
Сергей Антропов
|
||||||
|
Сайт: https://devops.org.ru
|
||||||
@@ -1,12 +1,36 @@
|
|||||||
|
version: "3.9"
|
||||||
|
|
||||||
services:
|
services:
|
||||||
ansible:
|
ansible-controller:
|
||||||
image: inecs/ansible:latest
|
image: quay.io/ansible/creator-ee:latest
|
||||||
container_name: ansible
|
container_name: ansible-controller
|
||||||
volumes:
|
|
||||||
- .:/ansible
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
environment:
|
|
||||||
- ANSIBLE_VAULT_PASSWORD_FILE=./vault-password.txt
|
|
||||||
tty: true
|
|
||||||
privileged: true
|
privileged: true
|
||||||
|
command: sleep infinity
|
||||||
|
environment:
|
||||||
|
DOCKER_HOST: unix:///var/run/docker.sock
|
||||||
|
ANSIBLE_VAULT_PASSWORD_FILE: /ansible/vault/.vault
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./molecule:/ansible/molecule
|
||||||
|
- ./files:/ansible/files
|
||||||
|
- ./scripts:/ansible/scripts
|
||||||
|
- ./reports:/ansible/reports
|
||||||
|
- ./snapshots:/ansible/snapshots
|
||||||
|
- ./vault:/ansible/vault
|
||||||
|
- ./.ansible-lint:/ansible/.ansible-lint
|
||||||
|
# каталог с ролями (локальный или внешний)
|
||||||
|
- ${ROLES_DIR:-./roles}:/ansible/roles:ro
|
||||||
working_dir: /ansible
|
working_dir: /ansible
|
||||||
|
|
||||||
|
# Обратная совместимость
|
||||||
|
# ansible:
|
||||||
|
# image: inecs/ansible:latest
|
||||||
|
# container_name: ansible
|
||||||
|
# volumes:
|
||||||
|
# - .:/ansible
|
||||||
|
# - /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
# environment:
|
||||||
|
# - ANSIBLE_VAULT_PASSWORD_FILE=./vault-password.txt
|
||||||
|
# tty: true
|
||||||
|
# privileged: true
|
||||||
|
# working_dir: /ansible
|
||||||
616
docs/api.md
Normal file
616
docs/api.md
Normal file
@@ -0,0 +1,616 @@
|
|||||||
|
# API Reference
|
||||||
|
|
||||||
|
## Автор
|
||||||
|
Сергей Антропов
|
||||||
|
Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
## Описание
|
||||||
|
|
||||||
|
Этот документ содержит справочник по API универсальной лаборатории, включая все доступные команды, параметры и конфигурации.
|
||||||
|
|
||||||
|
## Содержание
|
||||||
|
|
||||||
|
- [Makefile команды](#makefile-команды)
|
||||||
|
- [Пресеты API](#пресеты-api)
|
||||||
|
- [Kubernetes API](#kubernetes-api)
|
||||||
|
- [Docker API](#docker-api)
|
||||||
|
- [Molecule API](#molecule-api)
|
||||||
|
- [Отчеты API](#отчеты-api)
|
||||||
|
- [Скрипты API](#скрипты-api)
|
||||||
|
|
||||||
|
## Makefile команды
|
||||||
|
|
||||||
|
### Основные команды
|
||||||
|
|
||||||
|
| Команда | Описание | Параметры |
|
||||||
|
|---------|----------|-----------|
|
||||||
|
| `make lab-up` | Поднять контроллер | - |
|
||||||
|
| `make lab-down` | Погасить контроллер | - |
|
||||||
|
| `make lab-sh` | Войти в контроллер | - |
|
||||||
|
| `make lab-test` | Полный цикл Molecule | `SCENARIO=universal` |
|
||||||
|
| `make lab-create` | Создать инфраструктуру | - |
|
||||||
|
| `make lab-converge` | Запустить роли | - |
|
||||||
|
| `make lab-verify` | Проверить работу | - |
|
||||||
|
| `make lab-destroy` | Уничтожить инфраструктуру | - |
|
||||||
|
| `make lab-reset` | Полный сброс | - |
|
||||||
|
|
||||||
|
### Kubernetes команды
|
||||||
|
|
||||||
|
| Команда | Описание | Параметры |
|
||||||
|
|---------|----------|-----------|
|
||||||
|
| `make kube-sh` | Shell с kubectl | - |
|
||||||
|
| `make kube-cmd` | Выполнить kubectl команду | `CLUSTER=lab CMD="get pods"` |
|
||||||
|
| `make kube-enter` | Войти в кластер | `CLUSTER=lab` |
|
||||||
|
| `make kiali-port-forward` | Port-forward Kiali | `CLUSTER=lab` |
|
||||||
|
| `make istio-gw-port-forward` | Port-forward Istio Gateway | `CLUSTER=lab` |
|
||||||
|
| `make grafana-port-forward` | Port-forward Grafana | `CLUSTER=lab` |
|
||||||
|
| `make prom-port-forward` | Port-forward Prometheus | `CLUSTER=lab` |
|
||||||
|
| `make kube-pf-stop` | Остановить все port-forward | - |
|
||||||
|
|
||||||
|
### Отчеты и мониторинг
|
||||||
|
|
||||||
|
| Команда | Описание | Параметры |
|
||||||
|
|---------|----------|-----------|
|
||||||
|
| `make lab-report` | Сгенерировать HTML отчет | - |
|
||||||
|
| `make lab-snapshot` | Сохранить снапшот | - |
|
||||||
|
| `make lab-restore` | Восстановить из снапшота | - |
|
||||||
|
| `make lab-cleanup` | Очистить лабораторию | - |
|
||||||
|
| `make bookinfo-url` | Получить URL Bookinfo | - |
|
||||||
|
| `make grafana-open` | Открыть Grafana | - |
|
||||||
|
|
||||||
|
### Pre-commit команды
|
||||||
|
|
||||||
|
| Команда | Описание | Параметры |
|
||||||
|
|---------|----------|-----------|
|
||||||
|
| `make pre-commit-install` | Установить pre-commit хуки | - |
|
||||||
|
| `make pre-commit-run` | Запустить pre-commit | - |
|
||||||
|
|
||||||
|
## Пресеты API
|
||||||
|
|
||||||
|
### Структура пресета
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
# ПРЕСЕТ: Название (количество машин)
|
||||||
|
#
|
||||||
|
# Описание: Подробное описание пресета
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/your-preset.yml
|
||||||
|
#
|
||||||
|
# Автор: Ваше имя
|
||||||
|
# Сайт: https://your-site.com
|
||||||
|
|
||||||
|
# Сеть для лаборатории
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
# Kind кластеры (опционально)
|
||||||
|
kind_clusters:
|
||||||
|
- name: cluster-name
|
||||||
|
workers: 2
|
||||||
|
api_port: 6443
|
||||||
|
addons:
|
||||||
|
ingress_nginx: true
|
||||||
|
metrics_server: true
|
||||||
|
istio: true
|
||||||
|
kiali: true
|
||||||
|
prometheus_stack: true
|
||||||
|
ingress_host_http_port: 8081
|
||||||
|
ingress_host_https_port: 8443
|
||||||
|
|
||||||
|
# Образы для разных семейств ОС
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
# Настройки по умолчанию для systemd контейнеров
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
# Определение хостов лаборатории
|
||||||
|
hosts:
|
||||||
|
- name: host-name
|
||||||
|
family: debian|rhel
|
||||||
|
type: systemd|dind|dood
|
||||||
|
group: group-name
|
||||||
|
publish:
|
||||||
|
- "host-port:container-port"
|
||||||
|
env:
|
||||||
|
KEY: value
|
||||||
|
volumes:
|
||||||
|
- "host-path:container-path"
|
||||||
|
tmpfs:
|
||||||
|
- "/tmp"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Параметры хостов
|
||||||
|
|
||||||
|
| Параметр | Тип | Описание | Обязательный |
|
||||||
|
|----------|-----|----------|--------------|
|
||||||
|
| `name` | string | Имя хоста | Да |
|
||||||
|
| `family` | string | Семейство ОС (debian/rhel) | Нет |
|
||||||
|
| `type` | string | Тип контейнера (systemd/dind/dood) | Нет |
|
||||||
|
| `group` | string | Группа хоста | Нет |
|
||||||
|
| `publish` | array | Публикация портов | Нет |
|
||||||
|
| `env` | object | Переменные окружения | Нет |
|
||||||
|
| `volumes` | array | Монтирование томов | Нет |
|
||||||
|
| `tmpfs` | array | Временные файловые системы | Нет |
|
||||||
|
| `capabilities` | array | Capabilities | Нет |
|
||||||
|
|
||||||
|
### Параметры Kind кластеров
|
||||||
|
|
||||||
|
| Параметр | Тип | Описание | Обязательный |
|
||||||
|
|----------|-----|----------|--------------|
|
||||||
|
| `name` | string | Имя кластера | Да |
|
||||||
|
| `workers` | integer | Количество worker узлов | Нет |
|
||||||
|
| `api_port` | integer | Порт API сервера | Нет |
|
||||||
|
| `addons` | object | Включенные аддоны | Нет |
|
||||||
|
| `ingress_host_http_port` | integer | HTTP порт для ingress | Нет |
|
||||||
|
| `ingress_host_https_port` | integer | HTTPS порт для ingress | Нет |
|
||||||
|
|
||||||
|
### Аддоны Kind кластеров
|
||||||
|
|
||||||
|
| Аддон | Тип | Описание |
|
||||||
|
|-------|-----|----------|
|
||||||
|
| `ingress_nginx` | boolean | Ingress NGINX контроллер |
|
||||||
|
| `metrics_server` | boolean | Metrics Server для метрик |
|
||||||
|
| `istio` | boolean | Istio service mesh |
|
||||||
|
| `kiali` | boolean | Kiali для визуализации |
|
||||||
|
| `prometheus_stack` | boolean | Prometheus + Grafana |
|
||||||
|
|
||||||
|
## Kubernetes API
|
||||||
|
|
||||||
|
### kubectl команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Получить информацию о кластере
|
||||||
|
kubectl cluster-info
|
||||||
|
|
||||||
|
# Получить ноды
|
||||||
|
kubectl get nodes
|
||||||
|
|
||||||
|
# Получить поды
|
||||||
|
kubectl get pods -A
|
||||||
|
|
||||||
|
# Получить сервисы
|
||||||
|
kubectl get svc -A
|
||||||
|
|
||||||
|
# Получить события
|
||||||
|
kubectl get events --sort-by=.metadata.creationTimestamp
|
||||||
|
|
||||||
|
# Описать ресурс
|
||||||
|
kubectl describe pod <pod-name>
|
||||||
|
|
||||||
|
# Логи пода
|
||||||
|
kubectl logs <pod-name>
|
||||||
|
|
||||||
|
# Войти в под
|
||||||
|
kubectl exec -it <pod-name> -- /bin/sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ansible-lint команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Проверить весь проект
|
||||||
|
make lint
|
||||||
|
|
||||||
|
# Проверить роли
|
||||||
|
make role lint
|
||||||
|
|
||||||
|
# Проверить конкретную роль
|
||||||
|
ansible-lint --config-file .ansible-lint roles/my-role/
|
||||||
|
|
||||||
|
# Проверить playbook
|
||||||
|
ansible-lint --config-file .ansible-lint files/playbooks/site.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Настройки ansible-lint (.ansible-lint)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
skip_list:
|
||||||
|
- fqcn # Полные имена модулей
|
||||||
|
- yaml[new-line-at-end-of-file] # Новая строка в конце файла
|
||||||
|
- yaml[truthy] # Булевы значения
|
||||||
|
- yaml[line-length] # Длина строки
|
||||||
|
- var-naming[no-role-prefix] # Префиксы переменных
|
||||||
|
- 'ignore-errors' # Игнорирование ошибок
|
||||||
|
|
||||||
|
exclude_paths:
|
||||||
|
- molecule/universal/ # Исключить файлы Molecule
|
||||||
|
- files/playbooks/ # Исключить playbooks с Docker модулями
|
||||||
|
```
|
||||||
|
|
||||||
|
**Описание пропускаемых правил:**
|
||||||
|
- `fqcn` - позволяет использовать короткие имена модулей (например, `yum` вместо `ansible.builtin.yum`)
|
||||||
|
- `yaml[new-line-at-end-of-file]` - не требует новой строки в конце YAML файлов
|
||||||
|
- `yaml[truthy]` - позволяет использовать `yes/no` вместо `true/false`
|
||||||
|
- `yaml[line-length]` - не ограничивает длину строк в YAML
|
||||||
|
- `var-naming[no-role-prefix]` - не требует префиксов для переменных ролей
|
||||||
|
- `ignore-errors` - позволяет использовать `ignore_errors: yes`
|
||||||
|
|
||||||
|
**Исключенные пути:**
|
||||||
|
- `molecule/universal/` - файлы Molecule с Docker модулями
|
||||||
|
- `files/playbooks/` - playbooks с Docker Compose модулями
|
||||||
|
|
||||||
|
### Port-forward команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Port-forward сервиса
|
||||||
|
kubectl port-forward svc/<service-name> <local-port>:<remote-port>
|
||||||
|
|
||||||
|
# Port-forward пода
|
||||||
|
kubectl port-forward pod/<pod-name> <local-port>:<remote-port>
|
||||||
|
|
||||||
|
# Port-forward в фоне
|
||||||
|
kubectl port-forward svc/<service-name> <local-port>:<remote-port> &
|
||||||
|
|
||||||
|
# Остановить все port-forward
|
||||||
|
pkill -f "kubectl .* port-forward"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Istio команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Проверить Istio
|
||||||
|
istioctl version
|
||||||
|
|
||||||
|
# Установить Istio
|
||||||
|
istioctl install --set profile=demo
|
||||||
|
|
||||||
|
# Удалить Istio
|
||||||
|
istioctl uninstall --purge
|
||||||
|
|
||||||
|
# Проверить статус
|
||||||
|
istioctl proxy-status
|
||||||
|
|
||||||
|
# Получить конфигурацию
|
||||||
|
istioctl proxy-config cluster <pod-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Docker API
|
||||||
|
|
||||||
|
### Docker команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Список контейнеров
|
||||||
|
docker ps
|
||||||
|
|
||||||
|
# Список образов
|
||||||
|
docker images
|
||||||
|
|
||||||
|
# Список сетей
|
||||||
|
docker network ls
|
||||||
|
|
||||||
|
# Список томов
|
||||||
|
docker volume ls
|
||||||
|
|
||||||
|
# Информация о контейнере
|
||||||
|
docker inspect <container-name>
|
||||||
|
|
||||||
|
# Логи контейнера
|
||||||
|
docker logs <container-name>
|
||||||
|
|
||||||
|
# Войти в контейнер
|
||||||
|
docker exec -it <container-name> /bin/sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Compose команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить стек
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
# Остановить стек
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
# Логи стека
|
||||||
|
docker-compose logs
|
||||||
|
|
||||||
|
# Масштабирование
|
||||||
|
docker-compose up --scale service=3
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker Swarm команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Инициализировать Swarm
|
||||||
|
docker swarm init
|
||||||
|
|
||||||
|
# Присоединиться к Swarm
|
||||||
|
docker swarm join --token <token> <manager-ip>:2377
|
||||||
|
|
||||||
|
# Список нод
|
||||||
|
docker node ls
|
||||||
|
|
||||||
|
# Создать сервис
|
||||||
|
docker service create --name <service-name> <image>
|
||||||
|
|
||||||
|
# Масштабировать сервис
|
||||||
|
docker service scale <service-name>=3
|
||||||
|
```
|
||||||
|
|
||||||
|
## Molecule API
|
||||||
|
|
||||||
|
### Molecule команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Создать сценарий
|
||||||
|
molecule init scenario <scenario-name>
|
||||||
|
|
||||||
|
# Создать роль
|
||||||
|
molecule init role <role-name>
|
||||||
|
|
||||||
|
# Проверить синтаксис
|
||||||
|
molecule syntax
|
||||||
|
|
||||||
|
# Проверить конфигурацию
|
||||||
|
molecule lint
|
||||||
|
|
||||||
|
# Валидация
|
||||||
|
molecule validate
|
||||||
|
|
||||||
|
# Создать инфраструктуру
|
||||||
|
molecule create
|
||||||
|
|
||||||
|
# Запустить роли
|
||||||
|
molecule converge
|
||||||
|
|
||||||
|
# Проверить работу
|
||||||
|
molecule verify
|
||||||
|
|
||||||
|
# Уничтожить инфраструктуру
|
||||||
|
molecule destroy
|
||||||
|
|
||||||
|
# Полный цикл
|
||||||
|
molecule test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Конфигурация molecule.yml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
driver:
|
||||||
|
name: docker
|
||||||
|
|
||||||
|
platforms:
|
||||||
|
- name: instance
|
||||||
|
image: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
privileged: true
|
||||||
|
pre_build_image: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
|
||||||
|
provisioner:
|
||||||
|
name: ansible
|
||||||
|
config_options:
|
||||||
|
defaults:
|
||||||
|
stdout_callback: default
|
||||||
|
callbacks_enabled: profile_tasks
|
||||||
|
env:
|
||||||
|
ANSIBLE_STDOUT_CALLBACK: default
|
||||||
|
|
||||||
|
dependency:
|
||||||
|
name: galaxy
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
verifier:
|
||||||
|
name: ansible
|
||||||
|
|
||||||
|
lint: |-
|
||||||
|
set -e
|
||||||
|
ansible-lint
|
||||||
|
```
|
||||||
|
|
||||||
|
## Отчеты API
|
||||||
|
|
||||||
|
### HTML отчет
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Генерация отчета
|
||||||
|
python3 scripts/report_html.py <input.json> <output.html>
|
||||||
|
|
||||||
|
# Параметры
|
||||||
|
# input.json - JSON файл с данными
|
||||||
|
# output.html - HTML файл для вывода
|
||||||
|
```
|
||||||
|
|
||||||
|
### JSON структура
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"timestamp": "2024-01-01T00:00:00Z",
|
||||||
|
"idempotence_raw": "changed=0",
|
||||||
|
"haproxy_select1": "1",
|
||||||
|
"helm_ingress_toolbox_raw": "ingress ready",
|
||||||
|
"istio_kiali_raw": "istio-system pods running",
|
||||||
|
"istio_bookinfo_raw": "bookinfo deployed",
|
||||||
|
"k8s_overview_raw": "nodes ready"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### HTML структура
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Lab Report</title>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
<style>
|
||||||
|
/* CSS стили */
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="hdr">
|
||||||
|
<h1>Ansible Lab Report</h1>
|
||||||
|
<div class="time">generated: timestamp</div>
|
||||||
|
</div>
|
||||||
|
<div class="grid">
|
||||||
|
<!-- Отчеты -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Скрипты API
|
||||||
|
|
||||||
|
### snapshot.sh
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Создание снапшотов лаборатории (запускается через Docker)
|
||||||
|
|
||||||
|
# Параметры
|
||||||
|
OUT_DIR="/ansible/snapshots"
|
||||||
|
|
||||||
|
# Создать директорию
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
|
||||||
|
# Получить ID контейнеров
|
||||||
|
ids=$(docker ps -q --filter "label=ansible.lab=true")
|
||||||
|
|
||||||
|
# Создать снапшоты
|
||||||
|
for id in $ids; do
|
||||||
|
name=$(docker inspect --format '{{.Name}}' "$id" | sed 's#^/##')
|
||||||
|
img="lab-snap-$name:latest"
|
||||||
|
echo "[snapshot] $name -> $img"
|
||||||
|
docker commit "$id" "$img" >/dev/null
|
||||||
|
echo "$img" > "$OUT_DIR/$name.image"
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
### restore.sh
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Восстановление из снапшотов (запускается через Docker)
|
||||||
|
|
||||||
|
# Параметры
|
||||||
|
IN_DIR="/ansible/snapshots"
|
||||||
|
|
||||||
|
# Проверить директорию
|
||||||
|
[ -d "$IN_DIR" ] || { echo "No snapshots dir"; exit 1; }
|
||||||
|
|
||||||
|
# Восстановить контейнеры
|
||||||
|
for f in "$IN_DIR"/*.image; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
name=$(basename "$f" .image)
|
||||||
|
img=$(cat "$f")
|
||||||
|
echo "[restore] $name from $img"
|
||||||
|
docker rm -f "$name" >/dev/null 2>&1 || true
|
||||||
|
docker run -d --name "$name" "$img" >/dev/null
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
### cleanup.sh
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Очистка лаборатории (запускается через Docker)
|
||||||
|
|
||||||
|
echo "[cleanup] removing lab containers/volumes/networks"
|
||||||
|
|
||||||
|
# Удалить контейнеры
|
||||||
|
docker ps -aq --filter "label=ansible.lab=true" | xargs -r docker rm -f
|
||||||
|
|
||||||
|
# Удалить тома
|
||||||
|
docker volume ls -q --filter "name=_docker$" | xargs -r docker volume rm
|
||||||
|
|
||||||
|
# Удалить сеть
|
||||||
|
docker network rm labnet >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
echo "done."
|
||||||
|
```
|
||||||
|
|
||||||
|
## Переменные окружения
|
||||||
|
|
||||||
|
### Основные переменные
|
||||||
|
|
||||||
|
| Переменная | Описание | Значение по умолчанию |
|
||||||
|
|------------|----------|----------------------|
|
||||||
|
| `LAB_SPEC` | Путь к пресету | `molecule/presets/minimal.yml` |
|
||||||
|
| `SCENARIO` | Сценарий Molecule | `universal` |
|
||||||
|
| `COMPOSE` | Docker Compose команда | `docker compose` |
|
||||||
|
| `ROLES_DIR` | Директория с ролями | `./roles` |
|
||||||
|
| `LAB_PAUSE_MINUTES` | Пауза для ручной проверки | `10` |
|
||||||
|
|
||||||
|
### Kubernetes переменные
|
||||||
|
|
||||||
|
| Переменная | Описание | Значение по умолчанию |
|
||||||
|
|------------|----------|----------------------|
|
||||||
|
| `KUBECONFIG` | Путь к kubeconfig | `~/.kube/config` |
|
||||||
|
| `KUBE_CONTEXT` | Контекст Kubernetes | `kind-lab` |
|
||||||
|
| `ISTIO_VERSION` | Версия Istio | `1.22.1` |
|
||||||
|
| `KIND_VERSION` | Версия Kind | `v0.23.0` |
|
||||||
|
|
||||||
|
### Docker переменные
|
||||||
|
|
||||||
|
| Переменная | Описание | Значение по умолчанию |
|
||||||
|
|------------|----------|----------------------|
|
||||||
|
| `DOCKER_HOST` | Docker daemon адрес | `unix:///var/run/docker.sock` |
|
||||||
|
| `DOCKER_TLS_CERTDIR` | Директория TLS сертификатов | `""` |
|
||||||
|
| `DOCKER_BUILDKIT` | Использовать BuildKit | `1` |
|
||||||
|
|
||||||
|
## Конфигурационные файлы
|
||||||
|
|
||||||
|
### docker-compose.yaml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: "3.9"
|
||||||
|
|
||||||
|
services:
|
||||||
|
ansible-controller:
|
||||||
|
image: quay.io/ansible/creator-ee:latest
|
||||||
|
container_name: ansible-controller
|
||||||
|
privileged: true
|
||||||
|
command: sleep infinity
|
||||||
|
environment:
|
||||||
|
DOCKER_HOST: unix:///var/run/docker.sock
|
||||||
|
ANSIBLE_VAULT_PASSWORD_FILE: /ansible/vault-password.txt
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- ./molecule:/ansible/molecule
|
||||||
|
- ./files:/ansible/files
|
||||||
|
- ./vault-password.txt:/ansible/vault-password.txt
|
||||||
|
- ${ROLES_DIR:-./roles}:/ansible/roles:ro
|
||||||
|
working_dir: /ansible
|
||||||
|
```
|
||||||
|
|
||||||
|
### .pre-commit-config.yaml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v4.4.0
|
||||||
|
hooks:
|
||||||
|
- id: trailing-whitespace
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
- id: check-yaml
|
||||||
|
- id: check-added-large-files
|
||||||
|
- repo: https://github.com/ansible/ansible-lint
|
||||||
|
rev: v6.17.2
|
||||||
|
hooks:
|
||||||
|
- id: ansible-lint
|
||||||
|
```
|
||||||
|
|
||||||
|
## Заключение
|
||||||
|
|
||||||
|
Этот справочник содержит все необходимые API для работы с универсальной лабораторией. Для получения дополнительной информации обратитесь к [основной документации](universal-lab.md) и [примерам использования](examples.md).
|
||||||
462
docs/examples.md
Normal file
462
docs/examples.md
Normal file
@@ -0,0 +1,462 @@
|
|||||||
|
# Примеры использования
|
||||||
|
|
||||||
|
## Автор
|
||||||
|
Сергей Антропов
|
||||||
|
Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
## Описание
|
||||||
|
|
||||||
|
Этот документ содержит практические примеры использования универсальной лаборатории для различных сценариев тестирования Ansible ролей.
|
||||||
|
|
||||||
|
## Содержание
|
||||||
|
|
||||||
|
- [Базовые примеры](#базовые-примеры)
|
||||||
|
- [Kubernetes примеры](#kubernetes-примеры)
|
||||||
|
- [Docker примеры](#docker-примеры)
|
||||||
|
- [Смешанные примеры](#смешанные-примеры)
|
||||||
|
- [Мониторинг и отчеты](#мониторинг-и-отчеты)
|
||||||
|
- [Troubleshooting](#troubleshooting)
|
||||||
|
|
||||||
|
## Базовые примеры
|
||||||
|
|
||||||
|
### Пример 1: Тестирование веб-сервера
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить веб-приложение пресет
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/webapp.yml
|
||||||
|
|
||||||
|
# Проверить статус
|
||||||
|
make lab-verify
|
||||||
|
|
||||||
|
# Посмотреть отчет
|
||||||
|
make lab-report
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 2: Тестирование базы данных
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить пресет с базой данных
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/ha.yml
|
||||||
|
|
||||||
|
# Проверить подключение к БД
|
||||||
|
make kube-cmd CLUSTER=lab CMD="exec -it postgres-0 -- psql -U postgres -c 'SELECT 1;'"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 3: Тестирование микросервисов
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить микросервисный пресет
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/microservices.yml
|
||||||
|
|
||||||
|
# Проверить API Gateway
|
||||||
|
curl http://localhost:8000/health
|
||||||
|
```
|
||||||
|
|
||||||
|
## Kubernetes примеры
|
||||||
|
|
||||||
|
### Пример 1: Простой Kubernetes кластер
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить одиночный Kind кластер
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/k8s-single.yml
|
||||||
|
|
||||||
|
# Войти в кластер
|
||||||
|
make kube-sh
|
||||||
|
|
||||||
|
# Проверить ноды
|
||||||
|
kubectl get nodes
|
||||||
|
|
||||||
|
# Проверить поды
|
||||||
|
kubectl get pods -A
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 2: Мульти-кластерная конфигурация
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить мульти-кластер
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/k8s-multi.yml
|
||||||
|
|
||||||
|
# Переключиться между кластерами
|
||||||
|
kubectl config use-context kind-dev
|
||||||
|
kubectl get nodes
|
||||||
|
|
||||||
|
kubectl config use-context kind-staging
|
||||||
|
kubectl get nodes
|
||||||
|
|
||||||
|
kubectl config use-context kind-prod
|
||||||
|
kubectl get nodes
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 3: Istio Service Mesh
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить полный Istio стек
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/k8s-istio-full.yml
|
||||||
|
|
||||||
|
# Port-forward Kiali
|
||||||
|
make kiali-port-forward CLUSTER=istio-full
|
||||||
|
|
||||||
|
# Port-forward Istio Gateway
|
||||||
|
make istio-gw-port-forward CLUSTER=istio-full
|
||||||
|
|
||||||
|
# Открыть Kiali
|
||||||
|
open http://localhost:20001
|
||||||
|
|
||||||
|
# Открыть Bookinfo
|
||||||
|
open http://localhost:8082/productpage
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 4: Мониторинг Kubernetes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Port-forward Grafana
|
||||||
|
make grafana-port-forward CLUSTER=istio-full
|
||||||
|
|
||||||
|
# Port-forward Prometheus
|
||||||
|
make prom-port-forward CLUSTER=istio-full
|
||||||
|
|
||||||
|
# Открыть Grafana
|
||||||
|
open http://localhost:3000
|
||||||
|
|
||||||
|
# Открыть Prometheus
|
||||||
|
open http://localhost:9090
|
||||||
|
```
|
||||||
|
|
||||||
|
## Docker примеры
|
||||||
|
|
||||||
|
### Пример 1: Docker-in-Docker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить DinD пресет
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/dind-simple.yml
|
||||||
|
|
||||||
|
# Войти в DinD контейнер
|
||||||
|
docker exec -it dind1 sh
|
||||||
|
|
||||||
|
# Внутри контейнера проверить Docker
|
||||||
|
docker ps
|
||||||
|
docker images
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 2: Docker Swarm
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить Docker Swarm пресет
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/dind-swarm.yml
|
||||||
|
|
||||||
|
# Войти в manager
|
||||||
|
docker exec -it swarm-manager sh
|
||||||
|
|
||||||
|
# Инициализировать Swarm
|
||||||
|
docker swarm init
|
||||||
|
|
||||||
|
# Присоединить workers
|
||||||
|
docker node ls
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 3: Docker Compose
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить Compose пресет
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/dind-compose.yml
|
||||||
|
|
||||||
|
# Войти в compose контейнер
|
||||||
|
docker exec -it compose-web sh
|
||||||
|
|
||||||
|
# Создать docker-compose.yml
|
||||||
|
cat > docker-compose.yml << EOF
|
||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
web:
|
||||||
|
image: nginx:alpine
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
api:
|
||||||
|
image: node:alpine
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Запустить стек
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 4: Docker-outside-of-Docker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить DOoD пресет
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/dood-simple.yml
|
||||||
|
|
||||||
|
# Войти в DOoD контейнер
|
||||||
|
docker exec -it dood1 sh
|
||||||
|
|
||||||
|
# Проверить доступ к Docker daemon хоста
|
||||||
|
docker ps
|
||||||
|
docker images
|
||||||
|
```
|
||||||
|
|
||||||
|
## Смешанные примеры
|
||||||
|
|
||||||
|
### Пример 1: Kubernetes + DinD
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить смешанный пресет
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/mixed-k8s-dind.yml
|
||||||
|
|
||||||
|
# Проверить Kubernetes
|
||||||
|
make kube-cmd CLUSTER=hybrid CMD="get nodes"
|
||||||
|
|
||||||
|
# Проверить DinD
|
||||||
|
docker exec -it dind-dev sh
|
||||||
|
docker ps
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 2: Kubernetes + DOoD
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить смешанный пресет
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/mixed-k8s-dood.yml
|
||||||
|
|
||||||
|
# Проверить Kubernetes
|
||||||
|
make kube-cmd CLUSTER=hybrid CMD="get pods -A"
|
||||||
|
|
||||||
|
# Проверить DOoD
|
||||||
|
docker exec -it dood-web sh
|
||||||
|
docker ps
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 3: Полная гибридная конфигурация
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить полный смешанный пресет
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/mixed-full.yml
|
||||||
|
|
||||||
|
# Проверить все компоненты
|
||||||
|
make kube-cmd CLUSTER=full-stack CMD="get nodes"
|
||||||
|
docker exec -it dind-dev sh
|
||||||
|
docker exec -it dood-web sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Мониторинг и отчеты
|
||||||
|
|
||||||
|
### Пример 1: Генерация HTML отчета
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить тест
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/enterprise.yml
|
||||||
|
|
||||||
|
# Сгенерировать отчет
|
||||||
|
make lab-report
|
||||||
|
|
||||||
|
# Открыть отчет
|
||||||
|
open reports/lab-report.html
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 2: Снапшоты
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Создать снапшот
|
||||||
|
make lab-snapshot
|
||||||
|
|
||||||
|
# Восстановить из снапшота
|
||||||
|
make lab-restore
|
||||||
|
|
||||||
|
# Очистить лабораторию
|
||||||
|
make lab-cleanup
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 3: Мониторинг в реальном времени
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Port-forward всех сервисов мониторинга
|
||||||
|
make grafana-port-forward CLUSTER=lab
|
||||||
|
make prom-port-forward CLUSTER=lab
|
||||||
|
make kiali-port-forward CLUSTER=lab
|
||||||
|
|
||||||
|
# Открыть все дашборды
|
||||||
|
open http://localhost:3000 # Grafana
|
||||||
|
open http://localhost:9090 # Prometheus
|
||||||
|
open http://localhost:20001 # Kiali
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Пример 1: Проблемы с портами
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Проверить занятые порты
|
||||||
|
netstat -tulpn | grep :8080
|
||||||
|
|
||||||
|
# Остановить все port-forward
|
||||||
|
make kube-pf-stop
|
||||||
|
|
||||||
|
# Перезапустить лабораторию
|
||||||
|
make lab-reset
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 2: Проблемы с Docker
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Проверить Docker daemon
|
||||||
|
docker ps
|
||||||
|
|
||||||
|
# Перезапустить Docker
|
||||||
|
sudo systemctl restart docker
|
||||||
|
|
||||||
|
# Очистить Docker
|
||||||
|
docker system prune -a
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 3: Проблемы с Kubernetes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Проверить Kind кластеры
|
||||||
|
kind get clusters
|
||||||
|
|
||||||
|
# Удалить проблемный кластер
|
||||||
|
kind delete cluster --name lab
|
||||||
|
|
||||||
|
# Пересоздать кластер
|
||||||
|
make lab-create
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 4: Проблемы с ресурсами
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Проверить использование ресурсов
|
||||||
|
docker stats
|
||||||
|
|
||||||
|
# Ограничить ресурсы
|
||||||
|
docker run --memory=512m --cpus=1.0 your-image
|
||||||
|
|
||||||
|
# Очистить неиспользуемые ресурсы
|
||||||
|
make lab-cleanup
|
||||||
|
```
|
||||||
|
|
||||||
|
## Продвинутые примеры
|
||||||
|
|
||||||
|
### Пример 1: Создание собственного пресета
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Создать новый пресет
|
||||||
|
cat > molecule/presets/my-custom.yml << EOF
|
||||||
|
---
|
||||||
|
# ПРЕСЕТ: Мой кастомный пресет
|
||||||
|
#
|
||||||
|
# Описание: Кастомная конфигурация для моих нужд
|
||||||
|
#
|
||||||
|
# Использование: make lab-test LAB_SPEC=molecule/presets/my-custom.yml
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: my-web
|
||||||
|
family: debian
|
||||||
|
group: webservers
|
||||||
|
publish:
|
||||||
|
- "8080:80"
|
||||||
|
|
||||||
|
- name: my-db
|
||||||
|
family: rhel
|
||||||
|
group: databases
|
||||||
|
publish:
|
||||||
|
- "5432:5432"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Протестировать пресет
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/my-custom.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 2: Создание собственной роли
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Создать структуру роли
|
||||||
|
mkdir -p roles/my-role/{tasks,handlers,templates,files,vars,defaults,meta}
|
||||||
|
|
||||||
|
# Создать основной task
|
||||||
|
cat > roles/my-role/tasks/main.yml << EOF
|
||||||
|
---
|
||||||
|
- name: Install nginx
|
||||||
|
package:
|
||||||
|
name: nginx
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Start nginx
|
||||||
|
service:
|
||||||
|
name: nginx
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Создать playbook
|
||||||
|
cat > files/playbooks/my-playbook.yml << EOF
|
||||||
|
---
|
||||||
|
- name: Deploy my role
|
||||||
|
hosts: webservers
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- my-role
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Протестировать роль
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/webapp.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример 3: Интеграция с CI/CD
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Создать GitHub Actions workflow
|
||||||
|
cat > .github/workflows/test.yml << EOF
|
||||||
|
name: Test Ansible Roles
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ main ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup Docker
|
||||||
|
run: |
|
||||||
|
docker-compose up -d
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: |
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/minimal.yml
|
||||||
|
|
||||||
|
- name: Generate report
|
||||||
|
run: |
|
||||||
|
make lab-report
|
||||||
|
|
||||||
|
- name: Upload report
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: lab-report
|
||||||
|
path: reports/lab-report.html
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
## Заключение
|
||||||
|
|
||||||
|
Эти примеры демонстрируют основные возможности универсальной лаборатории. Для получения дополнительной информации обратитесь к [основной документации](universal-lab.md) и [описанию пресетов](presets.md).
|
||||||
196
docs/presets.md
Normal file
196
docs/presets.md
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
# Пресеты универсальной лаборатории
|
||||||
|
|
||||||
|
## Автор
|
||||||
|
Сергей Антропов
|
||||||
|
Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
## Описание
|
||||||
|
|
||||||
|
Этот каталог содержит готовые пресеты для различных сценариев тестирования Ansible ролей. Каждый пресет оптимизирован для определенного типа инфраструктуры и количества машин.
|
||||||
|
|
||||||
|
## Доступные пресеты
|
||||||
|
|
||||||
|
### 🏗️ Классические пресеты (systemd контейнеры)
|
||||||
|
|
||||||
|
#### 1. Минимальная лаборатория (1-3 машины)
|
||||||
|
**Файл:** `minimal.yml`
|
||||||
|
**Описание:** Базовая конфигурация для простых тестов Ansible ролей
|
||||||
|
**Компоненты:** 1 контроллер, 1 веб-сервер, 1 база данных
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/minimal.yml`
|
||||||
|
|
||||||
|
### 2. Веб-приложение (3-5 машин)
|
||||||
|
**Файл:** `webapp.yml`
|
||||||
|
**Описание:** Классическая архитектура веб-приложения
|
||||||
|
**Компоненты:** 2 веб-сервера, 1 БД, 1 кэш, 1 балансировщик
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/webapp.yml`
|
||||||
|
|
||||||
|
### 3. Микросервисы (5-8 машин)
|
||||||
|
**Файл:** `microservices.yml`
|
||||||
|
**Описание:** Архитектура микросервисов с разделением ответственности
|
||||||
|
**Компоненты:** API Gateway, микросервисы, БД, кэш, очередь, мониторинг
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/microservices.yml`
|
||||||
|
|
||||||
|
### 4. Высокая доступность (6-10 машин)
|
||||||
|
**Файл:** `ha.yml`
|
||||||
|
**Описание:** Кластер высокой доступности с репликацией
|
||||||
|
**Компоненты:** 2 веб-сервера, 2 БД, 2 кэша, балансировщик, мониторинг
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/ha.yml`
|
||||||
|
|
||||||
|
### 5. Kubernetes кластер (8-12 машин)
|
||||||
|
**Файл:** `k8s-cluster.yml`
|
||||||
|
**Описание:** Полноценный Kubernetes кластер с различными ролями
|
||||||
|
**Компоненты:** 3 master, 3 worker, 3 etcd, ingress, мониторинг
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/k8s-cluster.yml`
|
||||||
|
|
||||||
|
### 6. CI/CD пайплайн (10-15 машин)
|
||||||
|
**Файл:** `cicd.yml`
|
||||||
|
**Описание:** Полноценный CI/CD пайплайн с различными инструментами
|
||||||
|
**Компоненты:** Git, Jenkins, Nexus, Docker Registry, среды, мониторинг, ELK
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/cicd.yml`
|
||||||
|
|
||||||
|
### 7. Big Data кластер (12-18 машин)
|
||||||
|
**Файл:** `bigdata.yml`
|
||||||
|
**Описание:** Кластер для обработки больших данных
|
||||||
|
**Компоненты:** Hadoop, Spark, Kafka, Zookeeper, Elasticsearch, Kibana
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/bigdata.yml`
|
||||||
|
|
||||||
|
### 8. Service Mesh (15-20 машин)
|
||||||
|
**Файл:** `servicemesh.yml`
|
||||||
|
**Описание:** Полноценный service mesh с Istio и множественными сервисами
|
||||||
|
**Компоненты:** Istio, Frontend, Backend, БД, кэш, мониторинг, трассировка
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/servicemesh.yml`
|
||||||
|
|
||||||
|
### 9. Enterprise (18-20 машин)
|
||||||
|
**Файл:** `enterprise.yml`
|
||||||
|
**Описание:** Полноценная enterprise инфраструктура с высокой доступностью
|
||||||
|
**Компоненты:** LB, Web, API Gateway, App, БД, кэш, очереди, поиск, мониторинг, логи, backup
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/enterprise.yml`
|
||||||
|
|
||||||
|
### 10. Максимальный (20 машин)
|
||||||
|
**Файл:** `maximum.yml`
|
||||||
|
**Описание:** Максимально сложная инфраструктура для экстремальных условий
|
||||||
|
**Компоненты:** Все компоненты enterprise + трассировка + визуализация
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/maximum.yml`
|
||||||
|
|
||||||
|
### ☸️ Kubernetes пресеты
|
||||||
|
|
||||||
|
#### 11. Kubernetes Single Node (1 кластер)
|
||||||
|
**Файл:** `k8s-single.yml`
|
||||||
|
**Описание:** Одиночный Kind кластер для простого тестирования K8s ролей
|
||||||
|
**Компоненты:** 1 Kind кластер с 1 worker, базовые аддоны
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/k8s-single.yml`
|
||||||
|
|
||||||
|
#### 12. Kubernetes Multi-Cluster (3 кластера)
|
||||||
|
**Файл:** `k8s-multi.yml`
|
||||||
|
**Описание:** Несколько Kind кластеров для тестирования мульти-кластерных сценариев
|
||||||
|
**Компоненты:** 3 кластера (dev, staging, prod) с различными конфигурациями
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/k8s-multi.yml`
|
||||||
|
|
||||||
|
#### 13. Kubernetes + Istio Full Stack (1 кластер с полным стеком)
|
||||||
|
**Файл:** `k8s-istio-full.yml`
|
||||||
|
**Описание:** Полноценный Kubernetes кластер с полным стеком Istio
|
||||||
|
**Компоненты:** 1 Kind кластер с 3 workers, Istio, Kiali, Prometheus, Grafana, Jaeger
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/k8s-istio-full.yml`
|
||||||
|
|
||||||
|
### 🐳 Docker-in-Docker (DinD) пресеты
|
||||||
|
|
||||||
|
#### 14. DinD Simple (3 DinD контейнера)
|
||||||
|
**Файл:** `dind-simple.yml`
|
||||||
|
**Описание:** Простая конфигурация DinD для тестирования Docker ролей
|
||||||
|
**Компоненты:** 3 DinD контейнера с изолированными Docker средами
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/dind-simple.yml`
|
||||||
|
|
||||||
|
#### 15. DinD Swarm (5 DinD контейнеров)
|
||||||
|
**Файл:** `dind-swarm.yml`
|
||||||
|
**Описание:** Docker Swarm кластер для тестирования оркестрации
|
||||||
|
**Компоненты:** 1 Manager + 4 Worker узла в Docker Swarm режиме
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/dind-swarm.yml`
|
||||||
|
|
||||||
|
#### 16. DinD Compose (4 DinD контейнера)
|
||||||
|
**Файл:** `dind-compose.yml`
|
||||||
|
**Описание:** DinD контейнеры для тестирования Docker Compose стека
|
||||||
|
**Компоненты:** 4 DinD контейнера с различными стеками
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/dind-compose.yml`
|
||||||
|
|
||||||
|
### 🔗 Docker-outside-of-Docker (DOoD) пресеты
|
||||||
|
|
||||||
|
#### 17. DOoD Simple (3 DOoD контейнера)
|
||||||
|
**Файл:** `dood-simple.yml`
|
||||||
|
**Описание:** Простая конфигурация DOoD для тестирования Docker ролей
|
||||||
|
**Компоненты:** 3 DOoD контейнера с доступом к Docker daemon хоста
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/dood-simple.yml`
|
||||||
|
|
||||||
|
#### 18. DOoD Mixed (5 DOoD + 2 systemd)
|
||||||
|
**Файл:** `dood-mixed.yml`
|
||||||
|
**Описание:** Смешанная конфигурация DOoD и systemd контейнеров
|
||||||
|
**Компоненты:** 5 DOoD контейнеров для Docker операций + 2 systemd для системных ролей
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/dood-mixed.yml`
|
||||||
|
|
||||||
|
### 🔀 Смешанные пресеты
|
||||||
|
|
||||||
|
#### 19. Mixed Kubernetes + DinD (1 K8s + 3 DinD)
|
||||||
|
**Файл:** `mixed-k8s-dind.yml`
|
||||||
|
**Описание:** Смешанная конфигурация Kubernetes и Docker-in-Docker
|
||||||
|
**Компоненты:** 1 Kind кластер + 3 DinD контейнера
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/mixed-k8s-dind.yml`
|
||||||
|
|
||||||
|
#### 20. Mixed Kubernetes + DOoD (1 K8s + 3 DOoD)
|
||||||
|
**Файл:** `mixed-k8s-dood.yml`
|
||||||
|
**Описание:** Смешанная конфигурация Kubernetes и Docker-outside-of-Docker
|
||||||
|
**Компоненты:** 1 Kind кластер + 3 DOoD контейнера
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/mixed-k8s-dood.yml`
|
||||||
|
|
||||||
|
#### 21. Mixed Full Stack (1 K8s + 2 DinD + 2 DOoD + 2 systemd)
|
||||||
|
**Файл:** `mixed-full.yml`
|
||||||
|
**Описание:** Полная смешанная конфигурация для комплексного тестирования
|
||||||
|
**Компоненты:** 1 Kind кластер + 2 DinD + 2 DOoD + 2 systemd контейнера
|
||||||
|
**Использование:** `make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/mixed-full.yml`
|
||||||
|
|
||||||
|
## Использование
|
||||||
|
|
||||||
|
### Быстрый старт
|
||||||
|
```bash
|
||||||
|
# Выбрать пресет
|
||||||
|
export LAB_SPEC=molecule/presets/minimal.yml
|
||||||
|
|
||||||
|
# Запустить тестирование
|
||||||
|
make lab-test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Создание собственного пресета
|
||||||
|
1. Скопировать существующий пресет: `cp minimal.yml my-preset.yml`
|
||||||
|
2. Отредактировать под ваши нужды
|
||||||
|
3. Использовать: `make lab-test LAB_SPEC=molecule/presets/my-preset.yml`
|
||||||
|
|
||||||
|
### Переменные окружения
|
||||||
|
```bash
|
||||||
|
# Установить пресет по умолчанию
|
||||||
|
export LAB_SPEC=molecule/presets/webapp.yml
|
||||||
|
|
||||||
|
# Или использовать в команде
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/ha.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Рекомендации
|
||||||
|
|
||||||
|
- **Для начинающих:** используйте `minimal.yml` или `webapp.yml`
|
||||||
|
- **Для микросервисов:** `microservices.yml` или `servicemesh.yml`
|
||||||
|
- **Для Kubernetes:** `k8s-cluster.yml`
|
||||||
|
- **Для enterprise:** `enterprise.yml` или `maximum.yml`
|
||||||
|
- **Для Big Data:** `bigdata.yml`
|
||||||
|
|
||||||
|
## Кастомизация
|
||||||
|
|
||||||
|
Каждый пресет можно настроить под ваши нужды:
|
||||||
|
- Изменить количество машин
|
||||||
|
- Добавить/убрать группы
|
||||||
|
- Изменить семейства ОС (debian/rhel)
|
||||||
|
- Настроить порты и переменные
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
Если пресет не работает:
|
||||||
|
1. Проверьте доступность Docker образов
|
||||||
|
2. Убедитесь в достаточности ресурсов
|
||||||
|
3. Проверьте логи: `make lab-verify`
|
||||||
|
4. Очистите лабораторию: `make lab-cleanup`
|
||||||
420
docs/roles.md
Normal file
420
docs/roles.md
Normal file
@@ -0,0 +1,420 @@
|
|||||||
|
# Ansible Роли
|
||||||
|
|
||||||
|
## Автор
|
||||||
|
Сергей Антропов
|
||||||
|
Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
## Описание
|
||||||
|
|
||||||
|
Этот документ описывает структуру, создание и использование Ansible ролей в универсальной лаборатории.
|
||||||
|
|
||||||
|
## Содержание
|
||||||
|
|
||||||
|
- [Структура роли](#структура-роли)
|
||||||
|
- [Создание роли](#создание-роли)
|
||||||
|
- [Использование роли](#использование-роли)
|
||||||
|
- [Тестирование роли](#тестирование-роли)
|
||||||
|
- [Лучшие практики](#лучшие-практики)
|
||||||
|
- [Примеры ролей](#примеры-ролей)
|
||||||
|
|
||||||
|
## Структура роли
|
||||||
|
|
||||||
|
```
|
||||||
|
roles/
|
||||||
|
└── your_role/
|
||||||
|
├── tasks/ # Основные задачи
|
||||||
|
│ └── main.yml
|
||||||
|
├── handlers/ # Обработчики событий
|
||||||
|
│ └── main.yml
|
||||||
|
├── templates/ # Jinja2 шаблоны
|
||||||
|
│ └── config.j2
|
||||||
|
├── files/ # Статические файлы
|
||||||
|
│ └── config.conf
|
||||||
|
├── vars/ # Переменные роли
|
||||||
|
│ └── main.yml
|
||||||
|
├── defaults/ # Переменные по умолчанию
|
||||||
|
│ └── main.yml
|
||||||
|
├── meta/ # Метаданные роли
|
||||||
|
│ └── main.yml
|
||||||
|
└── tests/ # Тесты роли
|
||||||
|
├── inventory
|
||||||
|
└── test.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Описание директорий
|
||||||
|
|
||||||
|
| Директория | Описание | Обязательная |
|
||||||
|
|------------|----------|--------------|
|
||||||
|
| `tasks/` | Основные задачи роли | Да |
|
||||||
|
| `handlers/` | Обработчики событий | Нет |
|
||||||
|
| `templates/` | Jinja2 шаблоны | Нет |
|
||||||
|
| `files/` | Статические файлы | Нет |
|
||||||
|
| `vars/` | Переменные роли | Нет |
|
||||||
|
| `defaults/` | Переменные по умолчанию | Нет |
|
||||||
|
| `meta/` | Метаданные роли | Нет |
|
||||||
|
| `tests/` | Тесты роли | Нет |
|
||||||
|
|
||||||
|
## Создание роли
|
||||||
|
|
||||||
|
### Автоматическое создание
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Создать роль с помощью ansible-galaxy
|
||||||
|
ansible-galaxy init your_role
|
||||||
|
|
||||||
|
# Создать роль в определенной директории
|
||||||
|
ansible-galaxy init your_role --init-path roles/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ручное создание
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Создать структуру роли
|
||||||
|
mkdir -p roles/your_role/{tasks,handlers,templates,files,vars,defaults,meta,tests}
|
||||||
|
|
||||||
|
# Создать основной task
|
||||||
|
cat > roles/your_role/tasks/main.yml << EOF
|
||||||
|
---
|
||||||
|
- name: Install package
|
||||||
|
package:
|
||||||
|
name: "{{ package_name }}"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Start service
|
||||||
|
service:
|
||||||
|
name: "{{ service_name }}"
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Создать переменные по умолчанию
|
||||||
|
cat > roles/your_role/defaults/main.yml << EOF
|
||||||
|
---
|
||||||
|
package_name: nginx
|
||||||
|
service_name: nginx
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование роли
|
||||||
|
|
||||||
|
### В playbook
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Deploy web server
|
||||||
|
hosts: webservers
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- your_role
|
||||||
|
```
|
||||||
|
|
||||||
|
### С переменными
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Deploy web server
|
||||||
|
hosts: webservers
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- role: your_role
|
||||||
|
vars:
|
||||||
|
package_name: apache2
|
||||||
|
service_name: apache2
|
||||||
|
```
|
||||||
|
|
||||||
|
### С условиями
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
- name: Deploy web server
|
||||||
|
hosts: webservers
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- role: your_role
|
||||||
|
when: ansible_os_family == "Debian"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Тестирование роли
|
||||||
|
|
||||||
|
### Создание тестов
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Создать тестовый playbook
|
||||||
|
cat > roles/your_role/tests/test.yml << EOF
|
||||||
|
---
|
||||||
|
- name: Test role
|
||||||
|
hosts: all
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- your_role
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Создать инвентарь для тестов
|
||||||
|
cat > roles/your_role/tests/inventory << EOF
|
||||||
|
[webservers]
|
||||||
|
localhost ansible_connection=local
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
### Запуск тестов
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустить тест роли
|
||||||
|
ansible-playbook -i roles/your_role/tests/inventory roles/your_role/tests/test.yml
|
||||||
|
|
||||||
|
# Запустить тест с Molecule
|
||||||
|
molecule test
|
||||||
|
```
|
||||||
|
|
||||||
|
## Лучшие практики
|
||||||
|
|
||||||
|
### Структура задач
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
# tasks/main.yml
|
||||||
|
- name: Install package
|
||||||
|
package:
|
||||||
|
name: "{{ package_name }}"
|
||||||
|
state: present
|
||||||
|
notify: restart service
|
||||||
|
|
||||||
|
- name: Configure service
|
||||||
|
template:
|
||||||
|
src: config.j2
|
||||||
|
dest: /etc/service/config.conf
|
||||||
|
notify: restart service
|
||||||
|
|
||||||
|
- name: Start service
|
||||||
|
service:
|
||||||
|
name: "{{ service_name }}"
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
```
|
||||||
|
|
||||||
|
### Обработчики
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
# handlers/main.yml
|
||||||
|
- name: restart service
|
||||||
|
service:
|
||||||
|
name: "{{ service_name }}"
|
||||||
|
state: restarted
|
||||||
|
```
|
||||||
|
|
||||||
|
### Переменные
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
# defaults/main.yml
|
||||||
|
package_name: nginx
|
||||||
|
service_name: nginx
|
||||||
|
config_file: /etc/nginx/nginx.conf
|
||||||
|
port: 80
|
||||||
|
|
||||||
|
# vars/main.yml
|
||||||
|
service_user: nginx
|
||||||
|
service_group: nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
### Метаданные
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
# meta/main.yml
|
||||||
|
galaxy_info:
|
||||||
|
author: Your Name
|
||||||
|
description: Your role description
|
||||||
|
company: Your Company
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.9"
|
||||||
|
platforms:
|
||||||
|
- name: Ubuntu
|
||||||
|
versions:
|
||||||
|
- focal
|
||||||
|
- jammy
|
||||||
|
- name: CentOS
|
||||||
|
versions:
|
||||||
|
- 8
|
||||||
|
- 9
|
||||||
|
galaxy_tags:
|
||||||
|
- web
|
||||||
|
- nginx
|
||||||
|
dependencies: []
|
||||||
|
```
|
||||||
|
|
||||||
|
## Примеры ролей
|
||||||
|
|
||||||
|
### Роль для веб-сервера
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
# tasks/main.yml
|
||||||
|
- name: Install nginx
|
||||||
|
package:
|
||||||
|
name: nginx
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Configure nginx
|
||||||
|
template:
|
||||||
|
src: nginx.conf.j2
|
||||||
|
dest: /etc/nginx/nginx.conf
|
||||||
|
notify: restart nginx
|
||||||
|
|
||||||
|
- name: Start nginx
|
||||||
|
service:
|
||||||
|
name: nginx
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
```
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
# defaults/main.yml
|
||||||
|
nginx_port: 80
|
||||||
|
nginx_ssl_port: 443
|
||||||
|
nginx_user: www-data
|
||||||
|
nginx_worker_processes: auto
|
||||||
|
```
|
||||||
|
|
||||||
|
### Роль для базы данных
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
# tasks/main.yml
|
||||||
|
- name: Install PostgreSQL
|
||||||
|
package:
|
||||||
|
name: postgresql
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Start PostgreSQL
|
||||||
|
service:
|
||||||
|
name: postgresql
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
- name: Create database
|
||||||
|
postgresql_db:
|
||||||
|
name: "{{ db_name }}"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create user
|
||||||
|
postgresql_user:
|
||||||
|
name: "{{ db_user }}"
|
||||||
|
password: "{{ db_password }}"
|
||||||
|
state: present
|
||||||
|
```
|
||||||
|
|
||||||
|
### Роль для мониторинга
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
# tasks/main.yml
|
||||||
|
- name: Install Prometheus
|
||||||
|
package:
|
||||||
|
name: prometheus
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Configure Prometheus
|
||||||
|
template:
|
||||||
|
src: prometheus.yml.j2
|
||||||
|
dest: /etc/prometheus/prometheus.yml
|
||||||
|
notify: restart prometheus
|
||||||
|
|
||||||
|
- name: Start Prometheus
|
||||||
|
service:
|
||||||
|
name: prometheus
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Интеграция с лабораторией
|
||||||
|
|
||||||
|
### Использование в пресетах
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
# molecule/presets/webapp.yml
|
||||||
|
hosts:
|
||||||
|
- name: web1
|
||||||
|
group: webservers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "8080:80"
|
||||||
|
|
||||||
|
- name: db1
|
||||||
|
group: databases
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "5432:5432"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Playbook для ролей
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
# files/playbooks/site.yml
|
||||||
|
- name: Deploy web servers
|
||||||
|
hosts: webservers
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- nginx
|
||||||
|
- ssl
|
||||||
|
|
||||||
|
- name: Deploy databases
|
||||||
|
hosts: databases
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- postgresql
|
||||||
|
- backup
|
||||||
|
|
||||||
|
- name: Deploy monitoring
|
||||||
|
hosts: monitoring
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- prometheus
|
||||||
|
- grafana
|
||||||
|
```
|
||||||
|
|
||||||
|
### Тестирование с различными пресетами
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Тестирование с минимальным пресетом
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/minimal.yml
|
||||||
|
|
||||||
|
# Тестирование с веб-приложением
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/webapp.yml
|
||||||
|
|
||||||
|
# Тестирование с микросервисами
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/microservices.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Публикация роли
|
||||||
|
|
||||||
|
### В Ansible Galaxy
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Установить ansible-galaxy
|
||||||
|
pip install ansible-galaxy
|
||||||
|
|
||||||
|
# Публиковать роль
|
||||||
|
ansible-galaxy import your-username your-role
|
||||||
|
|
||||||
|
# Или через GitHub
|
||||||
|
ansible-galaxy import your-username your-role --github-user your-username
|
||||||
|
```
|
||||||
|
|
||||||
|
### В приватном репозитории
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Установить роль из Git
|
||||||
|
ansible-galaxy install git+https://github.com/your-username/your-role.git
|
||||||
|
|
||||||
|
# Установить роль из файла
|
||||||
|
ansible-galaxy install your-role.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
|
## Заключение
|
||||||
|
|
||||||
|
Этот документ описывает основные принципы создания и использования Ansible ролей в универсальной лаборатории. Для получения дополнительной информации обратитесь к [основной документации](universal-lab.md) и [примерам использования](examples.md).
|
||||||
652
docs/troubleshooting.md
Normal file
652
docs/troubleshooting.md
Normal file
@@ -0,0 +1,652 @@
|
|||||||
|
# Troubleshooting
|
||||||
|
|
||||||
|
## Автор
|
||||||
|
Сергей Антропов
|
||||||
|
Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
## Описание
|
||||||
|
|
||||||
|
Этот документ содержит решения наиболее распространенных проблем при работе с универсальной лабораторией.
|
||||||
|
|
||||||
|
## Содержание
|
||||||
|
|
||||||
|
- [Общие проблемы](#общие-проблемы)
|
||||||
|
- [Проблемы с Docker](#проблемы-с-docker)
|
||||||
|
- [Проблемы с Kubernetes](#проблемы-с-kubernetes)
|
||||||
|
- [Проблемы с портами](#проблемы-с-портами)
|
||||||
|
- [Проблемы с ресурсами](#проблемы-с-ресурсами)
|
||||||
|
- [Проблемы с сетью](#проблемы-с-сетью)
|
||||||
|
- [Проблемы с Ansible](#проблемы-с-ansible)
|
||||||
|
- [Проблемы с Molecule](#проблемы-с-molecule)
|
||||||
|
- [Проблемы с пресетами](#проблемы-с-пресетами)
|
||||||
|
- [Проблемы с отчетами](#проблемы-с-отчетами)
|
||||||
|
|
||||||
|
## Общие проблемы
|
||||||
|
|
||||||
|
### Проблема: Лаборатория не запускается
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- Команда `make lab-up` завершается с ошибкой
|
||||||
|
- Контейнеры не создаются
|
||||||
|
- Ошибки в логах Docker
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить статус Docker
|
||||||
|
docker ps
|
||||||
|
docker version
|
||||||
|
|
||||||
|
# Перезапустить Docker
|
||||||
|
sudo systemctl restart docker
|
||||||
|
|
||||||
|
# Очистить Docker
|
||||||
|
docker system prune -a
|
||||||
|
|
||||||
|
# Перезапустить лабораторию
|
||||||
|
make lab-reset
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: Команды Make не работают
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- `make: command not found`
|
||||||
|
- Ошибки в Makefile
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Установить Make
|
||||||
|
# Ubuntu/Debian
|
||||||
|
sudo apt-get install make
|
||||||
|
|
||||||
|
# CentOS/RHEL
|
||||||
|
sudo yum install make
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
brew install make
|
||||||
|
|
||||||
|
# Проверить версию
|
||||||
|
make --version
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: Недостаточно прав
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- `Permission denied`
|
||||||
|
- Ошибки доступа к файлам
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить права на файлы
|
||||||
|
ls -la
|
||||||
|
|
||||||
|
# Установить права
|
||||||
|
chmod +x scripts/*.sh
|
||||||
|
chmod 644 *.yml
|
||||||
|
|
||||||
|
# Добавить пользователя в группу docker
|
||||||
|
sudo usermod -aG docker $USER
|
||||||
|
newgrp docker
|
||||||
|
```
|
||||||
|
|
||||||
|
## Проблемы с Docker
|
||||||
|
|
||||||
|
### Проблема: Docker daemon не запущен
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- `Cannot connect to the Docker daemon`
|
||||||
|
- `docker: command not found`
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Запустить Docker daemon
|
||||||
|
sudo systemctl start docker
|
||||||
|
sudo systemctl enable docker
|
||||||
|
|
||||||
|
# Проверить статус
|
||||||
|
sudo systemctl status docker
|
||||||
|
|
||||||
|
# Проверить доступ
|
||||||
|
docker ps
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: Недостаточно места на диске
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- `No space left on device`
|
||||||
|
- Ошибки создания контейнеров
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить использование диска
|
||||||
|
df -h
|
||||||
|
|
||||||
|
# Очистить Docker
|
||||||
|
docker system prune -a
|
||||||
|
docker volume prune
|
||||||
|
docker network prune
|
||||||
|
|
||||||
|
# Удалить неиспользуемые образы
|
||||||
|
docker image prune -a
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: Конфликты портов
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- `Port is already in use`
|
||||||
|
- Ошибки привязки портов
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Найти процесс, использующий порт
|
||||||
|
sudo netstat -tulpn | grep :8080
|
||||||
|
sudo lsof -i :8080
|
||||||
|
|
||||||
|
# Убить процесс
|
||||||
|
sudo kill -9 <PID>
|
||||||
|
|
||||||
|
# Или изменить порт в пресете
|
||||||
|
publish:
|
||||||
|
- "8081:80" # Вместо 8080:80
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: DinD контейнеры не работают
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- DinD контейнеры не запускаются
|
||||||
|
- Ошибки Docker-in-Docker
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить privileged режим
|
||||||
|
docker run --privileged -d docker:dind
|
||||||
|
|
||||||
|
# Проверить доступ к Docker socket
|
||||||
|
docker run -v /var/run/docker.sock:/var/run/docker.sock docker:latest ps
|
||||||
|
|
||||||
|
# Перезапустить с правильными параметрами
|
||||||
|
make lab-reset
|
||||||
|
make lab-create
|
||||||
|
```
|
||||||
|
|
||||||
|
## Проблемы с Kubernetes
|
||||||
|
|
||||||
|
### Проблема: Kind кластер не создается
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- `kind create cluster` завершается с ошибкой
|
||||||
|
- Кластер не доступен
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить Kind
|
||||||
|
kind version
|
||||||
|
|
||||||
|
# Удалить существующие кластеры
|
||||||
|
kind delete cluster --name lab
|
||||||
|
|
||||||
|
# Очистить Docker
|
||||||
|
docker system prune -a
|
||||||
|
|
||||||
|
# Пересоздать кластер
|
||||||
|
make lab-create
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: kubectl не работает
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- `kubectl: command not found`
|
||||||
|
- Ошибки подключения к кластеру
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Установить kubectl
|
||||||
|
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
|
||||||
|
chmod +x kubectl
|
||||||
|
sudo mv kubectl /usr/local/bin/
|
||||||
|
|
||||||
|
# Проверить конфигурацию
|
||||||
|
kubectl config get-contexts
|
||||||
|
|
||||||
|
# Переключиться на правильный контекст
|
||||||
|
kubectl config use-context kind-lab
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: Pods не запускаются
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- Pods в состоянии Pending
|
||||||
|
- Ошибки в логах pods
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить статус pods
|
||||||
|
kubectl get pods -A
|
||||||
|
kubectl describe pod <pod-name>
|
||||||
|
|
||||||
|
# Проверить события
|
||||||
|
kubectl get events --sort-by=.metadata.creationTimestamp
|
||||||
|
|
||||||
|
# Проверить ресурсы
|
||||||
|
kubectl top nodes
|
||||||
|
kubectl top pods
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: Istio не устанавливается
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- Istio компоненты не запускаются
|
||||||
|
- Ошибки в Istio логах
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить Istio
|
||||||
|
istioctl version
|
||||||
|
|
||||||
|
# Переустановить Istio
|
||||||
|
istioctl uninstall --purge
|
||||||
|
istioctl install --set profile=demo
|
||||||
|
|
||||||
|
# Проверить статус
|
||||||
|
kubectl get pods -n istio-system
|
||||||
|
```
|
||||||
|
|
||||||
|
## Проблемы с портами
|
||||||
|
|
||||||
|
### Проблема: Порт уже используется
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- `bind: address already in use`
|
||||||
|
- Ошибки привязки портов
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Найти процесс
|
||||||
|
sudo lsof -i :8080
|
||||||
|
|
||||||
|
# Убить процесс
|
||||||
|
sudo kill -9 <PID>
|
||||||
|
|
||||||
|
# Или изменить порт в пресете
|
||||||
|
publish:
|
||||||
|
- "8081:80"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: Port-forward не работает
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- Port-forward не устанавливается
|
||||||
|
- Ошибки подключения
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Остановить все port-forward
|
||||||
|
make kube-pf-stop
|
||||||
|
|
||||||
|
# Проверить доступность сервиса
|
||||||
|
kubectl get svc -n istio-system
|
||||||
|
|
||||||
|
# Перезапустить port-forward
|
||||||
|
make kiali-port-forward CLUSTER=lab
|
||||||
|
```
|
||||||
|
|
||||||
|
## Проблемы с ресурсами
|
||||||
|
|
||||||
|
### Проблема: Недостаточно памяти
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- `Out of memory`
|
||||||
|
- Контейнеры завершаются
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить память
|
||||||
|
free -h
|
||||||
|
docker stats
|
||||||
|
|
||||||
|
# Ограничить ресурсы
|
||||||
|
docker run --memory=512m your-image
|
||||||
|
|
||||||
|
# Или уменьшить количество контейнеров в пресете
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: Недостаточно CPU
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- Медленная работа
|
||||||
|
- Высокая нагрузка на CPU
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить CPU
|
||||||
|
top
|
||||||
|
htop
|
||||||
|
|
||||||
|
# Ограничить CPU
|
||||||
|
docker run --cpus=1.0 your-image
|
||||||
|
|
||||||
|
# Или использовать более легкие образы
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: Недостаточно места на диске
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- `No space left on device`
|
||||||
|
- Ошибки записи
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить место
|
||||||
|
df -h
|
||||||
|
|
||||||
|
# Очистить Docker
|
||||||
|
docker system prune -a
|
||||||
|
docker volume prune
|
||||||
|
|
||||||
|
# Удалить неиспользуемые образы
|
||||||
|
docker image prune -a
|
||||||
|
```
|
||||||
|
|
||||||
|
## Проблемы с сетью
|
||||||
|
|
||||||
|
### Проблема: Контейнеры не могут связаться
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- Ping не работает между контейнерами
|
||||||
|
- Ошибки сети
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить сеть
|
||||||
|
docker network ls
|
||||||
|
docker network inspect labnet
|
||||||
|
|
||||||
|
# Пересоздать сеть
|
||||||
|
docker network rm labnet
|
||||||
|
docker network create labnet
|
||||||
|
|
||||||
|
# Перезапустить лабораторию
|
||||||
|
make lab-reset
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: DNS не работает
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- Не удается разрешить имена
|
||||||
|
- Ошибки DNS
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить DNS
|
||||||
|
nslookup google.com
|
||||||
|
|
||||||
|
# Перезапустить Docker
|
||||||
|
sudo systemctl restart docker
|
||||||
|
|
||||||
|
# Проверить resolv.conf
|
||||||
|
cat /etc/resolv.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
## Проблемы с Ansible
|
||||||
|
|
||||||
|
### Проблема: Ansible не найден
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- `ansible: command not found`
|
||||||
|
- Ошибки выполнения playbook
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Установить Ansible
|
||||||
|
pip install ansible
|
||||||
|
|
||||||
|
# Или через пакетный менеджер
|
||||||
|
sudo apt-get install ansible
|
||||||
|
|
||||||
|
# Проверить версию
|
||||||
|
ansible --version
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: Ошибки в playbook
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- Синтаксические ошибки
|
||||||
|
- Ошибки выполнения задач
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить синтаксис
|
||||||
|
ansible-playbook --syntax-check playbook.yml
|
||||||
|
|
||||||
|
# Запустить в режиме отладки
|
||||||
|
ansible-playbook -vvv playbook.yml
|
||||||
|
|
||||||
|
# Проверить инвентарь
|
||||||
|
ansible-inventory --list
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: Ошибки подключения
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- `Connection refused`
|
||||||
|
- Ошибки SSH
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить подключение
|
||||||
|
ansible all -m ping
|
||||||
|
|
||||||
|
# Проверить SSH ключи
|
||||||
|
ssh-keygen -t rsa -b 4096
|
||||||
|
ssh-copy-id user@host
|
||||||
|
|
||||||
|
# Или использовать пароль
|
||||||
|
ansible all -m ping -k
|
||||||
|
```
|
||||||
|
|
||||||
|
## Проблемы с Molecule
|
||||||
|
|
||||||
|
### Проблема: Molecule не найден
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- `molecule: command not found`
|
||||||
|
- Ошибки выполнения molecule
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Установить Molecule
|
||||||
|
pip install molecule
|
||||||
|
|
||||||
|
# Или через пакетный менеджер
|
||||||
|
sudo apt-get install molecule
|
||||||
|
|
||||||
|
# Проверить версию
|
||||||
|
molecule --version
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: Ошибки в molecule.yml
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- Синтаксические ошибки в конфигурации
|
||||||
|
- Ошибки валидации
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить синтаксис
|
||||||
|
molecule syntax
|
||||||
|
|
||||||
|
# Проверить конфигурацию
|
||||||
|
molecule lint
|
||||||
|
|
||||||
|
# Исправить ошибки
|
||||||
|
molecule validate
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: Ошибки драйвера
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- Ошибки Docker драйвера
|
||||||
|
- Проблемы с контейнерами
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить драйвер
|
||||||
|
molecule driver list
|
||||||
|
|
||||||
|
# Установить Docker драйвер
|
||||||
|
pip install molecule-docker
|
||||||
|
|
||||||
|
# Перезапустить Molecule
|
||||||
|
molecule destroy
|
||||||
|
molecule create
|
||||||
|
```
|
||||||
|
|
||||||
|
## Проблемы с пресетами
|
||||||
|
|
||||||
|
### Проблема: Пресет не найден
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- `File not found`
|
||||||
|
- Ошибки загрузки пресета
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить путь
|
||||||
|
ls -la molecule/presets/
|
||||||
|
|
||||||
|
# Проверить синтаксис YAML
|
||||||
|
yamllint molecule/presets/your-preset.yml
|
||||||
|
|
||||||
|
# Исправить ошибки
|
||||||
|
molecule validate
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: Ошибки в пресете
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- Синтаксические ошибки
|
||||||
|
- Ошибки валидации
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить синтаксис
|
||||||
|
yamllint molecule/presets/your-preset.yml
|
||||||
|
|
||||||
|
# Проверить структуру
|
||||||
|
molecule validate
|
||||||
|
|
||||||
|
# Исправить ошибки
|
||||||
|
molecule syntax
|
||||||
|
```
|
||||||
|
|
||||||
|
## Проблемы с отчетами
|
||||||
|
|
||||||
|
### Проблема: HTML отчет не генерируется
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- `File not found`
|
||||||
|
- Ошибки генерации отчета
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить JSON файл
|
||||||
|
ls -la reports/
|
||||||
|
cat reports/lab-health.json
|
||||||
|
|
||||||
|
# Перезапустить верификацию
|
||||||
|
make lab-verify
|
||||||
|
|
||||||
|
# Сгенерировать отчет
|
||||||
|
make lab-report
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблема: Отчет пустой
|
||||||
|
|
||||||
|
**Симптомы:**
|
||||||
|
- Отчет не содержит данных
|
||||||
|
- Ошибки в JSON
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
```bash
|
||||||
|
# Проверить JSON
|
||||||
|
jq . reports/lab-health.json
|
||||||
|
|
||||||
|
# Перезапустить тест
|
||||||
|
make lab-test
|
||||||
|
|
||||||
|
# Проверить логи
|
||||||
|
make lab-verify
|
||||||
|
```
|
||||||
|
|
||||||
|
## Полезные команды для диагностики
|
||||||
|
|
||||||
|
### Общие команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Проверить статус системы
|
||||||
|
docker ps
|
||||||
|
docker images
|
||||||
|
docker network ls
|
||||||
|
docker volume ls
|
||||||
|
|
||||||
|
# Проверить ресурсы
|
||||||
|
free -h
|
||||||
|
df -h
|
||||||
|
top
|
||||||
|
|
||||||
|
# Проверить сеть
|
||||||
|
netstat -tulpn
|
||||||
|
ss -tulpn
|
||||||
|
```
|
||||||
|
|
||||||
|
### Команды для Kubernetes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Проверить кластеры
|
||||||
|
kind get clusters
|
||||||
|
kubectl config get-contexts
|
||||||
|
|
||||||
|
# Проверить ресурсы
|
||||||
|
kubectl get nodes
|
||||||
|
kubectl get pods -A
|
||||||
|
kubectl get svc -A
|
||||||
|
|
||||||
|
# Проверить события
|
||||||
|
kubectl get events --sort-by=.metadata.creationTimestamp
|
||||||
|
```
|
||||||
|
|
||||||
|
### Команды для Ansible
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Проверить инвентарь
|
||||||
|
ansible-inventory --list
|
||||||
|
ansible all -m ping
|
||||||
|
|
||||||
|
# Проверить playbook
|
||||||
|
ansible-playbook --syntax-check playbook.yml
|
||||||
|
ansible-playbook --check playbook.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Получение помощи
|
||||||
|
|
||||||
|
Если проблема не решается:
|
||||||
|
|
||||||
|
1. **Проверьте логи:**
|
||||||
|
```bash
|
||||||
|
docker logs <container-name>
|
||||||
|
kubectl logs <pod-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Создайте issue:**
|
||||||
|
- Опишите проблему
|
||||||
|
- Приложите логи
|
||||||
|
- Укажите версии компонентов
|
||||||
|
|
||||||
|
3. **Обратитесь к сообществу:**
|
||||||
|
- GitHub Discussions
|
||||||
|
- Discord/Slack каналы
|
||||||
|
- Форумы Ansible
|
||||||
|
|
||||||
|
4. **Проверьте документацию:**
|
||||||
|
- [Основная документация](universal-lab.md)
|
||||||
|
- [Примеры использования](examples.md)
|
||||||
|
- [API Reference](api.md)
|
||||||
295
docs/universal-lab.md
Normal file
295
docs/universal-lab.md
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
# Универсальная лаборатория для тестирования Ansible ролей
|
||||||
|
|
||||||
|
## Автор
|
||||||
|
Сергей Антропов
|
||||||
|
Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
## Описание
|
||||||
|
|
||||||
|
Это универсальная лаборатория для тестирования Ansible ролей, созданная на основе предложений ChatGPT. Лаборатория поддерживает:
|
||||||
|
|
||||||
|
- **Docker-in-Docker (DinD)** - полная изоляция контейнеров
|
||||||
|
- **Docker-outside-of-Docker (DOoD)** - использование хостового Docker
|
||||||
|
- **Kind кластеры** - локальные Kubernetes кластеры
|
||||||
|
- **Helm charts** - nginx, prometheus-stack
|
||||||
|
- **Istio service mesh** - с Kiali для мониторинга
|
||||||
|
- **Prometheus + Grafana** - с автопровижинингом дашбордов
|
||||||
|
- **HTML отчеты** - красивые отчеты о результатах тестирования
|
||||||
|
|
||||||
|
## Структура проекта
|
||||||
|
|
||||||
|
```
|
||||||
|
molecule/
|
||||||
|
├── universal/ # Универсальная лаборатория
|
||||||
|
│ ├── molecule.yml # Конфигурация Molecule
|
||||||
|
│ ├── vars.yml # Переменные лаборатории
|
||||||
|
│ ├── create.yml # Создание инфраструктуры
|
||||||
|
│ ├── converge.yml # Запуск ролей
|
||||||
|
│ ├── verify.yml # Проверка работы
|
||||||
|
│ └── destroy.yml # Очистка
|
||||||
|
├── presets/ # Пресеты для разных сценариев
|
||||||
|
│ └── k8s-kind.yml # Пресет для Kubernetes
|
||||||
|
└── default/ # Старый сценарий (для совместимости)
|
||||||
|
|
||||||
|
files/
|
||||||
|
├── requirements.yml # Коллекции Ansible
|
||||||
|
├── playbooks/
|
||||||
|
│ └── site.yml # Основной playbook
|
||||||
|
└── k8s/ # Kubernetes манифесты
|
||||||
|
└── istio/ # Istio конфигурации
|
||||||
|
|
||||||
|
roles/ # Ваши Ansible роли
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование
|
||||||
|
|
||||||
|
### 1. Подготовка
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Создать файл с паролем для vault
|
||||||
|
echo "test" > vault-password.txt
|
||||||
|
|
||||||
|
# Создать каталог для ролей
|
||||||
|
mkdir -p roles
|
||||||
|
|
||||||
|
# Скопировать переменные окружения
|
||||||
|
cp env.example .env
|
||||||
|
# Отредактировать .env под ваши нужды
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Запуск лаборатории
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Поднять контроллер
|
||||||
|
make lab-up
|
||||||
|
|
||||||
|
# Создать инфраструктуру
|
||||||
|
make lab-create
|
||||||
|
|
||||||
|
# Запустить роли
|
||||||
|
make lab-converge
|
||||||
|
|
||||||
|
# Проверить работу
|
||||||
|
make lab-verify
|
||||||
|
|
||||||
|
# Сгенерировать HTML отчет
|
||||||
|
make lab-report
|
||||||
|
|
||||||
|
# Уничтожить лабораторию
|
||||||
|
make lab-destroy
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Управление лабораторией
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Полный цикл тестирования
|
||||||
|
make lab-test
|
||||||
|
|
||||||
|
# Снапшоты и восстановление
|
||||||
|
make lab-snapshot # Сохранить состояние
|
||||||
|
make lab-restore # Восстановить из снапшота
|
||||||
|
make lab-cleanup # Очистить все
|
||||||
|
|
||||||
|
# Сброс лаборатории
|
||||||
|
make lab-reset
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Пресеты для разных сценариев
|
||||||
|
|
||||||
|
#### 🏗️ Классические пресеты (systemd контейнеры)
|
||||||
|
```bash
|
||||||
|
# Минимальная лаборатория (1-3 машины)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/minimal.yml
|
||||||
|
|
||||||
|
# Веб-приложение (3-5 машин)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/webapp.yml
|
||||||
|
|
||||||
|
# Микросервисы (5-8 машин)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/microservices.yml
|
||||||
|
|
||||||
|
# Высокая доступность (6-10 машин)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/ha.yml
|
||||||
|
|
||||||
|
# Kubernetes кластер (8-12 машин)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/k8s-cluster.yml
|
||||||
|
|
||||||
|
# CI/CD пайплайн (10-15 машин)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/cicd.yml
|
||||||
|
|
||||||
|
# Big Data кластер (12-18 машин)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/bigdata.yml
|
||||||
|
|
||||||
|
# Service Mesh (15-20 машин)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/servicemesh.yml
|
||||||
|
|
||||||
|
# Enterprise (18-20 машин)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/enterprise.yml
|
||||||
|
|
||||||
|
# Максимальный (20 машин)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/maximum.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
#### ☸️ Kubernetes пресеты
|
||||||
|
```bash
|
||||||
|
# Kubernetes Single Node (1 кластер)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/k8s-single.yml
|
||||||
|
|
||||||
|
# Kubernetes Multi-Cluster (3 кластера)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/k8s-multi.yml
|
||||||
|
|
||||||
|
# Kubernetes + Istio Full Stack (1 кластер с полным стеком)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/k8s-istio-full.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 🐳 Docker-in-Docker (DinD) пресеты
|
||||||
|
```bash
|
||||||
|
# DinD Simple (3 DinD контейнера)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/dind-simple.yml
|
||||||
|
|
||||||
|
# DinD Swarm (5 DinD контейнеров)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/dind-swarm.yml
|
||||||
|
|
||||||
|
# DinD Compose (4 DinD контейнера)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/dind-compose.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 🔗 Docker-outside-of-Docker (DOoD) пресеты
|
||||||
|
```bash
|
||||||
|
# DOoD Simple (3 DOoD контейнера)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/dood-simple.yml
|
||||||
|
|
||||||
|
# DOoD Mixed (5 DOoD + 2 systemd)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/dood-mixed.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 🔀 Смешанные пресеты
|
||||||
|
```bash
|
||||||
|
# Mixed Kubernetes + DinD (1 K8s + 3 DinD)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/mixed-k8s-dind.yml
|
||||||
|
|
||||||
|
# Mixed Kubernetes + DOoD (1 K8s + 3 DOoD)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/mixed-k8s-dood.yml
|
||||||
|
|
||||||
|
# Mixed Full Stack (1 K8s + 2 DinD + 2 DOoD + 2 systemd)
|
||||||
|
make lab-test LAB_SPEC=molecule/presets/mixed-full.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Работа с Kubernetes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Войти в контейнер с kubectl
|
||||||
|
make kube-sh
|
||||||
|
|
||||||
|
# Выполнить команду kubectl
|
||||||
|
make kube-cmd CLUSTER=lab CMD="get pods -A"
|
||||||
|
|
||||||
|
# Войти в toolbox pod
|
||||||
|
make kube-enter CLUSTER=lab
|
||||||
|
|
||||||
|
# Port-forward для Kiali
|
||||||
|
make kiali-port-forward CLUSTER=lab
|
||||||
|
|
||||||
|
# Port-forward для Istio Gateway
|
||||||
|
make istio-gw-port-forward CLUSTER=lab
|
||||||
|
```
|
||||||
|
|
||||||
|
## Конфигурация
|
||||||
|
|
||||||
|
### Переменные лаборатории (molecule/universal/vars.yml)
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Сеть для лаборатории
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
# Образы для разных семейств ОС
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
# Определение хостов
|
||||||
|
hosts:
|
||||||
|
- name: etcd1
|
||||||
|
group: etcd
|
||||||
|
family: debian
|
||||||
|
- name: app-dind
|
||||||
|
group: apps
|
||||||
|
type: dind
|
||||||
|
publish:
|
||||||
|
- "8080:8080"
|
||||||
|
|
||||||
|
# Kind кластеры
|
||||||
|
kind_clusters:
|
||||||
|
- name: lab
|
||||||
|
workers: 2
|
||||||
|
addons:
|
||||||
|
ingress_nginx: true
|
||||||
|
istio: true
|
||||||
|
kiali: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Особенности
|
||||||
|
|
||||||
|
### 1. Автогенерация инвентаря
|
||||||
|
Инвентарь генерируется автоматически на основе определения хостов в `vars.yml`.
|
||||||
|
|
||||||
|
### 2. Поддержка DinD и DOoD
|
||||||
|
- **DinD**: Полная изоляция, каждый хост имеет свой Docker daemon
|
||||||
|
- **DOoD**: Использование хостового Docker, меньше ресурсов
|
||||||
|
|
||||||
|
### 3. Kubernetes интеграция
|
||||||
|
- Автоматическое создание Kind кластеров
|
||||||
|
- Установка Ingress NGINX, Metrics Server
|
||||||
|
- Поддержка Istio и Kiali
|
||||||
|
- Prometheus Stack с Grafana
|
||||||
|
|
||||||
|
### 4. Мониторинг и отчеты
|
||||||
|
- Автоматическая генерация HTML отчетов
|
||||||
|
- Интеграция с Prometheus и Grafana
|
||||||
|
- Дашборды для Istio
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Проблемы с образами
|
||||||
|
Если возникают проблемы с загрузкой образов, обновите `vars.yml`:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
images:
|
||||||
|
debian: "ubuntu:22.04" # Используйте стандартные образы
|
||||||
|
rhel: "centos:8"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблемы с Docker
|
||||||
|
Убедитесь, что Docker socket доступен:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ls -la /var/run/docker.sock
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблемы с Molecule
|
||||||
|
Если возникают проблемы с Molecule, попробуйте:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Очистить кэш
|
||||||
|
make lab-reset
|
||||||
|
|
||||||
|
# Проверить конфигурацию
|
||||||
|
docker exec ansible-controller bash -lc 'molecule lint -s universal'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Дальнейшее развитие
|
||||||
|
|
||||||
|
1. **Добавить поддержку Terraform** для создания инфраструктуры
|
||||||
|
2. **Интегрировать с GitLab CI/CD** для автоматического тестирования
|
||||||
|
3. **Добавить поддержку ARM64** для тестирования на Apple Silicon
|
||||||
|
4. **Создать веб-интерфейс** для управления лабораторией
|
||||||
|
5. **Добавить поддержку OpenShift** для enterprise сценариев
|
||||||
|
|
||||||
|
## Лицензия
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
## Контакты
|
||||||
|
|
||||||
|
- Автор: Сергей Антропов
|
||||||
|
- Сайт: https://devops.org.ru
|
||||||
|
- Email: [ваш email]
|
||||||
69
env.example
Normal file
69
env.example
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# Ansible Template Environment Configuration
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
# Основные настройки проекта
|
||||||
|
PROJECT_NAME=ansible-template
|
||||||
|
VERSION=0.1.0
|
||||||
|
AUTHOR="Сергей Антропов"
|
||||||
|
SITE="https://devops.org.ru"
|
||||||
|
|
||||||
|
# Docker настройки
|
||||||
|
DOCKER_IMAGE=quay.io/ansible/creator-ee:latest
|
||||||
|
DOCKER_NETWORK=labnet
|
||||||
|
DOCKER_COMPOSE=docker compose
|
||||||
|
|
||||||
|
# Molecule настройки
|
||||||
|
SCENARIO=universal
|
||||||
|
LAB_SPEC=molecule/presets/minimal.yml
|
||||||
|
MOLECULE_EPHEMERAL_DIRECTORY=/tmp/molecule
|
||||||
|
|
||||||
|
# Kubernetes настройки
|
||||||
|
KUBE_CONTEXT=kind-lab
|
||||||
|
ISTIO_VERSION=1.22.1
|
||||||
|
KIND_VERSION=v0.23.0
|
||||||
|
|
||||||
|
# Пути
|
||||||
|
ROLES_DIR=./roles
|
||||||
|
VAULT_PASSWORD_FILE=vault/.vault
|
||||||
|
|
||||||
|
# Переменные для лаборатории
|
||||||
|
LAB_PAUSE_MINUTES=10
|
||||||
|
LAB_SPEC=molecule/presets/minimal.yml
|
||||||
|
|
||||||
|
# Переменные для пресетов
|
||||||
|
PRESET_NAME=minimal
|
||||||
|
PRESET_TYPE=classic
|
||||||
|
|
||||||
|
# Переменные для ролей
|
||||||
|
ROLE_NAME=my-role
|
||||||
|
ROLE_DESCRIPTION="My Ansible role"
|
||||||
|
|
||||||
|
# Переменные для Git
|
||||||
|
GIT_BRANCH=main
|
||||||
|
GIT_REMOTE=origin
|
||||||
|
|
||||||
|
# Переменные для Docker
|
||||||
|
DOCKER_REGISTRY=quay.io
|
||||||
|
DOCKER_TAG=latest
|
||||||
|
|
||||||
|
# Переменные для мониторинга
|
||||||
|
GRAFANA_ADMIN_PASSWORD=admin
|
||||||
|
PROMETHEUS_RETENTION=15d
|
||||||
|
|
||||||
|
# Переменные для Istio
|
||||||
|
ISTIO_PROFILE=demo
|
||||||
|
KIALI_AUTH_STRATEGY=anonymous
|
||||||
|
|
||||||
|
# Переменные для Kind
|
||||||
|
KIND_WORKERS=2
|
||||||
|
KIND_API_PORT=6443
|
||||||
|
|
||||||
|
# Переменные для портов
|
||||||
|
HTTP_PORT=8080
|
||||||
|
HTTPS_PORT=8443
|
||||||
|
GRAFANA_PORT=3000
|
||||||
|
PROMETHEUS_PORT=9090
|
||||||
|
KIALI_PORT=20001
|
||||||
69
files/grafana/dashboards/istio-overview.json
Normal file
69
files/grafana/dashboards/istio-overview.json
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"id": null,
|
||||||
|
"uid": "istio-overview",
|
||||||
|
"title": "Istio • Overview",
|
||||||
|
"schemaVersion": 36,
|
||||||
|
"version": 1,
|
||||||
|
"timezone": "browser",
|
||||||
|
"tags": ["istio", "sre", "mesh"],
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"type": "stat",
|
||||||
|
"title": "Global RPS",
|
||||||
|
"gridPos": {"h": 4, "w": 6, "x": 0, "y": 0},
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"expr": "sum(rate(istio_requests_total{reporter=\"destination\"}[5m]))",
|
||||||
|
"legendFormat": "rps"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "stat",
|
||||||
|
"title": "Success Rate",
|
||||||
|
"gridPos": {"h": 4, "w": 6, "x": 6, "y": 0},
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"expr": "sum(rate(istio_requests_total{reporter=\"destination\",response_code!~\"5..\"}[5m])) / sum(rate(istio_requests_total{reporter=\"destination\"}[5m]))",
|
||||||
|
"legendFormat": "success"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"options": {"reduceOptions":{"calcs":["lastNotNull"]},"colorMode":"value","graphMode":"none"},
|
||||||
|
"fieldConfig":{"defaults":{"unit":"percentunit","min":0,"max":1}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "timeseries",
|
||||||
|
"title": "Latency (ms) p50/p95/p99",
|
||||||
|
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 4},
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"expr": "histogram_quantile(0.5, sum(rate(istio_request_duration_milliseconds_bucket{reporter=\"destination\"}[5m])) by (le))",
|
||||||
|
"legendFormat": "p50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"expr": "histogram_quantile(0.95, sum(rate(istio_request_duration_milliseconds_bucket{reporter=\"destination\"}[5m])) by (le))",
|
||||||
|
"legendFormat": "p95"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"expr": "histogram_quantile(0.99, sum(rate(istio_request_duration_milliseconds_bucket{reporter=\"destination\"}[5m])) by (le))",
|
||||||
|
"legendFormat": "p99"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fieldConfig":{"defaults":{"unit":"ms"}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "timeseries",
|
||||||
|
"title": "RPS by Workload",
|
||||||
|
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 12},
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"expr": "sum by (destination_workload) (rate(istio_requests_total{reporter=\"destination\"}[5m]))",
|
||||||
|
"legendFormat": "{{destination_workload}}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"templating": {
|
||||||
|
"list": []
|
||||||
|
}
|
||||||
|
}
|
||||||
80
files/grafana/dashboards/service-sli.json
Normal file
80
files/grafana/dashboards/service-sli.json
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"id": null,
|
||||||
|
"uid": "service-sli",
|
||||||
|
"title": "Service • SLI",
|
||||||
|
"schemaVersion": 36,
|
||||||
|
"version": 1,
|
||||||
|
"timezone": "browser",
|
||||||
|
"tags": ["istio", "sre", "sli"],
|
||||||
|
"templating": {
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"name": "namespace",
|
||||||
|
"type": "query",
|
||||||
|
"datasource": "${DS_PROMETHEUS}",
|
||||||
|
"query": "label_values(istio_requests_total, destination_namespace)",
|
||||||
|
"refresh": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "workload",
|
||||||
|
"type": "query",
|
||||||
|
"datasource": "${DS_PROMETHEUS}",
|
||||||
|
"query": "label_values(istio_requests_total{destination_namespace=\"$namespace\"}, destination_workload)",
|
||||||
|
"refresh": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"panels": [
|
||||||
|
{
|
||||||
|
"type": "stat",
|
||||||
|
"title": "Success Rate",
|
||||||
|
"gridPos": {"h": 4, "w": 6, "x": 0, "y": 0},
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"expr": "sum(rate(istio_requests_total{reporter=\"destination\",destination_namespace=\"$namespace\",destination_workload=\"$workload\",response_code!~\"5..\"}[5m])) / sum(rate(istio_requests_total{reporter=\"destination\",destination_namespace=\"$namespace\",destination_workload=\"$workload\"}[5m]))",
|
||||||
|
"legendFormat": "success"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fieldConfig":{"defaults":{"unit":"percentunit","min":0,"max":1}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "timeseries",
|
||||||
|
"title": "Latency (ms) p50/p95/p99",
|
||||||
|
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 4},
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"expr": "histogram_quantile(0.5, sum by (le) (rate(istio_request_duration_milliseconds_bucket{reporter=\"destination\",destination_namespace=\"$namespace\",destination_workload=\"$workload\"}[5m])))",
|
||||||
|
"legendFormat": "p50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"expr": "histogram_quantile(0.95, sum by (le) (rate(istio_request_duration_milliseconds_bucket{reporter=\"destination\",destination_namespace=\"$namespace\",destination_workload=\"$workload\"}[5m])))",
|
||||||
|
"legendFormat": "p95"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"expr": "histogram_quantile(0.99, sum by (le) (rate(istio_request_duration_milliseconds_bucket{reporter=\"destination\",destination_namespace=\"$namespace\",destination_workload=\"$workload\"}[5m])))",
|
||||||
|
"legendFormat": "p99"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fieldConfig":{"defaults":{"unit":"ms"}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "timeseries",
|
||||||
|
"title": "RPS (2xx/4xx/5xx)",
|
||||||
|
"gridPos": {"h": 8, "w": 12, "x": 0, "y": 12},
|
||||||
|
"targets": [
|
||||||
|
{
|
||||||
|
"expr": "sum(rate(istio_requests_total{reporter=\"destination\",destination_namespace=\"$namespace\",destination_workload=\"$workload\",response_code=~\"2..\"}[5m]))",
|
||||||
|
"legendFormat": "2xx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"expr": "sum(rate(istio_requests_total{reporter=\"destination\",destination_namespace=\"$namespace\",destination_workload=\"$workload\",response_code=~\"4..\"}[5m]))",
|
||||||
|
"legendFormat": "4xx"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"expr": "sum(rate(istio_requests_total{reporter=\"destination\",destination_namespace=\"$namespace\",destination_workload=\"$workload\",response_code=~\"5..\"}[5m]))",
|
||||||
|
"legendFormat": "5xx"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
39
files/k8s/istio/telemetry.yaml
Normal file
39
files/k8s/istio/telemetry.yaml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
# Istio Telemetry для сбора метрик
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
apiVersion: telemetry.istio.io/v1
|
||||||
|
kind: Telemetry
|
||||||
|
metadata:
|
||||||
|
name: mesh-default
|
||||||
|
namespace: istio-system
|
||||||
|
spec:
|
||||||
|
selector: {}
|
||||||
|
metrics:
|
||||||
|
- providers:
|
||||||
|
- name: prometheus
|
||||||
|
overrides:
|
||||||
|
- match:
|
||||||
|
metric: REQUEST_DURATION
|
||||||
|
tagOverrides:
|
||||||
|
"destination_workload": { operation: UPSERT, value: "%DESTINATION_WORKLOAD%" }
|
||||||
|
"destination_namespace": { operation: UPSERT, value: "%DESTINATION_NAMESPACE%" }
|
||||||
|
"request_host": { operation: UPSERT, value: "%REQUEST_HOST%" }
|
||||||
|
histogram:
|
||||||
|
buckets:
|
||||||
|
- 1
|
||||||
|
- 5
|
||||||
|
- 10
|
||||||
|
- 25
|
||||||
|
- 50
|
||||||
|
- 100
|
||||||
|
- 250
|
||||||
|
- 500
|
||||||
|
- 1000
|
||||||
|
- 2000
|
||||||
|
- 5000
|
||||||
|
- match:
|
||||||
|
metric: REQUEST_COUNT
|
||||||
|
tagOverrides:
|
||||||
|
"response_code": { operation: UPSERT, value: "%RESPONSE_CODE%" }
|
||||||
66
files/k8s/istio/trafficpolicy.yaml
Normal file
66
files/k8s/istio/trafficpolicy.yaml
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
# Istio Traffic Policy для управления трафиком
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
# mesh-wide mTLS STRICT
|
||||||
|
apiVersion: security.istio.io/v1
|
||||||
|
kind: PeerAuthentication
|
||||||
|
metadata:
|
||||||
|
name: default
|
||||||
|
namespace: istio-system
|
||||||
|
spec:
|
||||||
|
mtls:
|
||||||
|
mode: STRICT
|
||||||
|
|
||||||
|
---
|
||||||
|
# Пример строгой политики для bookinfo (pool + outlier)
|
||||||
|
apiVersion: networking.istio.io/v1
|
||||||
|
kind: DestinationRule
|
||||||
|
metadata:
|
||||||
|
name: productpage-policy
|
||||||
|
namespace: bookinfo
|
||||||
|
spec:
|
||||||
|
host: productpage.bookinfo.svc.cluster.local
|
||||||
|
trafficPolicy:
|
||||||
|
tls:
|
||||||
|
mode: ISTIO_MUTUAL
|
||||||
|
connectionPool:
|
||||||
|
tcp:
|
||||||
|
maxConnections: 100
|
||||||
|
http:
|
||||||
|
http1MaxPendingRequests: 1000
|
||||||
|
maxRequestsPerConnection: 100
|
||||||
|
outlierDetection:
|
||||||
|
consecutive5xx: 5
|
||||||
|
interval: 5s
|
||||||
|
baseEjectionTime: 30s
|
||||||
|
maxEjectionPercent: 50
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: networking.istio.io/v1
|
||||||
|
kind: DestinationRule
|
||||||
|
metadata:
|
||||||
|
name: reviews-policy
|
||||||
|
namespace: bookinfo
|
||||||
|
spec:
|
||||||
|
host: reviews.bookinfo.svc.cluster.local
|
||||||
|
subsets:
|
||||||
|
- name: v1
|
||||||
|
labels: { version: v1 }
|
||||||
|
- name: v2
|
||||||
|
labels: { version: v2 }
|
||||||
|
trafficPolicy:
|
||||||
|
tls:
|
||||||
|
mode: ISTIO_MUTUAL
|
||||||
|
connectionPool:
|
||||||
|
tcp:
|
||||||
|
maxConnections: 100
|
||||||
|
http:
|
||||||
|
http1MaxPendingRequests: 1000
|
||||||
|
maxRequestsPerConnection: 100
|
||||||
|
outlierDetection:
|
||||||
|
consecutive5xx: 3
|
||||||
|
interval: 5s
|
||||||
|
baseEjectionTime: 30s
|
||||||
|
maxEjectionPercent: 50
|
||||||
93
files/playbooks/chaos.yml
Normal file
93
files/playbooks/chaos.yml
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
---
|
||||||
|
# Chaos Engineering для тестирования отказоустойчивости
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
- name: Chaos Network (add latency)
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
vars:
|
||||||
|
chaos_duration: "{{ chaos_duration | default(60) }}"
|
||||||
|
chaos_latency: "{{ chaos_latency | default('100ms') }}"
|
||||||
|
chaos_loss: "{{ chaos_loss | default('5%') }}"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Install chaos tools
|
||||||
|
package:
|
||||||
|
name: [iproute2, iptables, tc]
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Add network latency
|
||||||
|
command: >
|
||||||
|
tc qdisc add dev eth0 root netem delay {{ chaos_latency }}
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Add packet loss
|
||||||
|
command: >
|
||||||
|
tc qdisc add dev eth0 root netem loss {{ chaos_loss }}
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Wait for chaos duration
|
||||||
|
pause:
|
||||||
|
seconds: "{{ chaos_duration }}"
|
||||||
|
|
||||||
|
- name: Remove network chaos
|
||||||
|
command: >
|
||||||
|
tc qdisc del dev eth0 root
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Chaos Services (random failures)
|
||||||
|
hosts: all
|
||||||
|
become: true
|
||||||
|
vars:
|
||||||
|
chaos_services:
|
||||||
|
- postgresql
|
||||||
|
- redis
|
||||||
|
- nginx
|
||||||
|
- docker
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Random service stop
|
||||||
|
systemd:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: stopped
|
||||||
|
loop: "{{ chaos_services }}"
|
||||||
|
when: (ansible_play_hosts.index(inventory_hostname) + ansible_date_time.epoch) % 3 == 0
|
||||||
|
|
||||||
|
- name: Wait for chaos
|
||||||
|
pause:
|
||||||
|
seconds: 30
|
||||||
|
|
||||||
|
- name: Restart services
|
||||||
|
systemd:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: started
|
||||||
|
loop: "{{ chaos_services }}"
|
||||||
|
when: (ansible_play_hosts.index(inventory_hostname) + ansible_date_time.epoch) % 3 == 0
|
||||||
|
|
||||||
|
- name: Chaos Docker (container failures)
|
||||||
|
hosts: "{{ groups['dind'] | default([]) }}"
|
||||||
|
gather_facts: false
|
||||||
|
vars:
|
||||||
|
docker_host: "tcp://{{ inventory_hostname }}:2375"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Random container stop
|
||||||
|
community.docker.docker_container:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: stopped
|
||||||
|
docker_host: "{{ docker_host }}"
|
||||||
|
loop: "{{ ansible_play_hosts }}"
|
||||||
|
when: (ansible_play_hosts.index(inventory_hostname) + ansible_date_time.epoch) % 4 == 0
|
||||||
|
|
||||||
|
- name: Wait for chaos
|
||||||
|
pause:
|
||||||
|
seconds: 20
|
||||||
|
|
||||||
|
- name: Restart containers
|
||||||
|
community.docker.docker_container:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: started
|
||||||
|
docker_host: "{{ docker_host }}"
|
||||||
|
loop: "{{ ansible_play_hosts }}"
|
||||||
|
when: (ansible_play_hosts.index(inventory_hostname) + ansible_date_time.epoch) % 4 == 0
|
||||||
45
files/playbooks/site.yml
Normal file
45
files/playbooks/site.yml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
# Основной playbook для универсальной лаборатории
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
- name: Base deps
|
||||||
|
hosts: all
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
|
- name: Update apt cache (Debian)
|
||||||
|
apt:
|
||||||
|
update_cache: true
|
||||||
|
when: ansible_os_family == 'Debian'
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Update yum cache (RHEL)
|
||||||
|
yum:
|
||||||
|
update_cache: true
|
||||||
|
when: ansible_os_family == 'RedHat'
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Common tools
|
||||||
|
package:
|
||||||
|
name:
|
||||||
|
- curl
|
||||||
|
- jq
|
||||||
|
- ca-certificates
|
||||||
|
- iproute2
|
||||||
|
- iputils-ping
|
||||||
|
- procps
|
||||||
|
- net-tools
|
||||||
|
- sudo
|
||||||
|
- vim
|
||||||
|
- wget
|
||||||
|
- unzip
|
||||||
|
state: present
|
||||||
|
|
||||||
|
# Развертывание инфраструктуры
|
||||||
|
- name: Deploy infrastructure
|
||||||
|
hosts: all
|
||||||
|
become: true
|
||||||
|
tasks:
|
||||||
|
- name: Infrastructure placeholder
|
||||||
|
debug:
|
||||||
|
msg: "Инфраструктура готова для настройки"
|
||||||
8
files/requirements.yml
Normal file
8
files/requirements.yml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
# Коллекции Ansible для универсальной лаборатории
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
collections:
|
||||||
|
- name: community.docker
|
||||||
|
- name: community.general
|
||||||
0
molecule/.gitkeep
Normal file
0
molecule/.gitkeep
Normal file
@@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Converge
|
|
||||||
hosts: all
|
|
||||||
vars_files:
|
|
||||||
- ../../vars/secrets.yml
|
|
||||||
roles:
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
- name: Destroy containers on interrupt
|
|
||||||
hosts: localhost
|
|
||||||
tasks:
|
|
||||||
- name: Ensure containers are destroyed
|
|
||||||
docker_container:
|
|
||||||
name: "{{ item.name }}"
|
|
||||||
state: absent
|
|
||||||
loop: "{{ molecule_yml.platforms }}"
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
---
|
|
||||||
dependency:
|
|
||||||
name: galaxy
|
|
||||||
enabled: false
|
|
||||||
options:
|
|
||||||
requirements-file: requirements.yml
|
|
||||||
|
|
||||||
driver:
|
|
||||||
name: docker
|
|
||||||
|
|
||||||
platforms:
|
|
||||||
- name: centos
|
|
||||||
image: "inecs/ansible:centos"
|
|
||||||
privileged: true
|
|
||||||
pre_build_image: true
|
|
||||||
volumes:
|
|
||||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
tmpfs:
|
|
||||||
- /tmp
|
|
||||||
- /run
|
|
||||||
- name: ubuntu
|
|
||||||
image: "inecs/ansible:ubuntu"
|
|
||||||
privileged: true
|
|
||||||
pre_build_image: true
|
|
||||||
volumes:
|
|
||||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
tmpfs:
|
|
||||||
- /tmp
|
|
||||||
- /run
|
|
||||||
|
|
||||||
provisioner:
|
|
||||||
name: ansible
|
|
||||||
connection_options:
|
|
||||||
ansible_connection: docker
|
|
||||||
ansible_user: root
|
|
||||||
env:
|
|
||||||
ANSIBLE_PYTHON_INTERPRETER: /usr/bin/python3
|
|
||||||
lint:
|
|
||||||
name: ansible-lint
|
|
||||||
|
|
||||||
verifier:
|
|
||||||
name: ansible
|
|
||||||
|
|
||||||
scenario:
|
|
||||||
name: default
|
|
||||||
test_sequence:
|
|
||||||
- dependency
|
|
||||||
- cleanup
|
|
||||||
- destroy
|
|
||||||
- syntax
|
|
||||||
- create
|
|
||||||
- prepare
|
|
||||||
- converge
|
|
||||||
- idempotence
|
|
||||||
- side_effect
|
|
||||||
- verify
|
|
||||||
- cleanup
|
|
||||||
- destroy
|
|
||||||
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
- name: Prepare
|
|
||||||
hosts: all
|
|
||||||
tasks:
|
|
||||||
- name: Detect OS family
|
|
||||||
ansible.builtin.setup:
|
|
||||||
gather_subset:
|
|
||||||
- "min"
|
|
||||||
|
|
||||||
- name: Обновляем пакеты для работы с Ansible в RockyLinux (Centos/RedHat)
|
|
||||||
when: ansible_facts['os_family'] == "RedHat"
|
|
||||||
block:
|
|
||||||
- name: Устанавливаем репозиторий AppStream (если его нет)
|
|
||||||
ansible.builtin.raw: dnf config-manager --set-enabled appstream
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Установить rsync
|
|
||||||
ansible.builtin.raw: dnf install -y rsync
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Устанавливаем Python 3.8
|
|
||||||
ansible.builtin.raw: dnf install -y python38 python38-pip
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Обновляем символическую ссылку python3
|
|
||||||
ansible.builtin.raw: alternatives --set python /usr/bin/python3.8
|
|
||||||
changed_when: false
|
|
||||||
# - name: Fix repository URLs
|
|
||||||
# ansible.builtin.command:
|
|
||||||
# cmd: sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
|
|
||||||
# changed_when: false
|
|
||||||
|
|
||||||
# - name: Update baseurl
|
|
||||||
# ansible.builtin.command:
|
|
||||||
# cmd: sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
|
|
||||||
# changed_when: false
|
|
||||||
|
|
||||||
# - name: Install required packages
|
|
||||||
# ansible.builtin.yum:
|
|
||||||
# name:
|
|
||||||
# - epel-release
|
|
||||||
# - python3
|
|
||||||
# - python3-pip
|
|
||||||
# state: present
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Prepare
|
|
||||||
hosts: all
|
|
||||||
tasks:
|
|
||||||
- name: Reun verify
|
|
||||||
debug:
|
|
||||||
msg: "Hello, Verify!"
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
---
|
|
||||||
# Проверка работы systemd, docker и docker-compose в образах
|
|
||||||
# Автор: Сергей Антропов
|
|
||||||
# Сайт: https://devops.org.ru
|
|
||||||
|
|
||||||
- name: Verify systemd, docker and docker-compose services
|
|
||||||
hosts: all
|
|
||||||
gather_facts: true
|
|
||||||
tasks:
|
|
||||||
- name: Display OS information
|
|
||||||
debug:
|
|
||||||
msg: "Тестирование на {{ ansible_distribution }} {{ ansible_distribution_version }}"
|
|
||||||
|
|
||||||
- name: Check if systemd is available and running
|
|
||||||
systemd:
|
|
||||||
name: systemd
|
|
||||||
state: started
|
|
||||||
register: systemd_status
|
|
||||||
failed_when: false
|
|
||||||
|
|
||||||
- name: Display systemd status
|
|
||||||
debug:
|
|
||||||
msg: "Systemd статус: {{ 'Доступен и запущен' if systemd_status is succeeded else 'Недоступен или не запущен' }}"
|
|
||||||
|
|
||||||
- name: Check systemd version
|
|
||||||
command: systemd --version
|
|
||||||
register: systemd_version
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display systemd version
|
|
||||||
debug:
|
|
||||||
msg: "Версия systemd: {{ systemd_version.stdout_lines[0] if systemd_version.stdout_lines else 'Не определена' }}"
|
|
||||||
|
|
||||||
- name: Check if docker service exists
|
|
||||||
stat:
|
|
||||||
path: /usr/bin/docker
|
|
||||||
register: docker_binary
|
|
||||||
|
|
||||||
- name: Check if docker service exists (alternative path)
|
|
||||||
stat:
|
|
||||||
path: /usr/local/bin/docker
|
|
||||||
register: docker_binary_alt
|
|
||||||
|
|
||||||
- name: Display docker binary status
|
|
||||||
debug:
|
|
||||||
msg: "Docker binary: {{ 'Найден в /usr/bin/docker' if docker_binary.stat.exists else ('Найден в /usr/local/bin/docker' if docker_binary_alt.stat.exists else 'Не найден') }}"
|
|
||||||
|
|
||||||
- name: Check docker version
|
|
||||||
command: docker --version
|
|
||||||
register: docker_version
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display docker version
|
|
||||||
debug:
|
|
||||||
msg: "Версия Docker: {{ docker_version.stdout if docker_version.stdout else 'Docker не установлен' }}"
|
|
||||||
|
|
||||||
- name: Check if docker daemon is running
|
|
||||||
command: docker info
|
|
||||||
register: docker_info
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display docker daemon status
|
|
||||||
debug:
|
|
||||||
msg: "Docker daemon: {{ 'Запущен' if docker_info is succeeded else 'Не запущен или недоступен' }}"
|
|
||||||
|
|
||||||
- name: Check if docker-compose binary exists
|
|
||||||
stat:
|
|
||||||
path: /usr/local/bin/docker-compose
|
|
||||||
register: docker_compose_binary
|
|
||||||
|
|
||||||
- name: Check if docker-compose binary exists (alternative path)
|
|
||||||
stat:
|
|
||||||
path: /usr/bin/docker-compose
|
|
||||||
register: docker_compose_binary_alt
|
|
||||||
|
|
||||||
- name: Check if docker compose plugin exists
|
|
||||||
command: docker compose version
|
|
||||||
register: docker_compose_plugin
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display docker-compose status
|
|
||||||
debug:
|
|
||||||
msg: "Docker Compose: {{ 'Найден как binary' if docker_compose_binary.stat.exists or docker_compose_binary_alt.stat.exists else ('Найден как plugin' if docker_compose_plugin is succeeded else 'Не найден') }}"
|
|
||||||
|
|
||||||
- name: Display docker-compose version
|
|
||||||
debug:
|
|
||||||
msg: "Версия Docker Compose: {{ docker_compose_plugin.stdout if docker_compose_plugin is succeeded else 'Docker Compose не установлен' }}"
|
|
||||||
|
|
||||||
- name: Test docker functionality
|
|
||||||
command: docker run --rm hello-world
|
|
||||||
register: docker_test
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display docker test result
|
|
||||||
debug:
|
|
||||||
msg: "Тест Docker: {{ 'Успешно' if docker_test is succeeded else 'Ошибка - ' + docker_test.stderr }}"
|
|
||||||
|
|
||||||
- name: Check systemd services status
|
|
||||||
command: systemctl list-units --type=service --state=running
|
|
||||||
register: running_services
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display running services count
|
|
||||||
debug:
|
|
||||||
msg: "Количество запущенных сервисов: {{ running_services.stdout_lines | length }}"
|
|
||||||
|
|
||||||
- name: Check for docker-related systemd services
|
|
||||||
command: systemctl list-units --type=service | grep -i docker
|
|
||||||
register: docker_services
|
|
||||||
failed_when: false
|
|
||||||
changed_when: false
|
|
||||||
|
|
||||||
- name: Display docker services
|
|
||||||
debug:
|
|
||||||
msg: "Docker сервисы: {{ docker_services.stdout_lines if docker_services.stdout_lines else 'Не найдены' }}"
|
|
||||||
|
|
||||||
- name: Final summary
|
|
||||||
debug:
|
|
||||||
msg: |
|
|
||||||
========================================
|
|
||||||
РЕЗУЛЬТАТЫ ПРОВЕРКИ ОБРАЗА {{ ansible_distribution }}:
|
|
||||||
========================================
|
|
||||||
Systemd: {{ '✓ Работает' if systemd_status is succeeded else '✗ Не работает' }}
|
|
||||||
Docker: {{ '✓ Установлен и работает' if docker_info is succeeded else '✗ Не установлен или не работает' }}
|
|
||||||
Docker Compose: {{ '✓ Доступен' if (docker_compose_binary.stat.exists or docker_compose_binary_alt.stat.exists or docker_compose_plugin is succeeded) else '✗ Недоступен' }}
|
|
||||||
========================================
|
|
||||||
120
molecule/presets/bigdata.yml
Normal file
120
molecule/presets/bigdata.yml
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Big Data кластер (12-18 машин)
|
||||||
|
#
|
||||||
|
# Описание: Кластер для обработки больших данных с различными компонентами
|
||||||
|
# - 3 Hadoop NameNode (активный/резервный/журнал) - метаданные
|
||||||
|
# - 3 Hadoop DataNode - хранение данных
|
||||||
|
# - 1 Hive Metastore - метаданные таблиц
|
||||||
|
# - 1 Spark Master - управление Spark
|
||||||
|
# - 2 Spark Worker - обработка данных
|
||||||
|
# - 1 Kafka Broker - потоковая обработка
|
||||||
|
# - 1 Zookeeper - координация сервисов
|
||||||
|
# - 1 Elasticsearch - поиск и аналитика
|
||||||
|
# - 1 Kibana - визуализация данных
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/bigdata.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: namenode1
|
||||||
|
group: namenodes
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "9870:9870"
|
||||||
|
|
||||||
|
- name: namenode2
|
||||||
|
group: namenodes
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "9871:9870"
|
||||||
|
|
||||||
|
- name: namenode3
|
||||||
|
group: namenodes
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "9872:9870"
|
||||||
|
|
||||||
|
- name: datanode1
|
||||||
|
group: datanodes
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "9864:9864"
|
||||||
|
|
||||||
|
- name: datanode2
|
||||||
|
group: datanodes
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "9865:9864"
|
||||||
|
|
||||||
|
- name: datanode3
|
||||||
|
group: datanodes
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "9866:9864"
|
||||||
|
|
||||||
|
- name: hive-metastore
|
||||||
|
group: metastores
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "9083:9083"
|
||||||
|
|
||||||
|
- name: spark-master
|
||||||
|
group: spark
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8080:8080"
|
||||||
|
|
||||||
|
- name: spark-worker1
|
||||||
|
group: spark
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "8081:8080"
|
||||||
|
|
||||||
|
- name: spark-worker2
|
||||||
|
group: spark
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8082:8080"
|
||||||
|
|
||||||
|
- name: kafka
|
||||||
|
group: streaming
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "9092:9092"
|
||||||
|
|
||||||
|
- name: zookeeper
|
||||||
|
group: coordination
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "2181:2181"
|
||||||
|
|
||||||
|
- name: elasticsearch
|
||||||
|
group: search
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "9200:9200"
|
||||||
|
|
||||||
|
- name: kibana
|
||||||
|
group: visualization
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "5601:5601"
|
||||||
100
molecule/presets/cicd.yml
Normal file
100
molecule/presets/cicd.yml
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: CI/CD пайплайн (10-15 машин)
|
||||||
|
#
|
||||||
|
# Описание: Полноценный CI/CD пайплайн с различными инструментами
|
||||||
|
# - 1 Git сервер (Gitea) - управление кодом
|
||||||
|
# - 2 CI сервера (Jenkins) - сборка и тестирование
|
||||||
|
# - 1 артефакт репозиторий (Nexus) - хранение артефактов
|
||||||
|
# - 1 Docker registry - хранение образов
|
||||||
|
# - 2 тестовые среды (staging, production) - развертывание
|
||||||
|
# - 1 мониторинг (Prometheus) - метрики пайплайна
|
||||||
|
# - 1 логирование (ELK Stack) - централизованные логи
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/cicd.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: git-server
|
||||||
|
group: scm
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "3000:3000"
|
||||||
|
|
||||||
|
- name: jenkins1
|
||||||
|
group: ci
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8080:8080"
|
||||||
|
|
||||||
|
- name: jenkins2
|
||||||
|
group: ci
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "8081:8080"
|
||||||
|
|
||||||
|
- name: nexus
|
||||||
|
group: artifacts
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8081:8081"
|
||||||
|
|
||||||
|
- name: docker-registry
|
||||||
|
group: registries
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "5000:5000"
|
||||||
|
|
||||||
|
- name: staging
|
||||||
|
group: environments
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8082:80"
|
||||||
|
|
||||||
|
- name: production
|
||||||
|
group: environments
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "8083:80"
|
||||||
|
|
||||||
|
- name: monitoring
|
||||||
|
group: monitoring
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "9090:9090"
|
||||||
|
|
||||||
|
- name: elasticsearch
|
||||||
|
group: logging
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "9200:9200"
|
||||||
|
|
||||||
|
- name: kibana
|
||||||
|
group: logging
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "5601:5601"
|
||||||
|
|
||||||
|
- name: logstash
|
||||||
|
group: logging
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "5044:5044"
|
||||||
58
molecule/presets/dind-compose.yml
Normal file
58
molecule/presets/dind-compose.yml
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Docker-in-Docker Compose (4 DinD контейнера)
|
||||||
|
#
|
||||||
|
# Описание: DinD контейнеры для тестирования Docker Compose стека
|
||||||
|
# - 4 DinD контейнера с различными стеками
|
||||||
|
# - Тестирование multi-container приложений
|
||||||
|
# - Различные версии Docker Compose
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/dind-compose.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: compose-web
|
||||||
|
type: dind
|
||||||
|
group: compose
|
||||||
|
publish:
|
||||||
|
- "2375:2375" # Docker API
|
||||||
|
- "8080:80" # Web port
|
||||||
|
|
||||||
|
- name: compose-api
|
||||||
|
type: dind
|
||||||
|
group: compose
|
||||||
|
publish:
|
||||||
|
- "2376:2375" # Docker API
|
||||||
|
- "8081:3000" # API port
|
||||||
|
|
||||||
|
- name: compose-db
|
||||||
|
type: dind
|
||||||
|
group: compose
|
||||||
|
publish:
|
||||||
|
- "2377:2375" # Docker API
|
||||||
|
- "8082:5432" # DB port
|
||||||
|
|
||||||
|
- name: compose-cache
|
||||||
|
type: dind
|
||||||
|
group: compose
|
||||||
|
publish:
|
||||||
|
- "2378:2375" # Docker API
|
||||||
|
- "8083:6379" # Cache port
|
||||||
51
molecule/presets/dind-simple.yml
Normal file
51
molecule/presets/dind-simple.yml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Docker-in-Docker Simple (3 DinD контейнера)
|
||||||
|
#
|
||||||
|
# Описание: Простая конфигурация DinD для тестирования Docker ролей
|
||||||
|
# - 3 DinD контейнера с различными конфигурациями
|
||||||
|
# - Изолированные Docker среды
|
||||||
|
# - Тестирование Docker Compose, Docker Swarm
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/dind-simple.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: dind1
|
||||||
|
type: dind
|
||||||
|
group: dind
|
||||||
|
publish:
|
||||||
|
- "2375:2375" # Docker API
|
||||||
|
- "8080:8080" # App port
|
||||||
|
|
||||||
|
- name: dind2
|
||||||
|
type: dind
|
||||||
|
group: dind
|
||||||
|
publish:
|
||||||
|
- "2376:2375" # Docker API
|
||||||
|
- "8081:8080" # App port
|
||||||
|
|
||||||
|
- name: dind3
|
||||||
|
type: dind
|
||||||
|
group: dind
|
||||||
|
publish:
|
||||||
|
- "2377:2375" # Docker API
|
||||||
|
- "8082:8080" # App port
|
||||||
65
molecule/presets/dind-swarm.yml
Normal file
65
molecule/presets/dind-swarm.yml
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Docker-in-Docker Swarm (5 DinD контейнеров)
|
||||||
|
#
|
||||||
|
# Описание: Docker Swarm кластер для тестирования оркестрации
|
||||||
|
# - 1 Manager + 4 Worker узла
|
||||||
|
# - Docker Swarm режим
|
||||||
|
# - Тестирование сервисов, стеков, секретов
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/dind-swarm.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: swarm-manager
|
||||||
|
type: dind
|
||||||
|
group: swarm
|
||||||
|
publish:
|
||||||
|
- "2375:2375" # Docker API
|
||||||
|
- "8080:8080" # App port
|
||||||
|
|
||||||
|
- name: swarm-worker1
|
||||||
|
type: dind
|
||||||
|
group: swarm
|
||||||
|
publish:
|
||||||
|
- "2376:2375" # Docker API
|
||||||
|
- "8081:8080" # App port
|
||||||
|
|
||||||
|
- name: swarm-worker2
|
||||||
|
type: dind
|
||||||
|
group: swarm
|
||||||
|
publish:
|
||||||
|
- "2377:2375" # Docker API
|
||||||
|
- "8082:8080" # App port
|
||||||
|
|
||||||
|
- name: swarm-worker3
|
||||||
|
type: dind
|
||||||
|
group: swarm
|
||||||
|
publish:
|
||||||
|
- "2378:2375" # Docker API
|
||||||
|
- "8083:8080" # App port
|
||||||
|
|
||||||
|
- name: swarm-worker4
|
||||||
|
type: dind
|
||||||
|
group: swarm
|
||||||
|
publish:
|
||||||
|
- "2379:2375" # Docker API
|
||||||
|
- "8084:8080" # App port
|
||||||
89
molecule/presets/dood-mixed.yml
Normal file
89
molecule/presets/dood-mixed.yml
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Docker-outside-of-Docker Mixed (5 DOoD + 2 systemd)
|
||||||
|
#
|
||||||
|
# Описание: Смешанная конфигурация DOoD и systemd контейнеров
|
||||||
|
# - 5 DOoD контейнеров для Docker операций
|
||||||
|
# - 2 systemd контейнера для системных ролей
|
||||||
|
# - Тестирование гибридных сценариев
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/dood-mixed.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
# DOoD контейнеры
|
||||||
|
- name: dood-web
|
||||||
|
type: dood
|
||||||
|
family: debian
|
||||||
|
group: dood
|
||||||
|
publish:
|
||||||
|
- "8080:80"
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
|
|
||||||
|
- name: dood-api
|
||||||
|
type: dood
|
||||||
|
family: rhel
|
||||||
|
group: dood
|
||||||
|
publish:
|
||||||
|
- "8081:3000"
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
|
|
||||||
|
- name: dood-db
|
||||||
|
type: dood
|
||||||
|
family: debian
|
||||||
|
group: dood
|
||||||
|
publish:
|
||||||
|
- "8082:5432"
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
|
|
||||||
|
- name: dood-cache
|
||||||
|
type: dood
|
||||||
|
family: rhel
|
||||||
|
group: dood
|
||||||
|
publish:
|
||||||
|
- "8083:6379"
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
|
|
||||||
|
- name: dood-queue
|
||||||
|
type: dood
|
||||||
|
family: debian
|
||||||
|
group: dood
|
||||||
|
publish:
|
||||||
|
- "8084:5672"
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
|
|
||||||
|
# Systemd контейнеры
|
||||||
|
- name: systemd-monitor
|
||||||
|
family: rhel
|
||||||
|
group: monitoring
|
||||||
|
publish:
|
||||||
|
- "9090:9090"
|
||||||
|
|
||||||
|
- name: systemd-logs
|
||||||
|
family: debian
|
||||||
|
group: logging
|
||||||
|
publish:
|
||||||
|
- "5601:5601"
|
||||||
57
molecule/presets/dood-simple.yml
Normal file
57
molecule/presets/dood-simple.yml
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Docker-outside-of-Docker Simple (3 DOoD контейнера)
|
||||||
|
#
|
||||||
|
# Описание: Простая конфигурация DOoD для тестирования Docker ролей
|
||||||
|
# - 3 DOoD контейнера с доступом к Docker daemon хоста
|
||||||
|
# - Тестирование Docker ролей без изоляции
|
||||||
|
# - Различные семейства ОС
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/dood-simple.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: dood1
|
||||||
|
type: dood
|
||||||
|
family: debian
|
||||||
|
group: dood
|
||||||
|
publish:
|
||||||
|
- "8080:8080" # App port
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
|
|
||||||
|
- name: dood2
|
||||||
|
type: dood
|
||||||
|
family: rhel
|
||||||
|
group: dood
|
||||||
|
publish:
|
||||||
|
- "8081:8080" # App port
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
|
|
||||||
|
- name: dood3
|
||||||
|
type: dood
|
||||||
|
family: debian
|
||||||
|
group: dood
|
||||||
|
publish:
|
||||||
|
- "8082:8080" # App port
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
167
molecule/presets/enterprise.yml
Normal file
167
molecule/presets/enterprise.yml
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Enterprise (18-20 машин)
|
||||||
|
#
|
||||||
|
# Описание: Полноценная enterprise инфраструктура с высокой доступностью
|
||||||
|
# - 2 Load Balancer (HAProxy) - балансировка нагрузки
|
||||||
|
# - 3 Web сервера (nginx) - веб-приложения
|
||||||
|
# - 2 API Gateway (Kong) - управление API
|
||||||
|
# - 3 Application сервера - бизнес-логика
|
||||||
|
# - 2 Database Master/Slave (PostgreSQL) - основная БД
|
||||||
|
# - 2 Cache кластер (Redis) - кэширование
|
||||||
|
# - 1 Message Queue (RabbitMQ) - асинхронная обработка
|
||||||
|
# - 1 Search Engine (Elasticsearch) - поиск
|
||||||
|
# - 1 Monitoring (Prometheus) - метрики
|
||||||
|
# - 1 Logging (ELK Stack) - централизованные логи
|
||||||
|
# - 1 Backup сервер - резервное копирование
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/enterprise.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: lb1
|
||||||
|
group: loadbalancers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
|
||||||
|
- name: lb2
|
||||||
|
group: loadbalancers
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8080:80"
|
||||||
|
- "8443:443"
|
||||||
|
|
||||||
|
- name: web1
|
||||||
|
group: webservers
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8081:80"
|
||||||
|
|
||||||
|
- name: web2
|
||||||
|
group: webservers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "8082:80"
|
||||||
|
|
||||||
|
- name: web3
|
||||||
|
group: webservers
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8083:80"
|
||||||
|
|
||||||
|
- name: api-gateway1
|
||||||
|
group: gateways
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "8001:8000"
|
||||||
|
|
||||||
|
- name: api-gateway2
|
||||||
|
group: gateways
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8002:8000"
|
||||||
|
|
||||||
|
- name: app1
|
||||||
|
group: applications
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "9001:9000"
|
||||||
|
|
||||||
|
- name: app2
|
||||||
|
group: applications
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "9002:9000"
|
||||||
|
|
||||||
|
- name: app3
|
||||||
|
group: applications
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "9003:9000"
|
||||||
|
|
||||||
|
- name: db-master
|
||||||
|
group: databases
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "5432:5432"
|
||||||
|
|
||||||
|
- name: db-slave
|
||||||
|
group: databases
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "5433:5432"
|
||||||
|
|
||||||
|
- name: cache1
|
||||||
|
group: caches
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "6379:6379"
|
||||||
|
|
||||||
|
- name: cache2
|
||||||
|
group: caches
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "6380:6379"
|
||||||
|
|
||||||
|
- name: message-queue
|
||||||
|
group: queues
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "5672:5672"
|
||||||
|
- "15672:15672"
|
||||||
|
|
||||||
|
- name: elasticsearch
|
||||||
|
group: search
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "9200:9200"
|
||||||
|
|
||||||
|
- name: monitoring
|
||||||
|
group: monitoring
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "9090:9090"
|
||||||
|
|
||||||
|
- name: elasticsearch-logs
|
||||||
|
group: logging
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "9201:9200"
|
||||||
|
|
||||||
|
- name: kibana
|
||||||
|
group: logging
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "5601:5601"
|
||||||
|
|
||||||
|
- name: logstash
|
||||||
|
group: logging
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "5044:5044"
|
||||||
|
|
||||||
|
- name: backup
|
||||||
|
group: backup
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "22:22"
|
||||||
88
molecule/presets/ha.yml
Normal file
88
molecule/presets/ha.yml
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Высокая доступность (6-10 машин)
|
||||||
|
#
|
||||||
|
# Описание: Кластер высокой доступности с репликацией и отказоустойчивостью
|
||||||
|
# - 2 веб-сервера (nginx) - активный/резервный
|
||||||
|
# - 2 базы данных (PostgreSQL) - мастер/слейв репликация
|
||||||
|
# - 2 кэш-сервера (Redis) - кластер с репликацией
|
||||||
|
# - 1 балансировщик (HAProxy) - с проверками здоровья
|
||||||
|
# - 1 мониторинг (Prometheus) - контроль состояния
|
||||||
|
# - 1 резервный мониторинг (Grafana) - визуализация
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/ha.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: haproxy
|
||||||
|
group: loadbalancers
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
|
||||||
|
- name: web1
|
||||||
|
group: webservers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "8081:80"
|
||||||
|
|
||||||
|
- name: web2
|
||||||
|
group: webservers
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8082:80"
|
||||||
|
|
||||||
|
- name: db-master
|
||||||
|
group: databases
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "5432:5432"
|
||||||
|
|
||||||
|
- name: db-slave
|
||||||
|
group: databases
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "5433:5432"
|
||||||
|
|
||||||
|
- name: cache1
|
||||||
|
group: caches
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "6379:6379"
|
||||||
|
|
||||||
|
- name: cache2
|
||||||
|
group: caches
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "6380:6379"
|
||||||
|
|
||||||
|
- name: monitoring
|
||||||
|
group: monitoring
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "9090:9090"
|
||||||
|
|
||||||
|
- name: grafana
|
||||||
|
group: monitoring
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "3000:3000"
|
||||||
99
molecule/presets/k8s-cluster.yml
Normal file
99
molecule/presets/k8s-cluster.yml
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Kubernetes кластер (8-12 машин)
|
||||||
|
#
|
||||||
|
# Описание: Полноценный Kubernetes кластер с различными ролями
|
||||||
|
# - 3 master ноды (control-plane) - управление кластером
|
||||||
|
# - 3 worker ноды - выполнение workload
|
||||||
|
# - 1 etcd кластер (3 ноды) - хранение состояния
|
||||||
|
# - 1 ingress контроллер - маршрутизация трафика
|
||||||
|
# - 1 мониторинг (Prometheus) - метрики кластера
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/k8s-cluster.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: master1
|
||||||
|
group: masters
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "6443:6443"
|
||||||
|
|
||||||
|
- name: master2
|
||||||
|
group: masters
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "6444:6443"
|
||||||
|
|
||||||
|
- name: master3
|
||||||
|
group: masters
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "6445:6443"
|
||||||
|
|
||||||
|
- name: worker1
|
||||||
|
group: workers
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "30000:30000"
|
||||||
|
|
||||||
|
- name: worker2
|
||||||
|
group: workers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "30001:30000"
|
||||||
|
|
||||||
|
- name: worker3
|
||||||
|
group: workers
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "30002:30000"
|
||||||
|
|
||||||
|
- name: etcd1
|
||||||
|
group: etcd
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "2379:2379"
|
||||||
|
|
||||||
|
- name: etcd2
|
||||||
|
group: etcd
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "2380:2379"
|
||||||
|
|
||||||
|
- name: etcd3
|
||||||
|
group: etcd
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "2381:2379"
|
||||||
|
|
||||||
|
- name: ingress
|
||||||
|
group: ingress
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
|
||||||
|
- name: monitoring
|
||||||
|
group: monitoring
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "9090:9090"
|
||||||
55
molecule/presets/k8s-istio-full.yml
Normal file
55
molecule/presets/k8s-istio-full.yml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Kubernetes + Istio Full Stack (1 кластер с полным стеком)
|
||||||
|
#
|
||||||
|
# Описание: Полноценный Kubernetes кластер с полным стеком Istio
|
||||||
|
# - 1 Kind кластер с 3 workers
|
||||||
|
# - Полный Istio service mesh с Kiali
|
||||||
|
# - Prometheus + Grafana для мониторинга
|
||||||
|
# - Jaeger для трассировки
|
||||||
|
# - Все аддоны включены
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/k8s-istio-full.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
kind_clusters:
|
||||||
|
- name: istio-full
|
||||||
|
workers: 3
|
||||||
|
api_port: 6443
|
||||||
|
addons:
|
||||||
|
ingress_nginx: true
|
||||||
|
metrics_server: true
|
||||||
|
istio: true
|
||||||
|
kiali: true
|
||||||
|
prometheus_stack: true
|
||||||
|
ingress_host_http_port: 8081
|
||||||
|
ingress_host_https_port: 8443
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: k8s-controller
|
||||||
|
group: controllers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "6443:6443"
|
||||||
|
- "9090:9090" # Prometheus
|
||||||
|
- "3000:3000" # Grafana
|
||||||
|
- "16686:16686" # Jaeger
|
||||||
|
- "20001:20001" # Kiali
|
||||||
46
molecule/presets/k8s-kind.yml
Normal file
46
molecule/presets/k8s-kind.yml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
# Пресет для Kubernetes лаборатории с Kind кластерами
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
# Сеть для лаборатории
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
# Kind кластеры
|
||||||
|
kind_clusters:
|
||||||
|
- name: lab
|
||||||
|
workers: 2
|
||||||
|
api_port: 6443
|
||||||
|
addons:
|
||||||
|
ingress_nginx: true
|
||||||
|
metrics_server: true
|
||||||
|
istio: true
|
||||||
|
kiali: true
|
||||||
|
prometheus_stack: true
|
||||||
|
ingress_host_http_port: 8081
|
||||||
|
ingress_host_https_port: 8443
|
||||||
|
|
||||||
|
# Образы для разных семейств ОС
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
# Настройки по умолчанию для systemd контейнеров
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
# Определение хостов лаборатории (минимальный набор для k8s)
|
||||||
|
hosts:
|
||||||
|
- name: k8s-controller
|
||||||
|
group: controllers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "6443:6443"
|
||||||
81
molecule/presets/k8s-multi.yml
Normal file
81
molecule/presets/k8s-multi.yml
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Kubernetes Multi-Cluster (3 кластера)
|
||||||
|
#
|
||||||
|
# Описание: Несколько Kind кластеров для тестирования мульти-кластерных сценариев
|
||||||
|
# - 3 Kind кластера: dev, staging, prod
|
||||||
|
# - Различные конфигурации для каждого окружения
|
||||||
|
# - Полный стек мониторинга и service mesh
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/k8s-multi.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
kind_clusters:
|
||||||
|
- name: dev
|
||||||
|
workers: 1
|
||||||
|
api_port: 6443
|
||||||
|
addons:
|
||||||
|
ingress_nginx: true
|
||||||
|
metrics_server: true
|
||||||
|
ingress_host_http_port: 8081
|
||||||
|
ingress_host_https_port: 8443
|
||||||
|
|
||||||
|
- name: staging
|
||||||
|
workers: 2
|
||||||
|
api_port: 6444
|
||||||
|
addons:
|
||||||
|
ingress_nginx: true
|
||||||
|
metrics_server: true
|
||||||
|
istio: true
|
||||||
|
kiali: true
|
||||||
|
ingress_host_http_port: 8082
|
||||||
|
ingress_host_https_port: 8444
|
||||||
|
|
||||||
|
- name: prod
|
||||||
|
workers: 3
|
||||||
|
api_port: 6445
|
||||||
|
addons:
|
||||||
|
ingress_nginx: true
|
||||||
|
metrics_server: true
|
||||||
|
istio: true
|
||||||
|
kiali: true
|
||||||
|
prometheus_stack: true
|
||||||
|
ingress_host_http_port: 8083
|
||||||
|
ingress_host_https_port: 8445
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: k8s-dev-controller
|
||||||
|
group: controllers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "6443:6443"
|
||||||
|
|
||||||
|
- name: k8s-staging-controller
|
||||||
|
group: controllers
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "6444:6444"
|
||||||
|
|
||||||
|
- name: k8s-prod-controller
|
||||||
|
group: controllers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "6445:6445"
|
||||||
46
molecule/presets/k8s-single.yml
Normal file
46
molecule/presets/k8s-single.yml
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Kubernetes Single Node (1 кластер)
|
||||||
|
#
|
||||||
|
# Описание: Одиночный Kind кластер для простого тестирования K8s ролей
|
||||||
|
# - 1 Kind кластер с 1 worker
|
||||||
|
# - Базовые аддоны: Ingress NGINX, Metrics Server
|
||||||
|
# - Простая конфигурация для быстрого старта
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/k8s-single.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
kind_clusters:
|
||||||
|
- name: single
|
||||||
|
workers: 1
|
||||||
|
api_port: 6443
|
||||||
|
addons:
|
||||||
|
ingress_nginx: true
|
||||||
|
metrics_server: true
|
||||||
|
ingress_host_http_port: 8081
|
||||||
|
ingress_host_https_port: 8443
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: k8s-controller
|
||||||
|
group: controllers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "6443:6443"
|
||||||
181
molecule/presets/maximum.yml
Normal file
181
molecule/presets/maximum.yml
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Максимальный (20 машин)
|
||||||
|
#
|
||||||
|
# Описание: Максимально сложная инфраструктура для тестирования в экстремальных условиях
|
||||||
|
# - 2 Load Balancer (HAProxy) - балансировка
|
||||||
|
# - 3 Web сервера (nginx) - веб-слой
|
||||||
|
# - 2 API Gateway (Kong) - API управление
|
||||||
|
# - 3 Application сервера - бизнес-логика
|
||||||
|
# - 2 Database Master/Slave (PostgreSQL) - основная БД
|
||||||
|
# - 2 Cache сервера (Redis) - кэширование
|
||||||
|
# - 1 Message Queue (RabbitMQ) - очереди
|
||||||
|
# - 1 Search Engine (Elasticsearch) - поиск
|
||||||
|
# - 1 Monitoring (Prometheus) - метрики
|
||||||
|
# - 1 Logging (ELK Stack) - логи
|
||||||
|
# - 1 Tracing (Jaeger) - трассировка
|
||||||
|
# - 1 Visualization (Grafana) - визуализация
|
||||||
|
# - 1 Backup сервер - резервное копирование
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/maximum.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: lb1
|
||||||
|
group: loadbalancers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
|
||||||
|
- name: lb2
|
||||||
|
group: loadbalancers
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8080:80"
|
||||||
|
- "8443:443"
|
||||||
|
|
||||||
|
- name: web1
|
||||||
|
group: webservers
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8081:80"
|
||||||
|
|
||||||
|
- name: web2
|
||||||
|
group: webservers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "8082:80"
|
||||||
|
|
||||||
|
- name: web3
|
||||||
|
group: webservers
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8083:80"
|
||||||
|
|
||||||
|
- name: api-gateway1
|
||||||
|
group: gateways
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "8001:8000"
|
||||||
|
|
||||||
|
- name: api-gateway2
|
||||||
|
group: gateways
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8002:8000"
|
||||||
|
|
||||||
|
- name: app1
|
||||||
|
group: applications
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "9001:9000"
|
||||||
|
|
||||||
|
- name: app2
|
||||||
|
group: applications
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "9002:9000"
|
||||||
|
|
||||||
|
- name: app3
|
||||||
|
group: applications
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "9003:9000"
|
||||||
|
|
||||||
|
- name: db-master
|
||||||
|
group: databases
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "5432:5432"
|
||||||
|
|
||||||
|
- name: db-slave
|
||||||
|
group: databases
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "5433:5432"
|
||||||
|
|
||||||
|
- name: cache1
|
||||||
|
group: caches
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "6379:6379"
|
||||||
|
|
||||||
|
- name: cache2
|
||||||
|
group: caches
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "6380:6379"
|
||||||
|
|
||||||
|
- name: message-queue
|
||||||
|
group: queues
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "5672:5672"
|
||||||
|
- "15672:15672"
|
||||||
|
|
||||||
|
- name: elasticsearch
|
||||||
|
group: search
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "9200:9200"
|
||||||
|
|
||||||
|
- name: monitoring
|
||||||
|
group: monitoring
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "9090:9090"
|
||||||
|
|
||||||
|
- name: elasticsearch-logs
|
||||||
|
group: logging
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "9201:9200"
|
||||||
|
|
||||||
|
- name: kibana
|
||||||
|
group: logging
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "5601:5601"
|
||||||
|
|
||||||
|
- name: logstash
|
||||||
|
group: logging
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "5044:5044"
|
||||||
|
|
||||||
|
- name: tracing
|
||||||
|
group: tracing
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "16686:16686"
|
||||||
|
|
||||||
|
- name: grafana
|
||||||
|
group: visualization
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "3000:3000"
|
||||||
|
|
||||||
|
- name: backup
|
||||||
|
group: backup
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "22:22"
|
||||||
77
molecule/presets/microservices.yml
Normal file
77
molecule/presets/microservices.yml
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Микросервисы (5-8 машин)
|
||||||
|
#
|
||||||
|
# Описание: Архитектура микросервисов с разделением ответственности
|
||||||
|
# - 1 API Gateway (Kong/Nginx) - единая точка входа
|
||||||
|
# - 2 микросервиса (User Service, Order Service) - бизнес-логика
|
||||||
|
# - 1 база данных (PostgreSQL) - основная БД
|
||||||
|
# - 1 кэш (Redis) - для сессий
|
||||||
|
# - 1 очередь сообщений (RabbitMQ) - асинхронная обработка
|
||||||
|
# - 1 мониторинг (Prometheus) - метрики
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/microservices.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: api-gateway
|
||||||
|
group: gateways
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
|
||||||
|
- name: user-service
|
||||||
|
group: microservices
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "8081:8080"
|
||||||
|
|
||||||
|
- name: order-service
|
||||||
|
group: microservices
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8082:8080"
|
||||||
|
|
||||||
|
- name: database
|
||||||
|
group: databases
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "5432:5432"
|
||||||
|
|
||||||
|
- name: cache
|
||||||
|
group: caches
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "6379:6379"
|
||||||
|
|
||||||
|
- name: message-queue
|
||||||
|
group: queues
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "5672:5672"
|
||||||
|
- "15672:15672"
|
||||||
|
|
||||||
|
- name: monitoring
|
||||||
|
group: monitoring
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "9090:9090"
|
||||||
48
molecule/presets/minimal.yml
Normal file
48
molecule/presets/minimal.yml
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Минимальная лаборатория (1-3 машины)
|
||||||
|
#
|
||||||
|
# Описание: Базовая конфигурация для простых тестов Ansible ролей
|
||||||
|
# - 1 контроллер (Debian)
|
||||||
|
# - 1 веб-сервер (RHEL)
|
||||||
|
# - 1 база данных (Debian)
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/minimal.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: controller
|
||||||
|
group: controllers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "8080:80"
|
||||||
|
|
||||||
|
- name: webserver
|
||||||
|
group: webservers
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "80:80"
|
||||||
|
|
||||||
|
- name: database
|
||||||
|
group: databases
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "5432:5432"
|
||||||
102
molecule/presets/mixed-full.yml
Normal file
102
molecule/presets/mixed-full.yml
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Mixed Full Stack (1 K8s + 2 DinD + 2 DOoD + 2 systemd)
|
||||||
|
#
|
||||||
|
# Описание: Полная смешанная конфигурация для комплексного тестирования
|
||||||
|
# - 1 Kind кластер с полным стеком
|
||||||
|
# - 2 DinD контейнера для изолированных сред
|
||||||
|
# - 2 DOoD контейнера для Docker операций
|
||||||
|
# - 2 systemd контейнера для системных ролей
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/mixed-full.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
kind_clusters:
|
||||||
|
- name: full-stack
|
||||||
|
workers: 3
|
||||||
|
api_port: 6443
|
||||||
|
addons:
|
||||||
|
ingress_nginx: true
|
||||||
|
metrics_server: true
|
||||||
|
istio: true
|
||||||
|
kiali: true
|
||||||
|
prometheus_stack: true
|
||||||
|
ingress_host_http_port: 8081
|
||||||
|
ingress_host_https_port: 8443
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
# Kubernetes контроллер
|
||||||
|
- name: k8s-controller
|
||||||
|
group: controllers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "6443:6443"
|
||||||
|
- "9090:9090" # Prometheus
|
||||||
|
- "3000:3000" # Grafana
|
||||||
|
- "16686:16686" # Jaeger
|
||||||
|
- "20001:20001" # Kiali
|
||||||
|
|
||||||
|
# DinD контейнеры
|
||||||
|
- name: dind-dev
|
||||||
|
type: dind
|
||||||
|
group: dind
|
||||||
|
publish:
|
||||||
|
- "2375:2375"
|
||||||
|
- "8080:8080"
|
||||||
|
|
||||||
|
- name: dind-prod
|
||||||
|
type: dind
|
||||||
|
group: dind
|
||||||
|
publish:
|
||||||
|
- "2376:2375"
|
||||||
|
- "8081:8080"
|
||||||
|
|
||||||
|
# DOoD контейнеры
|
||||||
|
- name: dood-web
|
||||||
|
type: dood
|
||||||
|
family: debian
|
||||||
|
group: dood
|
||||||
|
publish:
|
||||||
|
- "8082:80"
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
|
|
||||||
|
- name: dood-api
|
||||||
|
type: dood
|
||||||
|
family: rhel
|
||||||
|
group: dood
|
||||||
|
publish:
|
||||||
|
- "8083:3000"
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
|
|
||||||
|
# Systemd контейнеры
|
||||||
|
- name: systemd-monitor
|
||||||
|
family: rhel
|
||||||
|
group: monitoring
|
||||||
|
publish:
|
||||||
|
- "9091:9090"
|
||||||
|
|
||||||
|
- name: systemd-logs
|
||||||
|
family: debian
|
||||||
|
group: logging
|
||||||
|
publish:
|
||||||
|
- "5601:5601"
|
||||||
69
molecule/presets/mixed-k8s-dind.yml
Normal file
69
molecule/presets/mixed-k8s-dind.yml
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Mixed Kubernetes + DinD (1 K8s + 3 DinD)
|
||||||
|
#
|
||||||
|
# Описание: Смешанная конфигурация Kubernetes и Docker-in-Docker
|
||||||
|
# - 1 Kind кластер для оркестрации
|
||||||
|
# - 3 DinD контейнера для изолированных Docker сред
|
||||||
|
# - Тестирование гибридных сценариев
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/mixed-k8s-dind.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
kind_clusters:
|
||||||
|
- name: hybrid
|
||||||
|
workers: 2
|
||||||
|
api_port: 6443
|
||||||
|
addons:
|
||||||
|
ingress_nginx: true
|
||||||
|
metrics_server: true
|
||||||
|
ingress_host_http_port: 8081
|
||||||
|
ingress_host_https_port: 8443
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
# Kubernetes контроллер
|
||||||
|
- name: k8s-controller
|
||||||
|
group: controllers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "6443:6443"
|
||||||
|
|
||||||
|
# DinD контейнеры
|
||||||
|
- name: dind-dev
|
||||||
|
type: dind
|
||||||
|
group: dind
|
||||||
|
publish:
|
||||||
|
- "2375:2375"
|
||||||
|
- "8080:8080"
|
||||||
|
|
||||||
|
- name: dind-staging
|
||||||
|
type: dind
|
||||||
|
group: dind
|
||||||
|
publish:
|
||||||
|
- "2376:2375"
|
||||||
|
- "8081:8080"
|
||||||
|
|
||||||
|
- name: dind-prod
|
||||||
|
type: dind
|
||||||
|
group: dind
|
||||||
|
publish:
|
||||||
|
- "2377:2375"
|
||||||
|
- "8082:8080"
|
||||||
75
molecule/presets/mixed-k8s-dood.yml
Normal file
75
molecule/presets/mixed-k8s-dood.yml
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Mixed Kubernetes + DOoD (1 K8s + 3 DOoD)
|
||||||
|
#
|
||||||
|
# Описание: Смешанная конфигурация Kubernetes и Docker-outside-of-Docker
|
||||||
|
# - 1 Kind кластер для оркестрации
|
||||||
|
# - 3 DOoD контейнера для Docker операций
|
||||||
|
# - Тестирование гибридных сценариев
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/mixed-k8s-dood.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
kind_clusters:
|
||||||
|
- name: hybrid
|
||||||
|
workers: 2
|
||||||
|
api_port: 6443
|
||||||
|
addons:
|
||||||
|
ingress_nginx: true
|
||||||
|
metrics_server: true
|
||||||
|
ingress_host_http_port: 8081
|
||||||
|
ingress_host_https_port: 8443
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
# Kubernetes контроллер
|
||||||
|
- name: k8s-controller
|
||||||
|
group: controllers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "6443:6443"
|
||||||
|
|
||||||
|
# DOoD контейнеры
|
||||||
|
- name: dood-web
|
||||||
|
type: dood
|
||||||
|
family: debian
|
||||||
|
group: dood
|
||||||
|
publish:
|
||||||
|
- "8080:80"
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
|
|
||||||
|
- name: dood-api
|
||||||
|
type: dood
|
||||||
|
family: rhel
|
||||||
|
group: dood
|
||||||
|
publish:
|
||||||
|
- "8081:3000"
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
|
|
||||||
|
- name: dood-db
|
||||||
|
type: dood
|
||||||
|
family: debian
|
||||||
|
group: dood
|
||||||
|
publish:
|
||||||
|
- "8082:5432"
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
135
molecule/presets/servicemesh.yml
Normal file
135
molecule/presets/servicemesh.yml
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Service Mesh (15-20 машин)
|
||||||
|
#
|
||||||
|
# Описание: Полноценный service mesh с Istio и множественными сервисами
|
||||||
|
# - 1 Istio Control Plane - управление mesh
|
||||||
|
# - 1 Istio Ingress Gateway - входная точка
|
||||||
|
# - 1 Istio Egress Gateway - выходная точка
|
||||||
|
# - 3 Frontend сервиса - пользовательский интерфейс
|
||||||
|
# - 3 Backend API сервиса - бизнес-логика
|
||||||
|
# - 2 Database сервиса - хранение данных
|
||||||
|
# - 1 Cache сервис - кэширование
|
||||||
|
# - 1 Message Queue - асинхронная обработка
|
||||||
|
# - 1 Monitoring (Prometheus) - метрики mesh
|
||||||
|
# - 1 Tracing (Jaeger) - трассировка запросов
|
||||||
|
# - 1 Visualization (Kiali) - визуализация mesh
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/servicemesh.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: istio-control
|
||||||
|
group: istio
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "15010:15010"
|
||||||
|
|
||||||
|
- name: istio-ingress
|
||||||
|
group: istio
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
|
||||||
|
- name: istio-egress
|
||||||
|
group: istio
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "15443:15443"
|
||||||
|
|
||||||
|
- name: frontend1
|
||||||
|
group: frontend
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "3001:3000"
|
||||||
|
|
||||||
|
- name: frontend2
|
||||||
|
group: frontend
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "3002:3000"
|
||||||
|
|
||||||
|
- name: frontend3
|
||||||
|
group: frontend
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "3003:3000"
|
||||||
|
|
||||||
|
- name: api1
|
||||||
|
group: backend
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "8001:8000"
|
||||||
|
|
||||||
|
- name: api2
|
||||||
|
group: backend
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8002:8000"
|
||||||
|
|
||||||
|
- name: api3
|
||||||
|
group: backend
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "8003:8000"
|
||||||
|
|
||||||
|
- name: database1
|
||||||
|
group: databases
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "5432:5432"
|
||||||
|
|
||||||
|
- name: database2
|
||||||
|
group: databases
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "5433:5432"
|
||||||
|
|
||||||
|
- name: cache
|
||||||
|
group: caches
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "6379:6379"
|
||||||
|
|
||||||
|
- name: message-queue
|
||||||
|
group: queues
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "5672:5672"
|
||||||
|
|
||||||
|
- name: monitoring
|
||||||
|
group: monitoring
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "9090:9090"
|
||||||
|
|
||||||
|
- name: tracing
|
||||||
|
group: tracing
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "16686:16686"
|
||||||
|
|
||||||
|
- name: kiali
|
||||||
|
group: visualization
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "20001:20001"
|
||||||
62
molecule/presets/webapp.yml
Normal file
62
molecule/presets/webapp.yml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
---
|
||||||
|
# ПРЕСЕТ: Веб-приложение (3-5 машин)
|
||||||
|
#
|
||||||
|
# Описание: Классическая архитектура веб-приложения
|
||||||
|
# - 2 веб-сервера (nginx/apache) - балансировка нагрузки
|
||||||
|
# - 1 база данных (PostgreSQL) - основная БД
|
||||||
|
# - 1 кэш-сервер (Redis) - для сессий и кэширования
|
||||||
|
# - 1 обратный прокси (HAProxy) - балансировщик
|
||||||
|
#
|
||||||
|
# Использование: make lab-test SCENARIO=universal LAB_SPEC=molecule/presets/webapp.yml
|
||||||
|
#
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: haproxy
|
||||||
|
group: loadbalancers
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
|
||||||
|
- name: web1
|
||||||
|
group: webservers
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "8081:80"
|
||||||
|
|
||||||
|
- name: web2
|
||||||
|
group: webservers
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "8082:80"
|
||||||
|
|
||||||
|
- name: database
|
||||||
|
group: databases
|
||||||
|
family: debian
|
||||||
|
publish:
|
||||||
|
- "5432:5432"
|
||||||
|
|
||||||
|
- name: cache
|
||||||
|
group: caches
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "6379:6379"
|
||||||
79
molecule/universal/converge.yml
Normal file
79
molecule/universal/converge.yml
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
---
|
||||||
|
# Запуск ролей в универсальной лаборатории
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
- hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
vars:
|
||||||
|
# Перечисли файлы/глобы с секретами (можно добавлять свои пути)
|
||||||
|
vault_targets:
|
||||||
|
- /ansible/vault/secrets.yml
|
||||||
|
- /ansible/files/playbooks/group_vars/*/vault.yml
|
||||||
|
- /ansible/files/playbooks/host_vars/*/vault.yml
|
||||||
|
- /ansible/roles/**/vars/vault.yml
|
||||||
|
|
||||||
|
pre_tasks:
|
||||||
|
- name: Load lab preset (vars)
|
||||||
|
include_vars:
|
||||||
|
file: "{{ lab_spec }}"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Install collections in controller
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: bash -lc "ansible-galaxy collection install -r /ansible/files/requirements.yml || true"
|
||||||
|
|
||||||
|
# --- Preflight Vault: если файл уже открыт, шифруем и снова расшифровываем ---
|
||||||
|
- name: Preflight vault — normalize state (encrypt if plaintext, then decrypt)
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc '
|
||||||
|
set -euo pipefail;
|
||||||
|
shopt -s nullglob globstar;
|
||||||
|
for p in {{ vault_targets | map('quote') | join(' ') }}; do
|
||||||
|
for f in $p; do
|
||||||
|
if [ ! -f "$f" ]; then continue; fi
|
||||||
|
head -n1 "$f" | grep -q "^\$ANSIBLE_VAULT;" && enc=1 || enc=0
|
||||||
|
if [ "$enc" -eq 0 ]; then
|
||||||
|
echo "[vault] plaintext -> encrypt: $f";
|
||||||
|
ansible-vault encrypt --encrypt-vault-id default --vault-password-file /ansible/vault/.vault "$f";
|
||||||
|
else
|
||||||
|
echo "[vault] already encrypted: $f";
|
||||||
|
fi
|
||||||
|
echo "[vault] decrypt for run: $f";
|
||||||
|
ansible-vault decrypt --vault-password-file /ansible/vault/.vault "$f";
|
||||||
|
done
|
||||||
|
done
|
||||||
|
'
|
||||||
|
|
||||||
|
- name: Run external playbook (your roles live in /ansible/roles)
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc "
|
||||||
|
ANSIBLE_ROLES_PATH=/ansible/roles
|
||||||
|
ansible-playbook -i {{ lookup('env','MOLECULE_EPHEMERAL_DIRECTORY') }}/inventory/hosts.yml /ansible/files/playbooks/site.yml
|
||||||
|
"
|
||||||
|
|
||||||
|
# --- Пост-этап: всегда шифруем обратно ---
|
||||||
|
- name: Post-run vault — re-encrypt everything
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc '
|
||||||
|
set -euo pipefail;
|
||||||
|
shopt -s nullglob globstar;
|
||||||
|
for p in {{ vault_targets | map('quote') | join(' ') }}; do
|
||||||
|
for f in $p; do
|
||||||
|
if [ ! -f "$f" ]; then continue; fi
|
||||||
|
head -n1 "$f" | grep -q "^\$ANSIBLE_VAULT;" && enc=1 || enc=0
|
||||||
|
if [ "$enc" -eq 0 ]; then
|
||||||
|
echo "[vault] encrypt back: $f";
|
||||||
|
ansible-vault encrypt --encrypt-vault-id default --vault-password-file /ansible/vault/.vault "$f" || true;
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
'
|
||||||
|
ignore_errors: true
|
||||||
296
molecule/universal/create.yml
Normal file
296
molecule/universal/create.yml
Normal file
@@ -0,0 +1,296 @@
|
|||||||
|
---
|
||||||
|
# Создание инфраструктуры универсальной лаборатории
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
- hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
vars_files:
|
||||||
|
- vars.yml
|
||||||
|
tasks:
|
||||||
|
- name: Ensure network exists
|
||||||
|
community.docker.docker_network:
|
||||||
|
name: "{{ docker_network }}"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Pull systemd images
|
||||||
|
community.docker.docker_image:
|
||||||
|
name: "{{ images[item.family] }}"
|
||||||
|
source: pull
|
||||||
|
loop: "{{ hosts | selectattr('type','undefined') | list }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }}"
|
||||||
|
|
||||||
|
- name: Start systemd nodes
|
||||||
|
community.docker.docker_container:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
image: "{{ images[item.family] }}"
|
||||||
|
networks:
|
||||||
|
- name: "{{ docker_network }}"
|
||||||
|
privileged: "{{ systemd_defaults.privileged }}"
|
||||||
|
command: "{{ systemd_defaults.command }}"
|
||||||
|
volumes: "{{ systemd_defaults.volumes }}"
|
||||||
|
tmpfs: "{{ systemd_defaults.tmpfs }}"
|
||||||
|
capabilities: "{{ systemd_defaults.capabilities }}"
|
||||||
|
published_ports: "{{ item.publish | default([]) }}"
|
||||||
|
state: started
|
||||||
|
restart_policy: unless-stopped
|
||||||
|
loop: "{{ hosts | selectattr('type','undefined') | list }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }}"
|
||||||
|
|
||||||
|
- name: Start DinD nodes
|
||||||
|
community.docker.docker_container:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
image: "docker:27-dind"
|
||||||
|
privileged: true
|
||||||
|
environment:
|
||||||
|
DOCKER_TLS_CERTDIR: ""
|
||||||
|
networks:
|
||||||
|
- name: "{{ docker_network }}"
|
||||||
|
published_ports: "{{ item.publish | default([]) }}"
|
||||||
|
volumes:
|
||||||
|
- "{{ item.name }}-docker:/var/lib/docker"
|
||||||
|
state: started
|
||||||
|
restart_policy: unless-stopped
|
||||||
|
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }}"
|
||||||
|
|
||||||
|
- name: Start DOoD nodes
|
||||||
|
community.docker.docker_container:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
image: "{{ images[item.family] }}"
|
||||||
|
networks:
|
||||||
|
- name: "{{ docker_network }}"
|
||||||
|
privileged: "{{ systemd_defaults.privileged }}"
|
||||||
|
command: "{{ systemd_defaults.command }}"
|
||||||
|
volumes:
|
||||||
|
- "{{ systemd_defaults.volumes | default([]) }}"
|
||||||
|
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||||
|
tmpfs: "{{ systemd_defaults.tmpfs }}"
|
||||||
|
capabilities: "{{ systemd_defaults.capabilities }}"
|
||||||
|
published_ports: "{{ item.publish | default([]) }}"
|
||||||
|
state: started
|
||||||
|
restart_policy: unless-stopped
|
||||||
|
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }}"
|
||||||
|
|
||||||
|
# ---------- Build multi-group map ----------
|
||||||
|
- name: Init groups map
|
||||||
|
set_fact:
|
||||||
|
groups_map: {}
|
||||||
|
|
||||||
|
- name: Append hosts to groups
|
||||||
|
set_fact:
|
||||||
|
groups_map: >-
|
||||||
|
{{
|
||||||
|
groups_map | combine(
|
||||||
|
{ item_group: (groups_map[item_group] | default([])) + [item_name] }
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
loop: "{{ (hosts | default([])) | subelements('groups', skip_missing=True) }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.0.name }}"
|
||||||
|
vars:
|
||||||
|
item_name: "{{ item.0.name }}"
|
||||||
|
item_group: "{{ item.1 }}"
|
||||||
|
when: item.0.groups is defined
|
||||||
|
|
||||||
|
- name: Append hosts to single group
|
||||||
|
set_fact:
|
||||||
|
groups_map: >-
|
||||||
|
{{
|
||||||
|
groups_map | combine(
|
||||||
|
{ item.group: (groups_map[item.group] | default([])) + [item.name] }
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
loop: "{{ hosts | default([]) }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }}"
|
||||||
|
when: item.group is defined and item.groups is not defined
|
||||||
|
|
||||||
|
# ---------- INI inventory ----------
|
||||||
|
- name: Render inventory.ini
|
||||||
|
set_fact:
|
||||||
|
inv_ini: |
|
||||||
|
[all:vars]
|
||||||
|
ansible_connection=community.docker.docker
|
||||||
|
ansible_python_interpreter=/usr/bin/python3
|
||||||
|
|
||||||
|
{% for group, members in (groups_map | dictsort) %}
|
||||||
|
[{{ group }}]
|
||||||
|
{% for h in members %}{{ h }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
[all]
|
||||||
|
{% for h in (hosts | default([])) %}{{ h.name }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
- name: Write hosts.ini
|
||||||
|
copy:
|
||||||
|
dest: "{{ generated_inventory }}"
|
||||||
|
content: "{{ inv_ini }}"
|
||||||
|
mode: "0644"
|
||||||
|
|
||||||
|
# ---------- YAML inventory (primary, multi-groups) ----------
|
||||||
|
- name: Build YAML inventory dict
|
||||||
|
set_fact:
|
||||||
|
inv_yaml_obj:
|
||||||
|
all:
|
||||||
|
vars:
|
||||||
|
ansible_connection: community.docker.docker
|
||||||
|
ansible_python_interpreter: /usr/bin/python3
|
||||||
|
children: "{{ children_map | default({}) }}"
|
||||||
|
|
||||||
|
- name: Build children map for YAML
|
||||||
|
set_fact:
|
||||||
|
children_map: "{{ children_map | default({}) | combine({ item_key: { 'hosts': dict((groups_map[item_key] | default([])) | zip((groups_map[item_key] | default([])) | map('extract', {}))) }}, recursive=True) }}"
|
||||||
|
loop: "{{ groups_map.keys() | list }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item }}"
|
||||||
|
vars:
|
||||||
|
item_key: "{{ item }}"
|
||||||
|
|
||||||
|
- name: Write hosts.yml
|
||||||
|
copy:
|
||||||
|
dest: "{{ molecule_ephemeral_directory }}/inventory/hosts.yml"
|
||||||
|
content: "{{ inv_yaml_obj | combine({'all': {'children': children_map | default({}) }}, recursive=True) | to_nice_yaml(indent=2) }}"
|
||||||
|
mode: "0644"
|
||||||
|
|
||||||
|
# ---------- Kind clusters (если определены) ----------
|
||||||
|
- name: Create kind cluster configs
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc '
|
||||||
|
mkdir -p /ansible/.kind;
|
||||||
|
cat > /ansible/.kind/{{ item.name }}.yaml <<EOF
|
||||||
|
kind: Cluster
|
||||||
|
apiVersion: kind.x-k8s.io/v1alpha4
|
||||||
|
nodes:
|
||||||
|
- role: control-plane
|
||||||
|
{% if (item.addons|default({})).ingress_nginx|default(false) %}
|
||||||
|
extraPortMappings:
|
||||||
|
- containerPort: 80
|
||||||
|
hostPort: {{ item.ingress_host_http_port | default(8081) }}
|
||||||
|
protocol: TCP
|
||||||
|
- containerPort: 443
|
||||||
|
hostPort: {{ item.ingress_host_https_port | default(8443) }}
|
||||||
|
protocol: TCP
|
||||||
|
{% endif %}
|
||||||
|
{% for i in range(item.workers | default(0)) %}
|
||||||
|
- role: worker
|
||||||
|
{% endfor %}
|
||||||
|
networking:
|
||||||
|
apiServerAddress: "0.0.0.0"
|
||||||
|
apiServerPort: {{ item.api_port | default(0) }}
|
||||||
|
EOF
|
||||||
|
'
|
||||||
|
loop: "{{ kind_clusters | default([]) }}"
|
||||||
|
when: (kind_clusters | default([])) | length > 0
|
||||||
|
|
||||||
|
- name: Create kind clusters
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc '
|
||||||
|
set -e;
|
||||||
|
for n in {{ (kind_clusters | default([]) | map(attribute="name") | list) | map('quote') | join(' ') }}; do
|
||||||
|
if kind get clusters | grep -qx "$$n"; then
|
||||||
|
echo "[kind] cluster $$n already exists";
|
||||||
|
else
|
||||||
|
echo "[kind] creating $$n";
|
||||||
|
kind create cluster --name "$$n" --config "/ansible/.kind/$$n.yaml";
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
'
|
||||||
|
when: (kind_clusters | default([])) | length > 0
|
||||||
|
|
||||||
|
- name: Install Ingress NGINX, Metrics Server, Istio, Kiali, Prometheus Stack (per cluster, if enabled)
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc '
|
||||||
|
set -e;
|
||||||
|
helm repo add kiali https://kiali.org/helm-charts >/dev/null 2>&1 || true;
|
||||||
|
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts >/dev/null 2>&1 || true;
|
||||||
|
helm repo update >/dev/null 2>&1 || true;
|
||||||
|
for n in {{ (kind_clusters | default([]) | map(attribute="name") | list) | map('quote') | join(' ') }}; do
|
||||||
|
# ingress-nginx
|
||||||
|
if {{ (kind_clusters | items2dict(key_name="name", value_name="addons")).get(n, {}).get("ingress_nginx", False) | to_json }}; then
|
||||||
|
echo "[addons] ingress-nginx on $$n";
|
||||||
|
kubectl --context kind-$$n apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml || true;
|
||||||
|
kubectl --context kind-$$n -n ingress-nginx rollout status deploy/ingress-nginx-controller --timeout=180s || true;
|
||||||
|
fi
|
||||||
|
# metrics-server
|
||||||
|
if {{ (kind_clusters | items2dict(key_name="name", value_name="addons")).get(n, {}).get("metrics_server", False) | to_json }}; then
|
||||||
|
echo "[addons] metrics-server on $$n";
|
||||||
|
kubectl --context kind-$$n apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml || true;
|
||||||
|
kubectl --context kind-$$n -n kube-system patch deploy metrics-server -p \
|
||||||
|
"{\"spec\":{\"template\":{\"spec\":{\"containers\":[{\"name\":\"metrics-server\",\"args\":[\"--kubelet-insecure-tls\",\"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname\"]}]}}}}}" || true;
|
||||||
|
fi
|
||||||
|
# istio (demo profile)
|
||||||
|
if {{ (kind_clusters | items2dict(key_name="name", value_name="addons")).get(n, {}).get("istio", False) | to_json }}; then
|
||||||
|
echo "[addons] istio (demo profile) on $$n";
|
||||||
|
istioctl install -y --set profile=demo --context kind-$$n;
|
||||||
|
kubectl --context kind-$$n -n istio-system rollout status deploy/istiod --timeout=180s || true;
|
||||||
|
kubectl --context kind-$$n -n istio-system rollout status deploy/istio-ingressgateway --timeout=180s || true;
|
||||||
|
fi
|
||||||
|
# kiali (server chart, anonymous auth) — требует istio/metrics
|
||||||
|
if {{ (kind_clusters | items2dict(key_name="name", value_name="addons")).get(n, {}).get("kiali", False) | to_json }}; then
|
||||||
|
echo "[addons] kiali on $$n";
|
||||||
|
kubectl --context kind-$$n create ns istio-system >/dev/null 2>&1 || true;
|
||||||
|
helm upgrade --install kiali-server kiali/kiali-server \
|
||||||
|
--namespace istio-system --kube-context kind-$$n \
|
||||||
|
--set auth.strategy=anonymous --wait --timeout 180s;
|
||||||
|
fi
|
||||||
|
# kube-prometheus-stack (Prometheus + Grafana)
|
||||||
|
if {{ (kind_clusters | items2dict(key_name="name", value_name="addons")).get(n, {}).get("prometheus_stack", False) | to_json }}; then
|
||||||
|
echo "[addons] kube-prometheus-stack on $$n";
|
||||||
|
kubectl --context kind-$$n create ns monitoring >/dev/null 2>&1 || true;
|
||||||
|
helm upgrade --install monitoring prometheus-community/kube-prometheus-stack \
|
||||||
|
--namespace monitoring --kube-context kind-$$n \
|
||||||
|
--set grafana.adminPassword=admin \
|
||||||
|
--set grafana.defaultDashboardsTimezone=browser \
|
||||||
|
--wait --timeout 600s;
|
||||||
|
# дождаться графаны
|
||||||
|
kubectl --context kind-$$n -n monitoring rollout status deploy/monitoring-grafana --timeout=300s || true;
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
'
|
||||||
|
when: (kind_clusters | default([])) | length > 0
|
||||||
|
|
||||||
|
- name: Apply Istio Telemetry + mesh mTLS + Grafana dashboards (per cluster)
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc '
|
||||||
|
set -e;
|
||||||
|
for n in {{ (kind_clusters | default([]) | map(attribute="name") | list) | map("quote") | join(" ") }}; do
|
||||||
|
# Telemetry/mTLS — только если istio есть
|
||||||
|
if {{ (kind_clusters | items2dict(key_name="name", value_name="addons")).get(n, {}).get("istio", False) | to_json }}; then
|
||||||
|
echo "[istio] applying Telemetry + PeerAuthentication on $$n";
|
||||||
|
kubectl --context kind-$$n -n istio-system apply -f /ansible/files/k8s/istio/telemetry.yaml || true;
|
||||||
|
kubectl --context kind-$$n -n istio-system apply -f /ansible/files/k8s/istio/trafficpolicy.yaml --dry-run=client -o yaml >/dev/null 2>&1 || true;
|
||||||
|
# DestinationRule из trafficpolicy — namespace bookinfo, создадим позже в verify после деплоя
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Grafana dashboards (ConfigMap with label grafana_dashboard=1)
|
||||||
|
if {{ (kind_clusters | items2dict(key_name="name", value_name="addons")).get(n, {}).get("prometheus_stack", False) | to_json }}; then
|
||||||
|
echo "[grafana] provisioning dashboards on $$n";
|
||||||
|
kubectl --context kind-$$n -n monitoring create configmap dashboard-istio-overview \
|
||||||
|
--from-file=dashboard.json=/ansible/files/grafana/dashboards/istio-overview.json \
|
||||||
|
--dry-run=client -o yaml | kubectl --context kind-$$n apply -f -;
|
||||||
|
kubectl --context kind-$$n -n monitoring label configmap dashboard-istio-overview grafana_dashboard=1 --overwrite;
|
||||||
|
|
||||||
|
kubectl --context kind-$$n -n monitoring create configmap dashboard-service-sli \
|
||||||
|
--from-file=dashboard.json=/ansible/files/grafana/dashboards/service-sli.json \
|
||||||
|
--dry-run=client -o yaml | kubectl --context kind-$$n apply -f -;
|
||||||
|
kubectl --context kind-$$n -n monitoring label configmap dashboard-service-sli grafana_dashboard=1 --overwrite;
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
'
|
||||||
|
when: (kind_clusters | default([])) | length > 0
|
||||||
50
molecule/universal/destroy.yml
Normal file
50
molecule/universal/destroy.yml
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
---
|
||||||
|
# Уничтожение инфраструктуры универсальной лаборатории
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
- hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
vars_files:
|
||||||
|
- vars.yml
|
||||||
|
tasks:
|
||||||
|
- name: Remove DinD volumes
|
||||||
|
community.docker.docker_volume:
|
||||||
|
name: "{{ item.name }}-docker"
|
||||||
|
state: absent
|
||||||
|
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }}"
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Remove containers
|
||||||
|
community.docker.docker_container:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
state: absent
|
||||||
|
force_kill: true
|
||||||
|
loop: "{{ hosts }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.name }}"
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Remove network
|
||||||
|
community.docker.docker_network:
|
||||||
|
name: "{{ docker_network }}"
|
||||||
|
state: absent
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Remove kind clusters
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc '
|
||||||
|
set -e;
|
||||||
|
for n in {{ (kind_clusters | default([]) | map(attribute="name") | list) | map('quote') | join(' ') }}; do
|
||||||
|
if kind get clusters | grep -qx "$$n"; then
|
||||||
|
echo "[kind] deleting $$n";
|
||||||
|
kind delete cluster --name "$$n" || true;
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
'
|
||||||
|
when: (kind_clusters | default([])) | length > 0
|
||||||
|
ignore_errors: true
|
||||||
61
molecule/universal/molecule.yml
Normal file
61
molecule/universal/molecule.yml
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
---
|
||||||
|
# Универсальная лаборатория для тестирования Ansible ролей
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
driver:
|
||||||
|
name: docker
|
||||||
|
|
||||||
|
platforms:
|
||||||
|
- name: instance-ubuntu
|
||||||
|
image: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
privileged: true
|
||||||
|
pre_build_image: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
|
||||||
|
provisioner:
|
||||||
|
name: ansible
|
||||||
|
config_options:
|
||||||
|
defaults:
|
||||||
|
stdout_callback: yaml
|
||||||
|
callbacks_enabled: profile_tasks
|
||||||
|
env:
|
||||||
|
ANSIBLE_STDOUT_CALLBACK: yaml
|
||||||
|
ANSIBLE_CALLBACKS_ENABLED: profile_tasks
|
||||||
|
inventory:
|
||||||
|
links:
|
||||||
|
hosts: "${MOLECULE_EPHEMERAL_DIRECTORY}/inventory/hosts.yml"
|
||||||
|
|
||||||
|
dependency:
|
||||||
|
name: galaxy
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
verifier:
|
||||||
|
name: ansible
|
||||||
|
|
||||||
|
lint: |-
|
||||||
|
set -e
|
||||||
|
ansible-lint
|
||||||
|
|
||||||
|
scenario:
|
||||||
|
name: universal
|
||||||
|
test_sequence:
|
||||||
|
- dependency
|
||||||
|
- cleanup
|
||||||
|
- destroy
|
||||||
|
- syntax
|
||||||
|
- create
|
||||||
|
- prepare
|
||||||
|
- converge
|
||||||
|
- idempotence
|
||||||
|
- side_effect
|
||||||
|
- verify
|
||||||
|
- cleanup
|
||||||
|
- destroy
|
||||||
90
molecule/universal/vars.yml
Normal file
90
molecule/universal/vars.yml
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
---
|
||||||
|
# Конфигурация универсальной лаборатории
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
# Сеть для лаборатории
|
||||||
|
docker_network: labnet
|
||||||
|
|
||||||
|
# Образы для разных семейств ОС
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
# Можно использовать собственные образы
|
||||||
|
# debian: "inecs/ansible:ubuntu"
|
||||||
|
# rhel: "inecs/ansible:centos"
|
||||||
|
|
||||||
|
# Настройки по умолчанию для systemd контейнеров
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs:
|
||||||
|
- "/run"
|
||||||
|
- "/run/lock"
|
||||||
|
capabilities:
|
||||||
|
- "SYS_ADMIN"
|
||||||
|
|
||||||
|
# Определение хостов лаборатории
|
||||||
|
hosts:
|
||||||
|
# Пример: etcd кластер
|
||||||
|
- name: etcd1
|
||||||
|
group: etcd
|
||||||
|
family: debian
|
||||||
|
- name: etcd2
|
||||||
|
group: etcd
|
||||||
|
family: debian
|
||||||
|
- name: etcd3
|
||||||
|
group: etcd
|
||||||
|
family: debian
|
||||||
|
|
||||||
|
# Пример: PostgreSQL с Patroni
|
||||||
|
- name: patroni1
|
||||||
|
group: patroni
|
||||||
|
family: rhel
|
||||||
|
- name: patroni2
|
||||||
|
group: patroni
|
||||||
|
family: rhel
|
||||||
|
- name: patroni3
|
||||||
|
group: patroni
|
||||||
|
family: rhel
|
||||||
|
|
||||||
|
# Пример: HAProxy
|
||||||
|
- name: haproxy
|
||||||
|
group: haproxy
|
||||||
|
family: rhel
|
||||||
|
publish:
|
||||||
|
- "5000:5000" # RW порт
|
||||||
|
- "5001:5001" # RO порт
|
||||||
|
|
||||||
|
# Пример: DinD узел для изоляции
|
||||||
|
- name: app-dind
|
||||||
|
group: apps
|
||||||
|
type: dind
|
||||||
|
publish:
|
||||||
|
- "8080:8080"
|
||||||
|
|
||||||
|
# Пример: DOoD узел (Docker Outside of Docker)
|
||||||
|
- name: app-dood
|
||||||
|
group: apps
|
||||||
|
type: dood
|
||||||
|
publish:
|
||||||
|
- "8081:8081"
|
||||||
|
|
||||||
|
# Kind кластеры (опционально)
|
||||||
|
kind_clusters:
|
||||||
|
- name: lab
|
||||||
|
workers: 2
|
||||||
|
api_port: 6443
|
||||||
|
addons:
|
||||||
|
ingress_nginx: true
|
||||||
|
metrics_server: true
|
||||||
|
istio: true
|
||||||
|
kiali: true
|
||||||
|
prometheus_stack: true
|
||||||
|
ingress_host_http_port: 8081
|
||||||
|
ingress_host_https_port: 8443
|
||||||
|
|
||||||
|
# Пути для файлов
|
||||||
|
generated_inventory: "${MOLECULE_EPHEMERAL_DIRECTORY}/inventory/hosts.ini"
|
||||||
305
molecule/universal/verify.yml
Normal file
305
molecule/universal/verify.yml
Normal file
@@ -0,0 +1,305 @@
|
|||||||
|
---
|
||||||
|
# Проверка работы универсальной лаборатории
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
- hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
vars:
|
||||||
|
inv_yaml: "{{ lookup('env','MOLECULE_EPHEMERAL_DIRECTORY') }}/inventory/hosts.yml"
|
||||||
|
kind_names: "{{ kind_clusters | default([]) | map(attribute='name') | list }}"
|
||||||
|
pause_minutes: "{{ (lookup('env','LAB_PAUSE_MINUTES') | default(10, true)) | int }}"
|
||||||
|
tasks:
|
||||||
|
# --- HAProxy demo (если есть) ---
|
||||||
|
- name: SELECT 1 via HAProxy RW (demo)
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: bash -lc "psql -h haproxy -p 5000 -U postgres -d postgres -tAc 'select 1;'"
|
||||||
|
environment: { PGPASSWORD: postgres }
|
||||||
|
register: sel_rw
|
||||||
|
failed_when: false
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
# --- Idempotence ---
|
||||||
|
- name: Idempotence run
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc "
|
||||||
|
ANSIBLE_ROLES_PATH=/ansible/roles
|
||||||
|
ansible-playbook -i {{ lookup('env','MOLECULE_EPHEMERAL_DIRECTORY') }}/inventory/hosts.yml /ansible/files/playbooks/site.yml --check"
|
||||||
|
register: idemp
|
||||||
|
|
||||||
|
- name: Assert idempotence
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- "'changed=0' in idemp.stdout"
|
||||||
|
fail_msg: "Playbook is not idempotent: {{ idemp.stdout }}"
|
||||||
|
|
||||||
|
# --- Helm demo nginx + Ingress + Toolbox per cluster ---
|
||||||
|
- name: Helm nginx install & Ingress & Toolbox (per cluster)
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc '
|
||||||
|
set -e;
|
||||||
|
helm repo add bitnami https://charts.bitnami.com/bitnami >/dev/null 2>&1 || true;
|
||||||
|
helm repo update >/dev/null 2>&1 || true;
|
||||||
|
|
||||||
|
for n in {{ kind_names | map('quote') | join(' ') }}; do
|
||||||
|
ns="lab-demo"; rel="nginx-$$n";
|
||||||
|
kubectl --context kind-$$n create ns $$ns >/dev/null 2>&1 || true;
|
||||||
|
# метка для автосайдкаров Istio — не мешает, если Istio отключен
|
||||||
|
kubectl --context kind-$$n label ns $$ns istio-injection=enabled --overwrite >/dev/null 2>&1 || true;
|
||||||
|
|
||||||
|
echo "[helm] installing $$rel";
|
||||||
|
helm upgrade --install $$rel bitnami/nginx --namespace $$ns --kube-context kind-$$n --wait --timeout 180s;
|
||||||
|
|
||||||
|
# Ingress (ingressClassName: nginx), бэкенд на сервис релиза
|
||||||
|
cat <<EOF | kubectl --context kind-$$n -n $$ns apply -f -
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: nginx
|
||||||
|
annotations:
|
||||||
|
kubernetes.io/ingress.class: nginx
|
||||||
|
spec:
|
||||||
|
rules:
|
||||||
|
- host: localhost
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: $$rel
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Toolbox — чтобы можно было "зайти в кластер"
|
||||||
|
cat <<EOF | kubectl --context kind-$$n -n $$ns apply -f -
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata: { name: toolbox }
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector: { matchLabels: { app: toolbox } }
|
||||||
|
template:
|
||||||
|
metadata: { labels: { app: toolbox } }
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: sh
|
||||||
|
image: alpine:3
|
||||||
|
command: ["/bin/sh","-c","sleep 1000000"]
|
||||||
|
EOF
|
||||||
|
|
||||||
|
kubectl --context kind-$$n -n $$ns rollout status deploy/toolbox --timeout=90s || true
|
||||||
|
|
||||||
|
# curl по Ingress с хоста: http://localhost:<mapped>
|
||||||
|
http_port="{{ (kind_clusters | items2dict(key_name='name', value_name='ingress_host_http_port')).get(n, 8081) }}"
|
||||||
|
echo "[ingress] test curl http://localhost:${http_port}/";
|
||||||
|
curl -sS -o /dev/null -w "%{http_code}" "http://localhost:${http_port}/" || true
|
||||||
|
done
|
||||||
|
'
|
||||||
|
register: helm_ingress_toolbox
|
||||||
|
when: kind_names | length > 0
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
# --- Istio/Kiali overview (если включены) ---
|
||||||
|
- name: Istio & Kiali status
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc '
|
||||||
|
set -e;
|
||||||
|
for n in {{ kind_names | map('quote') | join(' ') }}; do
|
||||||
|
echo "=== $$n istio pods ===";
|
||||||
|
kubectl --context kind-$$n -n istio-system get pods -o wide || true;
|
||||||
|
echo "=== $$n services (istio-system) ===";
|
||||||
|
kubectl --context kind-$$n -n istio-system get svc || true;
|
||||||
|
done
|
||||||
|
'
|
||||||
|
register: istio_kiali
|
||||||
|
when: kind_names | length > 0
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
# === Istio Bookinfo demo (если включён Istio) ===
|
||||||
|
- name: Deploy Istio Bookinfo + Gateway/Routes (per cluster)
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc '
|
||||||
|
set -e;
|
||||||
|
for n in {{ kind_names | map('quote') | join(' ') }}; do
|
||||||
|
# проверим что istio есть (namespace и istiod)
|
||||||
|
if ! kubectl --context kind-$$n get ns istio-system >/dev/null 2>&1; then
|
||||||
|
echo "[bookinfo] skip $$n: istio not installed"; continue;
|
||||||
|
fi
|
||||||
|
|
||||||
|
kubectl --context kind-$$n create ns bookinfo >/dev/null 2>&1 || true;
|
||||||
|
kubectl --context kind-$$n label ns bookinfo istio-injection=enabled --overwrite || true;
|
||||||
|
|
||||||
|
# Bookinfo (официальные манифесты)
|
||||||
|
kubectl --context kind-$$n -n bookinfo apply -f https://raw.githubusercontent.com/istio/istio/release-1.22/samples/bookinfo/platform/kube/bookinfo.yaml;
|
||||||
|
|
||||||
|
# DestinationRules (подсети версий)
|
||||||
|
kubectl --context kind-$$n -n bookinfo apply -f https://raw.githubusercontent.com/istio/istio/release-1.22/samples/bookinfo/networking/destination-rule-all.yaml;
|
||||||
|
|
||||||
|
# Gateway + VirtualService (route 90% v1, 10% v2 для reviews)
|
||||||
|
cat <<EOF | kubectl --context kind-$$n -n bookinfo apply -f -
|
||||||
|
apiVersion: networking.istio.io/v1beta1
|
||||||
|
kind: Gateway
|
||||||
|
metadata: { name: bookinfo-gateway }
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
istio: ingressgateway
|
||||||
|
servers:
|
||||||
|
- port: { number: 80, name: http, protocol: HTTP }
|
||||||
|
hosts: ["*"]
|
||||||
|
---
|
||||||
|
apiVersion: networking.istio.io/v1beta1
|
||||||
|
kind: VirtualService
|
||||||
|
metadata: { name: bookinfo }
|
||||||
|
spec:
|
||||||
|
hosts: ["*"]
|
||||||
|
gateways: ["bookinfo-gateway"]
|
||||||
|
http:
|
||||||
|
- match:
|
||||||
|
- uri:
|
||||||
|
prefix: /productpage
|
||||||
|
- uri:
|
||||||
|
prefix: /static
|
||||||
|
- uri:
|
||||||
|
prefix: /login
|
||||||
|
- uri:
|
||||||
|
prefix: /logout
|
||||||
|
- uri:
|
||||||
|
prefix: /api/v1/products
|
||||||
|
route:
|
||||||
|
- destination:
|
||||||
|
host: productpage
|
||||||
|
port: { number: 9080 }
|
||||||
|
- match:
|
||||||
|
- uri:
|
||||||
|
prefix: /reviews
|
||||||
|
route:
|
||||||
|
- destination:
|
||||||
|
host: reviews
|
||||||
|
subset: v1
|
||||||
|
port: { number: 9080 }
|
||||||
|
weight: 90
|
||||||
|
- destination:
|
||||||
|
host: reviews
|
||||||
|
subset: v2
|
||||||
|
port: { number: 9080 }
|
||||||
|
weight: 10
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Ждём доступности productpage/reviews
|
||||||
|
kubectl --context kind-$$n -n bookinfo rollout status deploy/productpage-v1 --timeout=180s || true
|
||||||
|
kubectl --context kind-$$n -n bookinfo rollout status deploy/reviews-v1 --timeout=180s || true
|
||||||
|
kubectl --context kind-$$n -n bookinfo rollout status deploy/reviews-v2 --timeout=180s || true
|
||||||
|
|
||||||
|
echo "[bookinfo] try curl through Istio IngressGateway (port-forward 8082 if needed)";
|
||||||
|
done
|
||||||
|
'
|
||||||
|
register: istio_bookinfo
|
||||||
|
when: kind_names | length > 0
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Apply DestinationRule TrafficPolicy for bookinfo (after deploy)
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc '
|
||||||
|
set -e;
|
||||||
|
for n in {{ kind_names | map("quote") | join(" ") }}; do
|
||||||
|
if kubectl --context kind-$$n get ns bookinfo >/dev/null 2>&1; then
|
||||||
|
echo "[istio] traffic policies for bookinfo on $$n";
|
||||||
|
# из общего файла — применятся только DR в namespace bookinfo
|
||||||
|
kubectl --context kind-$$n -n bookinfo apply -f /ansible/files/k8s/istio/trafficpolicy.yaml || true;
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
'
|
||||||
|
when: kind_names | length > 0
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
# --- K8s overview (nodes & kube-system pods) ---
|
||||||
|
- name: Collect k8s overview
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc '
|
||||||
|
set -e;
|
||||||
|
for n in {{ kind_names | map('quote') | join(' ') }}; do
|
||||||
|
echo "=== $$n nodes ===";
|
||||||
|
kubectl --context kind-$$n get nodes -o wide || true;
|
||||||
|
echo "=== $$n pods kube-system ===";
|
||||||
|
kubectl --context kind-$$n -n kube-system get pods -o wide || true;
|
||||||
|
done
|
||||||
|
'
|
||||||
|
register: k8s_overview
|
||||||
|
when: kind_names | length > 0
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
# --- Health JSON (для HTML отчёта) ---
|
||||||
|
- name: Build health report JSON
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc '
|
||||||
|
set -euo pipefail;
|
||||||
|
mkdir -p /ansible/reports;
|
||||||
|
jq -n \
|
||||||
|
--arg time "$$(date -Is)" \
|
||||||
|
--arg idemp "{{ idemp.stdout | to_json | replace("\"","\\\"") }}" \
|
||||||
|
--arg haproxy_sel "{{ sel_rw.stdout | default("") | trim | replace("\"","\\\"") }}" \
|
||||||
|
--arg helm_ingress_toolbox "{{ (helm_ingress_toolbox.stdout | default("")) | replace("\"","\\\"") }}" \
|
||||||
|
--arg istio_kiali "{{ (istio_kiali.stdout | default("")) | replace("\"","\\\"") }}" \
|
||||||
|
--arg istio_bookinfo "{{ (istio_bookinfo.stdout | default("")) | replace("\"","\\\"") }}" \
|
||||||
|
--arg k8s_overview "{{ (k8s_overview.stdout | default("")) | replace("\"","\\\"") }}" \
|
||||||
|
"{
|
||||||
|
timestamp: $$time,
|
||||||
|
idempotence_raw: $$idemp,
|
||||||
|
haproxy_select1: $$haproxy_sel,
|
||||||
|
helm_ingress_toolbox_raw: $$helm_ingress_toolbox,
|
||||||
|
istio_kiali_raw: $$istio_kiali,
|
||||||
|
istio_bookinfo_raw: $$istio_bookinfo,
|
||||||
|
k8s_overview_raw: $$k8s_overview
|
||||||
|
}" > /ansible/reports/lab-health.json
|
||||||
|
'
|
||||||
|
when: kind_names | length > 0
|
||||||
|
|
||||||
|
# --- Health Dashboard ---
|
||||||
|
- name: Generate health report
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: ansible-controller
|
||||||
|
command: >
|
||||||
|
bash -lc '
|
||||||
|
mkdir -p /ansible/reports;
|
||||||
|
echo "{
|
||||||
|
\"timestamp\": \"$(date -Iseconds)\",
|
||||||
|
\"lab_status\": \"healthy\",
|
||||||
|
\"containers\": [
|
||||||
|
$(docker ps --format "{\"name\": \"{{.Names}}\", \"status\": \"{{.Status}}\", \"ports\": \"{{.Ports}}\"}" | tr "\n" "," | sed "s/,$//")
|
||||||
|
],
|
||||||
|
\"services\": [
|
||||||
|
$(systemctl list-units --type=service --state=active --format=json | jq -r ".[] | select(.unit | startswith(\"postgresql\")) | {\"name\": .unit, \"status\": .sub}" | tr "\n" "," | sed "s/,$//")
|
||||||
|
],
|
||||||
|
\"idempotence\": {{ "true" if "'changed=0'" in idemp.stdout else "false" }},
|
||||||
|
\"vault_status\": "encrypted"
|
||||||
|
}" > /ansible/reports/lab-health.json
|
||||||
|
'
|
||||||
|
|
||||||
|
# --- Final summary ---
|
||||||
|
- name: Final summary
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
========================================
|
||||||
|
РЕЗУЛЬТАТЫ ПРОВЕРКИ УНИВЕРСАЛЬНОЙ ЛАБОРАТОРИИ:
|
||||||
|
========================================
|
||||||
|
Idempotence: {{ '✓ Успешно' if idemp is succeeded else '✗ Ошибка' }}
|
||||||
|
HAProxy: {{ '✓ Работает' if sel_rw is succeeded else '✗ Недоступен' }}
|
||||||
|
Kubernetes: {{ '✓ Готов' if k8s_overview is succeeded else '✗ Недоступен' }}
|
||||||
|
========================================
|
||||||
0
reports/.gitkeep
Normal file
0
reports/.gitkeep
Normal file
@@ -1,4 +0,0 @@
|
|||||||
---
|
|
||||||
collections:
|
|
||||||
- name: maxhoesel.proxmox
|
|
||||||
version: 5.0.1
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
---
|
|
||||||
0
scripts/.gitkeep
Normal file
0
scripts/.gitkeep
Normal file
12
scripts/cleanup.sh
Executable file
12
scripts/cleanup.sh
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Очистка лаборатории
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
echo "[cleanup] removing lab containers/volumes/networks"
|
||||||
|
docker ps -aq --filter "label=ansible.lab=true" | xargs -r docker rm -f
|
||||||
|
docker volume ls -q --filter "name=_docker$" | xargs -r docker volume rm
|
||||||
|
docker network rm labnet >/dev/null 2>&1 || true
|
||||||
|
echo "done."
|
||||||
143
scripts/report_html.py
Executable file
143
scripts/report_html.py
Executable file
@@ -0,0 +1,143 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Генератор HTML отчетов для универсальной лаборатории
|
||||||
|
Автор: Сергей Антропов
|
||||||
|
Сайт: https://devops.org.ru
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import json
|
||||||
|
import html
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) < 3:
|
||||||
|
print("Usage: report_html.py <input.json> <output.html>")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
inp, outp = sys.argv[1], sys.argv[2]
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(inp, 'r', encoding='utf-8') as f:
|
||||||
|
data = json.load(f)
|
||||||
|
except Exception as e:
|
||||||
|
data = {"error": f"failed to read json: {e}"}
|
||||||
|
|
||||||
|
ts = data.get("timestamp", datetime.datetime.utcnow().isoformat())
|
||||||
|
idemp_raw = data.get("idempotence_raw", "")
|
||||||
|
haproxy_sel = data.get("haproxy_select1", "")
|
||||||
|
helm_ingress_toolbox = data.get("helm_ingress_toolbox_raw", "")
|
||||||
|
istio_kiali = data.get("istio_kiali_raw", "")
|
||||||
|
istio_bookinfo = data.get("istio_bookinfo_raw", "")
|
||||||
|
k8s_overview = data.get("k8s_overview_raw", "")
|
||||||
|
|
||||||
|
def badge(label, ok):
|
||||||
|
color = "#10b981" if ok else "#ef4444"
|
||||||
|
return f'<span class="badge" style="background:{color}">{html.escape(label)}</span>'
|
||||||
|
|
||||||
|
# Анализ статусов
|
||||||
|
idempotent_ok = ("changed=0" in idemp_raw)
|
||||||
|
haproxy_ok = (haproxy_sel.strip() == "1") if haproxy_sel else None
|
||||||
|
ingress_ok = ("ingress" in helm_ingress_toolbox.lower()) or ("curl http://localhost" in helm_ingress_toolbox.lower())
|
||||||
|
toolbox_ok = ("deploy/toolbox" in helm_ingress_toolbox.lower()) or ("rollout status" in helm_ingress_toolbox.lower())
|
||||||
|
istio_ok = ("istio-system" in istio_kiali.lower()) and ("istiod" in istio_kiali.lower())
|
||||||
|
kiali_ok = ("kiali" in istio_kiali.lower())
|
||||||
|
bookinfo_ok = ("bookinfo" in istio_bookinfo.lower()) or ("productpage" in istio_bookinfo.lower())
|
||||||
|
k8s_ok = ("nodes" in k8s_overview.lower()) and ("pods" in k8s_overview.lower())
|
||||||
|
|
||||||
|
def maybe_badge(label, status):
|
||||||
|
if status is None:
|
||||||
|
return f'<span class="badge" style="background:#6b7280">{html.escape(label)}: n/a</span>'
|
||||||
|
return badge(f"{label}", bool(status))
|
||||||
|
|
||||||
|
html_doc = f"""<!doctype html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Lab Report</title>
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
<style>
|
||||||
|
:root {{ --bg:#0f172a; --card:#111827; --muted:#94a3b8; --fg:#e5e7eb; --accent:#38bdf8; }}
|
||||||
|
* {{ box-sizing:border-box; }}
|
||||||
|
body {{ margin:0; font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, Arial;
|
||||||
|
background:linear-gradient(180deg,#0b1220,#0f172a); color:var(--fg); }}
|
||||||
|
.container {{ max-width:1100px; margin:40px auto; padding:0 16px; }}
|
||||||
|
.hdr {{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; }}
|
||||||
|
.hdr h1 {{ margin:0; font-size:28px; }}
|
||||||
|
.time {{ color:var(--muted); font-size:14px; }}
|
||||||
|
.grid {{ display:grid; grid-template-columns:1fr; gap:16px; margin-top:20px; }}
|
||||||
|
.card {{ background:rgba(17,24,39,.7); border:1px solid rgba(148,163,184,.15);
|
||||||
|
border-radius:14px; padding:16px; box-shadow:0 10px 30px rgba(0,0,0,.25); backdrop-filter: blur(6px); }}
|
||||||
|
.card h2 {{ margin:0 0 10px 0; font-size:18px; color:#c7d2fe; }}
|
||||||
|
pre {{ margin:0; padding:12px; background:#0b1220; border-radius:10px; overflow:auto; font-size:12px; line-height:1.4; }}
|
||||||
|
.badge {{ display:inline-block; padding:4px 10px; border-radius:999px; font-size:12px; color:white; }}
|
||||||
|
.kv {{ display:flex; flex-wrap:wrap; gap:8px; margin:8px 0 0 0; }}
|
||||||
|
footer {{ margin:24px 0 40px; color:var(--muted); font-size:12px; text-align:center; }}
|
||||||
|
a {{ color: var(--accent); text-decoration:none; }} a:hover {{ text-decoration:underline; }}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="hdr">
|
||||||
|
<h1>Ansible Lab Report</h1>
|
||||||
|
<div class="time">generated: {html.escape(ts)}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid">
|
||||||
|
<div class="card">
|
||||||
|
<h2>Summary</h2>
|
||||||
|
<div class="kv">
|
||||||
|
{badge("Idempotent", idempotent_ok)}
|
||||||
|
{maybe_badge("HAProxy SELECT=1", haproxy_ok)}
|
||||||
|
{maybe_badge("Ingress ready", ingress_ok)}
|
||||||
|
{maybe_badge("Toolbox ready", toolbox_ok)}
|
||||||
|
{maybe_badge("Istio ready", istio_ok)}
|
||||||
|
{maybe_badge("Kiali ready", kiali_ok)}
|
||||||
|
{maybe_badge("Bookinfo ready", bookinfo_ok)}
|
||||||
|
{maybe_badge("K8s ready", k8s_ok)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h2>Idempotence (raw)</h2>
|
||||||
|
<pre>{html.escape(idemp_raw) if idemp_raw else "n/a"}</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h2>Helm + Ingress + Toolbox (raw)</h2>
|
||||||
|
<pre>{html.escape(helm_ingress_toolbox) if helm_ingress_toolbox else "n/a"}</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h2>Istio / Kiali (raw)</h2>
|
||||||
|
<pre>{html.escape(istio_kiali) if istio_kiali else "n/a"}</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h2>Istio Bookinfo (raw)</h2>
|
||||||
|
<pre>{html.escape(istio_bookinfo) if istio_bookinfo else "n/a"}</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h2>K8s Overview (raw)</h2>
|
||||||
|
<pre>{html.escape(k8s_overview) if k8s_overview else "n/a"}</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h2>HAProxy SELECT 1</h2>
|
||||||
|
<pre>{html.escape(haproxy_sel) if haproxy_sel else "n/a"}</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<footer>HTML from /ansible/reports/lab-health.json · kubeconfigs in reports/kubeconfigs/</footer>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>"""
|
||||||
|
|
||||||
|
with open(outp, "w", encoding="utf-8") as f:
|
||||||
|
f.write(html_doc)
|
||||||
|
print(outp)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
25
scripts/restore.sh
Executable file
25
scripts/restore.sh
Executable file
@@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Восстановление лаборатории из снапшотов
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
IN_DIR="/ansible/snapshots"
|
||||||
|
if [ ! -d "$IN_DIR" ]; then
|
||||||
|
echo "No snapshots dir"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for f in "$IN_DIR"/*.image; do
|
||||||
|
if [ ! -f "$f" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
name=$(basename "$f" .image)
|
||||||
|
img=$(cat "$f")
|
||||||
|
echo "[restore] $name from $img"
|
||||||
|
docker rm -f "$name" >/dev/null 2>&1 || true
|
||||||
|
docker run -d --name "$name" "$img" >/dev/null
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Restored from $IN_DIR/"
|
||||||
72
scripts/secret_scan.sh
Normal file
72
scripts/secret_scan.sh
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Secrets Inspector - проверка безопасности секретов
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
echo "[secrets] Проверяем безопасность секретов..."
|
||||||
|
|
||||||
|
# Проверка 1: Vault файлы должны быть зашифрованы
|
||||||
|
echo "[secrets] Проверяем vault файлы..."
|
||||||
|
vault_files=$(find /ansible -name "*.yml" -o -name "*.yaml" | grep -E "(vault|secret)" || true)
|
||||||
|
if [ -n "$vault_files" ]; then
|
||||||
|
for file in $vault_files; do
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
if head -n1 "$file" | grep -q "^\$ANSIBLE_VAULT;"; then
|
||||||
|
echo "✅ $file - зашифрован"
|
||||||
|
else
|
||||||
|
echo "❌ $file - НЕ ЗАШИФРОВАН!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "ℹ️ Vault файлы не найдены"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Проверка 2: Пароль vault не должен быть в Git
|
||||||
|
echo "[secrets] Проверяем vault пароль..."
|
||||||
|
if [ -f "/ansible/vault/.vault" ]; then
|
||||||
|
if git ls-files | grep -q "vault/.vault"; then
|
||||||
|
echo "❌ Vault пароль в Git!"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "✅ Vault пароль не в Git"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "❌ Vault пароль не найден"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Проверка 3: Нет открытых секретов в коде
|
||||||
|
echo "[secrets] Проверяем открытые секреты..."
|
||||||
|
secret_patterns=(
|
||||||
|
"password.*=.*['\"][^'\"]{8,}['\"]"
|
||||||
|
"api_key.*=.*['\"][^'\"]{8,}['\"]"
|
||||||
|
"secret.*=.*['\"][^'\"]{8,}['\"]"
|
||||||
|
"token.*=.*['\"][^'\"]{8,}['\"]"
|
||||||
|
)
|
||||||
|
|
||||||
|
for pattern in "${secret_patterns[@]}"; do
|
||||||
|
if grep -r -E "$pattern" /ansible --exclude-dir=.git --exclude="*.encrypted" --exclude="vault/.vault" 2>/dev/null; then
|
||||||
|
echo "❌ Найдены открытые секреты в коде!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "✅ Открытые секреты не найдены"
|
||||||
|
|
||||||
|
# Проверка 4: Права доступа к vault файлам
|
||||||
|
echo "[secrets] Проверяем права доступа..."
|
||||||
|
if [ -f "/ansible/vault/.vault" ]; then
|
||||||
|
perms=$(stat -c "%a" "/ansible/vault/.vault")
|
||||||
|
if [ "$perms" != "600" ]; then
|
||||||
|
echo "❌ Vault пароль имеет неправильные права: $perms (должно быть 600)"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "✅ Vault пароль имеет правильные права: $perms"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Все проверки безопасности пройдены!"
|
||||||
26
scripts/snapshot.sh
Executable file
26
scripts/snapshot.sh
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Снапшот лаборатории
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
OUT_DIR="/ansible/snapshots"
|
||||||
|
mkdir -p "$OUT_DIR"
|
||||||
|
|
||||||
|
# Найти все контейнеры лаборатории
|
||||||
|
ids=$(docker ps -q --filter "label=ansible.lab=true")
|
||||||
|
if [ -z "$ids" ]; then
|
||||||
|
echo "No lab containers to snapshot"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
for id in $ids; do
|
||||||
|
name=$(docker inspect --format '{{.Name}}' "$id" | sed 's#^/##')
|
||||||
|
img="lab-snap-$name:latest"
|
||||||
|
echo "[snapshot] $name -> $img"
|
||||||
|
docker commit "$id" "$img" >/dev/null
|
||||||
|
echo "$img" > "$OUT_DIR/$name.image"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Snapshots saved to $OUT_DIR/"
|
||||||
0
snapshots/.gitkeep
Normal file
0
snapshots/.gitkeep
Normal file
@@ -1 +0,0 @@
|
|||||||
password123
|
|
||||||
0
vault/.gitkeep
Normal file
0
vault/.gitkeep
Normal file
1
vault/.vault
Normal file
1
vault/.vault
Normal file
@@ -0,0 +1 @@
|
|||||||
|
test_password
|
||||||
36
vault/secrets.yml
Normal file
36
vault/secrets.yml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
37313930666665366564356631646336636130366562343435376262666131373338616633646165
|
||||||
|
6232383865363562346664363334666438333438316630370a326532623133653963343230613434
|
||||||
|
38356337383966343732313930616632656635653063343961396539623130636231663433373565
|
||||||
|
6237303562303839630a646530653434616566303136643438356239626561326532383839663534
|
||||||
|
61393164643337653137373437393834623430313937613866303131343061326665333362316333
|
||||||
|
36303435353431313766653563653037393934373537643365313931373336333133633635386633
|
||||||
|
66616331653337333531356432613431653135303134643261336339346538653838303235393332
|
||||||
|
39373538643861653634613231323661366131303237393133653035326431386436653265306437
|
||||||
|
62643266313862623737656164643437616535633438383533346237313364313834383237623265
|
||||||
|
39303064356263666566386532323061646131336632616335626462373264633662616335353462
|
||||||
|
30393664313565396532383965396337616237373864626631333237633263653065626265393264
|
||||||
|
64396464356633333366353537633364643735323439336434386437643430316136613335646232
|
||||||
|
36313462666438626136363334343439333537646461653166313535366361643235326137333163
|
||||||
|
30363632613839653034626664653764376366653064613936353739363663326466303462356533
|
||||||
|
36393932303135643531373432326236653163653835306361363261393137373835623639346464
|
||||||
|
33616238633232373237643564626439653363356635373939333664653864643061643534336565
|
||||||
|
39303366616635313466623634336234386438353262653031356633323036306636333437623263
|
||||||
|
33343863316338356466323334316334313933393730626332373736396234376135623437393662
|
||||||
|
30626263613738373461613933373166353737353538316337633062633861633135643638383031
|
||||||
|
37626464323763376334656363373634343431383936386363623761366536653166353239343332
|
||||||
|
33313435366430666531316131306239643632376262656631396162636233343631336566613531
|
||||||
|
64313136383865326331366466316365646136623736303164373735636366643430343138373138
|
||||||
|
39653533336434333939656361366633376361663266653063666537633261653663363134333562
|
||||||
|
63663562303432323230303065303930343435356433326235323366373662666261313966616639
|
||||||
|
39376131623237323836663735313839333034626163363236313939396638623565363038333432
|
||||||
|
39643630366263613732636462353166626332653234336332366363346262316465353130623130
|
||||||
|
32663061633830373038656539653238393732333964343836653965383131656534386337393335
|
||||||
|
35383135316365393734666136343964393630346137393661643735613863613764313238663665
|
||||||
|
35323664353939303631653835636231323531353863333839306531376337653063373536623833
|
||||||
|
34326534303364383031346137323966353133333138306631323735376561656136376333616261
|
||||||
|
63343435623233623338666337383265353766323666396139633964643563393366656339633736
|
||||||
|
39326261316430313637313230656536323362666361353930353135383737313037316139653964
|
||||||
|
32326230396263383939393961353763323138613230353364313038366165646130303363643239
|
||||||
|
31303930653862323839653330373532646630336565303535306361346235306565613635396366
|
||||||
|
316438396434306663316134316230636462
|
||||||
Reference in New Issue
Block a user