- Добавлена полная поддержка 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
271 lines
12 KiB
Makefile
271 lines
12 KiB
Makefile
# Глобальные переменные
|
||
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
|