Files
DevOpsLab/Makefile
Sergey Antropoff 33ada54c12 feat: Завершена реализация универсальной лаборатории
- Добавлена полная поддержка Istio service mesh с Kiali
- Интегрированы Helm charts (nginx, prometheus-stack)
- Созданы Grafana дашборды для Istio мониторинга
- Добавлен HTML генератор отчетов с красивым дизайном
- Созданы скрипты для снапшотов и восстановления
- Добавлена поддержка Istio Bookinfo demo
- Обновлена документация с полным описанием возможностей

Компоненты:
- Istio с Telemetry и Traffic Policy
- Prometheus + Grafana с автопровижинингом дашбордов
- HTML отчеты с анализом статусов
- Снапшоты и восстановление состояния
- Полная интеграция с Kubernetes

Автор: Сергей Антропов
Сайт: https://devops.org.ru
2025-10-22 13:08:55 +03:00

271 lines
12 KiB
Makefile
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Глобальные переменные
IMAGE ?= ansible
TAG ?= 0.1
REGISTRY ?= inecs/ansible
# По умолчанию используем 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
####################################################################################################
# Инициализация новой роли
####################################################################################################
init:
@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
####################################################################################################
# Управление контейнерами с помощью docker compose или docker run
####################################################################################################
docker:
@case "$(word 2, $(MAKECMDGOALS))" in \
build) \
docker buildx create --use --name multiarch-builder --driver docker-container; \
if [ "$(RUN_MODE)" = "docker-compose" ]; then \
docker compose build $(c); \
else \
docker build -t $(REGISTRY)/$(IMAGE) .; \
fi;; \
rebuild) \
docker buildx create --use --name multiarch-builder --driver docker-container; \
if [ "$(RUN_MODE)" = "docker-compose" ]; then \
docker compose build --no-cache $(c); \
else \
docker build --no-cache -t $(REGISTRY)/$(IMAGE) .; \
fi;; \
prune) \
docker system prune -af;; \
shell) \
clear; \
echo "Entering to Ansible container shell..."; \
$(RUN) bash ;; \
release) \
docker buildx create --use --name multiarch-builder --driver docker-container; \
docker login $(REGISTRY); \
docker buildx build -t $(REGISTRY)/$(IMAGE):$(TAG) -t $(REGISTRY)/$(IMAGE):latest --platform linux/amd64,linux/arm64 --push .;; \
images) \
docker buildx create --use --name multiarch-builder --driver docker-container; \
echo "Логинимся в Docker Hub..."; \
docker login; \
echo "Собираем и пушим основной Ansible образ..."; \
docker buildx build -t $(REGISTRY)/$(IMAGE):$(TAG) -t $(REGISTRY)/$(IMAGE):latest --platform linux/amd64,linux/arm64 --push .; \
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
####################################################################################################
# Работа с ролью
####################################################################################################
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:
@case "$(word 2, $(MAKECMDGOALS))" in \
new) \
clear; \
echo "Введите название новой роли на английском:"; \
read ROLE_NAME; \
echo "Введите описание роли:"; \
read ROLE_DESC; \
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
####################################################################################################
# Работа с Git
####################################################################################################
git:
@case "$(word 2, $(MAKECMDGOALS))" in \
push) \
git branch; \
read -p "Выберите ветку для пуша: " BRANCH; \
read -p "Введите описание коммита: " COMMIT; \
commitname=$$COMMIT; \
git add . ; \
git commit -m "$$commitname"; \
git push -u origin $$BRANCH; \
echo "Изменения внесены в Git";; \
pull) \
git pull;; \
new) \
read -p "Введите имя новой ветки: " BRANCH_NAME; \
NEW_BRANCH="$$BRANCH_NAME"; \
git checkout -b $$NEW_BRANCH; \
echo "Создана и переключена на новую ветку: $$NEW_BRANCH";; \
*) echo "Unknown action. Available actions: push, pull, cluster-branch";; \
esac
# ====== УНИВЕРСАЛЬНАЯ ЛАБОРАТОРИЯ (Molecule universal) ======
SCENARIO ?= universal
COMPOSE ?= docker compose
lab-up: ## Поднять контроллер
$(COMPOSE) up -d
lab-down: ## Погасить контроллер
$(COMPOSE) down -v
lab-sh: ## Войти в контроллер
docker exec -it ansible-controller bash
lab-test: lab-up ## Полный цикл Molecule (create+converge+verify+destroy)
docker exec -e MOLECULE_EPHEMERAL_DIRECTORY=/tmp/molecule ansible-controller \
bash -lc 'cd /ansible && molecule test -s $(SCENARIO)'
lab-create: lab-up ## Создать инфраструктуру лаборатории
docker exec -e MOLECULE_EPHEMERAL_DIRECTORY=/tmp/molecule ansible-controller \
bash -lc 'cd /ansible && molecule create -s $(SCENARIO)'
lab-converge: ## Запустить роли в лаборатории
docker exec -e MOLECULE_EPHEMERAL_DIRECTORY=/tmp/molecule ansible-controller \
bash -lc 'cd /ansible && molecule converge -s $(SCENARIO)'
lab-verify: ## Проверить работу лаборатории
docker exec -e MOLECULE_EPHEMERAL_DIRECTORY=/tmp/molecule ansible-controller \
bash -lc 'cd /ansible && molecule verify -s $(SCENARIO)'
lab-destroy: ## Уничтожить инфраструктуру лаборатории
docker exec -e MOLECULE_EPHEMERAL_DIRECTORY=/tmp/molecule ansible-controller \
bash -lc 'cd /ansible && molecule destroy -s $(SCENARIO)'
lab-reset: lab-destroy lab-down lab-up ## Полный сброс лаборатории
# ====== K8S ХЕЛПЕРЫ ======
kube-sh: ## Shell с kubectl/helm/istioctl внутри контейнера
docker exec -it ansible-controller bash
kube-cmd: ## make kube-cmd CLUSTER=lab CMD="get pods -A"
ifeq ($(strip $(CLUSTER)),)
@echo "Usage: make kube-cmd CLUSTER=lab CMD=\"get pods -A\""; exit 1
endif
docker exec -it ansible-controller bash -lc 'kubectl --context kind-$(CLUSTER) $(CMD)'
kube-enter: ## make kube-enter CLUSTER=lab
ifeq ($(strip $(CLUSTER)),)
@echo "Usage: make kube-enter CLUSTER=lab"; exit 1
endif
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'
# Port-forward Kiali (http://localhost:20001)
kiali-port-forward: ## make kiali-port-forward CLUSTER=lab
ifeq ($(strip $(CLUSTER)),)
@echo "Usage: make kiali-port-forward CLUSTER=lab"; exit 1
endif
docker exec -d ansible-controller bash -lc 'kubectl --context kind-$(CLUSTER) -n istio-system port-forward svc/kiali 20001:20001'
# Port-forward Istio IngressGateway (HTTP 8082, HTTPS 8444)
istio-gw-port-forward: ## make istio-gw-port-forward CLUSTER=lab
ifeq ($(strip $(CLUSTER)),)
@echo "Usage: make istio-gw-port-forward CLUSTER=lab"; exit 1
endif
docker exec -d ansible-controller bash -lc 'kubectl --context kind-$(CLUSTER) -n istio-system port-forward svc/istio-ingressgateway 8082:80 8444:443'
@echo "Istio GW forwarded: http://localhost:8082 https://localhost:8444"
# Port-forward Grafana (http://localhost:3000)
grafana-port-forward: ## make grafana-port-forward CLUSTER=lab
ifeq ($(strip $(CLUSTER)),)
@echo "Usage: make grafana-port-forward CLUSTER=lab"; exit 1
endif
docker exec -d ansible-controller bash -lc 'kubectl --context kind-$(CLUSTER) -n monitoring port-forward svc/monitoring-grafana 3000:80'
@echo "Grafana: http://localhost:3000 (admin/admin)"
# Port-forward Prometheus (http://localhost:9090)
prom-port-forward: ## make prom-port-forward CLUSTER=lab
ifeq ($(strip $(CLUSTER)),)
@echo "Usage: make prom-port-forward CLUSTER=lab"; exit 1
endif
docker exec -d ansible-controller bash -lc 'kubectl --context kind-$(CLUSTER) -n monitoring port-forward svc/monitoring-kube-prometheus-prometheus 9090:9090'
@echo "Prometheus: http://localhost:9090"
# Stop all port-forwards
kube-pf-stop: ## убить все port-forward в контроллере
docker exec -it ansible-controller bash -lc 'pkill -f "kubectl .* port-forward" || true'
# ====== ОТЧЕТЫ ======
lab-report: ## Сгенерировать HTML отчет
docker exec ansible-controller bash -lc 'python3 /ansible/scripts/report_html.py /ansible/reports/lab-health.json /ansible/reports/lab-report.html'
@echo "HTML report: reports/lab-report.html"
# ====== ДОПОЛНИТЕЛЬНЫЕ ХЕЛПЕРЫ ======
bookinfo-url: ## echo productpage URL via Istio Gateway (needs istio-gw-port-forward first)
@echo "Open: http://localhost:8082/productpage"
grafana-open: ## echo URL to Grafana + hint dashboards
@echo "Grafana: http://localhost:3000 (admin/admin)"
@echo "Dashboards:"
@echo " - Istio • Overview (uid: istio-overview)"
@echo " - Service • SLI (uid: service-sli)"
# ====== СНАПШОТЫ И ОЧИСТКА ======
lab-snapshot: ## Сохранить снапшот лаборатории
bash scripts/snapshot.sh
lab-restore: ## Восстановить из снапшота
bash scripts/restore.sh
lab-cleanup: ## Очистить лабораторию
bash scripts/cleanup.sh