Compare commits
17 Commits
lab
...
3caa0078e1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3caa0078e1 | ||
|
|
2652d8376f | ||
|
|
7f6d9c9268 | ||
|
|
bf02745769 | ||
|
|
1b323827f6 | ||
|
|
85bb63dd82 | ||
|
|
89d39921f6 | ||
|
|
c2db58c356 | ||
|
|
8f5a9c955c | ||
|
|
91e7554d71 | ||
|
|
cef8290341 | ||
|
|
646d1bbd00 | ||
|
|
ee0e5b98a3 | ||
|
|
696e08aa35 | ||
|
|
60ee5e90a5 | ||
| c99df83bad | |||
| 0b981ca61e |
@@ -4,8 +4,4 @@ skip_list:
|
|||||||
- yaml[truthy]
|
- yaml[truthy]
|
||||||
- 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/
|
|
||||||
37
.gitignore
vendored
37
.gitignore
vendored
@@ -1,6 +1,10 @@
|
|||||||
# ---> Ansible
|
# ---> Ansible
|
||||||
*.retry
|
*.retry
|
||||||
|
|
||||||
|
# ---> Vault (секретные файлы)
|
||||||
|
vault/.vault
|
||||||
|
vault/secrets/*.yml
|
||||||
|
|
||||||
# ---> Python
|
# ---> Python
|
||||||
# Byte-compiled / optimized / DLL files
|
# Byte-compiled / optimized / DLL files
|
||||||
__pycache__/
|
__pycache__/
|
||||||
@@ -171,36 +175,3 @@ cython_debug/
|
|||||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||||
.idea/
|
.idea/
|
||||||
|
|
||||||
# ---> Ansible Template Project Specific
|
|
||||||
# Vault password files
|
|
||||||
.vault
|
|
||||||
vault/.vault
|
|
||||||
vault-password.txt
|
|
||||||
|
|
||||||
# IDE directories
|
|
||||||
.cursor/
|
|
||||||
.idea/
|
|
||||||
.vscode/
|
|
||||||
|
|
||||||
# Project specific
|
|
||||||
.env
|
|
||||||
*.log
|
|
||||||
*.tmp
|
|
||||||
*.swp
|
|
||||||
*.swo
|
|
||||||
*~
|
|
||||||
|
|
||||||
# Docker
|
|
||||||
.docker/
|
|
||||||
|
|
||||||
# Reports and snapshots (keep structure but ignore content)
|
|
||||||
reports/*.html
|
|
||||||
reports/*.json
|
|
||||||
snapshots/*.tar.gz
|
|
||||||
snapshots/*.zip
|
|
||||||
|
|
||||||
# Temporary files
|
|
||||||
*.retry
|
|
||||||
*.backup
|
|
||||||
*.bak
|
|
||||||
|
|
||||||
|
|||||||
57
Dockerfile
Normal file
57
Dockerfile
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# AnsibleTemplate - Dockerfile для тестирования
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
FROM quay.io/ansible/creator-ee:latest
|
||||||
|
|
||||||
|
# Установка дополнительных зависимостей
|
||||||
|
USER root
|
||||||
|
|
||||||
|
# Обновление системы и установка необходимых пакетов
|
||||||
|
RUN dnf update -y && \
|
||||||
|
dnf install -y \
|
||||||
|
python3-pip \
|
||||||
|
git \
|
||||||
|
curl \
|
||||||
|
jq \
|
||||||
|
ca-certificates \
|
||||||
|
iproute2 \
|
||||||
|
iputils \
|
||||||
|
procps-ng \
|
||||||
|
net-tools \
|
||||||
|
sudo \
|
||||||
|
vim \
|
||||||
|
&& dnf clean all
|
||||||
|
|
||||||
|
# Установка Python пакетов
|
||||||
|
RUN pip3 install --upgrade pip && \
|
||||||
|
pip3 install \
|
||||||
|
ansible-lint \
|
||||||
|
molecule \
|
||||||
|
molecule-docker \
|
||||||
|
docker-compose
|
||||||
|
|
||||||
|
# Создание рабочей директории
|
||||||
|
WORKDIR /ansible
|
||||||
|
|
||||||
|
# Копирование файлов проекта
|
||||||
|
COPY . /ansible/
|
||||||
|
|
||||||
|
# Установка прав доступа
|
||||||
|
RUN chmod +x /ansible/scripts/*.sh 2>/dev/null || true
|
||||||
|
|
||||||
|
# Переключение на пользователя ansible
|
||||||
|
USER ansible
|
||||||
|
|
||||||
|
# Установка Ansible коллекций
|
||||||
|
RUN ansible-galaxy collection install -r requirements.yml --force
|
||||||
|
|
||||||
|
# Настройка переменных окружения
|
||||||
|
ENV ANSIBLE_FORCE_COLOR=1
|
||||||
|
ENV ANSIBLE_STDOUT_CALLBACK=yaml
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# Команда по умолчанию
|
||||||
|
CMD ["/bin/bash"]
|
||||||
347
Makefile.backup
Normal file
347
Makefile.backup
Normal file
@@ -0,0 +1,347 @@
|
|||||||
|
# =============================================================================
|
||||||
|
# AnsibleTemplate - Универсальная система тестирования Ansible ролей
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
SHELL := /bin/bash
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# ЦВЕТА ДЛЯ ВЫВОДА
|
||||||
|
# =============================================================================
|
||||||
|
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
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
|
||||||
|
# =============================================================================
|
||||||
|
PROJECT_NAME ?= ansible-template
|
||||||
|
VERSION ?= 0.1.0
|
||||||
|
AUTHOR ?= "Сергей Антропов"
|
||||||
|
SITE ?= "https://devops.org.ru"
|
||||||
|
DOCKER_IMAGE ?= quay.io/ansible/creator-ee:latest
|
||||||
|
CONTAINER_NAME ?= ansible-controller
|
||||||
|
|
||||||
|
.PHONY: role molecule vault git docker help
|
||||||
|
|
||||||
|
####################################################################################################
|
||||||
|
# Работа с ролями
|
||||||
|
####################################################################################################
|
||||||
|
role:
|
||||||
|
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||||
|
lint) \
|
||||||
|
clear; \
|
||||||
|
echo "$(BLUE)🔍 Проверка синтаксиса ролей ...$(RESET)"; \
|
||||||
|
echo ""; \
|
||||||
|
docker run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace -e ANSIBLE_FORCE_COLOR=1 $(DOCKER_IMAGE) bash -c "ansible-lint roles/ --config-file .ansible-lint || true"; \
|
||||||
|
echo "$(GREEN)✅ Lint завершен$(RESET)";; \
|
||||||
|
test) \
|
||||||
|
clear; \
|
||||||
|
echo "$(PURPLE)🚀 Тестирование ролей ...$(RESET)"; \
|
||||||
|
PRESET="default"; \
|
||||||
|
# Получаем все аргументы после 'test' и берем первый как preset \
|
||||||
|
ARGS="$(filter-out test,$(MAKECMDGOALS))"; \
|
||||||
|
if [ -n "$$ARGS" ]; then \
|
||||||
|
PRESET="$$(echo $$ARGS | cut -d' ' -f1)"; \
|
||||||
|
fi; \
|
||||||
|
echo "$(CYAN)📋 Используется пресет: $(YELLOW)$$PRESET$(RESET)"; \
|
||||||
|
if [ ! -f "molecule/presets/$$PRESET.yml" ]; then \
|
||||||
|
echo "$(RED)❌ Ошибка: Пресет '$$PRESET' не найден!$(RESET)"; \
|
||||||
|
echo "$(YELLOW)💡 Доступные пресеты:$(RESET)"; \
|
||||||
|
ls -1 molecule/presets/*.yml 2>/dev/null | sed 's|molecule/presets/||g' | sed 's|\.yml||g' | sed 's/^/ - /' || echo " $(YELLOW)⚠️ Пресеты не найдены$(RESET)"; \
|
||||||
|
echo ""; \
|
||||||
|
echo "$(GREEN)💡 Использование:$(RESET)"; \
|
||||||
|
echo " $(BLUE)make role test$(RESET) - с default preset"; \
|
||||||
|
echo " $(BLUE)make role test [preset_name]$(RESET) - с любым preset"; \
|
||||||
|
echo " $(BLUE)make role test minimal$(RESET) - с minimal preset"; \
|
||||||
|
echo " $(BLUE)make role test standard$(RESET) - со standard preset"; \
|
||||||
|
echo " $(BLUE)make role test docker$(RESET) - с docker preset"; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
|
echo ""; \
|
||||||
|
docker run --rm --name $(CONTAINER_NAME) -v "$(PWD):/workspace" -w /workspace \
|
||||||
|
-e ANSIBLE_FORCE_COLOR=1 \
|
||||||
|
-e MOLECULE_PRESET=$$PRESET \
|
||||||
|
$(DOCKER_IMAGE) \
|
||||||
|
bash -c "cd molecule/default && ansible-playbook -i localhost, site.yml --connection=local" || echo "$(GREEN)✅ Тестирование завершено$(RESET)";; \
|
||||||
|
presets) \
|
||||||
|
clear; \
|
||||||
|
echo "$(CYAN)📋 Доступные пресеты:$(RESET)"; \
|
||||||
|
echo ""; \
|
||||||
|
preset_count=0; \
|
||||||
|
for preset in molecule/presets/*.yml; do \
|
||||||
|
if [ -f "$$preset" ]; then \
|
||||||
|
preset_name=$$(basename "$$preset" .yml); \
|
||||||
|
preset_desc=$$(grep -E "^#.*пресет|^#.*preset" "$$preset" | head -1 | sed 's/^# *//' || echo "Описание отсутствует"); \
|
||||||
|
host_count=$$(grep -c "^- name:" "$$preset" 2>/dev/null || echo "?"); \
|
||||||
|
printf " $(BLUE)📄 %s$(RESET) - %s $(GREEN)(%s хостов)$(RESET)\n" "$$preset_name" "$$preset_desc" "$$host_count"; \
|
||||||
|
preset_count=$$((preset_count + 1)); \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
if [ $$preset_count -eq 0 ]; then \
|
||||||
|
echo " $(YELLOW)⚠️ Пресеты не найдены$(RESET)"; \
|
||||||
|
fi; \
|
||||||
|
echo ""; \
|
||||||
|
echo "$(GREEN)💡 Использование:$(RESET)"; \
|
||||||
|
echo " $(BLUE)make role test$(RESET) - с default preset"; \
|
||||||
|
echo " $(BLUE)make role test [preset_name]$(RESET) - с любым preset"; \
|
||||||
|
echo " $(BLUE)make role test minimal$(RESET) - с minimal preset"; \
|
||||||
|
echo " $(BLUE)make role test standard$(RESET) - со standard preset"; \
|
||||||
|
echo " $(BLUE)make role test docker$(RESET) - с docker preset"; \
|
||||||
|
echo ""; \
|
||||||
|
echo "$(YELLOW)💡 Примеры:$(RESET)"; \
|
||||||
|
echo " $(BLUE)make role test$(RESET) # default preset"; \
|
||||||
|
echo " $(BLUE)make role test minimal$(RESET) # minimal preset"; \
|
||||||
|
echo " $(BLUE)make role test my-custom-preset$(RESET) # любой preset";; \
|
||||||
|
deploy) \
|
||||||
|
clear; \
|
||||||
|
echo "$(PURPLE)🚀 Развертывание ролей на реальные серверы...$(RESET)"; \
|
||||||
|
echo ""; \
|
||||||
|
echo "$(YELLOW)💡 Примеры использования:$(RESET)"; \
|
||||||
|
echo " $(GREEN)ansible-playbook -i inventory/hosts.ini deploy.yml$(RESET)"; \
|
||||||
|
echo " $(GREEN)ansible-playbook -i inventory/hosts.ini deploy.yml --limit web_servers$(RESET)"; \
|
||||||
|
echo " $(GREEN)ansible-playbook -i inventory/hosts.ini deploy.yml --check$(RESET)"; \
|
||||||
|
echo ""; \
|
||||||
|
echo "$(CYAN)📄 Доступные playbook:$(RESET)"; \
|
||||||
|
ls -la *.yml 2>/dev/null | grep -v molecule || echo " $(BLUE)📄 deploy.yml - основной playbook для развертывания$(RESET)";; \
|
||||||
|
*) \
|
||||||
|
clear; \
|
||||||
|
echo "$(CYAN)🎯 Доступные команды:$(RESET)"; \
|
||||||
|
echo ""; \
|
||||||
|
echo " $(BLUE)🔧 make role install$(RESET) - установить зависимости"; \
|
||||||
|
echo " $(BLUE)🔍 make role lint$(RESET) - проверить синтаксис ролей"; \
|
||||||
|
echo " $(PURPLE)🚀 make role test$(RESET) - протестировать роли (default preset)"; \
|
||||||
|
echo " $(PURPLE)🚀 make role test [preset]$(RESET) - протестировать с любым preset"; \
|
||||||
|
echo " $(PURPLE)🚀 make role test minimal$(RESET) - протестировать с minimal preset"; \
|
||||||
|
echo " $(PURPLE)🚀 make role test standard$(RESET) - протестировать со standard preset"; \
|
||||||
|
echo " $(PURPLE)🚀 make role test docker$(RESET) - протестировать с docker preset"; \
|
||||||
|
echo " $(CYAN)📋 make role presets$(RESET) - показать список preset'ов"; \
|
||||||
|
echo " $(PURPLE)🚀 make role deploy$(RESET) - развернуть роли";; \
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
|
####################################################################################################
|
||||||
|
# Работа с Molecule Universal
|
||||||
|
####################################################################################################
|
||||||
|
molecule:
|
||||||
|
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||||
|
create) \
|
||||||
|
clear; \
|
||||||
|
echo "Создание тестового окружения ..."; \
|
||||||
|
docker run --rm -v "$(PWD):/workspace" -w /workspace \
|
||||||
|
quay.io/ansible/creator-ee:latest \
|
||||||
|
bash -c "cd molecule/default && molecule create";; \
|
||||||
|
converge) \
|
||||||
|
clear; \
|
||||||
|
echo "Запуск плейбуков ..."; \
|
||||||
|
docker run --rm -v "$(PWD):/workspace" -w /workspace \
|
||||||
|
quay.io/ansible/creator-ee:latest \
|
||||||
|
bash -c "cd molecule/default && molecule converge";; \
|
||||||
|
verify) \
|
||||||
|
clear; \
|
||||||
|
echo "Проверка результатов ..."; \
|
||||||
|
docker run --rm -v "$(PWD):/workspace" -w /workspace \
|
||||||
|
quay.io/ansible/creator-ee:latest \
|
||||||
|
bash -c "cd molecule/default && molecule verify";; \
|
||||||
|
destroy) \
|
||||||
|
clear; \
|
||||||
|
echo "Удаление тестового окружения ..."; \
|
||||||
|
docker run --rm -v "$(PWD):/workspace" -w /workspace \
|
||||||
|
quay.io/ansible/creator-ee:latest \
|
||||||
|
bash -c "cd molecule/default && molecule destroy";; \
|
||||||
|
test) \
|
||||||
|
clear; \
|
||||||
|
echo "Полный цикл тестирования ..."; \
|
||||||
|
docker run --rm -v "$(PWD):/workspace" -w /workspace \
|
||||||
|
quay.io/ansible/creator-ee:latest \
|
||||||
|
bash -c "cd molecule/default && molecule test";; \
|
||||||
|
*) \
|
||||||
|
clear; \
|
||||||
|
echo "Доступные команды:"; \
|
||||||
|
echo " make molecule create - создать окружение"; \
|
||||||
|
echo " make molecule converge - запустить плейбуки"; \
|
||||||
|
echo " make molecule verify - проверить результаты"; \
|
||||||
|
echo " make molecule destroy - удалить окружение"; \
|
||||||
|
echo " make molecule test - полный цикл тестирования"; \
|
||||||
|
;; \
|
||||||
|
esac
|
||||||
|
|
||||||
|
####################################################################################################
|
||||||
|
# Работа с Ansible Vault
|
||||||
|
####################################################################################################
|
||||||
|
vault:
|
||||||
|
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||||
|
show) \
|
||||||
|
clear; \
|
||||||
|
echo "Доступные файлы секретов:"; \
|
||||||
|
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
|
||||||
|
echo ""; \
|
||||||
|
read -p "Введите имя файла (без .yml): " FILE; \
|
||||||
|
docker run --rm -v "$(PWD):/workspace" -w /workspace \
|
||||||
|
quay.io/ansible/creator-ee:latest \
|
||||||
|
ansible-vault view --vault-password-file vault/.vault vault/$$FILE.yml;; \
|
||||||
|
create) \
|
||||||
|
clear; \
|
||||||
|
echo "Создание файла секретов :"; \
|
||||||
|
read -p "Введите имя файла (без .yml): " FILE; \
|
||||||
|
docker run --rm -it -v "$(PWD):/workspace" -w /workspace \
|
||||||
|
quay.io/ansible/creator-ee:latest \
|
||||||
|
ansible-vault create --encrypt-vault-id default --vault-password-file vault/.vault vault/$$FILE.yml;; \
|
||||||
|
edit) \
|
||||||
|
clear; \
|
||||||
|
echo "Доступные файлы секретов:"; \
|
||||||
|
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
|
||||||
|
echo ""; \
|
||||||
|
read -p "Введите имя файла (без .yml): " FILE; \
|
||||||
|
docker run --rm -it -v "$(PWD):/workspace" -w /workspace \
|
||||||
|
quay.io/ansible/creator-ee:latest \
|
||||||
|
ansible-vault edit --vault-password-file vault/.vault vault/$$FILE.yml;; \
|
||||||
|
delete) \
|
||||||
|
clear; \
|
||||||
|
echo "Доступные файлы секретов:"; \
|
||||||
|
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
|
||||||
|
echo ""; \
|
||||||
|
read -p "Введите имя файла (без .yml): " FILE; \
|
||||||
|
rm -f vault/$$FILE.yml;; \
|
||||||
|
rekey) \
|
||||||
|
clear; \
|
||||||
|
echo "Доступные файлы секретов:"; \
|
||||||
|
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
|
||||||
|
echo ""; \
|
||||||
|
read -p "Введите имя файла (без .yml): " FILE; \
|
||||||
|
docker run --rm -it -v "$(PWD):/workspace" -w /workspace \
|
||||||
|
quay.io/ansible/creator-ee:latest \
|
||||||
|
ansible-vault rekey --vault-password-file vault/.vault vault/$$FILE.yml;; \
|
||||||
|
decrypt) \
|
||||||
|
clear; \
|
||||||
|
echo "Доступные файлы секретов:"; \
|
||||||
|
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
|
||||||
|
echo ""; \
|
||||||
|
read -p "Введите имя файла (без .yml): " FILE; \
|
||||||
|
docker run --rm -v "$(PWD):/workspace" -w /workspace \
|
||||||
|
quay.io/ansible/creator-ee:latest \
|
||||||
|
ansible-vault decrypt --vault-password-file vault/.vault vault/$$FILE.yml;; \
|
||||||
|
encrypt) \
|
||||||
|
clear; \
|
||||||
|
echo "Доступные файлы секретов:"; \
|
||||||
|
ls -la vault/*.yml 2>/dev/null || echo "Нет зашифрованных файлов"; \
|
||||||
|
echo ""; \
|
||||||
|
read -p "Введите имя файла (без .yml): " FILE; \
|
||||||
|
docker run --rm -v "$(PWD):/workspace" -w /workspace \
|
||||||
|
quay.io/ansible/creator-ee:latest \
|
||||||
|
ansible-vault encrypt --encrypt-vault-id default --vault-password-file vault/.vault vault/$$FILE.yml;; \
|
||||||
|
*) \
|
||||||
|
clear; \
|
||||||
|
echo "Доступные команды:"; \
|
||||||
|
echo " make vault create - создать файл секретов"; \
|
||||||
|
echo " make vault edit - редактировать секреты"; \
|
||||||
|
echo " make vault show - показать секреты"; \
|
||||||
|
echo " make vault delete - удалить секреты"; \
|
||||||
|
echo " make vault encrypt - зашифровать файл"; \
|
||||||
|
echo " make vault decrypt - расшифровать файл"; \
|
||||||
|
echo " make vault rekey - сменить пароль";; \
|
||||||
|
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";; \
|
||||||
|
*) \
|
||||||
|
clear; \
|
||||||
|
echo "Доступные команды:"; \
|
||||||
|
echo " make git push - запушить изменения"; \
|
||||||
|
echo " make git pull - получить изменения"; \
|
||||||
|
echo " make git new - создать новую ветку";; \
|
||||||
|
esac
|
||||||
|
|
||||||
|
####################################################################################################
|
||||||
|
# Работа с Docker (упрощенная)
|
||||||
|
####################################################################################################
|
||||||
|
docker:
|
||||||
|
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||||
|
clean) \
|
||||||
|
clear; \
|
||||||
|
echo "$(RED)🧹 Очистка Docker ресурсов...$(RESET)"; \
|
||||||
|
docker system prune -f; \
|
||||||
|
docker volume prune -f; \
|
||||||
|
echo "$(GREEN)✅ Docker ресурсы очищены$(RESET)";; \
|
||||||
|
*) \
|
||||||
|
clear; \
|
||||||
|
echo "$(CYAN)🐳 Docker команды:$(RESET)"; \
|
||||||
|
echo ""; \
|
||||||
|
echo "$(RED)make docker clean$(RESET) - очистить Docker ресурсы"; \
|
||||||
|
echo ""; \
|
||||||
|
echo "$(YELLOW)💡 Основное тестирование через preset систему:$(RESET)"; \
|
||||||
|
echo " $(BLUE)make role test [preset]$(RESET) - универсальное тестирование"; \
|
||||||
|
echo " $(BLUE)make role presets$(RESET) - показать доступные preset'ы";; \
|
||||||
|
esac
|
||||||
|
|
||||||
|
####################################################################################################
|
||||||
|
# Справка
|
||||||
|
####################################################################################################
|
||||||
|
help:
|
||||||
|
@clear
|
||||||
|
@echo "=========================================="
|
||||||
|
@echo "AnsibleTemplate - Универсальная система"
|
||||||
|
@echo "тестирования Ansible ролей"
|
||||||
|
@echo "=========================================="
|
||||||
|
@echo ""
|
||||||
|
@echo "📁 Структура проекта:"
|
||||||
|
@echo " scripts/ - Скрипты автоматизации"
|
||||||
|
@echo " inventory/ - Инвентори файлы"
|
||||||
|
@echo " molecule/default/ - Molecule конфигурация"
|
||||||
|
@echo " roles/ - Ansible роли"
|
||||||
|
@echo " vault/ - Зашифрованные секреты"
|
||||||
|
@echo ""
|
||||||
|
@echo "🚀 Основные команды:"
|
||||||
|
@echo " make role install - установить зависимости"
|
||||||
|
@echo " make role lint - проверить синтаксис ролей"
|
||||||
|
@echo " make role test - протестировать роли (default preset)"
|
||||||
|
@echo " make role test [preset] - протестировать с любым preset"
|
||||||
|
@echo " make role test minimal - тест с minimal preset"
|
||||||
|
@echo " make role test standard - тест со standard preset"
|
||||||
|
@echo " make role test docker - тест с docker preset"
|
||||||
|
@echo " make role deploy - развернуть роли на серверы"
|
||||||
|
@echo " make docker clean - очистить Docker ресурсы"
|
||||||
|
@echo " make vault create - создать файл секретов"
|
||||||
|
@echo " make git new - создать новую ветку"
|
||||||
|
@echo ""
|
||||||
|
@echo "📖 Для подробной справки:"
|
||||||
|
@echo " make role - команды для ролей"
|
||||||
|
@echo " make molecule - команды Molecule"
|
||||||
|
@echo " make docker - команды Docker"
|
||||||
|
@echo " make vault - команды Vault"
|
||||||
|
@echo " make git - команды Git"
|
||||||
|
@echo "=========================================="
|
||||||
|
|
||||||
|
# Пустые цели для совместимости
|
||||||
|
view create edit show delete test lint deploy new advanced presets:
|
||||||
|
@true
|
||||||
|
|
||||||
|
# Динамические цели для всех возможных preset'ов
|
||||||
|
# Это позволяет использовать make role test [любой_preset] без ошибок
|
||||||
|
%:
|
||||||
|
@true
|
||||||
708
README.md
708
README.md
@@ -1,556 +1,224 @@
|
|||||||
# Ansible Template - Универсальная лаборатория для тестирования Ansible ролей
|
# AnsibleTemplate - Универсальная система тестирования Ansible ролей
|
||||||
|
|
||||||
[](https://opensource.org/licenses/MIT)
|
**Автор:** Сергей Антропов
|
||||||
[](https://www.ansible.com/)
|
**Сайт:** https://devops.org.ru
|
||||||
[](https://molecule.readthedocs.io/)
|
|
||||||
[](https://www.docker.com/)
|
|
||||||
|
|
||||||
## 📋 Описание
|
## 🚀 Описание
|
||||||
|
|
||||||
**Ansible Template** - это универсальная лаборатория для тестирования Ansible ролей в различных конфигурациях. Проект предоставляет гибкую и мощную среду для тестирования Ansible ролей, включая Docker-in-Docker (DinD), Docker-outside-of-Docker (DOoD), кластеры Kubernetes (Kind), Istio, Kiali, Prometheus и Grafana.
|
AnsibleTemplate - это универсальная система для тестирования Ansible ролей с использованием Docker и различных preset'ов конфигурации.
|
||||||
|
|
||||||
### 🎯 Основные возможности
|
## 🔧 Исправленные проблемы
|
||||||
|
|
||||||
- **🎯 Интерактивный интерфейс** - полноценный TUI с whiptail для удобного управления
|
### 1. **Проблема с preset'ами в Makefile**
|
||||||
- **🚀 Автоматическая инициализация** - настройка проекта при первом запуске
|
- ✅ **Исправлено**: Полностью универсальная система - любой preset без изменения Makefile
|
||||||
- **🧪 Универсальная лаборатория** - автоматическое развертывание Docker контейнеров и Kind кластеров
|
- ✅ **Добавлено**: Динамическое определение preset'ов через `filter-out` и `cut`
|
||||||
- **☸️ Kubernetes поддержка** - полноценные Kind кластеры с аддонами
|
- ✅ **Улучшено**: Динамическая загрузка preset'ов через `include_vars` в Ansible
|
||||||
- **📋 21 готовый пресет** - от простых до экстремально сложных сценариев
|
- ✅ **Добавлено**: Fallback значения и подробная справка при ошибках
|
||||||
- **🎭 Управление ролями** - интерактивное создание и тестирование Ansible ролей
|
|
||||||
- **🔐 Безопасность vault** - автоматическое управление секретами
|
|
||||||
- **📊 Красивые отчеты** - HTML отчеты о результатах тестирования
|
|
||||||
- **🔧 CI/CD команды** - автоматизированное тестирование, линтинг и развертывание
|
|
||||||
- **📸 Снапшоты** - сохранение и восстановление состояния лаборатории
|
|
||||||
- **🌐 Service Mesh** - Istio с Kiali для визуализации
|
|
||||||
- **📈 Мониторинг** - Prometheus, Grafana для полной наблюдаемости
|
|
||||||
|
|
||||||
## 🚀 Быстрый старт
|
### 2. **Дублирование файлов preset'ов**
|
||||||
|
- ✅ **Исправлено**: Создан уникальный `default.yml` preset с 2 хостами (Debian + RHEL)
|
||||||
|
- ✅ **Сохранено**: `minimal.yml` для быстрого тестирования с 1 хостом
|
||||||
|
- ✅ **Улучшено**: Различные конфигурации для разных сценариев тестирования
|
||||||
|
|
||||||
### Предварительные требования
|
### 3. **Проблемы с именами контейнеров**
|
||||||
|
- ✅ **Исправлено**: Унифицированы имена контейнеров (`ansible-controller`)
|
||||||
|
- ✅ **Обновлено**: Все файлы теперь используют одинаковые имена контейнеров
|
||||||
|
|
||||||
- Docker 20.0+
|
### 4. **Проблемы с путями**
|
||||||
- Docker Compose 2.0+
|
- ✅ **Исправлено**: Пути в `create.yml` и `destroy.yml` теперь используют `preset.yml`
|
||||||
- Make
|
- ✅ **Добавлено**: Fallback значения для случаев отсутствия preset файлов
|
||||||
- Git
|
- ✅ **Улучшено**: Более надежная работа с переменными
|
||||||
|
|
||||||
### Установка
|
### 5. **Дополнительные улучшения**
|
||||||
|
- ✅ **Добавлено**: Универсальная Docker Compose конфигурация с поддержкой preset'ов
|
||||||
```bash
|
- ✅ **Создан**: Dockerfile для проекта
|
||||||
# Клонировать репозиторий
|
- ✅ **Добавлено**: Переменные окружения в `env.example`
|
||||||
git clone https://github.com/your-username/ansible-template.git
|
- ✅ **Улучшено**: Расширенная справка и команды Docker
|
||||||
cd ansible-template
|
- ✅ **Добавлено**: Команды для работы с preset'ами через Docker Compose
|
||||||
|
|
||||||
# Запустить проект (автоматическая инициализация)
|
|
||||||
make
|
|
||||||
# При первом запуске автоматически запустится интерактивная настройка:
|
|
||||||
# - Название проекта, версия, автор, сайт
|
|
||||||
# - Настройки Docker (образ, сеть)
|
|
||||||
# - Настройки лаборатории (сценарий, пресет)
|
|
||||||
# - Настройки Kubernetes (контекст, версии Istio/Kind)
|
|
||||||
# - Пути к папкам и файлам
|
|
||||||
# После настройки откроется главное меню
|
|
||||||
|
|
||||||
# Установить pre-commit хуки (опционально)
|
|
||||||
make pre-commit-install
|
|
||||||
```
|
|
||||||
|
|
||||||
### Первый запуск
|
|
||||||
|
|
||||||
```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 role playbook NAME=my-role # Управление playbooks роли
|
|
||||||
|
|
||||||
# Проверка всего проекта
|
|
||||||
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 # Очистить лабораторию
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🎯 Новые возможности
|
|
||||||
|
|
||||||
### Интерактивный интерфейс
|
|
||||||
|
|
||||||
Проект теперь имеет полноценный TUI (Text User Interface) с whiptail:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Главное меню (запускается автоматически)
|
|
||||||
make
|
|
||||||
|
|
||||||
# Интерактивные команды
|
|
||||||
make preset-create-interactive # Создание пресета через диалоги
|
|
||||||
make role-create-interactive # Создание роли через диалоги
|
|
||||||
```
|
|
||||||
|
|
||||||
### Автоматическая инициализация
|
|
||||||
|
|
||||||
При первом запуске проекта автоматически запускается интерактивная настройка:
|
|
||||||
|
|
||||||
- Настройка основных параметров проекта
|
|
||||||
- Конфигурация Docker и лаборатории
|
|
||||||
- Настройка Kubernetes и мониторинга
|
|
||||||
- Создание необходимых файлов и папок
|
|
||||||
|
|
||||||
### CI/CD команды
|
|
||||||
|
|
||||||
Полный набор команд для автоматизированного тестирования:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Основные CI/CD команды
|
|
||||||
make ci-validate # Валидация проекта
|
|
||||||
make ci-lint # Проверка синтаксиса
|
|
||||||
make ci-test # Запуск тестов
|
|
||||||
make ci-deploy # Развертывание
|
|
||||||
make ci-security # Проверка безопасности
|
|
||||||
make ci-report # Генерация отчета
|
|
||||||
make ci-cleanup # Очистка после тестов
|
|
||||||
|
|
||||||
# Комбинированные команды
|
|
||||||
make ci-full # Полный цикл (lint + test + deploy)
|
|
||||||
make ci-all # Все проверки
|
|
||||||
```
|
|
||||||
|
|
||||||
### Управление ролями
|
|
||||||
|
|
||||||
Интерактивное создание и управление Ansible ролями:
|
|
||||||
|
|
||||||
- Автоматическое создание структуры роли
|
|
||||||
- Универсальные задачи для Debian и RHEL
|
|
||||||
- Создание handlers, defaults, meta файлов
|
|
||||||
- Интерактивная настройка параметров
|
|
||||||
|
|
||||||
## 📚 Документация
|
|
||||||
|
|
||||||
### Основные разделы
|
|
||||||
|
|
||||||
- **[Универсальная лаборатория](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/
|
AnsibleTemplate/
|
||||||
├── README.md # Основная документация
|
├── molecule/
|
||||||
├── Makefile # Команды управления
|
│ ├── default/ # Molecule конфигурация
|
||||||
├── docker-compose.yaml # Docker Compose конфигурация
|
│ │ ├── create.yml # Создание тестовых контейнеров
|
||||||
├── vault-password.txt # Пароль для Ansible Vault
|
│ │ ├── converge.yml # Запуск тестов
|
||||||
├── docs/ # Документация
|
│ │ ├── destroy.yml # Удаление контейнеров
|
||||||
│ ├── universal-lab.md # Руководство по лаборатории
|
│ │ └── site.yml # Основной playbook
|
||||||
│ ├── presets.md # Описание пресетов
|
│ └── presets/ # Preset'ы конфигурации
|
||||||
│ ├── roles.md # Структура ролей
|
│ ├── default.yml # Стандартный preset (2 хоста)
|
||||||
│ ├── examples.md # Примеры использования
|
│ ├── minimal.yml # Минимальный preset (1 хост)
|
||||||
│ ├── troubleshooting.md # Решение проблем
|
│ ├── standard.yml # Расширенный preset (3 хоста)
|
||||||
│ └── api.md # API Reference
|
│ └── docker.yml # Docker preset (DinD/DOoD)
|
||||||
├── ci-cd/ # CI/CD конфигурация
|
├── roles/ # Ansible роли
|
||||||
│ ├── README.md # Документация CI/CD
|
├── vault/ # Зашифрованные секреты
|
||||||
│ ├── .gitlab-ci.yml # GitLab CI/CD
|
├── inventory/ # Инвентори файлы
|
||||||
│ ├── gitlab/ # GitLab Runner
|
├── Makefile # Основные команды
|
||||||
│ └── dockerfiles/ # Dockerfile'ы для разных ОС
|
├── docker-compose.yml # Docker Compose конфигурация
|
||||||
├── molecule/ # Molecule конфигурация
|
├── Dockerfile # Docker образ
|
||||||
│ ├── universal/ # Универсальный сценарий
|
└── env.example # Переменные окружения
|
||||||
│ │ ├── 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 конфигурация
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🤝 Участие в разработке
|
## 🚀 Использование
|
||||||
|
|
||||||
### Установка для разработки
|
### 🧪 Тестирование (Docker контейнеры)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Клонировать репозиторий
|
# Просмотр доступных preset'ов
|
||||||
git clone https://github.com/your-username/ansible-template.git
|
make role presets
|
||||||
cd ansible-template
|
|
||||||
|
|
||||||
# Установить pre-commit хуки
|
# Тестирование с разными preset'ами
|
||||||
make pre-commit-install
|
make role test # default preset
|
||||||
|
make role test minimal # minimal preset
|
||||||
# Запустить тесты
|
make role test standard # standard preset
|
||||||
make lab-test
|
make role test docker # docker preset
|
||||||
|
make role test performance # performance preset
|
||||||
|
make role test security # security preset
|
||||||
|
make role test my-custom-preset # любой custom preset
|
||||||
```
|
```
|
||||||
|
|
||||||
### Создание нового пресета
|
**Особенности тестирования:**
|
||||||
|
- Использует Docker контейнеры для изоляции
|
||||||
|
- Динамический inventory создается из preset файлов
|
||||||
|
- Временные контейнеры (u1, u2, u3, ...)
|
||||||
|
- Автоматическая очистка после тестов
|
||||||
|
|
||||||
1. Создать файл в `molecule/presets/your-preset.yml`
|
### 🚀 Развертывание (Реальные серверы)
|
||||||
2. Добавить описание в `docs/presets.md`
|
|
||||||
3. Протестировать: `make lab-test LAB_SPEC=molecule/presets/your-preset.yml`
|
|
||||||
4. Создать Pull Request
|
|
||||||
|
|
||||||
### Создание новой роли
|
```bash
|
||||||
|
# Развертывание на реальные серверы
|
||||||
|
make role deploy # развертывание ролей
|
||||||
|
```
|
||||||
|
|
||||||
1. Создать структуру роли в `roles/your-role/`
|
**Особенности развертывания:**
|
||||||
2. Добавить описание в `docs/roles.md`
|
- Использует статический `inventory/hosts.ini`
|
||||||
3. Протестировать с подходящим пресетом
|
- Подключение по SSH к реальным серверам
|
||||||
4. Создать Pull Request
|
- Dry-run проверка перед развертыванием
|
||||||
|
- Подтверждение пользователя
|
||||||
|
|
||||||
## 📄 Лицензия
|
### 🔧 Вспомогательные команды
|
||||||
|
|
||||||
Этот проект распространяется под лицензией MIT. См. файл [LICENSE](LICENSE) для подробностей.
|
```bash
|
||||||
|
# Docker команды
|
||||||
|
make docker clean # очистить Docker ресурсы
|
||||||
|
|
||||||
## 👥 Авторы
|
# Другие команды
|
||||||
|
make role lint # проверка синтаксиса
|
||||||
|
make vault create # создание секретов
|
||||||
|
make help # полная справка
|
||||||
|
```
|
||||||
|
|
||||||
- **Сергей Антропов** - *Основной разработчик* - [devops.org.ru](https://devops.org.ru)
|
### Preset'ы конфигурации
|
||||||
|
|
||||||
## 🙏 Благодарности
|
| Preset | Описание | Хосты | Использование |
|
||||||
|
|--------|----------|-------|---------------|
|
||||||
|
| `default` | Стандартный preset | 2 хоста (Debian + RHEL) | Базовое тестирование |
|
||||||
|
| `minimal` | Минимальный preset | 1 хост (Debian) | Быстрое тестирование |
|
||||||
|
| `standard` | Расширенный preset | 3 хоста (Debian + RHEL + Debian) | Полное тестирование |
|
||||||
|
| `docker` | Docker preset | DinD + DOoD узлы | Тестирование Docker функциональности |
|
||||||
|
| `performance` | Performance preset | 5 хостов (Debian + RHEL) | Нагрузочное тестирование |
|
||||||
|
| `security` | Security preset | 3 хоста (Debian + RHEL) | Тестирование безопасности |
|
||||||
|
| `[custom]` | Любой custom preset | Любое количество | Пользовательские сценарии |
|
||||||
|
|
||||||
- [Ansible](https://www.ansible.com/) - за отличный инструмент автоматизации
|
## 🔧 Технические детали
|
||||||
- [Molecule](https://molecule.readthedocs.io/) - за фреймворк тестирования
|
|
||||||
- [Docker](https://www.docker.com/) - за контейнеризацию
|
### Исправления в Makefile
|
||||||
- [Kubernetes](https://kubernetes.io/) - за оркестрацию
|
|
||||||
- [Istio](https://istio.io/) - за service mesh
|
1. **Универсальное определение preset'а**:
|
||||||
|
```bash
|
||||||
|
ARGS="$(filter-out test,$(MAKECMDGOALS))"
|
||||||
|
PRESET="$$(echo $$ARGS | cut -d' ' -f1)"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Проверка существования preset'ов с подробной справкой**:
|
||||||
|
```bash
|
||||||
|
if [ ! -f "molecule/presets/$$PRESET.yml" ]; then
|
||||||
|
echo "❌ Ошибка: Пресет '$PRESET' не найден!"
|
||||||
|
# Показать доступные preset'ы и примеры использования
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Динамическая загрузка в Ansible**:
|
||||||
|
```yaml
|
||||||
|
- name: Load preset configuration
|
||||||
|
include_vars: "{{ preset_file }}"
|
||||||
|
when: preset_file is file
|
||||||
|
ignore_errors: true
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Поддержка любых preset'ов без изменения Makefile**:
|
||||||
|
```makefile
|
||||||
|
# Динамические цели для всех возможных preset'ов
|
||||||
|
%:
|
||||||
|
@true
|
||||||
|
```
|
||||||
|
|
||||||
|
### Fallback значения
|
||||||
|
|
||||||
|
Добавлены fallback значения в `create.yml` и `destroy.yml` для случаев отсутствия preset файлов:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
vars:
|
||||||
|
# Fallback значения если preset.yml не найден
|
||||||
|
docker_network: labnet
|
||||||
|
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
|
||||||
|
# ... остальные значения
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🐳 Docker поддержка
|
||||||
|
|
||||||
|
### Упрощенная архитектура
|
||||||
|
|
||||||
|
Docker-compose удален из проекта, так как он избыточен при наличии универсальной системы preset'ов. Все тестирование происходит через preset систему:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Основное тестирование через preset систему
|
||||||
|
make role test [любой_preset] # универсальное тестирование
|
||||||
|
make role presets # показать доступные preset'ы
|
||||||
|
|
||||||
|
# Очистка Docker ресурсов
|
||||||
|
make docker clean # очистить Docker ресурсы
|
||||||
|
```
|
||||||
|
|
||||||
|
**Преимущества упрощенной архитектуры:**
|
||||||
|
- ✅ **Простота**: Один способ тестирования через preset систему
|
||||||
|
- ✅ **Универсальность**: Любой preset без дополнительной конфигурации
|
||||||
|
- ✅ **Автономность**: Preset система сама управляет контейнерами
|
||||||
|
- ✅ **Меньше сложности**: Нет дублирования функциональности
|
||||||
|
|
||||||
|
## 📝 Переменные окружения
|
||||||
|
|
||||||
|
Скопируйте `env.example` в `.env` и настройте под свои нужды:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 Результат
|
||||||
|
|
||||||
|
Теперь система тестирования работает корректно:
|
||||||
|
|
||||||
|
1. ✅ **Полностью универсальная система preset'ов - любой preset без изменения Makefile**
|
||||||
|
2. ✅ **Динамическое определение preset'ов через `filter-out` и `cut`**
|
||||||
|
3. ✅ **Проверка существования preset'ов с подробной справкой**
|
||||||
|
4. ✅ **Унифицированные имена контейнеров**
|
||||||
|
5. ✅ **Надежные fallback значения**
|
||||||
|
6. ✅ **Упрощенная архитектура без docker-compose**
|
||||||
|
7. ✅ **Поддержка неограниченного количества custom preset'ов**
|
||||||
|
8. ✅ **Автономная preset система сама управляет контейнерами**
|
||||||
|
9. ✅ **Подробная документация и справка**
|
||||||
|
|
||||||
## 📞 Поддержка
|
## 📞 Поддержка
|
||||||
|
|
||||||
- **Документация**: [docs/](docs/)
|
При возникновении проблем:
|
||||||
- **Issues**: [GitHub Issues](https://github.com/your-username/ansible-template/issues)
|
|
||||||
- **Discussions**: [GitHub Discussions](https://github.com/your-username/ansible-template/discussions)
|
1. Проверьте наличие Docker и Docker Compose
|
||||||
- **Сайт**: [devops.org.ru](https://devops.org.ru)
|
2. Убедитесь, что все preset файлы существуют
|
||||||
|
3. Используйте `make help` для справки
|
||||||
|
4. Проверьте логи: `make docker shell` и `docker logs ansible-controller`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Сделано с ❤️ для сообщества DevOps**
|
**Автор:** Сергей Антропов
|
||||||
|
**Сайт:** https://devops.org.ru
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[defaults]
|
[defaults]
|
||||||
inventory = inventory/hosts
|
inventory = inventory/hosts.ini
|
||||||
vault_password_file = vault-password.txt
|
# vault_password_file = vault/.vault
|
||||||
remote_user = devops
|
remote_user = devops
|
||||||
host_key_checking = False
|
host_key_checking = False
|
||||||
enable_plugins = yaml, ini
|
enable_plugins = yaml, ini
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
stages:
|
|
||||||
- lint
|
|
||||||
- test
|
|
||||||
- deploy
|
|
||||||
- notify
|
|
||||||
|
|
||||||
services:
|
|
||||||
- name: docker:dind
|
|
||||||
command: ["--tls=false"]
|
|
||||||
|
|
||||||
variables:
|
|
||||||
DOCKER_IMAGE: "hub.cism-ms.ru/ansible/ansible:latest"
|
|
||||||
DOCKER_TLS_CERTDIR: ""
|
|
||||||
ANSIBLE_FORCE_COLOR: "true"
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- echo "$CI_REGISTRY_PASSWORD" | docker login hub.cism-ms.ru -u "$CI_REGISTRY_USER" --password-stdin
|
|
||||||
- docker pull $DOCKER_IMAGE
|
|
||||||
- echo "Fixing directory permissions..."
|
|
||||||
- chmod o-w $CI_PROJECT_DIR
|
|
||||||
|
|
||||||
lint:
|
|
||||||
stage: lint
|
|
||||||
script:
|
|
||||||
- echo "Начинаем стейдж Lint"
|
|
||||||
- echo "Распаковываем секреты..."
|
|
||||||
- ansible-vault decrypt vars/secrets.yml --vault-password-file ./vault-password.txt
|
|
||||||
- echo "Запускаем ansible-lint..."
|
|
||||||
- ansible-lint roles/*
|
|
||||||
- echo "Упаковываем секреты..."
|
|
||||||
- ansible-vault encrypt vars/secrets.yml --encrypt-vault-id default --vault-password-file ./vault-password.txt
|
|
||||||
allow_failure: false
|
|
||||||
rules:
|
|
||||||
- if: $CI_COMMIT_REF_NAME != "main" && $CI_COMMIT_REF_NAME != "master"
|
|
||||||
|
|
||||||
test:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- echo "Распаковываем секреты..."
|
|
||||||
- ansible-vault decrypt --vault-password-file ./vault-password.txt vars/secrets.yml
|
|
||||||
- echo "Запускаем тесты через Молекулу..."
|
|
||||||
- molecule test --parallel --destroy=always
|
|
||||||
- echo "Упаковываем секреты..."
|
|
||||||
- ansible-vault encrypt vars/secrets.yml --encrypt-vault-id default --vault-password-file ./vault-password.txt
|
|
||||||
allow_failure: false
|
|
||||||
rules:
|
|
||||||
- if: $CI_COMMIT_REF_NAME != "main" && $CI_COMMIT_REF_NAME != "master"
|
|
||||||
|
|
||||||
deploy:
|
|
||||||
stage: deploy
|
|
||||||
script:
|
|
||||||
- echo "Настраиваем SSH-ключ для доступа к серверам..."
|
|
||||||
# Создаем директорию .ssh и настраиваем права доступа
|
|
||||||
- mkdir -p ~/.ssh
|
|
||||||
- chmod 700 ~/.ssh
|
|
||||||
# Записываем SSH-ключ в файл ~/.ssh/id_rsa
|
|
||||||
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
|
|
||||||
- chmod 600 ~/.ssh/id_rsa
|
|
||||||
# Запускаем основной пайплайн
|
|
||||||
- echo "Распаковываем секреты..."
|
|
||||||
- ansible-vault decrypt --vault-password-file ./vault-password.txt vars/secrets.yml
|
|
||||||
- echo "Все ок. Деплоим в прод..."
|
|
||||||
- ansible-playbook roles/deploy.yaml
|
|
||||||
- echo "Упаковываем секреты..."
|
|
||||||
- ansible-vault encrypt vars/secrets.yml --encrypt-vault-id default --vault-password-file ./vault-password.txt
|
|
||||||
# Удаляем ключ
|
|
||||||
- rm -rf ~/.ssh
|
|
||||||
rules:
|
|
||||||
- if: $CI_COMMIT_REF_NAME != "main" && $CI_COMMIT_REF_NAME != "master"
|
|
||||||
when: manual
|
|
||||||
|
|
||||||
notify:
|
|
||||||
stage: notify
|
|
||||||
script:
|
|
||||||
- |
|
|
||||||
if [ "$CI_JOB_STATUS" == "success" ]; then
|
|
||||||
MESSAGE="✅ Пайплайн успешно завершен!%0AПроект: $CI_PROJECT_NAME%0AВетка: $CI_COMMIT_REF_NAME%0AСтатус: $CI_JOB_STATUS"
|
|
||||||
else
|
|
||||||
MESSAGE="❌ Пайплайн завершен с ошибкой!%0AПроект: $CI_PROJECT_NAME%0AВетка: $CI_COMMIT_REF_NAME%0AСтатус: $CI_JOB_STATUS"
|
|
||||||
fi
|
|
||||||
# curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \
|
|
||||||
# -d "chat_id=$TELEGRAM_CHAT_ID" \
|
|
||||||
# -d "text=$MESSAGE"
|
|
||||||
rules:
|
|
||||||
- if: $CI_JOB_STATUS # Отправлять уведомление только после завершения пайплайна
|
|
||||||
|
|
||||||
after_script:
|
|
||||||
- echo "Работа пайплайна завершена"
|
|
||||||
|
|
||||||
123
ci-cd/README.md
123
ci-cd/README.md
@@ -1,123 +0,0 @@
|
|||||||
# 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,40 +0,0 @@
|
|||||||
# Используем готовый образ с Ansible
|
|
||||||
FROM geerlingguy/docker-ubuntu2204-ansible:latest
|
|
||||||
|
|
||||||
# Добавляем метаданные
|
|
||||||
LABEL maintainer="Сергей Антропов <sergey@antropoff.ru>"
|
|
||||||
LABEL description="Этот Dockerfile создан для внедрения подхода IaC в Ansible."
|
|
||||||
LABEL version="0.1"
|
|
||||||
LABEL contact.website="https://devops.org.ru"
|
|
||||||
|
|
||||||
# Устанавливаем переменные окружения
|
|
||||||
ENV PYTHONUNBUFFERED=1
|
|
||||||
ENV EDITOR=nano
|
|
||||||
|
|
||||||
# Устанавливаем дополнительные зависимости Python для Molecule
|
|
||||||
RUN pip install --upgrade pip && \
|
|
||||||
pip install \
|
|
||||||
molecule \
|
|
||||||
molecule-docker \
|
|
||||||
ansible-lint \
|
|
||||||
yamllint \
|
|
||||||
docker \
|
|
||||||
&& rm -rf /root/.cache/pip
|
|
||||||
|
|
||||||
# Создаем рабочую директорию
|
|
||||||
WORKDIR /ansible
|
|
||||||
|
|
||||||
# Копируем файлы проекта
|
|
||||||
COPY . /ansible/
|
|
||||||
|
|
||||||
# Устанавливаем права на выполнение (если папка scripts существует)
|
|
||||||
RUN if [ -d /ansible/scripts ]; then chmod +x /ansible/scripts/*.sh; fi
|
|
||||||
|
|
||||||
# Устанавливаем пользователя
|
|
||||||
USER root
|
|
||||||
|
|
||||||
# Открываем порт для SSH
|
|
||||||
EXPOSE 22
|
|
||||||
|
|
||||||
# Команда по умолчанию
|
|
||||||
CMD ["/bin/bash"]
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
# Сборка контейнера с systemd для удобного тестирования ролей Ansible через Molecule
|
|
||||||
|
|
||||||
# Используем официальный образ Fedora
|
|
||||||
FROM quay.io/fedora/python-312
|
|
||||||
|
|
||||||
USER root
|
|
||||||
|
|
||||||
# Обновляем пакеты и устанавливаем systemd и необходимые пакеты
|
|
||||||
RUN dnf update -y && \
|
|
||||||
dnf install -y --nodocs --setopt=install_weak_deps=False \
|
|
||||||
systemd rsync \
|
|
||||||
git \
|
|
||||||
openssh \
|
|
||||||
gcc \
|
|
||||||
libffi-devel \
|
|
||||||
openssl-devel \
|
|
||||||
make \
|
|
||||||
sudo \
|
|
||||||
openssh-clients \
|
|
||||||
less \
|
|
||||||
ca-certificates \
|
|
||||||
curl \
|
|
||||||
gnupg2 \
|
|
||||||
nano \
|
|
||||||
sshpass \
|
|
||||||
redhat-lsb-core \
|
|
||||||
&& dnf clean all && \
|
|
||||||
rm -rf /var/cache/dnf /tmp/* /var/tmp/*
|
|
||||||
|
|
||||||
# Устанавливаем docker-compose
|
|
||||||
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \
|
|
||||||
chmod +x /usr/local/bin/docker-compose
|
|
||||||
|
|
||||||
# Устанавливаем Python пакеты для Ansible
|
|
||||||
RUN pip install --upgrade pip && \
|
|
||||||
pip install \
|
|
||||||
ansible \
|
|
||||||
ansible-vault \
|
|
||||||
molecule \
|
|
||||||
molecule-docker \
|
|
||||||
ansible-lint \
|
|
||||||
yamllint \
|
|
||||||
docker \
|
|
||||||
&& rm -rf /root/.cache/pip
|
|
||||||
|
|
||||||
# Настраиваем окружение для systemd
|
|
||||||
ENV container=docker
|
|
||||||
STOPSIGNAL SIGRTMIN+3
|
|
||||||
|
|
||||||
# Создаем необходимые директории для systemd
|
|
||||||
VOLUME [ "/sys/fs/cgroup" ]
|
|
||||||
|
|
||||||
# Запускаем systemd при старте контейнера
|
|
||||||
CMD ["/sbin/init"]
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
# Сборка контейнера с systemd для удобного тестирования ролей Ansible через Molecule
|
|
||||||
|
|
||||||
# Используем готовый образ с Ansible (более старый, но стабильный)
|
|
||||||
FROM geerlingguy/docker-ubuntu2004-ansible:latest
|
|
||||||
|
|
||||||
# Устанавливаем переменные окружения
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
|
||||||
ENV container=docker
|
|
||||||
|
|
||||||
# Устанавливаем дополнительные пакеты для тестирования
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get install -y --no-install-recommends \
|
|
||||||
systemd \
|
|
||||||
systemd-sysv \
|
|
||||||
rsync \
|
|
||||||
git \
|
|
||||||
ssh \
|
|
||||||
gcc \
|
|
||||||
libffi-dev \
|
|
||||||
libssl-dev \
|
|
||||||
make \
|
|
||||||
sudo \
|
|
||||||
sshpass \
|
|
||||||
openssh-client \
|
|
||||||
nano \
|
|
||||||
less \
|
|
||||||
ca-certificates \
|
|
||||||
curl \
|
|
||||||
gnupg \
|
|
||||||
lsb-release \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# Устанавливаем Python пакеты для Ansible с обновлением зависимостей
|
|
||||||
RUN pip install --upgrade pip && \
|
|
||||||
pip install --upgrade \
|
|
||||||
requests \
|
|
||||||
PyYAML \
|
|
||||||
ansible-core \
|
|
||||||
&& pip install \
|
|
||||||
ansible \
|
|
||||||
"ansible-vault<4.0.0" \
|
|
||||||
molecule \
|
|
||||||
molecule-docker \
|
|
||||||
ansible-lint \
|
|
||||||
yamllint \
|
|
||||||
docker \
|
|
||||||
&& rm -rf /root/.cache/pip
|
|
||||||
|
|
||||||
# Устанавливаем docker-compose
|
|
||||||
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \
|
|
||||||
chmod +x /usr/local/bin/docker-compose
|
|
||||||
|
|
||||||
|
|
||||||
# Указываем, что контейнер использует systemd в качестве init-системы
|
|
||||||
ENV container=docker
|
|
||||||
STOPSIGNAL SIGRTMIN+3
|
|
||||||
|
|
||||||
# Создаем необходимые директории для systemd
|
|
||||||
VOLUME [ "/sys/fs/cgroup" ]
|
|
||||||
|
|
||||||
# Запускаем systemd при старте контейнера
|
|
||||||
CMD ["/sbin/init"]
|
|
||||||
51
cicd/.gitlab-ci.yml
Normal file
51
cicd/.gitlab-ci.yml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# GitLab CI для AnsibleTemplate
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- test
|
||||||
|
- deploy
|
||||||
|
|
||||||
|
variables:
|
||||||
|
DOCKER_IMAGE: "quay.io/ansible/creator-ee:latest"
|
||||||
|
DOCKER_TLS_CERTDIR: ""
|
||||||
|
ANSIBLE_FORCE_COLOR: "true"
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- echo "Установка зависимостей..."
|
||||||
|
- pip install molecule[docker] ansible-lint
|
||||||
|
- ansible-galaxy collection install -r requirements.yml
|
||||||
|
|
||||||
|
# Тестирование с Molecule
|
||||||
|
test:
|
||||||
|
stage: test
|
||||||
|
image: $DOCKER_IMAGE
|
||||||
|
services:
|
||||||
|
- docker:dind
|
||||||
|
variables:
|
||||||
|
DOCKER_TLS_CERTDIR: ""
|
||||||
|
script:
|
||||||
|
- echo "Запуск тестов Molecule..."
|
||||||
|
- cd molecule/universal
|
||||||
|
- molecule test -s universal
|
||||||
|
artifacts:
|
||||||
|
reports:
|
||||||
|
junit: molecule/universal/.molecule/reports/junit.xml
|
||||||
|
paths:
|
||||||
|
- molecule/universal/.molecule/
|
||||||
|
expire_in: 1 week
|
||||||
|
only:
|
||||||
|
- merge_requests
|
||||||
|
- main
|
||||||
|
- develop
|
||||||
|
|
||||||
|
# Деплой (если нужен)
|
||||||
|
deploy:
|
||||||
|
stage: deploy
|
||||||
|
image: $DOCKER_IMAGE
|
||||||
|
script:
|
||||||
|
- echo "Деплой не настроен"
|
||||||
|
- echo "Добавьте логику деплоя в этот job"
|
||||||
|
when: manual
|
||||||
|
only:
|
||||||
|
- main
|
||||||
53
cicd/azure-devops/azure-pipelines.yml
Normal file
53
cicd/azure-devops/azure-pipelines.yml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# Azure DevOps Pipeline для AnsibleTemplate
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- main
|
||||||
|
- develop
|
||||||
|
|
||||||
|
pool:
|
||||||
|
vmImage: 'ubuntu-latest'
|
||||||
|
|
||||||
|
variables:
|
||||||
|
ANSIBLE_FORCE_COLOR: 'true'
|
||||||
|
DOCKER_TLS_CERTDIR: ''
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- stage: Test
|
||||||
|
displayName: 'Test Stage'
|
||||||
|
jobs:
|
||||||
|
- job: TestJob
|
||||||
|
displayName: 'Run Tests'
|
||||||
|
steps:
|
||||||
|
- task: UsePythonVersion@0
|
||||||
|
inputs:
|
||||||
|
versionSpec: '3.11'
|
||||||
|
displayName: 'Use Python 3.11'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
pip install --upgrade pip
|
||||||
|
pip install molecule[docker] ansible-lint
|
||||||
|
ansible-galaxy collection install -r requirements.yml
|
||||||
|
displayName: 'Install Dependencies'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
ansible-lint molecule/universal/
|
||||||
|
displayName: 'Run Ansible Lint'
|
||||||
|
|
||||||
|
- script: |
|
||||||
|
cd molecule/universal
|
||||||
|
molecule test -s universal
|
||||||
|
displayName: 'Run Molecule Tests'
|
||||||
|
|
||||||
|
- task: PublishTestResults@2
|
||||||
|
inputs:
|
||||||
|
testResultsFiles: 'molecule/universal/.molecule/reports/junit.xml'
|
||||||
|
testRunTitle: 'Molecule Test Results'
|
||||||
|
condition: always()
|
||||||
|
|
||||||
|
- task: PublishBuildArtifacts@1
|
||||||
|
inputs:
|
||||||
|
pathToPublish: 'molecule/universal/.molecule'
|
||||||
|
artifactName: 'molecule-reports'
|
||||||
|
condition: always()
|
||||||
70
cicd/github/workflows.yml
Normal file
70
cicd/github/workflows.yml
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
# GitHub Actions Workflow для AnsibleTemplate
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
name: Ansible Testing
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main, develop ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ main ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Install system dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y docker.io
|
||||||
|
sudo systemctl start docker
|
||||||
|
sudo usermod -aG docker $USER
|
||||||
|
|
||||||
|
- name: Install Python dependencies
|
||||||
|
run: |
|
||||||
|
pip install --upgrade pip
|
||||||
|
pip install molecule[docker] ansible-lint
|
||||||
|
ansible-galaxy collection install -r requirements.yml
|
||||||
|
|
||||||
|
- name: Run Molecule tests
|
||||||
|
run: |
|
||||||
|
cd molecule/universal
|
||||||
|
molecule test -s universal
|
||||||
|
|
||||||
|
- name: Upload test results
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: molecule-reports
|
||||||
|
path: molecule/universal/.molecule/
|
||||||
|
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.11'
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
pip install ansible-lint
|
||||||
|
ansible-galaxy collection install -r requirements.yml
|
||||||
|
|
||||||
|
- name: Run Ansible Lint
|
||||||
|
run: |
|
||||||
|
ansible-lint molecule/universal/
|
||||||
59
cicd/jenkins/Jenkinsfile
vendored
Normal file
59
cicd/jenkins/Jenkinsfile
vendored
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
// Jenkins Pipeline для AnsibleTemplate
|
||||||
|
// Автор: Сергей Антропов
|
||||||
|
// Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
|
||||||
|
environment {
|
||||||
|
ANSIBLE_FORCE_COLOR = 'true'
|
||||||
|
DOCKER_TLS_CERTDIR = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Checkout') {
|
||||||
|
steps {
|
||||||
|
checkout scm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Install Dependencies') {
|
||||||
|
steps {
|
||||||
|
sh '''
|
||||||
|
pip install --upgrade pip
|
||||||
|
pip install molecule[docker] ansible-lint
|
||||||
|
ansible-galaxy collection install -r requirements.yml
|
||||||
|
'''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Lint') {
|
||||||
|
steps {
|
||||||
|
sh 'ansible-lint molecule/universal/'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Test') {
|
||||||
|
steps {
|
||||||
|
dir('molecule/universal') {
|
||||||
|
sh 'molecule test -s universal'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
archiveArtifacts artifacts: 'molecule/universal/.molecule/**/*', allowEmptyArchive: true
|
||||||
|
publishTestResults testResultsPattern: 'molecule/universal/.molecule/reports/junit.xml'
|
||||||
|
}
|
||||||
|
|
||||||
|
success {
|
||||||
|
echo 'Pipeline completed successfully!'
|
||||||
|
}
|
||||||
|
|
||||||
|
failure {
|
||||||
|
echo 'Pipeline failed!'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,138 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Исправленная команда создания роли
|
|
||||||
ROLE_NAME="$1"
|
|
||||||
ROLE_DESC="$2"
|
|
||||||
ROLE_PACKAGE="$3"
|
|
||||||
ROLE_SERVICE="$4"
|
|
||||||
ROLE_TAGS="$5"
|
|
||||||
|
|
||||||
if [ -z "$ROLE_NAME" ]; then
|
|
||||||
echo "Использование: $0 ROLE_NAME ROLE_DESC ROLE_PACKAGE ROLE_SERVICE ROLE_TAGS"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Создание роли: $ROLE_NAME"
|
|
||||||
mkdir -p ./roles/${ROLE_NAME}/{tasks,handlers,templates,files,vars,defaults,meta,tests,playbooks}
|
|
||||||
|
|
||||||
# Создаем main.yml
|
|
||||||
cat > ./roles/${ROLE_NAME}/tasks/main.yml << 'MAIN_EOF'
|
|
||||||
---
|
|
||||||
# Основные задачи роли ROLE_NAME_PLACEHOLDER
|
|
||||||
# Автор: Сергей Антропов
|
|
||||||
# Сайт: https://devops.org.ru
|
|
||||||
|
|
||||||
- name: Включить задачи для Debian/Ubuntu
|
|
||||||
import_tasks: debian.yml
|
|
||||||
when: ansible_os_family == 'Debian'
|
|
||||||
|
|
||||||
- name: Включить задачи для RHEL/CentOS
|
|
||||||
import_tasks: redhat.yml
|
|
||||||
when: ansible_os_family == 'RedHat'
|
|
||||||
MAIN_EOF
|
|
||||||
|
|
||||||
# Создаем debian.yml
|
|
||||||
cat > ./roles/${ROLE_NAME}/tasks/debian.yml << 'DEBIAN_EOF'
|
|
||||||
---
|
|
||||||
# Задачи для Debian/Ubuntu
|
|
||||||
|
|
||||||
- name: Обновить кэш пакетов
|
|
||||||
apt:
|
|
||||||
update_cache: yes
|
|
||||||
cache_valid_time: 3600
|
|
||||||
|
|
||||||
- name: Установить пакет PACKAGE_PLACEHOLDER
|
|
||||||
apt:
|
|
||||||
name: "{{ ROLE_NAME_PLACEHOLDER_package }}"
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Запустить и включить сервис SERVICE_PLACEHOLDER
|
|
||||||
systemd:
|
|
||||||
name: "{{ ROLE_NAME_PLACEHOLDER_service }}"
|
|
||||||
enabled: "{{ ROLE_NAME_PLACEHOLDER_enabled }}"
|
|
||||||
state: "{{ 'started' if ROLE_NAME_PLACEHOLDER_started else 'stopped' }}"
|
|
||||||
DEBIAN_EOF
|
|
||||||
|
|
||||||
# Создаем redhat.yml
|
|
||||||
cat > ./roles/${ROLE_NAME}/tasks/redhat.yml << 'REDHAT_EOF'
|
|
||||||
---
|
|
||||||
# Задачи для RHEL/CentOS
|
|
||||||
|
|
||||||
- name: Установить пакет PACKAGE_PLACEHOLDER
|
|
||||||
yum:
|
|
||||||
name: "{{ ROLE_NAME_PLACEHOLDER_package }}"
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Запустить и включить сервис SERVICE_PLACEHOLDER
|
|
||||||
systemd:
|
|
||||||
name: "{{ ROLE_NAME_PLACEHOLDER_service }}"
|
|
||||||
enabled: "{{ ROLE_NAME_PLACEHOLDER_enabled }}"
|
|
||||||
state: "{{ 'started' if ROLE_NAME_PLACEHOLDER_started else 'stopped' }}"
|
|
||||||
REDHAT_EOF
|
|
||||||
|
|
||||||
# Создаем defaults/main.yml
|
|
||||||
cat > ./roles/${ROLE_NAME}/defaults/main.yml << 'DEFAULTS_EOF'
|
|
||||||
---
|
|
||||||
# Переменные по умолчанию для роли ROLE_NAME_PLACEHOLDER
|
|
||||||
# Автор: Сергей Антропов
|
|
||||||
# Сайт: https://devops.org.ru
|
|
||||||
|
|
||||||
ROLE_NAME_PLACEHOLDER_package: PACKAGE_PLACEHOLDER
|
|
||||||
ROLE_NAME_PLACEHOLDER_service: SERVICE_PLACEHOLDER
|
|
||||||
ROLE_NAME_PLACEHOLDER_enabled: true
|
|
||||||
ROLE_NAME_PLACEHOLDER_started: true
|
|
||||||
DEFAULTS_EOF
|
|
||||||
|
|
||||||
# Создаем meta/main.yml
|
|
||||||
cat > ./roles/${ROLE_NAME}/meta/main.yml << 'META_EOF'
|
|
||||||
---
|
|
||||||
galaxy_info:
|
|
||||||
author: Сергей Антропов
|
|
||||||
description: ROLE_DESC_PLACEHOLDER
|
|
||||||
company: https://devops.org.ru
|
|
||||||
license: MIT
|
|
||||||
min_ansible_version: 2.9
|
|
||||||
platforms:
|
|
||||||
- name: Ubuntu
|
|
||||||
versions: [18.04, 20.04, 22.04]
|
|
||||||
- name: Debian
|
|
||||||
versions: [10, 11, 12]
|
|
||||||
- name: EL
|
|
||||||
versions: [7, 8, 9]
|
|
||||||
galaxy_tags: [TAGS_PLACEHOLDER]
|
|
||||||
|
|
||||||
dependencies: []
|
|
||||||
META_EOF
|
|
||||||
|
|
||||||
# Создаем handlers/main.yml
|
|
||||||
cat > ./roles/${ROLE_NAME}/handlers/main.yml << 'HANDLERS_EOF'
|
|
||||||
---
|
|
||||||
# Обработчики роли ROLE_NAME_PLACEHOLDER
|
|
||||||
|
|
||||||
- name: Перезапустить SERVICE_PLACEHOLDER
|
|
||||||
systemd:
|
|
||||||
name: "{{ ROLE_NAME_PLACEHOLDER_service }}"
|
|
||||||
state: restarted
|
|
||||||
HANDLERS_EOF
|
|
||||||
|
|
||||||
# Заменяем плейсхолдеры
|
|
||||||
sed -i '' "s/ROLE_NAME_PLACEHOLDER/${ROLE_NAME}/g" ./roles/${ROLE_NAME}/tasks/main.yml
|
|
||||||
sed -i '' "s/ROLE_NAME_PLACEHOLDER/${ROLE_NAME}/g" ./roles/${ROLE_NAME}/tasks/debian.yml
|
|
||||||
sed -i '' "s/ROLE_NAME_PLACEHOLDER/${ROLE_NAME}/g" ./roles/${ROLE_NAME}/tasks/redhat.yml
|
|
||||||
sed -i '' "s/ROLE_NAME_PLACEHOLDER/${ROLE_NAME}/g" ./roles/${ROLE_NAME}/defaults/main.yml
|
|
||||||
sed -i '' "s/ROLE_NAME_PLACEHOLDER/${ROLE_NAME}/g" ./roles/${ROLE_NAME}/meta/main.yml
|
|
||||||
sed -i '' "s/ROLE_NAME_PLACEHOLDER/${ROLE_NAME}/g" ./roles/${ROLE_NAME}/handlers/main.yml
|
|
||||||
|
|
||||||
sed -i '' "s/PACKAGE_PLACEHOLDER/${ROLE_PACKAGE}/g" ./roles/${ROLE_NAME}/tasks/debian.yml
|
|
||||||
sed -i '' "s/PACKAGE_PLACEHOLDER/${ROLE_PACKAGE}/g" ./roles/${ROLE_NAME}/tasks/redhat.yml
|
|
||||||
sed -i '' "s/PACKAGE_PLACEHOLDER/${ROLE_PACKAGE}/g" ./roles/${ROLE_NAME}/defaults/main.yml
|
|
||||||
|
|
||||||
sed -i '' "s/SERVICE_PLACEHOLDER/${ROLE_SERVICE}/g" ./roles/${ROLE_NAME}/tasks/debian.yml
|
|
||||||
sed -i '' "s/SERVICE_PLACEHOLDER/${ROLE_SERVICE}/g" ./roles/${ROLE_NAME}/tasks/redhat.yml
|
|
||||||
sed -i '' "s/SERVICE_PLACEHOLDER/${ROLE_SERVICE}/g" ./roles/${ROLE_NAME}/handlers/main.yml
|
|
||||||
|
|
||||||
sed -i '' "s/ROLE_DESC_PLACEHOLDER/${ROLE_DESC}/g" ./roles/${ROLE_NAME}/meta/main.yml
|
|
||||||
sed -i '' "s/TAGS_PLACEHOLDER/${ROLE_TAGS}/g" ./roles/${ROLE_NAME}/meta/main.yml
|
|
||||||
|
|
||||||
echo "Роль ${ROLE_NAME} создана успешно!"
|
|
||||||
echo "Структура: ./roles/${ROLE_NAME}/"
|
|
||||||
13
deploy.yml
Normal file
13
deploy.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
# Плейбук для развертывания ролей
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
- name: Test nginx role
|
||||||
|
hosts: all
|
||||||
|
become: true
|
||||||
|
roles:
|
||||||
|
- nginx
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- test
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
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/.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
|
|
||||||
|
|
||||||
# Обратная совместимость
|
|
||||||
# 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
|
|
||||||
160
dockerfiles/README.md
Normal file
160
dockerfiles/README.md
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
# Docker образы для универсальной системы тестирования
|
||||||
|
|
||||||
|
## Обзор
|
||||||
|
|
||||||
|
Эта директория содержит Docker образы для различных операционных систем и компонентов, используемых в универсальной системе тестирования Ansible ролей.
|
||||||
|
|
||||||
|
## Структура
|
||||||
|
|
||||||
|
```
|
||||||
|
dockerfiles/
|
||||||
|
├── ansible-controller/ # Ansible контроллер с предустановленными коллекциями
|
||||||
|
├── alt-linux/ # ALT Linux с systemd
|
||||||
|
├── astra-linux/ # Astra Linux с systemd
|
||||||
|
├── redos/ # RED OS с systemd
|
||||||
|
├── Makefile # Команды для сборки образов
|
||||||
|
└── README.md # Документация
|
||||||
|
```
|
||||||
|
|
||||||
|
## Доступные образы
|
||||||
|
|
||||||
|
### ansible-controller
|
||||||
|
- **Базовый образ:** `quay.io/ansible/creator-ee:latest`
|
||||||
|
- **Описание:** Ansible контроллер с предустановленными коллекциями
|
||||||
|
- **Компоненты:**
|
||||||
|
- Ansible с коллекциями (community.docker, community.general, ansible.posix)
|
||||||
|
- Docker CLI
|
||||||
|
- kubectl
|
||||||
|
- Helm
|
||||||
|
- Kind
|
||||||
|
- Istio CLI
|
||||||
|
- Дополнительные роли (geerlingguy.docker, geerlingguy.kubernetes)
|
||||||
|
|
||||||
|
### alt-linux
|
||||||
|
- **Базовый образ:** `altlinux/p9`
|
||||||
|
- **Описание:** ALT Linux с systemd
|
||||||
|
- **Компоненты:**
|
||||||
|
- systemd
|
||||||
|
- Docker
|
||||||
|
- Docker Compose
|
||||||
|
- Python3
|
||||||
|
- Пользователь ansible
|
||||||
|
|
||||||
|
### astra-linux
|
||||||
|
- **Базовый образ:** `astralinux/astra-1.7`
|
||||||
|
- **Описание:** Astra Linux с systemd
|
||||||
|
- **Компоненты:**
|
||||||
|
- systemd
|
||||||
|
- Docker
|
||||||
|
- Docker Compose
|
||||||
|
- Python3
|
||||||
|
- Пользователь ansible
|
||||||
|
|
||||||
|
### redos
|
||||||
|
- **Базовый образ:** `redos/redos:9`
|
||||||
|
- **Описание:** RED OS с systemd
|
||||||
|
- **Компоненты:**
|
||||||
|
- systemd
|
||||||
|
- Docker
|
||||||
|
- Docker Compose
|
||||||
|
- Python3
|
||||||
|
- Пользователь ansible
|
||||||
|
|
||||||
|
## Использование
|
||||||
|
|
||||||
|
### Сборка всех образов
|
||||||
|
```bash
|
||||||
|
make docker-build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Сборка конкретного образа
|
||||||
|
```bash
|
||||||
|
make docker-build IMAGE=ansible-controller
|
||||||
|
```
|
||||||
|
|
||||||
|
### Отправка образов в registry
|
||||||
|
```bash
|
||||||
|
make docker-push
|
||||||
|
```
|
||||||
|
|
||||||
|
### Очистка образов
|
||||||
|
```bash
|
||||||
|
make docker-clean
|
||||||
|
```
|
||||||
|
|
||||||
|
### Информация об образах
|
||||||
|
```bash
|
||||||
|
make docker-info
|
||||||
|
```
|
||||||
|
|
||||||
|
## Настройка registry
|
||||||
|
|
||||||
|
По умолчанию образы собираются с тегом `localhost:5000/имя:latest`. Для изменения registry:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make docker-build REGISTRY=my-registry.com
|
||||||
|
make docker-push REGISTRY=my-registry.com
|
||||||
|
```
|
||||||
|
|
||||||
|
## Использование в preset'ах
|
||||||
|
|
||||||
|
После сборки образов их можно использовать в preset'ах:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# molecule/presets/my-preset.yml
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
alt: "localhost:5000/alt-linux:latest"
|
||||||
|
astra: "localhost:5000/astra-linux:latest"
|
||||||
|
redos: "localhost:5000/redos:latest"
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
- name: alt-server
|
||||||
|
family: alt
|
||||||
|
groups: [servers]
|
||||||
|
- name: astra-server
|
||||||
|
family: astra
|
||||||
|
groups: [servers]
|
||||||
|
- name: redos-server
|
||||||
|
family: redos
|
||||||
|
groups: [servers]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Лучшие практики
|
||||||
|
|
||||||
|
### 1. Версионирование образов
|
||||||
|
```bash
|
||||||
|
make docker-build VERSION=v1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Использование registry
|
||||||
|
```bash
|
||||||
|
make docker-push REGISTRY=my-registry.com VERSION=v1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Очистка старых образов
|
||||||
|
```bash
|
||||||
|
make docker-clean
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Проблемы с сборкой
|
||||||
|
1. Проверьте доступность базовых образов
|
||||||
|
2. Убедитесь, что Docker запущен
|
||||||
|
3. Проверьте права доступа к Docker
|
||||||
|
|
||||||
|
### Проблемы с registry
|
||||||
|
1. Убедитесь, что registry доступен
|
||||||
|
2. Проверьте аутентификацию
|
||||||
|
3. Проверьте права на push
|
||||||
|
|
||||||
|
### Проблемы с образами
|
||||||
|
1. Проверьте размер образов
|
||||||
|
2. Убедитесь, что все зависимости установлены
|
||||||
|
3. Проверьте совместимость с базовыми образами
|
||||||
|
|
||||||
|
## Заключение
|
||||||
|
|
||||||
|
Эти Docker образы предоставляют готовую среду для тестирования Ansible ролей на различных операционных системах. Используйте их в своих preset'ах для создания универсальной системы тестирования.
|
||||||
51
dockerfiles/alma/Dockerfile
Normal file
51
dockerfiles/alma/Dockerfile
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
# AlmaLinux с systemd
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
# https://hub.docker.com/_/almalinux
|
||||||
|
|
||||||
|
FROM almalinux:8
|
||||||
|
|
||||||
|
# Обновляем систему
|
||||||
|
RUN dnf update -y && dnf upgrade -y
|
||||||
|
|
||||||
|
# Устанавливаем systemd и необходимые пакеты
|
||||||
|
RUN dnf install -y \
|
||||||
|
systemd \
|
||||||
|
systemd-sysv \
|
||||||
|
dbus \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
git \
|
||||||
|
vim \
|
||||||
|
nano \
|
||||||
|
jq \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
&& dnf clean all
|
||||||
|
|
||||||
|
# Устанавливаем yq
|
||||||
|
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||||
|
&& chmod +x /usr/local/bin/yq
|
||||||
|
|
||||||
|
# Устанавливаем Docker
|
||||||
|
RUN dnf install -y dnf-plugins-core \
|
||||||
|
&& dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo \
|
||||||
|
&& dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||||
|
|
||||||
|
# Устанавливаем Docker Compose
|
||||||
|
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
|
||||||
|
&& chmod +x /usr/local/bin/docker-compose
|
||||||
|
|
||||||
|
# Настраиваем systemd
|
||||||
|
RUN systemctl set-default multi-user.target
|
||||||
|
|
||||||
|
# Создаем пользователя для Ansible
|
||||||
|
RUN useradd -m -s /bin/bash ansible \
|
||||||
|
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||||
|
|
||||||
|
# Переключаемся на пользователя ansible
|
||||||
|
USER ansible
|
||||||
|
WORKDIR /home/ansible
|
||||||
|
|
||||||
|
# Команда по умолчанию
|
||||||
|
CMD ["/sbin/init"]
|
||||||
56
dockerfiles/alt-linux/Dockerfile
Normal file
56
dockerfiles/alt-linux/Dockerfile
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# ALT Linux с systemd
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
# https://hub.docker.com/_/alt/tags
|
||||||
|
|
||||||
|
FROM alt:p9
|
||||||
|
|
||||||
|
# Обновляем систему
|
||||||
|
RUN apt-get update && apt-get dist-upgrade -y
|
||||||
|
|
||||||
|
# Устанавливаем systemd и необходимые пакеты
|
||||||
|
RUN apt-get install -y \
|
||||||
|
systemd \
|
||||||
|
dbus \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
git \
|
||||||
|
vim-enhanced \
|
||||||
|
nano \
|
||||||
|
htop \
|
||||||
|
tree \
|
||||||
|
jq \
|
||||||
|
python3 \
|
||||||
|
&& apt-get clean
|
||||||
|
|
||||||
|
# Устанавливаем pip для Python 3.7
|
||||||
|
RUN curl -sS https://bootstrap.pypa.io/pip/3.7/get-pip.py | python3
|
||||||
|
|
||||||
|
# Устанавливаем yq
|
||||||
|
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||||
|
&& chmod +x /usr/local/bin/yq
|
||||||
|
|
||||||
|
# Устанавливаем Docker вручную для ALT Linux
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
gnupg \
|
||||||
|
&& apt-get clean
|
||||||
|
|
||||||
|
# Устанавливаем Docker Compose
|
||||||
|
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
|
||||||
|
&& chmod +x /usr/local/bin/docker-compose
|
||||||
|
|
||||||
|
# Настраиваем systemd
|
||||||
|
RUN systemctl set-default multi-user.target
|
||||||
|
|
||||||
|
# Создаем пользователя для Ansible
|
||||||
|
RUN useradd -m -s /bin/bash ansible \
|
||||||
|
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||||
|
|
||||||
|
# Переключаемся на пользователя ansible
|
||||||
|
USER ansible
|
||||||
|
WORKDIR /home/ansible
|
||||||
|
|
||||||
|
# Команда по умолчанию
|
||||||
|
CMD ["/sbin/init"]
|
||||||
89
dockerfiles/ansible-controller/Dockerfile
Normal file
89
dockerfiles/ansible-controller/Dockerfile
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# Ansible Controller с предустановленными коллекциями
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
# Обновляем систему
|
||||||
|
RUN apt-get update && apt-get upgrade -y && apt-get clean
|
||||||
|
|
||||||
|
# Устанавливаем Python и Ansible
|
||||||
|
RUN apt-get install -y \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
python3-venv \
|
||||||
|
python3-dev \
|
||||||
|
build-essential \
|
||||||
|
&& apt-get clean
|
||||||
|
|
||||||
|
# Устанавливаем Ansible
|
||||||
|
RUN pip3 install ansible ansible-core
|
||||||
|
|
||||||
|
# Устанавливаем дополнительные пакеты
|
||||||
|
RUN apt-get install -y \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
git \
|
||||||
|
vim \
|
||||||
|
nano \
|
||||||
|
htop \
|
||||||
|
tree \
|
||||||
|
jq \
|
||||||
|
&& apt-get clean
|
||||||
|
|
||||||
|
# Устанавливаем yq
|
||||||
|
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||||
|
&& chmod +x /usr/local/bin/yq
|
||||||
|
|
||||||
|
# Устанавливаем Docker CLI
|
||||||
|
RUN apt-get install -y docker.io docker-compose
|
||||||
|
|
||||||
|
# Устанавливаем kubectl
|
||||||
|
RUN curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" \
|
||||||
|
&& chmod +x kubectl \
|
||||||
|
&& mv kubectl /usr/local/bin/
|
||||||
|
|
||||||
|
# Устанавливаем Helm
|
||||||
|
RUN curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
|
||||||
|
|
||||||
|
# Устанавливаем Kind
|
||||||
|
RUN curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.23.0/kind-linux-amd64 \
|
||||||
|
&& chmod +x ./kind \
|
||||||
|
&& mv ./kind /usr/local/bin/
|
||||||
|
|
||||||
|
## Устанавливаем Istio CLI
|
||||||
|
#RUN curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.22.1 sh - \
|
||||||
|
# && mv istio-1.22.1/bin/istioctl /usr/local/bin/ \
|
||||||
|
# && rm -rf istio-1.22.1
|
||||||
|
|
||||||
|
# Копируем requirements.yml
|
||||||
|
COPY requirements.yml /tmp/requirements.yml
|
||||||
|
|
||||||
|
# Устанавливаем Ansible коллекции
|
||||||
|
RUN ansible-galaxy collection install -r /tmp/requirements.yml
|
||||||
|
|
||||||
|
# Создаем пользователя ansible
|
||||||
|
RUN useradd -m -s /bin/bash ansible \
|
||||||
|
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||||
|
|
||||||
|
# Создаем рабочую директорию
|
||||||
|
WORKDIR /ansible
|
||||||
|
|
||||||
|
# Устанавливаем права
|
||||||
|
RUN chown -R ansible:ansible /ansible
|
||||||
|
|
||||||
|
# Переключаемся на пользователя ansible
|
||||||
|
USER ansible
|
||||||
|
|
||||||
|
# Устанавливаем дополнительные роли
|
||||||
|
RUN ansible-galaxy install geerlingguy.docker \
|
||||||
|
&& ansible-galaxy install geerlingguy.kubernetes
|
||||||
|
|
||||||
|
# Настройки для работы с Docker
|
||||||
|
ENV DOCKER_HOST=unix:///var/run/docker.sock
|
||||||
|
ENV ANSIBLE_FORCE_COLOR=1
|
||||||
|
ENV ANSIBLE_STDOUT_CALLBACK=yaml
|
||||||
|
ENV ANSIBLE_CALLBACKS_ENABLED=profile_tasks
|
||||||
|
|
||||||
|
# Команда по умолчанию
|
||||||
|
CMD ["sleep", "infinity"]
|
||||||
23
dockerfiles/ansible-controller/docker-compose.yml
Normal file
23
dockerfiles/ansible-controller/docker-compose.yml
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
version: "3.9"
|
||||||
|
|
||||||
|
services:
|
||||||
|
ansible-controller:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
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
|
||||||
|
- .:/ansible
|
||||||
|
working_dir: /ansible
|
||||||
|
networks:
|
||||||
|
- labnet
|
||||||
|
|
||||||
|
networks:
|
||||||
|
labnet:
|
||||||
|
external: true
|
||||||
9
dockerfiles/ansible-controller/requirements.yml
Normal file
9
dockerfiles/ansible-controller/requirements.yml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
# Ansible Collections для Molecule Universal
|
||||||
|
collections:
|
||||||
|
- name: community.docker
|
||||||
|
version: ">=3.0.0"
|
||||||
|
- name: community.general
|
||||||
|
version: ">=7.0.0"
|
||||||
|
- name: ansible.posix
|
||||||
|
version: ">=1.5.4"
|
||||||
61
dockerfiles/astra-linux/Dockerfile
Normal file
61
dockerfiles/astra-linux/Dockerfile
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# Astra Linux с systemd
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
# https://registry.astralinux.ru/browse/library/
|
||||||
|
|
||||||
|
FROM registry.astralinux.ru/library/astra/ubi17:1.7.6.uu2
|
||||||
|
|
||||||
|
# Обновляем систему
|
||||||
|
RUN apt-get update && apt-get dist-upgrade -y
|
||||||
|
|
||||||
|
# Устанавливаем systemd и необходимые пакеты
|
||||||
|
RUN apt-get install -y \
|
||||||
|
systemd \
|
||||||
|
systemd-sysv \
|
||||||
|
dbus \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
git \
|
||||||
|
vim \
|
||||||
|
nano \
|
||||||
|
htop \
|
||||||
|
tree \
|
||||||
|
jq \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
&& apt-get clean
|
||||||
|
|
||||||
|
# Устанавливаем yq
|
||||||
|
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||||
|
&& chmod +x /usr/local/bin/yq
|
||||||
|
|
||||||
|
# Устанавливаем Docker вручную для AstraLinux
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
gnupg \
|
||||||
|
lsb-release \
|
||||||
|
&& mkdir -p /usr/share/keyrings \
|
||||||
|
&& curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \
|
||||||
|
&& echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian buster stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin \
|
||||||
|
&& apt-get clean
|
||||||
|
|
||||||
|
# Устанавливаем Docker Compose
|
||||||
|
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
|
||||||
|
&& chmod +x /usr/local/bin/docker-compose
|
||||||
|
|
||||||
|
# Настраиваем systemd
|
||||||
|
RUN systemctl set-default multi-user.target
|
||||||
|
|
||||||
|
# Создаем пользователя для Ansible
|
||||||
|
RUN useradd -m -s /bin/bash ansible \
|
||||||
|
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||||
|
|
||||||
|
# Переключаемся на пользователя ansible
|
||||||
|
USER ansible
|
||||||
|
WORKDIR /home/ansible
|
||||||
|
|
||||||
|
# Команда по умолчанию
|
||||||
|
CMD ["/sbin/init"]
|
||||||
48
dockerfiles/centos/Dockerfile
Normal file
48
dockerfiles/centos/Dockerfile
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# CentOS с systemd
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
FROM quay.io/centos/centos:stream9
|
||||||
|
|
||||||
|
# Обновляем систему
|
||||||
|
RUN dnf update -y && dnf upgrade -y
|
||||||
|
|
||||||
|
# Устанавливаем systemd и необходимые пакеты
|
||||||
|
RUN dnf install -y --allowerasing \
|
||||||
|
systemd \
|
||||||
|
systemd-sysv \
|
||||||
|
dbus \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
git \
|
||||||
|
vim \
|
||||||
|
nano \
|
||||||
|
jq \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
&& dnf clean all
|
||||||
|
|
||||||
|
# Устанавливаем yq
|
||||||
|
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||||
|
&& chmod +x /usr/local/bin/yq
|
||||||
|
|
||||||
|
# Устанавливаем Docker
|
||||||
|
RUN curl -fsSL https://get.docker.com | sh
|
||||||
|
|
||||||
|
# Устанавливаем Docker Compose
|
||||||
|
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
|
||||||
|
&& chmod +x /usr/local/bin/docker-compose
|
||||||
|
|
||||||
|
# Настраиваем systemd
|
||||||
|
RUN systemctl set-default multi-user.target
|
||||||
|
|
||||||
|
# Создаем пользователя для Ansible
|
||||||
|
RUN useradd -m -s /bin/bash ansible \
|
||||||
|
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||||
|
|
||||||
|
# Переключаемся на пользователя ansible
|
||||||
|
USER ansible
|
||||||
|
WORKDIR /home/ansible
|
||||||
|
|
||||||
|
# Команда по умолчанию
|
||||||
|
CMD ["/sbin/init"]
|
||||||
53
dockerfiles/redos/Dockerfile
Normal file
53
dockerfiles/redos/Dockerfile
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# RED OS с systemd
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
# https://registry.red-soft.ru/ubi7/ubi/tags
|
||||||
|
# docker search registry.red-soft.ru/ubi7/ubi
|
||||||
|
|
||||||
|
FROM registry.red-soft.ru/ubi7/ubi
|
||||||
|
|
||||||
|
# Обновляем систему
|
||||||
|
RUN dnf update -y && dnf upgrade -y
|
||||||
|
|
||||||
|
# Устанавливаем systemd и необходимые пакеты
|
||||||
|
RUN dnf install -y \
|
||||||
|
systemd \
|
||||||
|
systemd-sysv \
|
||||||
|
dbus \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
git \
|
||||||
|
vim \
|
||||||
|
nano \
|
||||||
|
jq \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
&& dnf clean all
|
||||||
|
|
||||||
|
# Устанавливаем yq
|
||||||
|
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||||
|
&& chmod +x /usr/local/bin/yq
|
||||||
|
|
||||||
|
# Устанавливаем Docker вручную для RED OS
|
||||||
|
RUN dnf install -y dnf-plugins-core \
|
||||||
|
&& dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo \
|
||||||
|
&& dnf install -y docker-ce docker-ce-cli containerd.io \
|
||||||
|
&& dnf clean all
|
||||||
|
|
||||||
|
# Устанавливаем Docker Compose
|
||||||
|
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
|
||||||
|
&& chmod +x /usr/local/bin/docker-compose
|
||||||
|
|
||||||
|
# Настраиваем systemd
|
||||||
|
RUN systemctl set-default multi-user.target
|
||||||
|
|
||||||
|
# Создаем пользователя для Ansible
|
||||||
|
RUN useradd -m -s /bin/bash ansible \
|
||||||
|
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||||
|
|
||||||
|
# Переключаемся на пользователя ansible
|
||||||
|
USER ansible
|
||||||
|
WORKDIR /home/ansible
|
||||||
|
|
||||||
|
# Команда по умолчанию
|
||||||
|
CMD ["/sbin/init"]
|
||||||
48
dockerfiles/rhel/Dockerfile
Normal file
48
dockerfiles/rhel/Dockerfile
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# RHEL с systemd
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
FROM registry.access.redhat.com/ubi8/ubi
|
||||||
|
|
||||||
|
# Обновляем систему
|
||||||
|
RUN dnf update -y && dnf upgrade -y
|
||||||
|
|
||||||
|
# Устанавливаем systemd и необходимые пакеты
|
||||||
|
RUN dnf install -y \
|
||||||
|
systemd \
|
||||||
|
systemd-sysv \
|
||||||
|
dbus \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
git \
|
||||||
|
vim \
|
||||||
|
nano \
|
||||||
|
jq \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
&& dnf clean all
|
||||||
|
|
||||||
|
# Устанавливаем yq
|
||||||
|
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||||
|
&& chmod +x /usr/local/bin/yq
|
||||||
|
|
||||||
|
# Устанавливаем Docker
|
||||||
|
RUN curl -fsSL https://get.docker.com | sh
|
||||||
|
|
||||||
|
# Устанавливаем Docker Compose
|
||||||
|
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
|
||||||
|
&& chmod +x /usr/local/bin/docker-compose
|
||||||
|
|
||||||
|
# Настраиваем systemd
|
||||||
|
RUN systemctl set-default multi-user.target
|
||||||
|
|
||||||
|
# Создаем пользователя для Ansible
|
||||||
|
RUN useradd -m -s /bin/bash ansible \
|
||||||
|
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||||
|
|
||||||
|
# Переключаемся на пользователя ansible
|
||||||
|
USER ansible
|
||||||
|
WORKDIR /home/ansible
|
||||||
|
|
||||||
|
# Команда по умолчанию
|
||||||
|
CMD ["/sbin/init"]
|
||||||
50
dockerfiles/rocky/Dockerfile
Normal file
50
dockerfiles/rocky/Dockerfile
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
# Rocky Linux с systemd
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
FROM rockylinux:8
|
||||||
|
|
||||||
|
# Обновляем систему
|
||||||
|
RUN dnf update -y && dnf upgrade -y
|
||||||
|
|
||||||
|
# Устанавливаем systemd и необходимые пакеты
|
||||||
|
RUN dnf install -y \
|
||||||
|
systemd \
|
||||||
|
systemd-sysv \
|
||||||
|
dbus \
|
||||||
|
curl \
|
||||||
|
wget \
|
||||||
|
git \
|
||||||
|
vim \
|
||||||
|
nano \
|
||||||
|
jq \
|
||||||
|
python3 \
|
||||||
|
python3-pip \
|
||||||
|
&& dnf clean all
|
||||||
|
|
||||||
|
# Устанавливаем yq
|
||||||
|
RUN wget -qO /usr/local/bin/yq https://github.com/mikefarah/yq/releases/latest/download/yq_linux_arm64 \
|
||||||
|
&& chmod +x /usr/local/bin/yq
|
||||||
|
|
||||||
|
# Устанавливаем Docker
|
||||||
|
RUN dnf install -y dnf-plugins-core \
|
||||||
|
&& dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo \
|
||||||
|
&& dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||||
|
|
||||||
|
# Устанавливаем Docker Compose
|
||||||
|
RUN curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \
|
||||||
|
&& chmod +x /usr/local/bin/docker-compose
|
||||||
|
|
||||||
|
# Настраиваем systemd
|
||||||
|
RUN systemctl set-default multi-user.target
|
||||||
|
|
||||||
|
# Создаем пользователя для Ansible
|
||||||
|
RUN useradd -m -s /bin/bash ansible \
|
||||||
|
&& echo "ansible ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
||||||
|
|
||||||
|
# Переключаемся на пользователя ansible
|
||||||
|
USER ansible
|
||||||
|
WORKDIR /home/ansible
|
||||||
|
|
||||||
|
# Команда по умолчанию
|
||||||
|
CMD ["/sbin/init"]
|
||||||
616
docs/api.md
616
docs/api.md
@@ -1,616 +0,0 @@
|
|||||||
# 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).
|
|
||||||
706
docs/examples.md
706
docs/examples.md
@@ -1,354 +1,315 @@
|
|||||||
# Примеры использования
|
# Примеры использования универсальной системы тестирования
|
||||||
|
|
||||||
## Автор
|
## Пример 1: Тестирование кластера etcd + PostgreSQL + Patroni
|
||||||
Сергей Антропов
|
|
||||||
Сайт: https://devops.org.ru
|
|
||||||
|
|
||||||
## Описание
|
### Описание
|
||||||
|
Этот пример демонстрирует тестирование высокодоступного кластера PostgreSQL с Patroni и etcd.
|
||||||
|
|
||||||
Этот документ содержит практические примеры использования универсальной лаборатории для различных сценариев тестирования Ansible ролей.
|
### Preset: etcd-patroni
|
||||||
|
|
||||||
## Содержание
|
```yaml
|
||||||
|
# molecule/presets/etcd-patroni.yml
|
||||||
|
hosts:
|
||||||
|
# ETCD кластер (5 узлов для высокой доступности)
|
||||||
|
- name: etcd1
|
||||||
|
family: debian
|
||||||
|
groups: [etcd, cluster]
|
||||||
|
- name: etcd2
|
||||||
|
family: rhel
|
||||||
|
groups: [etcd, cluster]
|
||||||
|
- name: etcd3
|
||||||
|
family: debian
|
||||||
|
groups: [etcd, cluster]
|
||||||
|
- name: etcd4
|
||||||
|
family: rhel
|
||||||
|
groups: [etcd, cluster]
|
||||||
|
- name: etcd5
|
||||||
|
family: debian
|
||||||
|
groups: [etcd, cluster]
|
||||||
|
|
||||||
- [Базовые примеры](#базовые-примеры)
|
# Patroni кластер (3 узла PostgreSQL)
|
||||||
- [Kubernetes примеры](#kubernetes-примеры)
|
- name: patroni1
|
||||||
- [Docker примеры](#docker-примеры)
|
family: rhel
|
||||||
- [Смешанные примеры](#смешанные-примеры)
|
groups: [patroni, database, cluster]
|
||||||
- [Мониторинг и отчеты](#мониторинг-и-отчеты)
|
- name: patroni2
|
||||||
- [Troubleshooting](#troubleshooting)
|
family: debian
|
||||||
|
groups: [patroni, database, cluster]
|
||||||
|
- name: patroni3
|
||||||
|
family: rhel
|
||||||
|
groups: [patroni, database, cluster]
|
||||||
|
|
||||||
## Базовые примеры
|
# HAProxy для балансировки
|
||||||
|
- name: haproxy
|
||||||
|
family: debian
|
||||||
|
groups: [haproxy, loadbalancer]
|
||||||
|
publish: ["5000:5000", "5001:5001"] # RW и RO порты
|
||||||
|
|
||||||
### Пример 1: Тестирование веб-сервера
|
# DinD узел для тестирования Docker Compose внутри
|
||||||
|
- name: app-dind
|
||||||
```bash
|
type: dind
|
||||||
# Запустить веб-приложение пресет
|
groups: [apps, docker]
|
||||||
make lab-test LAB_SPEC=molecule/presets/webapp.yml
|
publish: ["8080:8080"]
|
||||||
|
|
||||||
# Проверить статус
|
|
||||||
make lab-verify
|
|
||||||
|
|
||||||
# Посмотреть отчет
|
|
||||||
make lab-report
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Пример 2: Тестирование базы данных
|
### Запуск тестирования
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Запустить пресет с базой данных
|
# Информация о preset'е
|
||||||
make lab-test LAB_SPEC=molecule/presets/ha.yml
|
make preset-info PRESET=etcd-patroni
|
||||||
|
|
||||||
# Проверить подключение к БД
|
# Тестирование с preset'ом
|
||||||
make kube-cmd CLUSTER=lab CMD="exec -it postgres-0 -- psql -U postgres -c 'SELECT 1;'"
|
make preset-test PRESET=etcd-patroni
|
||||||
|
|
||||||
|
# Или через role test
|
||||||
|
make role test etcd-patroni
|
||||||
```
|
```
|
||||||
|
|
||||||
### Пример 3: Тестирование микросервисов
|
### Проверка результатов
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Запустить микросервисный пресет
|
# Проверить статус контейнеров
|
||||||
make lab-test LAB_SPEC=molecule/presets/microservices.yml
|
make container-info
|
||||||
|
|
||||||
# Проверить API Gateway
|
# Проверить vault файлы
|
||||||
curl http://localhost:8000/health
|
make vault-check
|
||||||
```
|
```
|
||||||
|
|
||||||
## Kubernetes примеры
|
## Пример 2: Нагрузочное тестирование
|
||||||
|
|
||||||
### Пример 1: Простой Kubernetes кластер
|
### Описание
|
||||||
|
Этот пример демонстрирует тестирование под нагрузкой с множественными серверами и кэшем.
|
||||||
|
|
||||||
```bash
|
### Preset: performance
|
||||||
# Запустить одиночный Kind кластер
|
|
||||||
make lab-test LAB_SPEC=molecule/presets/k8s-single.yml
|
|
||||||
|
|
||||||
# Войти в кластер
|
```yaml
|
||||||
make kube-sh
|
# molecule/presets/performance.yml
|
||||||
|
hosts:
|
||||||
|
# Основные серверы (5 узлов)
|
||||||
|
- name: server1
|
||||||
|
family: debian
|
||||||
|
groups: [servers, web, app]
|
||||||
|
- name: server2
|
||||||
|
family: rhel
|
||||||
|
groups: [servers, web, app]
|
||||||
|
- name: server3
|
||||||
|
family: debian
|
||||||
|
groups: [servers, web, app]
|
||||||
|
- name: server4
|
||||||
|
family: rhel
|
||||||
|
groups: [servers, web, app]
|
||||||
|
- name: server5
|
||||||
|
family: debian
|
||||||
|
groups: [servers, web, app]
|
||||||
|
|
||||||
# Проверить ноды
|
# База данных (3 узла)
|
||||||
kubectl get nodes
|
- name: db1
|
||||||
|
family: rhel
|
||||||
|
groups: [database, db]
|
||||||
|
- name: db2
|
||||||
|
family: debian
|
||||||
|
groups: [database, db]
|
||||||
|
- name: db3
|
||||||
|
family: rhel
|
||||||
|
groups: [database, db]
|
||||||
|
|
||||||
# Проверить поды
|
# Кэш (3 узла Redis)
|
||||||
kubectl get pods -A
|
- name: cache1
|
||||||
|
family: debian
|
||||||
|
groups: [cache, redis]
|
||||||
|
- name: cache2
|
||||||
|
family: rhel
|
||||||
|
groups: [cache, redis]
|
||||||
|
- name: cache3
|
||||||
|
family: debian
|
||||||
|
groups: [cache, redis]
|
||||||
|
|
||||||
|
# Load balancer
|
||||||
|
- name: lb1
|
||||||
|
family: rhel
|
||||||
|
groups: [loadbalancer, haproxy]
|
||||||
|
publish: ["80:80", "443:443"]
|
||||||
|
|
||||||
|
# DinD узел для тестирования Docker Compose
|
||||||
|
- name: compose-dind
|
||||||
|
type: dind
|
||||||
|
groups: [apps, docker]
|
||||||
|
publish: ["8080:8080", "8081:8081"]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Пример 2: Мульти-кластерная конфигурация
|
### Запуск тестирования
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Запустить мульти-кластер
|
# Тестирование с performance preset'ом
|
||||||
make lab-test LAB_SPEC=molecule/presets/k8s-multi.yml
|
make role test performance
|
||||||
|
|
||||||
# Переключиться между кластерами
|
# Проверка статуса
|
||||||
kubectl config use-context kind-dev
|
make container-info
|
||||||
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
|
## Пример 3: Тестирование безопасности
|
||||||
|
|
||||||
```bash
|
### Описание
|
||||||
# Запустить полный Istio стек
|
Этот пример демонстрирует тестирование в безопасной среде с bastion хостами и изоляцией.
|
||||||
make lab-test LAB_SPEC=molecule/presets/k8s-istio-full.yml
|
|
||||||
|
|
||||||
# Port-forward Kiali
|
### Preset: security
|
||||||
make kiali-port-forward CLUSTER=istio-full
|
|
||||||
|
|
||||||
# Port-forward Istio Gateway
|
```yaml
|
||||||
make istio-gw-port-forward CLUSTER=istio-full
|
# molecule/presets/security.yml
|
||||||
|
hosts:
|
||||||
|
# Bastion хосты (точки входа)
|
||||||
|
- name: bastion1
|
||||||
|
family: rhel
|
||||||
|
groups: [bastion, security, jump]
|
||||||
|
publish: ["2222:22"]
|
||||||
|
- name: bastion2
|
||||||
|
family: debian
|
||||||
|
groups: [bastion, security, jump]
|
||||||
|
publish: ["2223:22"]
|
||||||
|
|
||||||
# Открыть Kiali
|
# Внутренние серверы (без внешнего доступа)
|
||||||
open http://localhost:20001
|
- name: internal1
|
||||||
|
family: rhel
|
||||||
|
groups: [internal, servers, app]
|
||||||
|
- name: internal2
|
||||||
|
family: debian
|
||||||
|
groups: [internal, servers, app]
|
||||||
|
- name: internal3
|
||||||
|
family: rhel
|
||||||
|
groups: [internal, servers, app]
|
||||||
|
|
||||||
# Открыть Bookinfo
|
# База данных (изолированная сеть)
|
||||||
open http://localhost:8082/productpage
|
- name: db-secure1
|
||||||
|
family: rhel
|
||||||
|
groups: [database, secure, internal]
|
||||||
|
- name: db-secure2
|
||||||
|
family: debian
|
||||||
|
groups: [database, secure, internal]
|
||||||
|
|
||||||
|
# Мониторинг и логирование
|
||||||
|
- name: monitor1
|
||||||
|
family: debian
|
||||||
|
groups: [monitoring, security, logs]
|
||||||
|
- name: monitor2
|
||||||
|
family: rhel
|
||||||
|
groups: [monitoring, security, logs]
|
||||||
|
|
||||||
|
# Firewall и сетевые компоненты
|
||||||
|
- name: fw1
|
||||||
|
family: rhel
|
||||||
|
groups: [firewall, network, security]
|
||||||
|
- name: fw2
|
||||||
|
family: debian
|
||||||
|
groups: [firewall, network, security]
|
||||||
|
|
||||||
|
# DOoD узел для тестирования Docker безопасности
|
||||||
|
- name: docker-secure
|
||||||
|
type: dood
|
||||||
|
family: debian
|
||||||
|
groups: [docker, security, apps]
|
||||||
|
publish: ["8080:8080"]
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Пример 4: Мониторинг Kubernetes
|
### Запуск тестирования
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Port-forward Grafana
|
# Тестирование с security preset'ом
|
||||||
make grafana-port-forward CLUSTER=istio-full
|
make role test security
|
||||||
|
|
||||||
# Port-forward Prometheus
|
# Проверка безопасности
|
||||||
make prom-port-forward CLUSTER=istio-full
|
make vault-check
|
||||||
|
make vault-scan
|
||||||
# Открыть Grafana
|
|
||||||
open http://localhost:3000
|
|
||||||
|
|
||||||
# Открыть Prometheus
|
|
||||||
open http://localhost:9090
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Docker примеры
|
## Пример 4: Тестирование на разных ОС
|
||||||
|
|
||||||
### Пример 1: Docker-in-Docker
|
### Описание
|
||||||
|
Этот пример демонстрирует тестирование на различных операционных системах.
|
||||||
|
|
||||||
```bash
|
### Preset: multi-os
|
||||||
# Запустить DinD пресет
|
|
||||||
make lab-test LAB_SPEC=molecule/presets/dind-simple.yml
|
|
||||||
|
|
||||||
# Войти в DinD контейнер
|
```yaml
|
||||||
docker exec -it dind1 sh
|
# molecule/presets/multi-os.yml
|
||||||
|
hosts:
|
||||||
|
# Debian/Ubuntu серверы
|
||||||
|
- name: ubuntu1
|
||||||
|
family: ubuntu
|
||||||
|
groups: [ubuntu, servers, web]
|
||||||
|
- name: debian1
|
||||||
|
family: debian
|
||||||
|
groups: [debian, servers, web]
|
||||||
|
- name: ubuntu2
|
||||||
|
family: ubuntu
|
||||||
|
groups: [ubuntu, servers, app]
|
||||||
|
- name: debian2
|
||||||
|
family: debian
|
||||||
|
groups: [debian, servers, app]
|
||||||
|
|
||||||
# Внутри контейнера проверить Docker
|
# RHEL/CentOS серверы
|
||||||
docker ps
|
- name: rhel1
|
||||||
docker images
|
family: rhel
|
||||||
|
groups: [rhel, servers, web]
|
||||||
|
- name: centos1
|
||||||
|
family: centos
|
||||||
|
groups: [centos, servers, web]
|
||||||
|
- name: rhel2
|
||||||
|
family: rhel
|
||||||
|
groups: [rhel, servers, app]
|
||||||
|
- name: centos2
|
||||||
|
family: centos
|
||||||
|
groups: [centos, servers, app]
|
||||||
|
|
||||||
|
# База данных на разных ОС
|
||||||
|
- name: db-ubuntu
|
||||||
|
family: ubuntu
|
||||||
|
groups: [database, ubuntu, db]
|
||||||
|
- name: db-rhel
|
||||||
|
family: rhel
|
||||||
|
groups: [database, rhel, db]
|
||||||
|
|
||||||
|
# Load balancer
|
||||||
|
- name: lb-mixed
|
||||||
|
family: debian
|
||||||
|
groups: [loadbalancer, haproxy]
|
||||||
|
publish: ["80:80", "443:443"]
|
||||||
|
|
||||||
|
# DinD узел для тестирования Docker
|
||||||
|
- name: docker-mixed
|
||||||
|
type: dind
|
||||||
|
groups: [docker, apps]
|
||||||
|
publish: ["8080:8080"]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Пример 2: Docker Swarm
|
### Запуск тестирования
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Запустить Docker Swarm пресет
|
# Тестирование с multi-os preset'ом
|
||||||
make lab-test LAB_SPEC=molecule/presets/dind-swarm.yml
|
make role test multi-os
|
||||||
|
|
||||||
# Войти в manager
|
# Проверка типов контейнеров
|
||||||
docker exec -it swarm-manager sh
|
make container-types
|
||||||
|
|
||||||
# Инициализировать Swarm
|
|
||||||
docker swarm init
|
|
||||||
|
|
||||||
# Присоединить workers
|
|
||||||
docker node ls
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Пример 3: Docker Compose
|
## Пример 5: Создание собственного preset'а
|
||||||
|
|
||||||
|
### Описание
|
||||||
|
Этот пример демонстрирует создание собственного preset'а для специфических нужд.
|
||||||
|
|
||||||
|
### Создание preset'а
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Запустить Compose пресет
|
# Создать новый preset
|
||||||
make lab-test LAB_SPEC=molecule/presets/dind-compose.yml
|
cat > molecule/presets/my-custom.yml << 'EOF'
|
||||||
|
|
||||||
# Войти в 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
|
|
||||||
---
|
---
|
||||||
# ПРЕСЕТ: Мой кастомный пресет
|
# Пресет для тестирования веб-приложения
|
||||||
#
|
# Автор: Ваше имя
|
||||||
# Описание: Кастомная конфигурация для моих нужд
|
# Сайт: https://your-site.com
|
||||||
#
|
|
||||||
# Использование: make lab-test LAB_SPEC=molecule/presets/my-custom.yml
|
|
||||||
|
|
||||||
docker_network: labnet
|
docker_network: labnet
|
||||||
|
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
|
||||||
|
|
||||||
|
# systemd-ready образы
|
||||||
images:
|
images:
|
||||||
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
rhel: "quay.io/centos/centos:stream9-systemd"
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
@@ -358,105 +319,106 @@ systemd_defaults:
|
|||||||
command: "/sbin/init"
|
command: "/sbin/init"
|
||||||
volumes:
|
volumes:
|
||||||
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
tmpfs:
|
tmpfs: ["/run", "/run/lock"]
|
||||||
- "/run"
|
capabilities: ["SYS_ADMIN"]
|
||||||
- "/run/lock"
|
|
||||||
capabilities:
|
|
||||||
- "SYS_ADMIN"
|
|
||||||
|
|
||||||
|
# Описание кластера
|
||||||
hosts:
|
hosts:
|
||||||
- name: my-web
|
# Веб-серверы
|
||||||
|
- name: web1
|
||||||
family: debian
|
family: debian
|
||||||
group: webservers
|
groups: [web, servers]
|
||||||
publish:
|
publish: ["80:80", "443:443"]
|
||||||
- "8080:80"
|
- name: web2
|
||||||
|
|
||||||
- name: my-db
|
|
||||||
family: rhel
|
family: rhel
|
||||||
group: databases
|
groups: [web, servers]
|
||||||
publish:
|
publish: ["8080:80", "8443:443"]
|
||||||
- "5432:5432"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Протестировать пресет
|
# База данных
|
||||||
make lab-test LAB_SPEC=molecule/presets/my-custom.yml
|
- name: db1
|
||||||
|
family: rhel
|
||||||
|
groups: [database, db]
|
||||||
|
- name: db2
|
||||||
|
family: debian
|
||||||
|
groups: [database, db]
|
||||||
|
|
||||||
|
# Кэш
|
||||||
|
- name: cache1
|
||||||
|
family: debian
|
||||||
|
groups: [cache, redis]
|
||||||
|
|
||||||
|
# DinD узел для тестирования
|
||||||
|
- name: app-dind
|
||||||
|
type: dind
|
||||||
|
groups: [apps, docker]
|
||||||
|
publish: ["8080:8080"]
|
||||||
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
### Пример 2: Создание собственной роли
|
### Использование preset'а
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Создать структуру роли
|
# Информация о preset'е
|
||||||
mkdir -p roles/my-role/{tasks,handlers,templates,files,vars,defaults,meta}
|
make preset-info PRESET=my-custom
|
||||||
|
|
||||||
# Создать основной task
|
# Тестирование с preset'ом
|
||||||
cat > roles/my-role/tasks/main.yml << EOF
|
make preset-test PRESET=my-custom
|
||||||
---
|
|
||||||
- name: Install nginx
|
|
||||||
package:
|
|
||||||
name: nginx
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Start nginx
|
# Или через role test
|
||||||
service:
|
make role test my-custom
|
||||||
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
|
## Пример 6: Работа с Ansible Vault
|
||||||
|
|
||||||
|
### Создание vault файла
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Создать GitHub Actions workflow
|
# Создать файл секретов
|
||||||
cat > .github/workflows/test.yml << EOF
|
make vault create
|
||||||
name: Test Ansible Roles
|
|
||||||
|
|
||||||
on:
|
# Ввести имя файла: secrets
|
||||||
push:
|
# Ввести содержимое:
|
||||||
branches: [ main ]
|
# ---
|
||||||
pull_request:
|
# database_password: "super_secret_password"
|
||||||
branches: [ main ]
|
# api_key: "your_api_key_here"
|
||||||
|
# ssl_cert: "your_ssl_certificate"
|
||||||
|
```
|
||||||
|
|
||||||
jobs:
|
### Использование в ролях
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
```yaml
|
||||||
|
# roles/my-role/tasks/main.yml
|
||||||
steps:
|
- name: Configure database
|
||||||
- uses: actions/checkout@v3
|
template:
|
||||||
|
src: database.conf.j2
|
||||||
- name: Setup Docker
|
dest: /etc/database.conf
|
||||||
run: |
|
vars:
|
||||||
docker-compose up -d
|
db_password: "{{ database_password }}"
|
||||||
|
api_key: "{{ api_key }}"
|
||||||
- name: Run tests
|
```
|
||||||
run: |
|
|
||||||
make lab-test LAB_SPEC=molecule/presets/minimal.yml
|
### Проверка безопасности
|
||||||
|
|
||||||
- name: Generate report
|
```bash
|
||||||
run: |
|
# Проверить vault файлы
|
||||||
make lab-report
|
make vault-check
|
||||||
|
|
||||||
- name: Upload report
|
# Найти потенциальные секреты
|
||||||
uses: actions/upload-artifact@v3
|
make vault-scan
|
||||||
with:
|
|
||||||
name: lab-report
|
|
||||||
path: reports/lab-report.html
|
|
||||||
EOF
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Заключение
|
## Заключение
|
||||||
|
|
||||||
Эти примеры демонстрируют основные возможности универсальной лаборатории. Для получения дополнительной информации обратитесь к [основной документации](universal-lab.md) и [описанию пресетов](presets.md).
|
Эти примеры демонстрируют различные способы использования универсальной системы тестирования Ansible ролей. Вы можете:
|
||||||
|
|
||||||
|
1. Использовать готовые preset'ы для быстрого тестирования
|
||||||
|
2. Создавать собственные preset'ы для специфических нужд
|
||||||
|
3. Комбинировать различные типы контейнеров
|
||||||
|
4. Использовать Ansible Vault для безопасности
|
||||||
|
5. Тестировать на различных операционных системах
|
||||||
|
|
||||||
|
Для получения дополнительной информации используйте:
|
||||||
|
- `make help` - общая справка
|
||||||
|
- `make preset-list` - список preset'ов
|
||||||
|
- `make container-types` - типы контейнеров
|
||||||
|
- `make vault` - команды Vault
|
||||||
|
|||||||
196
docs/presets.md
196
docs/presets.md
@@ -1,196 +0,0 @@
|
|||||||
# Пресеты универсальной лаборатории
|
|
||||||
|
|
||||||
## Автор
|
|
||||||
Сергей Антропов
|
|
||||||
Сайт: 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`
|
|
||||||
372
docs/roles.md
372
docs/roles.md
@@ -1,372 +0,0 @@
|
|||||||
# Управление ролями Ansible
|
|
||||||
|
|
||||||
Полное руководство по созданию, управлению и использованию ролей в универсальной лаборатории.
|
|
||||||
|
|
||||||
## Создание роли
|
|
||||||
|
|
||||||
### Интерактивное создание
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make role create NAME=my-role
|
|
||||||
```
|
|
||||||
|
|
||||||
**Что происходит:**
|
|
||||||
1. **Запрашивается описание роли** - краткое описание функциональности
|
|
||||||
2. **Настраивается основной пакет** - имя пакета для установки
|
|
||||||
3. **Настраивается сервис** - имя сервиса для управления
|
|
||||||
4. **Выбираются платформы** - поддерживаемые ОС (ubuntu, centos, rhel)
|
|
||||||
5. **Указываются теги** - теги для Ansible Galaxy
|
|
||||||
6. **Создается универсальная структура роли** с поддержкой RHEL и Debian семейств
|
|
||||||
7. **Создается папка `playbooks/`** для playbooks роли
|
|
||||||
|
|
||||||
### Структура созданной роли
|
|
||||||
|
|
||||||
```
|
|
||||||
roles/my-role/
|
|
||||||
├── tasks/
|
|
||||||
│ ├── main.yml # Основные задачи (универсальные)
|
|
||||||
│ ├── debian.yml # Задачи для Debian/Ubuntu
|
|
||||||
│ └── redhat.yml # Задачи для RHEL/CentOS
|
|
||||||
├── handlers/
|
|
||||||
│ └── main.yml # Обработчики
|
|
||||||
├── templates/ # Шаблоны Jinja2
|
|
||||||
├── files/ # Статические файлы
|
|
||||||
├── vars/
|
|
||||||
│ └── main.yml # Переменные роли
|
|
||||||
├── defaults/
|
|
||||||
│ └── main.yml # Переменные по умолчанию
|
|
||||||
├── meta/
|
|
||||||
│ └── main.yml # Метаданные роли
|
|
||||||
├── tests/ # Тесты роли
|
|
||||||
└── playbooks/ # Playbooks роли
|
|
||||||
└── (создаются через make role playbook)
|
|
||||||
```
|
|
||||||
|
|
||||||
## Универсальные роли
|
|
||||||
|
|
||||||
### Принцип работы
|
|
||||||
|
|
||||||
Роли создаются **универсальными** для RHEL и Debian семейств:
|
|
||||||
|
|
||||||
1. **`tasks/main.yml`** - содержит общую логику и включает OS-специфичные задачи
|
|
||||||
2. **`tasks/debian.yml`** - задачи для Debian/Ubuntu (apt, systemd)
|
|
||||||
3. **`tasks/redhat.yml`** - задачи для RHEL/CentOS (yum, systemd)
|
|
||||||
|
|
||||||
### Автоматическое определение ОС
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
# tasks/main.yml
|
|
||||||
- name: Include OS-specific tasks
|
|
||||||
include_tasks: "{{ ansible_os_family | lower }}.yml"
|
|
||||||
```
|
|
||||||
|
|
||||||
**Поддерживаемые ОС:**
|
|
||||||
- **Debian семейство**: Ubuntu, Debian, Linux Mint
|
|
||||||
- **RHEL семейство**: CentOS, RHEL, Rocky Linux, AlmaLinux
|
|
||||||
|
|
||||||
### Примеры задач
|
|
||||||
|
|
||||||
#### Debian/Ubuntu (tasks/debian.yml)
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
# Задачи для Debian/Ubuntu семейства
|
|
||||||
|
|
||||||
- name: Update apt cache (Debian)
|
|
||||||
apt:
|
|
||||||
update_cache: true
|
|
||||||
cache_valid_time: 3600
|
|
||||||
when: ansible_os_family == 'Debian'
|
|
||||||
|
|
||||||
- name: Install nginx package (Debian)
|
|
||||||
apt:
|
|
||||||
name: "{{ nginx_package | default('nginx') }}"
|
|
||||||
state: present
|
|
||||||
when: ansible_os_family == 'Debian'
|
|
||||||
```
|
|
||||||
|
|
||||||
#### RHEL/CentOS (tasks/redhat.yml)
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
# Задачи для RHEL/CentOS семейства
|
|
||||||
|
|
||||||
- name: Update yum cache (RHEL)
|
|
||||||
yum:
|
|
||||||
update_cache: true
|
|
||||||
when: ansible_os_family == 'RedHat'
|
|
||||||
|
|
||||||
- name: Install nginx package (RHEL)
|
|
||||||
yum:
|
|
||||||
name: "{{ nginx_package | default('nginx') }}"
|
|
||||||
state: present
|
|
||||||
when: ansible_os_family == 'RedHat'
|
|
||||||
```
|
|
||||||
|
|
||||||
## Управление playbooks роли
|
|
||||||
|
|
||||||
### Создание playbook
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make role playbook NAME=my-role
|
|
||||||
# Выберите: create
|
|
||||||
# Введите имя: deploy
|
|
||||||
```
|
|
||||||
|
|
||||||
**Создается файл:** `roles/my-role/playbooks/deploy.yml`
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
# Playbook: deploy для роли my-role
|
|
||||||
# Автор: Сергей Антропов
|
|
||||||
# Сайт: https://devops.org.ru
|
|
||||||
|
|
||||||
- name: deploy
|
|
||||||
hosts: all
|
|
||||||
become: true
|
|
||||||
gather_facts: true
|
|
||||||
vars:
|
|
||||||
# Переменные для роли my-role
|
|
||||||
my_role_enabled: true
|
|
||||||
|
|
||||||
pre_tasks:
|
|
||||||
- name: Display OS information
|
|
||||||
debug:
|
|
||||||
msg: "OS Family: {{ ansible_os_family }}, OS: {{ ansible_distribution }} {{ ansible_distribution_version }}"
|
|
||||||
|
|
||||||
roles:
|
|
||||||
- role: my-role
|
|
||||||
|
|
||||||
post_tasks:
|
|
||||||
- name: Verify my-role installation
|
|
||||||
debug:
|
|
||||||
msg: "my-role successfully deployed on {{ inventory_hostname }}"
|
|
||||||
```
|
|
||||||
|
|
||||||
### Универсальные playbooks
|
|
||||||
|
|
||||||
Playbooks создаются **универсальными** с поддержкой:
|
|
||||||
|
|
||||||
1. **`gather_facts: true`** - сбор информации об ОС
|
|
||||||
2. **`pre_tasks`** - отображение информации об ОС
|
|
||||||
3. **`post_tasks`** - проверка успешного развертывания
|
|
||||||
4. **Переменные роли** - автоматически добавляются в `vars`
|
|
||||||
|
|
||||||
### Список playbooks
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make role playbook NAME=my-role
|
|
||||||
# Выберите: list
|
|
||||||
```
|
|
||||||
|
|
||||||
### Редактирование playbook
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make role playbook NAME=my-role
|
|
||||||
# Выберите: edit
|
|
||||||
# Введите имя: deploy
|
|
||||||
```
|
|
||||||
|
|
||||||
### Запуск playbook
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make role playbook NAME=my-role
|
|
||||||
# Выберите: run
|
|
||||||
# Введите имя: deploy
|
|
||||||
```
|
|
||||||
|
|
||||||
## Команды управления ролями
|
|
||||||
|
|
||||||
### Основные команды
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Список ролей
|
|
||||||
make role list
|
|
||||||
|
|
||||||
# Создать роль (интерактивно)
|
|
||||||
make role create NAME=my-role
|
|
||||||
|
|
||||||
# Редактировать роль
|
|
||||||
make role edit NAME=my-role
|
|
||||||
|
|
||||||
# Тестировать роль
|
|
||||||
make role test NAME=my-role
|
|
||||||
|
|
||||||
# Проверить синтаксис
|
|
||||||
make role lint
|
|
||||||
|
|
||||||
# Развернуть роли
|
|
||||||
make role deploy
|
|
||||||
|
|
||||||
# Информация о роли
|
|
||||||
make role info NAME=my-role
|
|
||||||
|
|
||||||
# Управление playbooks
|
|
||||||
make role playbook NAME=my-role
|
|
||||||
```
|
|
||||||
|
|
||||||
### Интерактивные возможности
|
|
||||||
|
|
||||||
#### При создании роли:
|
|
||||||
- **Описание роли** - автоматически добавляется в README.md
|
|
||||||
- **Основной пакет** - настраивается в defaults/main.yml
|
|
||||||
- **Сервис** - настраивается в defaults/main.yml
|
|
||||||
- **Платформы** - добавляются в meta/main.yml
|
|
||||||
- **Теги** - добавляются в meta/main.yml
|
|
||||||
|
|
||||||
#### При работе с playbooks:
|
|
||||||
- **Создание** - интерактивный ввод имени
|
|
||||||
- **Редактирование** - выбор из списка существующих
|
|
||||||
- **Запуск** - выбор playbook для выполнения
|
|
||||||
|
|
||||||
## Примеры использования
|
|
||||||
|
|
||||||
### Создание роли nginx
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make role create NAME=nginx
|
|
||||||
# Описание: Nginx web server role
|
|
||||||
# Пакет: nginx
|
|
||||||
# Сервис: nginx
|
|
||||||
# Платформы: ubuntu,centos
|
|
||||||
# Теги: web,nginx,server
|
|
||||||
```
|
|
||||||
|
|
||||||
### Создание playbook для nginx
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make role playbook NAME=nginx
|
|
||||||
# Выберите: create
|
|
||||||
# Имя: install
|
|
||||||
```
|
|
||||||
|
|
||||||
**Результат:** `roles/nginx/playbooks/install.yml`
|
|
||||||
|
|
||||||
### Запуск playbook
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make role playbook NAME=nginx
|
|
||||||
# Выберите: run
|
|
||||||
# Имя: install
|
|
||||||
```
|
|
||||||
|
|
||||||
## Структура файлов роли
|
|
||||||
|
|
||||||
### tasks/main.yml
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
# Основные задачи роли nginx
|
|
||||||
# Автор: Сергей Антропов
|
|
||||||
# Сайт: https://devops.org.ru
|
|
||||||
|
|
||||||
- name: nginx placeholder
|
|
||||||
debug:
|
|
||||||
msg: "Роль nginx готова для настройки"
|
|
||||||
|
|
||||||
- name: Install nginx package
|
|
||||||
package:
|
|
||||||
name: "{{ nginx_package | default('nginx') }}"
|
|
||||||
state: present
|
|
||||||
|
|
||||||
- name: Start nginx service
|
|
||||||
systemd:
|
|
||||||
name: "{{ nginx_service | default('nginx') }}"
|
|
||||||
state: started
|
|
||||||
enabled: true
|
|
||||||
when: nginx_service is defined
|
|
||||||
```
|
|
||||||
|
|
||||||
### defaults/main.yml
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
# Переменные по умолчанию для роли nginx
|
|
||||||
# Автор: Сергей Антропов
|
|
||||||
# Сайт: https://devops.org.ru
|
|
||||||
|
|
||||||
nginx_enabled: true
|
|
||||||
nginx_package: nginx
|
|
||||||
nginx_service: nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
### meta/main.yml
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
galaxy_info:
|
|
||||||
author: Сергей Антропов
|
|
||||||
description: Nginx web server role
|
|
||||||
company: https://devops.org.ru
|
|
||||||
license: MIT
|
|
||||||
min_ansible_version: 2.9
|
|
||||||
platforms:
|
|
||||||
- name: Ubuntu
|
|
||||||
versions: [focal, jammy]
|
|
||||||
- name: CentOS
|
|
||||||
versions: [7, 8, 9]
|
|
||||||
- name: RHEL
|
|
||||||
versions: [7, 8, 9]
|
|
||||||
galaxy_tags: [web,nginx,server]
|
|
||||||
dependencies: []
|
|
||||||
```
|
|
||||||
|
|
||||||
## Лучшие практики
|
|
||||||
|
|
||||||
### 1. Универсальные роли
|
|
||||||
- **Всегда создавайте OS-специфичные задачи** в `debian.yml` и `redhat.yml`
|
|
||||||
- **Используйте `ansible_os_family`** для определения ОС
|
|
||||||
- **Тестируйте на разных платформах** (Ubuntu, CentOS, RHEL)
|
|
||||||
- **Используйте универсальные модули** когда возможно (package, systemd)
|
|
||||||
|
|
||||||
### 2. Структура роли
|
|
||||||
- **`tasks/main.yml`** - общая логика и включение OS-специфичных задач
|
|
||||||
- **`tasks/debian.yml`** - задачи для Debian/Ubuntu (apt, systemd)
|
|
||||||
- **`tasks/redhat.yml`** - задачи для RHEL/CentOS (yum, systemd)
|
|
||||||
- **`handlers`** - для перезапуска сервисов
|
|
||||||
- **`templates`** - для конфигурационных файлов
|
|
||||||
- **`files`** - для статических файлов
|
|
||||||
|
|
||||||
### 3. Переменные
|
|
||||||
- **`defaults/main.yml`** - значения по умолчанию
|
|
||||||
- **`vars/main.yml`** - внутренние переменные роли
|
|
||||||
- **Используйте префиксы** для переменных роли
|
|
||||||
- **Создавайте OS-специфичные переменные** при необходимости
|
|
||||||
|
|
||||||
### 4. Playbooks
|
|
||||||
- **`gather_facts: true`** - всегда собирайте информацию об ОС
|
|
||||||
- **`pre_tasks`** - отображайте информацию об ОС
|
|
||||||
- **`post_tasks`** - проверяйте успешное развертывание
|
|
||||||
- **Используйте переменные** для настройки
|
|
||||||
|
|
||||||
### 5. Тестирование
|
|
||||||
- **`make role test`** - проверка роли
|
|
||||||
- **Тестируйте на разных ОС** - Ubuntu, CentOS, RHEL
|
|
||||||
- **Создавайте тесты** в папке tests/
|
|
||||||
- **Проверяйте идемпотентность** - повторный запуск не должен изменять систему
|
|
||||||
|
|
||||||
## Интеграция с лабораторией
|
|
||||||
|
|
||||||
### Автоматическое добавление в систему
|
|
||||||
|
|
||||||
При создании роли через `make role create`:
|
|
||||||
1. Роль автоматически добавляется в `deploy/tasks/main.yml`
|
|
||||||
2. Создается переменная `{role_name}_enabled: true`
|
|
||||||
3. Обновляется `site.yml` с новой ролью
|
|
||||||
|
|
||||||
### Использование в playbooks
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Deploy my-role
|
|
||||||
hosts: all
|
|
||||||
become: true
|
|
||||||
roles:
|
|
||||||
- role: my-role
|
|
||||||
vars:
|
|
||||||
my_role_enabled: true
|
|
||||||
my_role_package: custom-package
|
|
||||||
```
|
|
||||||
|
|
||||||
## Автор
|
|
||||||
|
|
||||||
Сергей Антропов
|
|
||||||
Сайт: https://devops.org.ru
|
|
||||||
99
docs/testing-vs-deployment.md
Normal file
99
docs/testing-vs-deployment.md
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
# Тестирование vs Развертывание
|
||||||
|
|
||||||
|
## Автор: Сергей Антропов
|
||||||
|
## Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
## Различие между тестированием и развертыванием
|
||||||
|
|
||||||
|
### 🧪 Тестирование (molecule)
|
||||||
|
|
||||||
|
**Команда:** `make role test [preset]`
|
||||||
|
|
||||||
|
**Использует:**
|
||||||
|
- Динамический inventory, создаваемый в `molecule/default/create.yml`
|
||||||
|
- Preset файлы из `molecule/presets/`
|
||||||
|
- Docker контейнеры для изоляции тестов
|
||||||
|
- Временные контейнеры (u1, u2, u3)
|
||||||
|
|
||||||
|
**Процесс:**
|
||||||
|
1. Загружается preset конфигурация
|
||||||
|
2. Создаются Docker контейнеры согласно preset
|
||||||
|
3. Генерируется временный inventory файл
|
||||||
|
4. Запускаются тесты на контейнерах
|
||||||
|
5. Контейнеры удаляются после тестов
|
||||||
|
|
||||||
|
**Пример:**
|
||||||
|
```bash
|
||||||
|
make role test standart # Тестирование в 3 контейнерах
|
||||||
|
make role test minimal # Тестирование в 1 контейнере
|
||||||
|
```
|
||||||
|
|
||||||
|
### 🚀 Развертывание (deploy)
|
||||||
|
|
||||||
|
**Команда:** `make role deploy`
|
||||||
|
|
||||||
|
**Использует:**
|
||||||
|
- Статический inventory файл `inventory/hosts.ini`
|
||||||
|
- Реальные серверы
|
||||||
|
- SSH подключение
|
||||||
|
|
||||||
|
**Процесс:**
|
||||||
|
1. Проверяется наличие `inventory/hosts.ini`
|
||||||
|
2. Показывается содержимое inventory
|
||||||
|
3. Запускается dry-run (--check)
|
||||||
|
4. Запрашивается подтверждение
|
||||||
|
5. Выполняется развертывание на реальные серверы
|
||||||
|
|
||||||
|
**Пример:**
|
||||||
|
```bash
|
||||||
|
make role deploy # Развертывание на реальные серверы
|
||||||
|
```
|
||||||
|
|
||||||
|
## Конфигурация
|
||||||
|
|
||||||
|
### Для тестирования
|
||||||
|
- Preset файлы: `molecule/presets/*.yml`
|
||||||
|
- Динамический inventory создается в `create.yml`
|
||||||
|
- Контейнеры: Docker
|
||||||
|
|
||||||
|
### Для развертывания
|
||||||
|
- Inventory файл: `inventory/hosts.ini`
|
||||||
|
- Серверы: Реальные хосты
|
||||||
|
- Подключение: SSH
|
||||||
|
|
||||||
|
## Примеры конфигурации
|
||||||
|
|
||||||
|
### Preset для тестирования (molecule/presets/standart.yml)
|
||||||
|
```yaml
|
||||||
|
hosts:
|
||||||
|
- name: u1
|
||||||
|
family: debian
|
||||||
|
groups: [test]
|
||||||
|
- name: u2
|
||||||
|
family: rhel
|
||||||
|
groups: [test]
|
||||||
|
- name: u3
|
||||||
|
family: debian
|
||||||
|
groups: [test]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Inventory для развертывания (inventory/hosts.ini)
|
||||||
|
```ini
|
||||||
|
[web_servers]
|
||||||
|
web1 ansible_host=192.168.1.10 ansible_user=ubuntu
|
||||||
|
web2 ansible_host=192.168.1.11 ansible_user=ubuntu
|
||||||
|
|
||||||
|
[db_servers]
|
||||||
|
db1 ansible_host=192.168.1.20 ansible_user=ubuntu
|
||||||
|
|
||||||
|
[all:vars]
|
||||||
|
ansible_ssh_private_key_file=~/.ssh/id_rsa
|
||||||
|
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Рекомендации
|
||||||
|
|
||||||
|
1. **Сначала тестируйте** с помощью `make role test [preset]`
|
||||||
|
2. **Затем развертывайте** с помощью `make role deploy`
|
||||||
|
3. **Используйте разные preset'ы** для разных сценариев тестирования
|
||||||
|
4. **Настройте inventory** для ваших реальных серверов
|
||||||
@@ -1,652 +0,0 @@
|
|||||||
# 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)
|
|
||||||
@@ -1,295 +0,0 @@
|
|||||||
# Универсальная лаборатория для тестирования 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]
|
|
||||||
281
docs/universal-testing.md
Normal file
281
docs/universal-testing.md
Normal file
@@ -0,0 +1,281 @@
|
|||||||
|
# Универсальная система тестирования Ansible ролей
|
||||||
|
|
||||||
|
## Обзор
|
||||||
|
|
||||||
|
Эта система предоставляет универсальную среду для тестирования и деплоя Ansible ролей с поддержкой различных типов контейнеров, автоматической генерации инвентаря и интеграции с Ansible Vault.
|
||||||
|
|
||||||
|
## Основные возможности
|
||||||
|
|
||||||
|
### 🐳 Типы контейнеров
|
||||||
|
|
||||||
|
#### Systemd контейнеры (по умолчанию)
|
||||||
|
- Полная поддержка systemd сервисов
|
||||||
|
- Работа как виртуальные машины
|
||||||
|
- Подходит для тестирования ролей
|
||||||
|
|
||||||
|
#### DinD (Docker-in-Docker)
|
||||||
|
- Изолированный Docker daemon
|
||||||
|
- Подходит для тестирования Docker Compose
|
||||||
|
- Полная изоляция от хостового Docker
|
||||||
|
|
||||||
|
#### DOoD (Docker-out-of-Docker)
|
||||||
|
- Доступ к хостовому Docker daemon
|
||||||
|
- Быстрое тестирование
|
||||||
|
- Подходит для CI/CD
|
||||||
|
|
||||||
|
### 📋 Preset'ы
|
||||||
|
|
||||||
|
#### etcd-patroni
|
||||||
|
- Кластер etcd (5 узлов)
|
||||||
|
- Кластер PostgreSQL с Patroni (3 узла)
|
||||||
|
- HAProxy для балансировки
|
||||||
|
- DinD узел для тестирования
|
||||||
|
|
||||||
|
#### performance
|
||||||
|
- 5 серверов приложений
|
||||||
|
- 3 узла базы данных
|
||||||
|
- 3 узла кэша Redis
|
||||||
|
- Load balancer
|
||||||
|
- DinD узел для тестирования
|
||||||
|
|
||||||
|
#### security
|
||||||
|
- Bastion хосты
|
||||||
|
- Внутренние серверы
|
||||||
|
- Изолированная база данных
|
||||||
|
- Мониторинг и логирование
|
||||||
|
- Firewall компоненты
|
||||||
|
- DOoD узел для тестирования
|
||||||
|
|
||||||
|
#### multi-os
|
||||||
|
- Тестирование на разных ОС
|
||||||
|
- Ubuntu, Debian, RHEL, CentOS
|
||||||
|
- Смешанные конфигурации
|
||||||
|
- DinD узел для тестирования
|
||||||
|
|
||||||
|
### 🔐 Ansible Vault интеграция
|
||||||
|
|
||||||
|
- Автоматическая расшифровка перед тестированием
|
||||||
|
- Безопасное хранение секретов
|
||||||
|
- Автоматическая повторная шифровка после тестирования
|
||||||
|
- Поддержка множественных vault'ов
|
||||||
|
|
||||||
|
## Использование
|
||||||
|
|
||||||
|
### Базовые команды
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Показать все preset'ы
|
||||||
|
make preset-list
|
||||||
|
|
||||||
|
# Информация о preset'е
|
||||||
|
make preset-info PRESET=etcd-patroni
|
||||||
|
|
||||||
|
# Тестирование с preset'ом
|
||||||
|
make preset-test PRESET=etcd-patroni
|
||||||
|
|
||||||
|
# Типы контейнеров
|
||||||
|
make container-types
|
||||||
|
|
||||||
|
# Информация о контейнерах
|
||||||
|
make container-info
|
||||||
|
|
||||||
|
# Проверка vault файлов
|
||||||
|
make vault-check
|
||||||
|
|
||||||
|
# Поиск секретов
|
||||||
|
make vault-scan
|
||||||
|
```
|
||||||
|
|
||||||
|
### Тестирование ролей
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# С default preset
|
||||||
|
make role test
|
||||||
|
|
||||||
|
# С конкретным preset'ом
|
||||||
|
make role test etcd-patroni
|
||||||
|
make role test performance
|
||||||
|
make role test security
|
||||||
|
make role test multi-os
|
||||||
|
```
|
||||||
|
|
||||||
|
### Работа с Ansible Vault
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Создать файл секретов
|
||||||
|
make vault create
|
||||||
|
|
||||||
|
# Редактировать секреты
|
||||||
|
make vault edit
|
||||||
|
|
||||||
|
# Показать секреты
|
||||||
|
make vault show
|
||||||
|
|
||||||
|
# Зашифровать файл
|
||||||
|
make vault encrypt
|
||||||
|
|
||||||
|
# Расшифровать файл
|
||||||
|
make vault decrypt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Структура проекта
|
||||||
|
|
||||||
|
```
|
||||||
|
.
|
||||||
|
├── molecule/
|
||||||
|
│ ├── default/
|
||||||
|
│ │ ├── create.yml # Создание контейнеров
|
||||||
|
│ │ ├── destroy.yml # Удаление контейнеров
|
||||||
|
│ │ ├── converge.yml # Запуск плейбуков
|
||||||
|
│ │ └── verify.yml # Проверка результатов
|
||||||
|
│ └── presets/
|
||||||
|
│ ├── etcd-patroni.yml
|
||||||
|
│ ├── performance.yml
|
||||||
|
│ ├── security.yml
|
||||||
|
│ └── multi-os.yml
|
||||||
|
├── files/
|
||||||
|
│ ├── requirements.yml
|
||||||
|
│ └── playbooks/
|
||||||
|
│ └── site.yml
|
||||||
|
├── vault/
|
||||||
|
│ └── secrets.yml
|
||||||
|
└── Makefile
|
||||||
|
```
|
||||||
|
|
||||||
|
## Создание собственных preset'ов
|
||||||
|
|
||||||
|
### Пример preset'а
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
---
|
||||||
|
# Пресет для тестирования кластера etcd + PostgreSQL + Patroni
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
|
||||||
|
|
||||||
|
# systemd-ready образы
|
||||||
|
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:
|
||||||
|
# Systemd узлы
|
||||||
|
- name: server1
|
||||||
|
family: debian
|
||||||
|
groups: [servers, web]
|
||||||
|
publish: ["80:80"]
|
||||||
|
|
||||||
|
# DinD узел
|
||||||
|
- name: app-dind
|
||||||
|
type: dind
|
||||||
|
groups: [apps, docker]
|
||||||
|
publish: ["8080:8080"]
|
||||||
|
|
||||||
|
# DOoD узел
|
||||||
|
- name: docker-secure
|
||||||
|
type: dood
|
||||||
|
family: debian
|
||||||
|
groups: [docker, security]
|
||||||
|
publish: ["8081:8081"]
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Параметры хостов
|
||||||
|
|
||||||
|
- `name` - имя хоста
|
||||||
|
- `family` - семейство ОС (debian, rhel, ubuntu, centos)
|
||||||
|
- `type` - тип контейнера (dind, dood)
|
||||||
|
- `groups` - группы для инвентаря
|
||||||
|
- `publish` - порты для публикации
|
||||||
|
- `env` - переменные окружения
|
||||||
|
- `volumes` - дополнительные тома
|
||||||
|
- `capabilities` - дополнительные возможности
|
||||||
|
|
||||||
|
## Лучшие практики
|
||||||
|
|
||||||
|
### 1. Использование групп
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
hosts:
|
||||||
|
- name: web1
|
||||||
|
groups: [web, servers, production]
|
||||||
|
- name: db1
|
||||||
|
groups: [database, servers, production]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Безопасность
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Используйте Ansible Vault для секретов
|
||||||
|
vault_targets:
|
||||||
|
- /ansible/vault/secrets.yml
|
||||||
|
- /ansible/files/playbooks/group_vars/*/vault.yml
|
||||||
|
- /ansible/files/playbooks/host_vars/*/vault.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Тестирование
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Проверяйте различные сценарии
|
||||||
|
- name: Test web servers
|
||||||
|
hosts: web
|
||||||
|
tasks:
|
||||||
|
- name: Check nginx status
|
||||||
|
systemd:
|
||||||
|
name: nginx
|
||||||
|
state: started
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Проблемы с контейнерами
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Проверить статус контейнеров
|
||||||
|
make container-info
|
||||||
|
|
||||||
|
# Очистить Docker ресурсы
|
||||||
|
make docker clean
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблемы с Vault
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Проверить vault файлы
|
||||||
|
make vault-check
|
||||||
|
|
||||||
|
# Найти потенциальные секреты
|
||||||
|
make vault-scan
|
||||||
|
```
|
||||||
|
|
||||||
|
### Проблемы с preset'ами
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Показать все preset'ы
|
||||||
|
make preset-list
|
||||||
|
|
||||||
|
# Информация о preset'е
|
||||||
|
make preset-info PRESET=имя_пресета
|
||||||
|
```
|
||||||
|
|
||||||
|
## Заключение
|
||||||
|
|
||||||
|
Универсальная система тестирования Ansible ролей предоставляет мощные инструменты для тестирования ролей в различных сценариях. Используйте preset'ы для быстрого создания тестовых сред, различные типы контейнеров для изоляции и Ansible Vault для безопасности.
|
||||||
|
|
||||||
|
Для получения дополнительной информации используйте:
|
||||||
|
- `make help` - общая справка
|
||||||
|
- `make role` - команды для ролей
|
||||||
|
- `make molecule` - команды Molecule
|
||||||
|
- `make vault` - команды Vault
|
||||||
69
env.example
69
env.example
@@ -1,69 +0,0 @@
|
|||||||
# =============================================================================
|
|
||||||
# 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
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
{
|
|
||||||
"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": []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
---
|
|
||||||
# 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%" }
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
---
|
|
||||||
# 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
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
---
|
|
||||||
# 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
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
---
|
|
||||||
# Основной 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: "Инфраструктура готова для настройки"
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
---
|
|
||||||
# Коллекции Ansible для универсальной лаборатории
|
|
||||||
# Автор: Сергей Антропов
|
|
||||||
# Сайт: https://devops.org.ru
|
|
||||||
|
|
||||||
collections:
|
|
||||||
- name: community.docker
|
|
||||||
- name: community.general
|
|
||||||
16
inventory/hosts.ini
Normal file
16
inventory/hosts.ini
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Инвентори для развертывания на реальные серверы
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
# Примеры серверов (замените на ваши реальные серверы)
|
||||||
|
[web_servers]
|
||||||
|
# web1 ansible_host=192.168.1.10 ansible_user=ubuntu
|
||||||
|
# web2 ansible_host=192.168.1.11 ansible_user=ubuntu
|
||||||
|
|
||||||
|
[db_servers]
|
||||||
|
# db1 ansible_host=192.168.1.20 ansible_user=ubuntu
|
||||||
|
|
||||||
|
[all:vars]
|
||||||
|
# Общие переменные для всех серверов
|
||||||
|
ansible_ssh_private_key_file=~/.ssh/id_rsa
|
||||||
|
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
|
||||||
@@ -1,79 +1,75 @@
|
|||||||
---
|
---
|
||||||
# Запуск ролей в универсальной лаборатории
|
|
||||||
# Автор: Сергей Антропов
|
|
||||||
# Сайт: https://devops.org.ru
|
|
||||||
|
|
||||||
- hosts: localhost
|
- hosts: localhost
|
||||||
gather_facts: false
|
gather_facts: false
|
||||||
vars:
|
vars:
|
||||||
# Перечисли файлы/глобы с секретами (можно добавлять свои пути)
|
# Получаем preset из переменной окружения или используем default
|
||||||
|
preset_name: "{{ lookup('env', 'MOLECULE_PRESET') | default('default') }}"
|
||||||
|
preset_file: "/workspace/molecule/presets/{{ preset_name }}.yml"
|
||||||
|
|
||||||
|
# перечисли файлы/глобы, которые нужно временно расшифровать
|
||||||
vault_targets:
|
vault_targets:
|
||||||
- /ansible/vault/secrets.yml
|
- /ansible/vault/secrets.yml
|
||||||
- /ansible/files/playbooks/group_vars/*/vault.yml
|
- /ansible/files/playbooks/group_vars/*/vault.yml
|
||||||
- /ansible/files/playbooks/host_vars/*/vault.yml
|
- /ansible/files/playbooks/host_vars/*/vault.yml
|
||||||
- /ansible/roles/**/vars/vault.yml
|
- /ansible/roles/**/vars/vault.yml
|
||||||
|
|
||||||
pre_tasks:
|
|
||||||
- name: Load lab preset (vars)
|
|
||||||
include_vars:
|
|
||||||
file: "{{ lab_spec }}"
|
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Install collections in controller
|
- name: Load preset configuration
|
||||||
|
include_vars: "{{ preset_file }}"
|
||||||
|
when: preset_file is file
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Install collections
|
||||||
community.docker.docker_container_exec:
|
community.docker.docker_container_exec:
|
||||||
container: ansible-controller
|
container: ansible-controller
|
||||||
command: bash -lc "ansible-galaxy collection install -r /ansible/files/requirements.yml || true"
|
command: bash -lc "ansible-galaxy collection install -r /ansible/requirements.yml --force --no-deps --upgrade >/dev/null 2>&1 || true"
|
||||||
|
|
||||||
# --- Preflight Vault: если файл уже открыт, шифруем и снова расшифровываем ---
|
|
||||||
- name: Preflight vault — normalize state (encrypt if plaintext, then decrypt)
|
- name: Preflight vault — normalize state (encrypt if plaintext, then decrypt)
|
||||||
community.docker.docker_container_exec:
|
community.docker.docker_container_exec:
|
||||||
container: ansible-controller
|
container: ansible-controller
|
||||||
command: >
|
command: >
|
||||||
bash -lc '
|
bash -lc '
|
||||||
set -euo pipefail;
|
set -euo pipefail; shopt -s nullglob globstar;
|
||||||
shopt -s nullglob globstar;
|
|
||||||
for p in {{ vault_targets | map('quote') | join(' ') }}; do
|
for p in {{ vault_targets | map('quote') | join(' ') }}; do
|
||||||
for f in $p; do
|
for f in $p; do
|
||||||
if [ ! -f "$f" ]; then continue; fi
|
[ -f "$f" ] || continue;
|
||||||
head -n1 "$f" | grep -q "^\$ANSIBLE_VAULT;" && enc=1 || enc=0
|
if head -n1 "$f" | grep -q "^\$ANSIBLE_VAULT;"; then
|
||||||
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";
|
echo "[vault] already encrypted: $f";
|
||||||
|
else
|
||||||
|
echo "[vault] plaintext -> encrypt: $f";
|
||||||
|
ansible-vault encrypt --encrypt-vault-id default --vault-password-file /ansible/vault-password.txt "$f";
|
||||||
fi
|
fi
|
||||||
echo "[vault] decrypt for run: $f";
|
echo "[vault] decrypt for run: $f";
|
||||||
ansible-vault decrypt --vault-password-file /ansible/vault/.vault "$f";
|
ansible-vault decrypt --vault-password-file /ansible/vault-password.txt "$f";
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
'
|
'
|
||||||
|
|
||||||
- name: Run external playbook (your roles live in /ansible/roles)
|
- name: Run lab playbook
|
||||||
community.docker.docker_container_exec:
|
community.docker.docker_container_exec:
|
||||||
container: ansible-controller
|
container: ansible-controller
|
||||||
command: >
|
command: >
|
||||||
bash -lc "
|
bash -lc "
|
||||||
ANSIBLE_ROLES_PATH=/ansible/roles
|
ANSIBLE_ROLES_PATH=/ansible/roles
|
||||||
ansible-playbook -i {{ lookup('env','MOLECULE_EPHEMERAL_DIRECTORY') }}/inventory/hosts.yml /ansible/files/playbooks/site.yml
|
ansible-playbook -i {{ lookup('env','MOLECULE_EPHEMERAL_DIRECTORY') }}/inventory/hosts.ini /ansible/files/playbooks/site.yml
|
||||||
"
|
"
|
||||||
|
|
||||||
# --- Пост-этап: всегда шифруем обратно ---
|
- name: Post-run — re-encrypt secrets
|
||||||
- name: Post-run vault — re-encrypt everything
|
|
||||||
community.docker.docker_container_exec:
|
community.docker.docker_container_exec:
|
||||||
container: ansible-controller
|
container: ansible-controller
|
||||||
command: >
|
command: >
|
||||||
bash -lc '
|
bash -lc '
|
||||||
set -euo pipefail;
|
set -euo pipefail; shopt -s nullglob globstar;
|
||||||
shopt -s nullglob globstar;
|
|
||||||
for p in {{ vault_targets | map('quote') | join(' ') }}; do
|
for p in {{ vault_targets | map('quote') | join(' ') }}; do
|
||||||
for f in $p; do
|
for f in $p; do
|
||||||
if [ ! -f "$f" ]; then continue; fi
|
[ -f "$f" ] || continue;
|
||||||
head -n1 "$f" | grep -q "^\$ANSIBLE_VAULT;" && enc=1 || enc=0
|
if head -n1 "$f" | grep -q "^\$ANSIBLE_VAULT;"; then
|
||||||
if [ "$enc" -eq 0 ]; then
|
echo "[vault] ok (encrypted): $f";
|
||||||
|
else
|
||||||
echo "[vault] encrypt back: $f";
|
echo "[vault] encrypt back: $f";
|
||||||
ansible-vault encrypt --encrypt-vault-id default --vault-password-file /ansible/vault/.vault "$f" || true;
|
ansible-vault encrypt --encrypt-vault-id default --vault-password-file /ansible/vault-password.txt "$f" || true;
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
'
|
'
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
165
molecule/default/create.yml
Normal file
165
molecule/default/create.yml
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
---
|
||||||
|
- hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
vars:
|
||||||
|
# Получаем preset из переменной окружения или используем default
|
||||||
|
preset_name: "{{ lookup('env', 'MOLECULE_PRESET') | default('default') }}"
|
||||||
|
preset_file: "/workspace/molecule/presets/{{ preset_name }}.yml"
|
||||||
|
|
||||||
|
# Fallback значения если preset файл не найден
|
||||||
|
docker_network: labnet
|
||||||
|
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
rhel: "quay.io/centos/centos:stream9-systemd"
|
||||||
|
ubuntu: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
centos: "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: u1
|
||||||
|
family: debian
|
||||||
|
groups: [test]
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Install required collections
|
||||||
|
command: ansible-galaxy collection install -r /workspace/requirements.yml
|
||||||
|
delegate_to: localhost
|
||||||
|
ignore_errors: true
|
||||||
|
register: collections_install
|
||||||
|
changed_when: false
|
||||||
|
run_once: true
|
||||||
|
become: true
|
||||||
|
vars:
|
||||||
|
ansible_python_interpreter: /usr/bin/python3
|
||||||
|
environment:
|
||||||
|
ANSIBLE_COLLECTIONS_PATH: /usr/share/ansible/collections
|
||||||
|
|
||||||
|
- name: Load preset configuration
|
||||||
|
include_vars: "{{ preset_file }}"
|
||||||
|
when: preset_file is file
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Ensure network exists
|
||||||
|
community.docker.docker_network:
|
||||||
|
name: "{{ docker_network }}"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
# SYSTEMD nodes
|
||||||
|
- 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 }}" }
|
||||||
|
when: item.family is defined and images[item.family] is defined
|
||||||
|
|
||||||
|
- 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 | default([]) + (item.volumes | default([])) }}"
|
||||||
|
tmpfs: "{{ systemd_defaults.tmpfs | default([]) }}"
|
||||||
|
capabilities: "{{ systemd_defaults.capabilities | default([]) }}"
|
||||||
|
published_ports: "{{ item.publish | default([]) }}"
|
||||||
|
environment: "{{ item.env | default({}) }}"
|
||||||
|
state: started
|
||||||
|
restart_policy: unless-stopped
|
||||||
|
loop: "{{ hosts | selectattr('type','undefined') | list }}"
|
||||||
|
loop_control: { label: "{{ item.name }}" }
|
||||||
|
when: item.family is defined and images[item.family] is defined
|
||||||
|
|
||||||
|
# DinD nodes
|
||||||
|
- name: Start DinD nodes (docker:27-dind)
|
||||||
|
community.docker.docker_container:
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
image: "docker:27-dind"
|
||||||
|
networks:
|
||||||
|
- name: "{{ docker_network }}"
|
||||||
|
privileged: true
|
||||||
|
environment:
|
||||||
|
DOCKER_TLS_CERTDIR: ""
|
||||||
|
published_ports: "{{ item.publish | default([]) }}"
|
||||||
|
volumes: "{{ (item.volumes | default([])) + [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 }}" }
|
||||||
|
|
||||||
|
# DOoD nodes (mount docker.sock)
|
||||||
|
- name: Start DOoD nodes (systemd + docker.sock mount)
|
||||||
|
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'] + (item.volumes | default([])) }}"
|
||||||
|
tmpfs: "{{ systemd_defaults.tmpfs | default([]) }}"
|
||||||
|
capabilities: "{{ systemd_defaults.capabilities | default([]) }}"
|
||||||
|
published_ports: "{{ item.publish | default([]) }}"
|
||||||
|
environment: "{{ item.env | default({}) }}"
|
||||||
|
state: started
|
||||||
|
restart_policy: unless-stopped
|
||||||
|
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list }}"
|
||||||
|
loop_control: { label: "{{ item.name }}" }
|
||||||
|
when: item.family is defined and images[item.family] is defined
|
||||||
|
|
||||||
|
# Build groups map
|
||||||
|
- name: Initialize 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 | subelements('groups', skip_missing=True) }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.0.name }}"
|
||||||
|
vars:
|
||||||
|
item_name: "{{ item.0.name }}"
|
||||||
|
item_group: "{{ item.1 }}"
|
||||||
|
|
||||||
|
# Render inventory
|
||||||
|
- name: Render inventory ini
|
||||||
|
set_fact:
|
||||||
|
inv_content: |
|
||||||
|
[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 %}{{ h.name }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
- name: Write inventory file
|
||||||
|
copy:
|
||||||
|
dest: "{{ generated_inventory }}"
|
||||||
|
content: "{{ inv_content }}"
|
||||||
|
mode: "0644"
|
||||||
|
|
||||||
|
- name: Display inventory summary
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
📋 Inventory Summary:
|
||||||
|
- Total hosts: {{ hosts | length }}
|
||||||
|
- Groups: {{ groups_map.keys() | list | join(', ') }}
|
||||||
|
- Systemd nodes: {{ hosts | selectattr('type','undefined') | list | length }}
|
||||||
|
- DinD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list | length }}
|
||||||
|
- DOoD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list | length }}
|
||||||
60
molecule/default/destroy.yml
Normal file
60
molecule/default/destroy.yml
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
- hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
vars:
|
||||||
|
# Получаем preset из переменной окружения или используем default
|
||||||
|
preset_name: "{{ lookup('env', 'MOLECULE_PRESET') | default('default') }}"
|
||||||
|
preset_file: "/workspace/molecule/presets/{{ preset_name }}.yml"
|
||||||
|
|
||||||
|
# Fallback значения если preset файл не найден
|
||||||
|
docker_network: labnet
|
||||||
|
hosts:
|
||||||
|
- name: u1
|
||||||
|
family: debian
|
||||||
|
groups: [test]
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Load preset configuration
|
||||||
|
include_vars: "{{ preset_file }}"
|
||||||
|
when: preset_file is file
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Stop and 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 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 custom volumes
|
||||||
|
community.docker.docker_volume:
|
||||||
|
name: "{{ item.volumes | default([]) | select('match', '^[^:]+$') | list }}"
|
||||||
|
state: absent
|
||||||
|
loop: "{{ hosts }}"
|
||||||
|
loop_control: { label: "{{ item.name }}" }
|
||||||
|
ignore_errors: true
|
||||||
|
when: item.volumes is defined
|
||||||
|
|
||||||
|
- name: Remove network
|
||||||
|
community.docker.docker_network:
|
||||||
|
name: "{{ docker_network }}"
|
||||||
|
state: absent
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Display cleanup summary
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
🧹 Cleanup Summary:
|
||||||
|
- Removed containers: {{ hosts | length }}
|
||||||
|
- Removed DinD volumes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list | length }}
|
||||||
|
- Network: {{ docker_network }}
|
||||||
38
molecule/default/molecule.yml
Normal file
38
molecule/default/molecule.yml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
---
|
||||||
|
# Универсальная конфигурация Molecule
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
driver:
|
||||||
|
name: docker
|
||||||
|
|
||||||
|
platforms:
|
||||||
|
# Платформы будут созданы динамически через preset файлы
|
||||||
|
- name: placeholder
|
||||||
|
image: ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy
|
||||||
|
pre_build_image: true
|
||||||
|
|
||||||
|
provisioner:
|
||||||
|
name: ansible
|
||||||
|
config_options:
|
||||||
|
defaults:
|
||||||
|
stdout_callback: yaml
|
||||||
|
env:
|
||||||
|
ANSIBLE_STDOUT_CALLBACK: yaml
|
||||||
|
inventory:
|
||||||
|
links:
|
||||||
|
hosts: "${MOLECULE_EPHEMERAL_DIRECTORY}/inventory/hosts.ini"
|
||||||
|
playbooks:
|
||||||
|
create: create.yml
|
||||||
|
converge: converge.yml
|
||||||
|
destroy: destroy.yml
|
||||||
|
|
||||||
|
dependency:
|
||||||
|
name: galaxy
|
||||||
|
|
||||||
|
verifier:
|
||||||
|
name: ansible
|
||||||
|
|
||||||
|
lint: |-
|
||||||
|
set -e
|
||||||
|
ansible-lint /workspace/roles/
|
||||||
29
molecule/default/site.yml
Normal file
29
molecule/default/site.yml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
# Универсальный плейбук для тестирования
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: 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: Common tools
|
||||||
|
raw: dnf install -y curl jq ca-certificates iproute2 iputils procps-ng net-tools sudo vim || yum install -y curl jq ca-certificates iproute2 iputils procps-ng net-tools sudo vim || apt-get update && apt-get install -y curl jq ca-certificates iproute2 iputils-ping procps net-tools sudo vim || true
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Update ansible-lint
|
||||||
|
raw: pip install --upgrade ansible-lint --quiet --no-warn-script-location || true
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Install ansible collections
|
||||||
|
raw: ansible-galaxy collection install -r requirements.yml --force --no-deps --upgrade || true
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- import_playbook: ../../deploy.yml
|
||||||
|
|
||||||
122
molecule/default/verify.yml
Normal file
122
molecule/default/verify.yml
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
---
|
||||||
|
- hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
vars:
|
||||||
|
# Получаем preset из переменной окружения или используем default
|
||||||
|
preset_name: "{{ lookup('env', 'MOLECULE_PRESET') | default('default') }}"
|
||||||
|
preset_file: "/workspace/molecule/presets/{{ preset_name }}.yml"
|
||||||
|
|
||||||
|
# Fallback значения если preset файл не найден
|
||||||
|
docker_network: labnet
|
||||||
|
hosts:
|
||||||
|
- name: u1
|
||||||
|
family: debian
|
||||||
|
groups: [test]
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Load preset configuration
|
||||||
|
include_vars: "{{ preset_file }}"
|
||||||
|
when: preset_file is file
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
# Проверка systemd узлов
|
||||||
|
- name: Check systemd nodes status
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ item.name }}"
|
||||||
|
command: systemctl is-system-running
|
||||||
|
loop: "{{ hosts | selectattr('type','undefined') | list }}"
|
||||||
|
loop_control: { label: "{{ item.name }}" }
|
||||||
|
register: systemd_status
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Display systemd nodes status
|
||||||
|
debug:
|
||||||
|
msg: "Systemd node {{ item.0.name }}: {{ item.1.stdout | default('unknown') }}"
|
||||||
|
loop: "{{ systemd_status.results | default([]) }}"
|
||||||
|
when: systemd_status is defined
|
||||||
|
|
||||||
|
# Проверка DinD узлов
|
||||||
|
- name: Check DinD nodes docker daemon
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ item.name }}"
|
||||||
|
command: docker version --format '{{.Server.Version}}'
|
||||||
|
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list }}"
|
||||||
|
loop_control: { label: "{{ item.name }}" }
|
||||||
|
register: dind_status
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Display DinD nodes status
|
||||||
|
debug:
|
||||||
|
msg: "DinD node {{ item.0.name }}: Docker {{ item.1.stdout | default('not running') }}"
|
||||||
|
loop: "{{ dind_status.results | default([]) }}"
|
||||||
|
when: dind_status is defined
|
||||||
|
|
||||||
|
# Проверка DOoD узлов
|
||||||
|
- name: Check DOoD nodes docker access
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ item.name }}"
|
||||||
|
command: docker ps --format '{{.Names}}'
|
||||||
|
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list }}"
|
||||||
|
loop_control: { label: "{{ item.name }}" }
|
||||||
|
register: dood_status
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Display DOoD nodes status
|
||||||
|
debug:
|
||||||
|
msg: "DOoD node {{ item.0.name }}: Can access {{ item.1.stdout_lines | length | default(0) }} containers"
|
||||||
|
loop: "{{ dood_status.results | default([]) }}"
|
||||||
|
when: dood_status is defined
|
||||||
|
|
||||||
|
# Проверка сетевого подключения
|
||||||
|
- name: Test network connectivity between nodes
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ item.0.name }}"
|
||||||
|
command: ping -c 1 {{ item.1.name }}
|
||||||
|
loop: "{{ hosts | subelements(hosts, 'name') }}"
|
||||||
|
loop_control: { label: "{{ item.0.name }} -> {{ item.1.name }}" }
|
||||||
|
when: item.0.name != item.1.name
|
||||||
|
register: ping_results
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Display network connectivity results
|
||||||
|
debug:
|
||||||
|
msg: "Network test {{ item.0.name }} -> {{ item.1.name }}: {{ 'OK' if item.2.rc == 0 else 'FAILED' }}"
|
||||||
|
loop: "{{ ping_results.results | default([]) }}"
|
||||||
|
when: ping_results is defined
|
||||||
|
|
||||||
|
# Проверка портов
|
||||||
|
- name: Check published ports
|
||||||
|
community.docker.docker_container_exec:
|
||||||
|
container: "{{ item.name }}"
|
||||||
|
command: netstat -tlnp
|
||||||
|
loop: "{{ hosts | selectattr('publish','defined') | list }}"
|
||||||
|
loop_control: { label: "{{ item.name }}" }
|
||||||
|
register: port_status
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Display port status
|
||||||
|
debug:
|
||||||
|
msg: "Node {{ item.0.name }} ports: {{ item.1.stdout_lines | select('match', 'LISTEN') | list | length }} listening"
|
||||||
|
loop: "{{ port_status.results | default([]) }}"
|
||||||
|
when: port_status is defined
|
||||||
|
|
||||||
|
# Проверка групп
|
||||||
|
- name: Display inventory groups
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
📋 Inventory Groups:
|
||||||
|
{% for group, members in (groups_map | default({}) | dictsort) %}
|
||||||
|
- {{ group }}: {{ members | join(', ') }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
# Финальная сводка
|
||||||
|
- name: Display verification summary
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
✅ Verification Summary:
|
||||||
|
- Total hosts: {{ hosts | length }}
|
||||||
|
- Systemd nodes: {{ hosts | selectattr('type','undefined') | list | length }}
|
||||||
|
- DinD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list | length }}
|
||||||
|
- DOoD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list | length }}
|
||||||
|
- Groups: {{ groups_map.keys() | list | join(', ') }}
|
||||||
|
- Network: {{ docker_network }}
|
||||||
29
molecule/presets/default.yml
Normal file
29
molecule/presets/default.yml
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
#description: Стандартный пресет по умолчанию для тестирования с 2 хостами (Debian + RHEL)
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
|
||||||
|
|
||||||
|
# systemd-ready образы
|
||||||
|
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:
|
||||||
|
# Стандартный набор - 2 хоста для базового тестирования
|
||||||
|
- name: u1
|
||||||
|
family: debian
|
||||||
|
groups: [test, web]
|
||||||
|
- name: u2
|
||||||
|
family: rhel
|
||||||
|
groups: [test, web]
|
||||||
44
molecule/presets/docker-test.yml
Normal file
44
molecule/presets/docker-test.yml
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
---
|
||||||
|
#description: Пресет с Docker контейнерами (DinD + DOoD) для тестирования Docker-задач
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
|
||||||
|
|
||||||
|
# systemd-ready образы
|
||||||
|
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: test1
|
||||||
|
family: debian
|
||||||
|
groups: [test]
|
||||||
|
- name: test2
|
||||||
|
family: rhel
|
||||||
|
groups: [test]
|
||||||
|
|
||||||
|
# DinD узел (Docker-in-Docker)
|
||||||
|
- name: docker1
|
||||||
|
type: dind
|
||||||
|
groups: [docker]
|
||||||
|
publish: ["8080:8080"]
|
||||||
|
|
||||||
|
# DOoD узел (Docker-out-of-Docker)
|
||||||
|
- name: dood1
|
||||||
|
type: dood
|
||||||
|
family: debian
|
||||||
|
groups: [dood]
|
||||||
|
publish: ["8081:8081"]
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: unix:///var/run/docker.sock
|
||||||
62
molecule/presets/etcd-patroni.yml
Normal file
62
molecule/presets/etcd-patroni.yml
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
---
|
||||||
|
#description: Пресет для тестирования кластера etcd + PostgreSQL + Patroni (9 хостов)
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
|
||||||
|
|
||||||
|
# systemd-ready образы
|
||||||
|
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"]
|
||||||
|
|
||||||
|
# Описание кластера etcd + Patroni + HAProxy
|
||||||
|
hosts:
|
||||||
|
# ETCD кластер (5 узлов для высокой доступности)
|
||||||
|
- name: etcd1
|
||||||
|
family: debian
|
||||||
|
groups: [etcd, cluster]
|
||||||
|
- name: etcd2
|
||||||
|
family: rhel
|
||||||
|
groups: [etcd, cluster]
|
||||||
|
- name: etcd3
|
||||||
|
family: debian
|
||||||
|
groups: [etcd, cluster]
|
||||||
|
- name: etcd4
|
||||||
|
family: rhel
|
||||||
|
groups: [etcd, cluster]
|
||||||
|
- name: etcd5
|
||||||
|
family: debian
|
||||||
|
groups: [etcd, cluster]
|
||||||
|
|
||||||
|
# Patroni кластер (3 узла PostgreSQL)
|
||||||
|
- name: patroni1
|
||||||
|
family: rhel
|
||||||
|
groups: [patroni, database, cluster]
|
||||||
|
- name: patroni2
|
||||||
|
family: debian
|
||||||
|
groups: [patroni, database, cluster]
|
||||||
|
- name: patroni3
|
||||||
|
family: rhel
|
||||||
|
groups: [patroni, database, cluster]
|
||||||
|
|
||||||
|
# HAProxy для балансировки
|
||||||
|
- name: haproxy
|
||||||
|
family: debian
|
||||||
|
groups: [haproxy, loadbalancer]
|
||||||
|
publish: ["5000:5000", "5001:5001"] # RW и RO порты
|
||||||
|
|
||||||
|
# DinD узел для тестирования Docker Compose внутри
|
||||||
|
- name: app-dind
|
||||||
|
type: dind
|
||||||
|
groups: [apps, docker]
|
||||||
|
publish: ["8080:8080"]
|
||||||
@@ -1,17 +1,25 @@
|
|||||||
---
|
---
|
||||||
# Минимальный пресет лаборатории
|
#description: Минимальный пресет для быстрого тестирования с 1 хостом (Debian)
|
||||||
# Автор: Сергей Антропов
|
# Автор: Сергей Антропов
|
||||||
# Сайт: https://devops.org.ru
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
hosts:
|
docker_network: labnet
|
||||||
- name: host1
|
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
|
||||||
family: debian
|
|
||||||
groups: [all]
|
|
||||||
|
|
||||||
features:
|
# systemd-ready образы
|
||||||
docker: true
|
images:
|
||||||
dind: false
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
k8s: false
|
|
||||||
istio: false
|
systemd_defaults:
|
||||||
monitoring: false
|
privileged: true
|
||||||
chaos: false
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs: ["/run", "/run/lock"]
|
||||||
|
capabilities: ["SYS_ADMIN"]
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
# Минимальный набор - один хост
|
||||||
|
- name: u1
|
||||||
|
family: debian
|
||||||
|
groups: [test]
|
||||||
|
|||||||
70
molecule/presets/multi-os.yml
Normal file
70
molecule/presets/multi-os.yml
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
---
|
||||||
|
#description: Пресет для тестирования на разных ОС с 12 хостами (Debian + RHEL)
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
|
||||||
|
|
||||||
|
# systemd-ready образы для разных ОС
|
||||||
|
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:
|
||||||
|
# Debian серверы
|
||||||
|
- name: debian1
|
||||||
|
family: debian
|
||||||
|
groups: [debian, servers, web]
|
||||||
|
- name: debian2
|
||||||
|
family: debian
|
||||||
|
groups: [debian, servers, web]
|
||||||
|
- name: debian3
|
||||||
|
family: debian
|
||||||
|
groups: [debian, servers, app]
|
||||||
|
- name: debian4
|
||||||
|
family: debian
|
||||||
|
groups: [debian, servers, app]
|
||||||
|
|
||||||
|
# RHEL серверы
|
||||||
|
- name: rhel1
|
||||||
|
family: rhel
|
||||||
|
groups: [rhel, servers, web]
|
||||||
|
- name: rhel2
|
||||||
|
family: rhel
|
||||||
|
groups: [rhel, servers, web]
|
||||||
|
- name: rhel3
|
||||||
|
family: rhel
|
||||||
|
groups: [rhel, servers, app]
|
||||||
|
- name: rhel4
|
||||||
|
family: rhel
|
||||||
|
groups: [rhel, servers, app]
|
||||||
|
|
||||||
|
# База данных на разных ОС
|
||||||
|
- name: db-debian
|
||||||
|
family: debian
|
||||||
|
groups: [database, debian, db]
|
||||||
|
- name: db-rhel
|
||||||
|
family: rhel
|
||||||
|
groups: [database, rhel, db]
|
||||||
|
|
||||||
|
# Load balancer
|
||||||
|
- name: lb-mixed
|
||||||
|
family: debian
|
||||||
|
groups: [loadbalancer, haproxy]
|
||||||
|
publish: ["80:80", "443:443"]
|
||||||
|
|
||||||
|
# DinD узел для тестирования Docker
|
||||||
|
- name: docker-mixed
|
||||||
|
type: dind
|
||||||
|
groups: [docker, apps]
|
||||||
|
publish: ["8080:8080"]
|
||||||
73
molecule/presets/performance.yml
Normal file
73
molecule/presets/performance.yml
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
---
|
||||||
|
#description: Пресет для нагрузочного тестирования с 12 хостами (серверы + БД + кэш)
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
|
||||||
|
|
||||||
|
# systemd-ready образы
|
||||||
|
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:
|
||||||
|
# Основные серверы (5 узлов)
|
||||||
|
- name: server1
|
||||||
|
family: debian
|
||||||
|
groups: [servers, web, app]
|
||||||
|
- name: server2
|
||||||
|
family: rhel
|
||||||
|
groups: [servers, web, app]
|
||||||
|
- name: server3
|
||||||
|
family: debian
|
||||||
|
groups: [servers, web, app]
|
||||||
|
- name: server4
|
||||||
|
family: rhel
|
||||||
|
groups: [servers, web, app]
|
||||||
|
- name: server5
|
||||||
|
family: debian
|
||||||
|
groups: [servers, web, app]
|
||||||
|
|
||||||
|
# База данных (3 узла)
|
||||||
|
- name: db1
|
||||||
|
family: rhel
|
||||||
|
groups: [database, db]
|
||||||
|
- name: db2
|
||||||
|
family: debian
|
||||||
|
groups: [database, db]
|
||||||
|
- name: db3
|
||||||
|
family: rhel
|
||||||
|
groups: [database, db]
|
||||||
|
|
||||||
|
# Кэш (3 узла Redis)
|
||||||
|
- name: cache1
|
||||||
|
family: debian
|
||||||
|
groups: [cache, redis]
|
||||||
|
- name: cache2
|
||||||
|
family: rhel
|
||||||
|
groups: [cache, redis]
|
||||||
|
- name: cache3
|
||||||
|
family: debian
|
||||||
|
groups: [cache, redis]
|
||||||
|
|
||||||
|
# Load balancer
|
||||||
|
- name: lb1
|
||||||
|
family: rhel
|
||||||
|
groups: [loadbalancer, haproxy]
|
||||||
|
publish: ["80:80", "443:443"]
|
||||||
|
|
||||||
|
# DinD узел для тестирования Docker Compose
|
||||||
|
- name: compose-dind
|
||||||
|
type: dind
|
||||||
|
groups: [apps, docker]
|
||||||
|
publish: ["8080:8080", "8081:8081"]
|
||||||
76
molecule/presets/security.yml
Normal file
76
molecule/presets/security.yml
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
---
|
||||||
|
#description: Пресет для тестирования безопасности с 10 хостами (bastion + internal + monitoring)
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
|
||||||
|
|
||||||
|
# systemd-ready образы
|
||||||
|
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:
|
||||||
|
# Bastion хосты (точки входа)
|
||||||
|
- name: bastion1
|
||||||
|
family: rhel
|
||||||
|
groups: [bastion, security, jump]
|
||||||
|
publish: ["2222:22"]
|
||||||
|
- name: bastion2
|
||||||
|
family: debian
|
||||||
|
groups: [bastion, security, jump]
|
||||||
|
publish: ["2223:22"]
|
||||||
|
|
||||||
|
# Внутренние серверы (без внешнего доступа)
|
||||||
|
- name: internal1
|
||||||
|
family: rhel
|
||||||
|
groups: [internal, servers, app]
|
||||||
|
- name: internal2
|
||||||
|
family: debian
|
||||||
|
groups: [internal, servers, app]
|
||||||
|
- name: internal3
|
||||||
|
family: rhel
|
||||||
|
groups: [internal, servers, app]
|
||||||
|
|
||||||
|
# База данных (изолированная сеть)
|
||||||
|
- name: db-secure1
|
||||||
|
family: rhel
|
||||||
|
groups: [database, secure, internal]
|
||||||
|
- name: db-secure2
|
||||||
|
family: debian
|
||||||
|
groups: [database, secure, internal]
|
||||||
|
|
||||||
|
# Мониторинг и логирование
|
||||||
|
- name: monitor1
|
||||||
|
family: debian
|
||||||
|
groups: [monitoring, security, logs]
|
||||||
|
- name: monitor2
|
||||||
|
family: rhel
|
||||||
|
groups: [monitoring, security, logs]
|
||||||
|
|
||||||
|
# Firewall и сетевые компоненты
|
||||||
|
- name: fw1
|
||||||
|
family: rhel
|
||||||
|
groups: [firewall, network, security]
|
||||||
|
- name: fw2
|
||||||
|
family: debian
|
||||||
|
groups: [firewall, network, security]
|
||||||
|
|
||||||
|
# DOoD узел для тестирования Docker безопасности
|
||||||
|
- name: docker-secure
|
||||||
|
type: dood
|
||||||
|
family: debian
|
||||||
|
groups: [docker, security, apps]
|
||||||
|
publish: ["8080:8080"]
|
||||||
|
env:
|
||||||
|
DOCKER_HOST: "unix:///var/run/docker.sock"
|
||||||
32
molecule/presets/standart.yml
Normal file
32
molecule/presets/standart.yml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
#description: Стандартный пресет для тестирования с 3 хостами (Debian + RHEL)
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
|
||||||
|
|
||||||
|
# systemd-ready образы
|
||||||
|
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:
|
||||||
|
# Стандартный набор - 3 хоста
|
||||||
|
- name: u1
|
||||||
|
family: debian
|
||||||
|
groups: [test]
|
||||||
|
- name: u2
|
||||||
|
family: rhel
|
||||||
|
groups: [test]
|
||||||
|
- name: u3
|
||||||
|
family: debian
|
||||||
|
groups: [test]
|
||||||
25
molecule/presets/test.yml
Normal file
25
molecule/presets/test.yml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
#description: Минимальный пресет для быстрого тестирования с 1 хостом (Debian)
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
docker_network: labnet
|
||||||
|
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
|
||||||
|
|
||||||
|
# systemd-ready образы
|
||||||
|
images:
|
||||||
|
debian: "ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy"
|
||||||
|
|
||||||
|
systemd_defaults:
|
||||||
|
privileged: true
|
||||||
|
command: "/sbin/init"
|
||||||
|
volumes:
|
||||||
|
- "/sys/fs/cgroup:/sys/fs/cgroup:ro"
|
||||||
|
tmpfs: ["/run", "/run/lock"]
|
||||||
|
capabilities: ["SYS_ADMIN"]
|
||||||
|
|
||||||
|
hosts:
|
||||||
|
# Минимальный набор - один хост
|
||||||
|
- name: u1
|
||||||
|
family: debian
|
||||||
|
groups: [test]
|
||||||
@@ -1,296 +0,0 @@
|
|||||||
---
|
|
||||||
# Создание инфраструктуры универсальной лаборатории
|
|
||||||
# Автор: Сергей Антропов
|
|
||||||
# Сайт: 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
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
---
|
|
||||||
# Уничтожение инфраструктуры универсальной лаборатории
|
|
||||||
# Автор: Сергей Антропов
|
|
||||||
# Сайт: 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
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
---
|
|
||||||
# Универсальная лаборатория для тестирования 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
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
---
|
|
||||||
# Конфигурация универсальной лаборатории
|
|
||||||
# Автор: Сергей Антропов
|
|
||||||
# Сайт: 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"
|
|
||||||
@@ -1,305 +0,0 @@
|
|||||||
---
|
|
||||||
# Проверка работы универсальной лаборатории
|
|
||||||
# Автор: Сергей Антропов
|
|
||||||
# Сайт: 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 '✗ Недоступен' }}
|
|
||||||
========================================
|
|
||||||
9
requirements.yml
Normal file
9
requirements.yml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
# Ansible Collections для Molecule Universal
|
||||||
|
collections:
|
||||||
|
- name: community.docker
|
||||||
|
version: ">=3.0.0"
|
||||||
|
- name: community.general
|
||||||
|
version: ">=7.0.0"
|
||||||
|
- name: ansible.posix
|
||||||
|
version: ">=1.5.4"
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
# Эта папка содержит Ansible роли
|
|
||||||
# Автор: Сергей Антропов
|
|
||||||
# Сайт: https://devops.org.ru
|
|
||||||
#
|
|
||||||
# Для создания новой роли используйте:
|
|
||||||
# make role create NAME=my-role
|
|
||||||
#
|
|
||||||
# Структура роли:
|
|
||||||
# roles/my-role/
|
|
||||||
# ├── tasks/
|
|
||||||
# │ ├── main.yml
|
|
||||||
# │ ├── debian.yml
|
|
||||||
# │ └── redhat.yml
|
|
||||||
# ├── handlers/main.yml
|
|
||||||
# ├── templates/
|
|
||||||
# ├── files/
|
|
||||||
# ├── vars/main.yml
|
|
||||||
# ├── defaults/main.yml
|
|
||||||
# ├── meta/main.yml
|
|
||||||
# ├── tests/
|
|
||||||
# └── playbooks/
|
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
# Ansible Roles
|
|
||||||
|
|
||||||
Эта папка содержит Ansible роли для универсальной лаборатории.
|
|
||||||
|
|
||||||
## Создание новой роли
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Интерактивное создание роли
|
|
||||||
make role create NAME=my-role
|
|
||||||
|
|
||||||
# Список ролей
|
|
||||||
make role list
|
|
||||||
|
|
||||||
# Управление playbooks роли
|
|
||||||
make role playbook NAME=my-role
|
|
||||||
```
|
|
||||||
|
|
||||||
## Структура роли
|
|
||||||
|
|
||||||
```
|
|
||||||
roles/my-role/
|
|
||||||
├── tasks/
|
|
||||||
│ ├── main.yml # Основные задачи (универсальные)
|
|
||||||
│ ├── debian.yml # Задачи для Debian/Ubuntu
|
|
||||||
│ └── redhat.yml # Задачи для RHEL/CentOS
|
|
||||||
├── handlers/
|
|
||||||
│ └── main.yml # Обработчики
|
|
||||||
├── templates/ # Шаблоны Jinja2
|
|
||||||
├── files/ # Статические файлы
|
|
||||||
├── vars/
|
|
||||||
│ └── main.yml # Переменные роли
|
|
||||||
├── defaults/
|
|
||||||
│ └── main.yml # Переменные по умолчанию
|
|
||||||
├── meta/
|
|
||||||
│ └── main.yml # Метаданные роли
|
|
||||||
├── tests/ # Тесты роли
|
|
||||||
└── playbooks/ # Playbooks роли
|
|
||||||
└── deploy.yml
|
|
||||||
└── install.yml
|
|
||||||
```
|
|
||||||
|
|
||||||
## Универсальные роли
|
|
||||||
|
|
||||||
Все роли создаются **универсальными** для RHEL и Debian семейств:
|
|
||||||
|
|
||||||
- **`tasks/main.yml`** - содержит общую логику и включает OS-специфичные задачи
|
|
||||||
- **`tasks/debian.yml`** - задачи для Debian/Ubuntu (apt, systemd)
|
|
||||||
- **`tasks/redhat.yml`** - задачи для RHEL/CentOS (yum, systemd)
|
|
||||||
|
|
||||||
## Поддерживаемые ОС
|
|
||||||
|
|
||||||
- **Debian семейство**: Ubuntu, Debian, Linux Mint
|
|
||||||
- **RHEL семейство**: CentOS, RHEL, Rocky Linux, AlmaLinux
|
|
||||||
|
|
||||||
## Команды управления
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Создать роль
|
|
||||||
make role create NAME=nginx
|
|
||||||
|
|
||||||
# Редактировать роль
|
|
||||||
make role edit NAME=nginx
|
|
||||||
|
|
||||||
# Тестировать роль
|
|
||||||
make role test NAME=nginx
|
|
||||||
|
|
||||||
# Проверить синтаксис
|
|
||||||
make role lint
|
|
||||||
|
|
||||||
# Развернуть роли
|
|
||||||
make role deploy
|
|
||||||
|
|
||||||
# Информация о роли
|
|
||||||
make role info NAME=nginx
|
|
||||||
|
|
||||||
# Управление playbooks
|
|
||||||
make role playbook NAME=nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
## Документация
|
|
||||||
|
|
||||||
- **[Полное руководство](../docs/roles.md)** - подробная документация по работе с ролями
|
|
||||||
- **[Примеры использования](../docs/examples.md)** - практические примеры
|
|
||||||
- **[API Reference](../docs/api.md)** - справочник по API
|
|
||||||
|
|
||||||
## Автор
|
|
||||||
|
|
||||||
Сергей Антропов
|
|
||||||
Сайт: https://devops.org.ru
|
|
||||||
60
roles/nginx/defaults/main.yml
Normal file
60
roles/nginx/defaults/main.yml
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
---
|
||||||
|
# Переменные по умолчанию для роли nginx
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
# Основные настройки nginx
|
||||||
|
nginx_user: "nginx"
|
||||||
|
nginx_worker_processes: "auto"
|
||||||
|
nginx_worker_connections: 1024
|
||||||
|
nginx_keepalive_timeout: 65
|
||||||
|
|
||||||
|
# Настройки сервера
|
||||||
|
nginx_server_name: "{{ ansible_fqdn | default(ansible_hostname) }}"
|
||||||
|
nginx_listen_port: 80
|
||||||
|
nginx_root_dir: "/var/www/html"
|
||||||
|
nginx_index_file: "index.html"
|
||||||
|
|
||||||
|
# Настройки логов
|
||||||
|
nginx_access_log: "/var/log/nginx/access.log"
|
||||||
|
nginx_error_log: "/var/log/nginx/error.log"
|
||||||
|
|
||||||
|
# Настройки безопасности
|
||||||
|
nginx_server_tokens: "off"
|
||||||
|
nginx_hide_version: true
|
||||||
|
|
||||||
|
# Настройки производительности
|
||||||
|
nginx_sendfile: "on"
|
||||||
|
nginx_tcp_nopush: "on"
|
||||||
|
nginx_tcp_nodelay: "on"
|
||||||
|
|
||||||
|
# Настройки gzip
|
||||||
|
nginx_gzip: true
|
||||||
|
nginx_gzip_vary: "on"
|
||||||
|
nginx_gzip_min_length: 1024
|
||||||
|
nginx_gzip_types:
|
||||||
|
- "text/plain"
|
||||||
|
- "text/css"
|
||||||
|
- "text/xml"
|
||||||
|
- "text/javascript"
|
||||||
|
- "application/javascript"
|
||||||
|
- "application/xml+rss"
|
||||||
|
- "application/json"
|
||||||
|
|
||||||
|
# Настройки для разных ОС
|
||||||
|
nginx_packages:
|
||||||
|
- nginx
|
||||||
|
|
||||||
|
# Дополнительные пакеты для Ubuntu/Debian
|
||||||
|
nginx_ubuntu_packages:
|
||||||
|
- nginx
|
||||||
|
- nginx-common
|
||||||
|
|
||||||
|
# Дополнительные пакеты для RHEL/CentOS
|
||||||
|
nginx_rhel_packages:
|
||||||
|
- nginx
|
||||||
|
- nginx-mod-http-geoip
|
||||||
|
- nginx-mod-http-image-filter
|
||||||
|
- nginx-mod-http-xslt-filter
|
||||||
|
- nginx-mod-mail
|
||||||
|
- nginx-mod-stream
|
||||||
44
roles/nginx/handlers/main.yml
Normal file
44
roles/nginx/handlers/main.yml
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
---
|
||||||
|
# Обработчики для роли nginx
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
- name: Restart nginx
|
||||||
|
systemd:
|
||||||
|
name: nginx
|
||||||
|
state: restarted
|
||||||
|
listen: restart nginx
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- service
|
||||||
|
- restart
|
||||||
|
|
||||||
|
- name: Reload nginx
|
||||||
|
systemd:
|
||||||
|
name: nginx
|
||||||
|
state: reloaded
|
||||||
|
listen: reload nginx
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- service
|
||||||
|
- reload
|
||||||
|
|
||||||
|
- name: Start nginx
|
||||||
|
systemd:
|
||||||
|
name: nginx
|
||||||
|
state: started
|
||||||
|
listen: start nginx
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- service
|
||||||
|
- start
|
||||||
|
|
||||||
|
- name: Stop nginx
|
||||||
|
systemd:
|
||||||
|
name: nginx
|
||||||
|
state: stopped
|
||||||
|
listen: stop nginx
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- service
|
||||||
|
- stop
|
||||||
26
roles/nginx/meta/main.yml
Normal file
26
roles/nginx/meta/main.yml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
# Метаданные роли nginx
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
galaxy_info:
|
||||||
|
author: Сергей Антропов
|
||||||
|
description: Простая роль для установки и настройки nginx
|
||||||
|
company: DevOps.org.ru
|
||||||
|
license: MIT
|
||||||
|
min_ansible_version: "2.9"
|
||||||
|
platforms:
|
||||||
|
- name: Ubuntu
|
||||||
|
versions:
|
||||||
|
- jammy
|
||||||
|
- focal
|
||||||
|
- name: EL
|
||||||
|
versions:
|
||||||
|
- all
|
||||||
|
galaxy_tags:
|
||||||
|
- web
|
||||||
|
- nginx
|
||||||
|
- http
|
||||||
|
- server
|
||||||
|
|
||||||
|
dependencies: []
|
||||||
196
roles/nginx/tasks/main.yml
Normal file
196
roles/nginx/tasks/main.yml
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
---
|
||||||
|
# Основные задачи для роли nginx
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
- name: Установка nginx на Ubuntu/Debian
|
||||||
|
apt:
|
||||||
|
name: "{{ nginx_ubuntu_packages }}"
|
||||||
|
state: present
|
||||||
|
update_cache: true
|
||||||
|
when: ansible_os_family == "Debian"
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- install
|
||||||
|
- debian
|
||||||
|
|
||||||
|
- name: Установка nginx на RHEL/CentOS
|
||||||
|
yum:
|
||||||
|
name: "{{ nginx_rhel_packages }}"
|
||||||
|
state: present
|
||||||
|
when: ansible_os_family == "RedHat"
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- install
|
||||||
|
- rhel
|
||||||
|
|
||||||
|
- name: Включение и запуск nginx на Ubuntu/Debian
|
||||||
|
systemd:
|
||||||
|
name: nginx
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
|
when: ansible_os_family == "Debian"
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- service
|
||||||
|
- debian
|
||||||
|
|
||||||
|
- name: Включение и запуск nginx на RHEL/CentOS
|
||||||
|
systemd:
|
||||||
|
name: nginx
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
|
when: ansible_os_family == "RedHat"
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- service
|
||||||
|
- rhel
|
||||||
|
|
||||||
|
- name: Создание директории для веб-контента
|
||||||
|
file:
|
||||||
|
path: "{{ nginx_root_dir }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ nginx_user }}"
|
||||||
|
group: "{{ nginx_user }}"
|
||||||
|
mode: '0755'
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- config
|
||||||
|
- directories
|
||||||
|
|
||||||
|
- name: Создание тестовой страницы
|
||||||
|
copy:
|
||||||
|
content: |
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Nginx Test Page</title>
|
||||||
|
<style>
|
||||||
|
body { font-family: Arial, sans-serif; margin: 40px; }
|
||||||
|
.container { max-width: 600px; margin: 0 auto; }
|
||||||
|
h1 { color: #333; }
|
||||||
|
.info { background: #f4f4f4; padding: 20px; border-radius: 5px; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Nginx работает!</h1>
|
||||||
|
<div class="info">
|
||||||
|
<p><strong>Сервер:</strong> {{ ansible_hostname }}</p>
|
||||||
|
<p><strong>ОС:</strong> {{ ansible_distribution }} \
|
||||||
|
{{ ansible_distribution_version }}</p>
|
||||||
|
<p><strong>Время:</strong> {{ ansible_date_time.iso8601 }}</p>
|
||||||
|
<p><strong>Роль:</strong> nginx (Сергей Антропов)</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
dest: "{{ nginx_root_dir }}/{{ nginx_index_file }}"
|
||||||
|
owner: "{{ nginx_user }}"
|
||||||
|
group: "{{ nginx_user }}"
|
||||||
|
mode: '0644'
|
||||||
|
notify: restart nginx
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- config
|
||||||
|
- content
|
||||||
|
|
||||||
|
- name: Создание резервной копии конфигурации nginx
|
||||||
|
copy:
|
||||||
|
src: "{{ item }}"
|
||||||
|
dest: "{{ item }}.backup"
|
||||||
|
remote_src: true
|
||||||
|
mode: '0644'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
loop:
|
||||||
|
- /etc/nginx/nginx.conf
|
||||||
|
- /etc/nginx/sites-available/default
|
||||||
|
ignore_errors: true
|
||||||
|
when: ansible_os_family == "Debian"
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- config
|
||||||
|
- backup
|
||||||
|
|
||||||
|
- name: Создание резервной копии конфигурации nginx (RHEL)
|
||||||
|
copy:
|
||||||
|
src: "{{ item }}"
|
||||||
|
dest: "{{ item }}.backup"
|
||||||
|
remote_src: true
|
||||||
|
mode: '0644'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
loop:
|
||||||
|
- /etc/nginx/nginx.conf
|
||||||
|
- /etc/nginx/conf.d/default.conf
|
||||||
|
ignore_errors: true
|
||||||
|
when: ansible_os_family == "RedHat"
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- config
|
||||||
|
- backup
|
||||||
|
|
||||||
|
- name: Настройка основной конфигурации nginx
|
||||||
|
template:
|
||||||
|
src: nginx.conf.j2
|
||||||
|
dest: /etc/nginx/nginx.conf
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
backup: true
|
||||||
|
notify: restart nginx
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- config
|
||||||
|
- main
|
||||||
|
|
||||||
|
- name: Настройка виртуального хоста (Ubuntu/Debian)
|
||||||
|
template:
|
||||||
|
src: default.conf.j2
|
||||||
|
dest: /etc/nginx/sites-available/default
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
backup: true
|
||||||
|
when: ansible_os_family == "Debian"
|
||||||
|
notify: restart nginx
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- config
|
||||||
|
- vhost
|
||||||
|
- debian
|
||||||
|
|
||||||
|
- name: Настройка виртуального хоста (RHEL/CentOS)
|
||||||
|
template:
|
||||||
|
src: default.conf.j2
|
||||||
|
dest: /etc/nginx/conf.d/default.conf
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
backup: true
|
||||||
|
when: ansible_os_family == "RedHat"
|
||||||
|
notify: restart nginx
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- config
|
||||||
|
- vhost
|
||||||
|
- rhel
|
||||||
|
|
||||||
|
- name: Проверка конфигурации nginx
|
||||||
|
command: nginx -t
|
||||||
|
register: nginx_config_test
|
||||||
|
changed_when: false
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- config
|
||||||
|
- test
|
||||||
|
|
||||||
|
- name: Показать результат проверки конфигурации
|
||||||
|
debug:
|
||||||
|
msg: "{{ nginx_config_test.stdout_lines }}"
|
||||||
|
when: nginx_config_test.stdout_lines is defined
|
||||||
|
tags:
|
||||||
|
- nginx
|
||||||
|
- config
|
||||||
|
- test
|
||||||
67
roles/nginx/templates/default.conf.j2
Normal file
67
roles/nginx/templates/default.conf.j2
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
# Конфигурация виртуального хоста nginx
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
# Сгенерировано: {{ ansible_date_time.iso8601 }}
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen {{ nginx_listen_port }};
|
||||||
|
server_name {{ nginx_server_name }};
|
||||||
|
|
||||||
|
# Настройки безопасности
|
||||||
|
{% if nginx_hide_version %}
|
||||||
|
server_tokens off;
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Корневая директория
|
||||||
|
root {{ nginx_root_dir }};
|
||||||
|
index {{ nginx_index_file }};
|
||||||
|
|
||||||
|
# Настройки логов для этого виртуального хоста
|
||||||
|
access_log {{ nginx_access_log }};
|
||||||
|
error_log {{ nginx_error_log }};
|
||||||
|
|
||||||
|
# Основная локация
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ =404;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Настройки для статических файлов
|
||||||
|
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
|
||||||
|
expires 1y;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
|
||||||
|
# Настройки безопасности
|
||||||
|
location ~ /\. {
|
||||||
|
deny all;
|
||||||
|
access_log off;
|
||||||
|
log_not_found off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Настройки для favicon
|
||||||
|
location = /favicon.ico {
|
||||||
|
log_not_found off;
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Настройки для robots.txt
|
||||||
|
location = /robots.txt {
|
||||||
|
log_not_found off;
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Настройки для health check
|
||||||
|
location /health {
|
||||||
|
access_log off;
|
||||||
|
return 200 "healthy\n";
|
||||||
|
add_header Content-Type text/plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Настройки для статуса nginx
|
||||||
|
location /nginx_status {
|
||||||
|
stub_status on;
|
||||||
|
access_log off;
|
||||||
|
allow 127.0.0.1;
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
||||||
58
roles/nginx/templates/nginx.conf.j2
Normal file
58
roles/nginx/templates/nginx.conf.j2
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
# Основная конфигурация nginx
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
# Сгенерировано: {{ ansible_date_time.iso8601 }}
|
||||||
|
|
||||||
|
user {{ nginx_user }};
|
||||||
|
worker_processes {{ nginx_worker_processes }};
|
||||||
|
|
||||||
|
error_log {{ nginx_error_log }};
|
||||||
|
pid /run/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections {{ nginx_worker_connections }};
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
# Основные настройки
|
||||||
|
sendfile {{ nginx_sendfile }};
|
||||||
|
tcp_nopush {{ nginx_tcp_nopush }};
|
||||||
|
tcp_nodelay {{ nginx_tcp_nodelay }};
|
||||||
|
keepalive_timeout {{ nginx_keepalive_timeout }};
|
||||||
|
types_hash_max_size 2048;
|
||||||
|
server_tokens {{ nginx_server_tokens }};
|
||||||
|
|
||||||
|
# Настройки MIME типов
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
# Настройки логирования
|
||||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||||
|
'$status $body_bytes_sent "$http_referer" '
|
||||||
|
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||||
|
|
||||||
|
access_log {{ nginx_access_log }} main;
|
||||||
|
|
||||||
|
# Настройки gzip
|
||||||
|
{% if nginx_gzip %}
|
||||||
|
gzip {{ nginx_gzip_vary }};
|
||||||
|
gzip_min_length {{ nginx_gzip_min_length }};
|
||||||
|
gzip_types
|
||||||
|
{% for gzip_type in nginx_gzip_types %}
|
||||||
|
{{ gzip_type }}{% if not loop.last %} {% endif %}
|
||||||
|
{% endfor %};
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Настройки безопасности
|
||||||
|
{% if nginx_hide_version %}
|
||||||
|
server_tokens off;
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Включение конфигураций виртуальных хостов
|
||||||
|
{% if ansible_os_family == "Debian" %}
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
include /etc/nginx/sites-enabled/*;
|
||||||
|
{% elif ansible_os_family == "RedHat" %}
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#!/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."
|
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
#!/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()
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#!/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/"
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
#!/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 "✅ Все проверки безопасности пройдены!"
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#!/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/"
|
|
||||||
52
scripts/test-playbook.yml
Normal file
52
scripts/test-playbook.yml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
# Простой тестовый playbook для проверки 3 контейнеров
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
- name: Test containers connectivity
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
tasks:
|
||||||
|
- name: Check container u1 (Debian)
|
||||||
|
command: docker exec u1 echo "Hello from u1"
|
||||||
|
register: u1_result
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Check container u2 (RHEL)
|
||||||
|
command: docker exec u2 echo "Hello from u2"
|
||||||
|
register: u2_result
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Check container u3 (Debian)
|
||||||
|
command: docker exec u3 echo "Hello from u3"
|
||||||
|
register: u3_result
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Display results
|
||||||
|
debug:
|
||||||
|
msg:
|
||||||
|
- "u1 (Debian): {{ u1_result.stdout }}"
|
||||||
|
- "u2 (RHEL): {{ u2_result.stdout }}"
|
||||||
|
- "u3 (Debian): {{ u3_result.stdout }}"
|
||||||
|
|
||||||
|
- name: Install nginx on u1
|
||||||
|
command: docker exec u1 bash -c "apt-get update && apt-get install -y nginx"
|
||||||
|
register: nginx_u1
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Install nginx on u2
|
||||||
|
command: docker exec u2 bash -c "yum install -y nginx"
|
||||||
|
register: nginx_u2
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Install nginx on u3
|
||||||
|
command: docker exec u3 bash -c "apt-get update && apt-get install -y nginx"
|
||||||
|
register: nginx_u3
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Display nginx installation results
|
||||||
|
debug:
|
||||||
|
msg:
|
||||||
|
- "Nginx installation on u1: {{ 'SUCCESS' if nginx_u1.rc == 0 else 'FAILED' }}"
|
||||||
|
- "Nginx installation on u2: {{ 'SUCCESS' if nginx_u2.rc == 0 else 'FAILED' }}"
|
||||||
|
- "Nginx installation on u3: {{ 'SUCCESS' if nginx_u3.rc == 0 else 'FAILED' }}"
|
||||||
83
scripts/test-standart.sh
Executable file
83
scripts/test-standart.sh
Executable file
@@ -0,0 +1,83 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Скрипт для тестирования с preset standart
|
||||||
|
# Автор: Сергей Антропов
|
||||||
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "🚀 Запуск тестирования с preset standart..."
|
||||||
|
|
||||||
|
# Очищаем старые контейнеры
|
||||||
|
echo "🧹 Очистка старых контейнеров..."
|
||||||
|
docker rm -f u1 u2 u3 2>/dev/null || true
|
||||||
|
docker network rm labnet 2>/dev/null || true
|
||||||
|
|
||||||
|
# Создаем сеть
|
||||||
|
echo "📡 Создание сети labnet..."
|
||||||
|
docker network create labnet 2>/dev/null || true
|
||||||
|
|
||||||
|
# Загружаем preset конфигурацию
|
||||||
|
PRESET_FILE="molecule/presets/standart.yml"
|
||||||
|
if [ ! -f "$PRESET_FILE" ]; then
|
||||||
|
echo "❌ Ошибка: Пресет файл $PRESET_FILE не найден!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Извлекаем конфигурацию из preset файла
|
||||||
|
echo "📋 Загрузка конфигурации из $PRESET_FILE..."
|
||||||
|
|
||||||
|
# Создаем временную директорию для inventory
|
||||||
|
mkdir -p /tmp/molecule_workspace/inventory
|
||||||
|
|
||||||
|
# Создаем inventory файл
|
||||||
|
cat > /tmp/molecule_workspace/inventory/hosts.ini << EOF
|
||||||
|
[all]
|
||||||
|
localhost ansible_connection=local
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "📄 Создан inventory файл:"
|
||||||
|
cat /tmp/molecule_workspace/inventory/hosts.ini
|
||||||
|
|
||||||
|
# Запускаем контейнеры
|
||||||
|
echo "🐳 Создание контейнеров..."
|
||||||
|
|
||||||
|
# u1 - Debian
|
||||||
|
echo "Создание u1 (Debian)..."
|
||||||
|
docker run -d --name u1 \
|
||||||
|
--network labnet \
|
||||||
|
-p 2201:22 \
|
||||||
|
ubuntu:20.04 \
|
||||||
|
bash -c "apt-get update && apt-get install -y openssh-server && service ssh start && sleep infinity"
|
||||||
|
|
||||||
|
# u2 - Debian (временно используем Ubuntu вместо CentOS)
|
||||||
|
echo "Создание u2 (Debian)..."
|
||||||
|
docker run -d --name u2 \
|
||||||
|
--network labnet \
|
||||||
|
-p 2202:22 \
|
||||||
|
ubuntu:20.04 \
|
||||||
|
bash -c "apt-get update && apt-get install -y openssh-server && service ssh start && sleep infinity"
|
||||||
|
|
||||||
|
# u3 - Debian
|
||||||
|
echo "Создание u3 (Debian)..."
|
||||||
|
docker run -d --name u3 \
|
||||||
|
--network labnet \
|
||||||
|
-p 2203:22 \
|
||||||
|
ubuntu:20.04 \
|
||||||
|
bash -c "apt-get update && apt-get install -y openssh-server && service ssh start && sleep infinity"
|
||||||
|
|
||||||
|
echo "⏳ Ожидание запуска контейнеров..."
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# Проверяем статус контейнеров
|
||||||
|
echo "📊 Статус контейнеров:"
|
||||||
|
docker ps --filter "name=u[123]" --format "table {{.Names}}\t{{.Status}}\t{{.Image}}"
|
||||||
|
|
||||||
|
# Запускаем тесты
|
||||||
|
echo "🧪 Запуск тестов..."
|
||||||
|
ansible-playbook -i /tmp/molecule_workspace/inventory/hosts.ini scripts/test-playbook.yml
|
||||||
|
|
||||||
|
echo "🧹 Очистка контейнеров..."
|
||||||
|
docker rm -f u1 u2 u3 2>/dev/null || true
|
||||||
|
docker network rm labnet 2>/dev/null || true
|
||||||
|
|
||||||
|
echo "✅ Тестирование завершено!"
|
||||||
@@ -1,45 +1,33 @@
|
|||||||
$ANSIBLE_VAULT;1.1;AES256
|
---
|
||||||
36616532373361616262643163656363656533663465653636646264376666313838386336643263
|
# Основные секреты для тестирования
|
||||||
6433626166306136653962646263643632353138396332380a393161333663333331303266373034
|
# Автор: Сергей Антропов
|
||||||
36366665626365323036353931353965343239613164393931636234396134343963333065373134
|
# Сайт: https://devops.org.ru
|
||||||
3661666162386339640a373639383233376263613164326234323064613030636336366239393339
|
|
||||||
37343565613837626236386339303565386531626238646139303266656264623031633663373236
|
# Пароли для баз данных
|
||||||
66663362393663633363646664303737343134396465323663376332363864313834643533663539
|
database_passwords:
|
||||||
65643636613437326535396335373333303938353837663632363238393061633431666334313733
|
root_password: "database-root-password"
|
||||||
37373730383732623632616261626335656534316230356638643266663965323139373239623238
|
app_user_password: "database-app-password"
|
||||||
38303831633436313439386639323535363036313539396361353462616338383633636432373338
|
monitoring_user_password: "monitoring-user-password"
|
||||||
64363035343337336233313534306166326438303031653034663639353663396435393531666238
|
|
||||||
66326331663933353463373338393765653434313565306162613135333864633131633035623966
|
# SSL сертификаты
|
||||||
62643239643138323532346165393961363637363864623738323633633862313966346238333464
|
ssl_certificates:
|
||||||
66363761306637666230373533356432333238633432383966316134353630643432643133303537
|
server_cert: |
|
||||||
31663863303163363433346166363232623737383230613637313435393737353361396565636233
|
-----BEGIN CERTIFICATE-----
|
||||||
62313835336438663438656536643339353738326539626530383834633061633939633436373262
|
# Server certificate content
|
||||||
35656234616538363936353162313436653764303337623032316561373866376266663165653765
|
-----END CERTIFICATE-----
|
||||||
31646533666536376366616638336232313830323330316564343864396130623633333530376665
|
server_key: |
|
||||||
36313365316664656331613863663162323161643732323963303561373765393165623834373766
|
-----BEGIN PRIVATE KEY-----
|
||||||
61383065376534396630333930633666633034303232366637316237373863643065306439643230
|
# Server private key content
|
||||||
37626533373666626263313538613864326539646631306166306637373134366331396138393931
|
-----END PRIVATE KEY-----
|
||||||
63326139306538313461383434343362313232353265373337326336666639393665396166626262
|
|
||||||
66353832396665333362643837666438613035323164326361396130643766396434366231616632
|
# API ключи
|
||||||
31383834616530376634643632376634366637336665393963326239643237363564636134336333
|
api_keys:
|
||||||
35643536653532343466643932336163643138636662316530663464353639363436663634326432
|
github_token: "ghp_example_token"
|
||||||
34376332323936336134396338623835633562343830666431616163643239653132343236303537
|
dockerhub_token: "dckr_example_token"
|
||||||
65663736333562396430643038313961323365616533323166633663326663633464323934353739
|
monitoring_api_key: "monitoring_api_key_example"
|
||||||
38656138323533346239356432663563336432396463626331623230303864326434616161326233
|
|
||||||
33303363376164333839333435386339386139633739333435346530633663313261633631383835
|
# Строки подключения
|
||||||
63623436356462316362663965366631383663646333356536643632363566636163343264343063
|
database_connections:
|
||||||
61316664656635363564303135343466393533383164643432656334313338663033306261396136
|
primary: "mysql://user:password@db1:3306/app"
|
||||||
62333962393039383831626537346566663566356266633364666362623462313166333661656362
|
replica: "mysql://user:password@db2:3306/app"
|
||||||
34323062393334343063343038646432336239383334303332313166383461663336656465393137
|
cache: "redis://cache1:6379/0"
|
||||||
33333364633033633765373432393038396231616139343665306335663231646264663537343637
|
|
||||||
37393537613338343736613062343963313963656164383734303439376265323135333239363361
|
|
||||||
30616539363364353333653039613036623966653266333130306634623236636337666437363534
|
|
||||||
61336130626261376334303636343231333666386132666365623365613735633433343133663031
|
|
||||||
36366338386630343766363464343536613761653464633138353238313462613265383135383766
|
|
||||||
35356265316535366231333664346337383266383064363731363437613732306231323339636631
|
|
||||||
64306535663264316561356531323864303866623331343635663836306333396634306333383764
|
|
||||||
62343439323433613963343033303535653762663633633130356235393437626164343432626332
|
|
||||||
33636136636562643166643461343135643265626434656136336236366131326462303036613139
|
|
||||||
61306263386532343365313539306339636238613062373162333036306166363933616664373962
|
|
||||||
32383036613961323633366431356434633839333864623565396265366365326162396434653233
|
|
||||||
35346237363764653866
|
|
||||||
|
|||||||
Reference in New Issue
Block a user