Compare commits
33 Commits
591cdaf831
...
37ff18c91b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37ff18c91b | ||
|
|
4e86b7f0c3 | ||
|
|
85b68dc4d0 | ||
|
|
a56de6183a | ||
|
|
d8e1052e7b | ||
|
|
c2ab17b7b6 | ||
|
|
c2a84a3aee | ||
|
|
0ffe1f1a90 | ||
|
|
df7473fbd9 | ||
|
|
eca556cca7 | ||
|
|
fcf3f33e80 | ||
|
|
6ef4090fb2 | ||
|
|
9677aea281 | ||
|
|
fd80db220a | ||
|
|
4ca882b5f7 | ||
|
|
3b8c6e52ea | ||
|
|
02eab55d73 | ||
|
|
e3d393ef91 | ||
|
|
6d55f924e5 | ||
|
|
69a589974e | ||
|
|
3238b3903a | ||
|
|
ab1231fce5 | ||
|
|
44fff158ce | ||
|
|
604c7816be | ||
|
|
06bfc00b5a | ||
|
|
ebed1f76ab | ||
|
|
69b547dda6 | ||
|
|
d48c273e50 | ||
|
|
87002cb9b3 | ||
|
|
e2b9d94075 | ||
|
|
791504abf6 | ||
|
|
33e329c091 | ||
|
|
5c8862e9bf |
114
Makefile
114
Makefile
@@ -1,5 +1,5 @@
|
||||
# =============================================================================
|
||||
# AnsibleLab - Универсальная система тестирования Ansible ролей
|
||||
# DevOpsLab - Универсальная система тестирования Ansible ролей
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
# =============================================================================
|
||||
@@ -20,7 +20,7 @@ WHITE := \033[0;37m
|
||||
RESET := \033[0m
|
||||
|
||||
# Глобальные переменные
|
||||
PROJECT_NAME ?= ansible-lab
|
||||
PROJECT_NAME ?= devops-lab
|
||||
VERSION ?= 0.1.0
|
||||
AUTHOR ?= "Сергей Антропов"
|
||||
SITE ?= "https://devops.org.ru"
|
||||
@@ -907,11 +907,13 @@ docker-get-base-tag:
|
||||
TAG="latest";; \
|
||||
k8s) \
|
||||
TAG="latest";; \
|
||||
k8s-portforward) \
|
||||
TAG="latest";; \
|
||||
*) \
|
||||
echo "❌ Неизвестный образ: $(IMAGE)"; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
echo "$$TAG"
|
||||
esac; \
|
||||
echo "$$TAG"
|
||||
|
||||
# Сборка одного образа с multi-arch
|
||||
docker-build-image:
|
||||
@@ -1049,6 +1051,7 @@ k8s:
|
||||
echo "🚀 Запуск создания кластера..."; \
|
||||
docker exec $$CONTAINER_NAME bash -c "cd /workspace && python3 /workspace/scripts/create_k8s_cluster.py molecule/presets/k8s/$$PRESET.yml $$CONTAINER_NAME"; \
|
||||
echo "✅ Kind кластер создан"; \
|
||||
echo "💡 Для создания port-forward: make k8s portforward create"; \
|
||||
echo "💡 Для подключения используйте: make k8s kubeconfig"; \
|
||||
echo "💡 Для остановки используйте: make k8s stop";; \
|
||||
destroy) \
|
||||
@@ -1056,6 +1059,8 @@ k8s:
|
||||
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
|
||||
PRESET=$${PRESET_ARG:-k8s-minimal}; \
|
||||
CONTAINER_NAME=k8s-controller; \
|
||||
echo "🔌 Очистка port-forward..."; \
|
||||
python3 scripts/portforward.py clear || echo "⚠️ Не удалось очистить port-forward"; \
|
||||
if docker ps | grep -q $$CONTAINER_NAME; then \
|
||||
echo "🗑️ Удаление Kind кластеров..."; \
|
||||
docker exec $$CONTAINER_NAME bash -c "kind delete clusters --all" 2>/dev/null || true; \
|
||||
@@ -1107,7 +1112,7 @@ k8s:
|
||||
docker exec $$CONTAINER_NAME bash -c "kind get clusters | xargs -I {} kind start cluster --name {}" 2>/dev/null || true; \
|
||||
echo "✅ Kind кластер запущен";; \
|
||||
status) \
|
||||
echo "📊 Статус Kind кластеров:"; \
|
||||
echo "📊 Детальный отчет о состоянии кластера..."; \
|
||||
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
|
||||
if [ -z "$$PRESET_ARG" ]; then \
|
||||
echo "❌ Ошибка: Укажите пресет"; \
|
||||
@@ -1116,8 +1121,7 @@ k8s:
|
||||
fi; \
|
||||
CONTAINER_NAME=k8s-controller; \
|
||||
if docker ps | grep -q $$CONTAINER_NAME; then \
|
||||
docker exec $$CONTAINER_NAME bash -c "kind get clusters" 2>/dev/null || echo " Нет кластеров"; \
|
||||
docker exec $$CONTAINER_NAME bash -c "kind get clusters | while read cluster; do echo \"Кластер: \$$cluster\"; kubectl --context kind-\$$cluster get nodes 2>/dev/null || true; done" 2>/dev/null || true; \
|
||||
python3 scripts/k8s_status.py; \
|
||||
else \
|
||||
echo "⚠️ Контейнер $$CONTAINER_NAME не запущен"; \
|
||||
echo "💡 Запустите: make k8s create $$PRESET_ARG"; \
|
||||
@@ -1151,30 +1155,6 @@ k8s:
|
||||
echo "❌ Не удалось получить kubeconfig"; \
|
||||
rm -f $$KUBECONFIG_FILE; \
|
||||
fi;; \
|
||||
addon) \
|
||||
echo "📦 Установка аддона..."; \
|
||||
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
|
||||
MANIFEST_ARG="$(word 4, $(MAKECMDGOALS))"; \
|
||||
if [ -z "$$PRESET_ARG" ]; then \
|
||||
echo "❌ Ошибка: Укажите пресет"; \
|
||||
echo "💡 Пример: make k8s addon kubernetes https://example.com/manifest.yaml"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
if [ -z "$$MANIFEST_ARG" ]; then \
|
||||
echo "❌ Ошибка: Укажите URL манифеста"; \
|
||||
echo "💡 Пример: make k8s addon kubernetes https://example.com/manifest.yaml"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
CONTAINER_NAME=k8s-controller; \
|
||||
if ! docker ps | grep -q $$CONTAINER_NAME; then \
|
||||
echo "❌ Контейнер $$CONTAINER_NAME не запущен"; \
|
||||
echo "💡 Запустите: make k8s create $$PRESET_ARG"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
CLUSTER_NAME=$$(docker exec $$CONTAINER_NAME kind get clusters | head -1); \
|
||||
echo "📥 Установка аддона из $$MANIFEST_ARG..."; \
|
||||
docker exec $$CONTAINER_NAME bash -c "CLUSTER_NAME=$$CLUSTER_NAME; kubectl --server=https://\$${CLUSTER_NAME}-control-plane:6443 --insecure-skip-tls-verify apply -f $$MANIFEST_ARG"; \
|
||||
echo "✅ Аддон установлен";; \
|
||||
nodes) \
|
||||
echo "🖥️ Просмотр узлов кластера..."; \
|
||||
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
|
||||
@@ -1230,12 +1210,9 @@ k8s:
|
||||
delete) \
|
||||
echo "🗑️ Удаление ресурсов из манифеста: $$MANIFEST_ARG"; \
|
||||
docker exec $$CONTAINER_NAME bash -c "CLUSTER_NAME=$$CLUSTER_NAME; kubectl --server=https://\$${CLUSTER_NAME}-control-plane:6443 --insecure-skip-tls-verify delete -f $$MANIFEST_ARG";; \
|
||||
update) \
|
||||
echo "🔄 Обновление манифеста: $$MANIFEST_ARG"; \
|
||||
docker exec $$CONTAINER_NAME bash -c "CLUSTER_NAME=$$CLUSTER_NAME; kubectl --server=https://\$${CLUSTER_NAME}-control-plane:6443 --insecure-skip-tls-verify apply -f $$MANIFEST_ARG --force";; \
|
||||
*) \
|
||||
echo "❌ Неизвестная команда: $$MANIFEST_CMD"; \
|
||||
echo "💡 Доступные команды: apply, delete, update"; \
|
||||
echo "💡 Доступные команды: apply, delete"; \
|
||||
exit 1;; \
|
||||
esac;; \
|
||||
helm) \
|
||||
@@ -1358,6 +1335,40 @@ k8s:
|
||||
echo "💡 Доступные команды: add, list, delete, update, packages"; \
|
||||
exit 1;; \
|
||||
esac;; \
|
||||
portforward) \
|
||||
PORTFWD_CMD="$(word 3, $(MAKECMDGOALS))"; \
|
||||
PORT_ARG="$(word 4, $(MAKECMDGOALS))"; \
|
||||
if [ -z "$$PORTFWD_CMD" ]; then \
|
||||
echo "❌ Ошибка: Укажите команду"; \
|
||||
echo "💡 Пример: make k8s portforward create"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
case "$$PORTFWD_CMD" in \
|
||||
create) \
|
||||
echo "🔌 Создание port-forward..."; \
|
||||
python3 scripts/portforward.py create;; \
|
||||
list) \
|
||||
echo "📋 Список активных port-forward..."; \
|
||||
python3 scripts/portforward.py list;; \
|
||||
clear) \
|
||||
echo "🗑️ Очистка всех port-forward..."; \
|
||||
python3 scripts/portforward.py clear;; \
|
||||
recreate) \
|
||||
echo "🔄 Пересоздание port-forward..."; \
|
||||
python3 scripts/portforward.py recreate;; \
|
||||
delete) \
|
||||
if [ -z "$$PORT_ARG" ]; then \
|
||||
echo "❌ Ошибка: Укажите порт"; \
|
||||
echo "💡 Пример: make k8s portforward delete 3000"; \
|
||||
exit 1; \
|
||||
fi; \
|
||||
echo "🗑️ Удаление port-forward на порту $$PORT_ARG..."; \
|
||||
python3 scripts/portforward.py delete $$PORT_ARG;; \
|
||||
*) \
|
||||
echo "❌ Неизвестная команда: $$PORTFWD_CMD"; \
|
||||
echo "💡 Доступные команды: create, list, clear, recreate, delete"; \
|
||||
exit 1;; \
|
||||
esac;; \
|
||||
*) \
|
||||
echo "☸️ Доступные команды:"; \
|
||||
echo ""; \
|
||||
@@ -1376,17 +1387,15 @@ k8s:
|
||||
echo " make k8s start [cluster] - запустить остановленный кластер"; \
|
||||
echo " 💡 Можно указать имя кластера или запустить все"; \
|
||||
echo ""; \
|
||||
echo " make k8s status [cluster] - показать статус кластеров"; \
|
||||
echo " 💡 Можно указать имя конкретного кластера"; \
|
||||
echo " make k8s status [preset] - детальный отчет о состоянии кластера"; \
|
||||
echo " 💡 Показывает: узлы, pods, сервисы, Ingress, события, Helm релизы и т.д."; \
|
||||
echo " 💡 Требует: пресет"; \
|
||||
echo " 💡 Пример: make k8s status kubernetes"; \
|
||||
echo ""; \
|
||||
echo " make k8s config [cluster] - получить kubeconfig для подключения"; \
|
||||
echo " 💡 Сохраняет: kubeconfig в корне проекта"; \
|
||||
echo " 💡 Можно указать имя конкретного кластера"; \
|
||||
echo ""; \
|
||||
echo " make k8s addon [preset] [url] - установить аддон из манифеста"; \
|
||||
echo " 💡 Требует: пресет и URL манифеста"; \
|
||||
echo " 💡 Пример: make k8s addon kubernetes https://example.com/manifest.yaml"; \
|
||||
echo ""; \
|
||||
echo " make k8s nodes [preset] - показать узлы кластера"; \
|
||||
echo " 💡 Требует: пресет"; \
|
||||
echo " 💡 Пример: make k8s nodes kubernetes"; \
|
||||
@@ -1396,7 +1405,7 @@ k8s:
|
||||
echo " 💡 Пример: make k8s shell kubernetes"; \
|
||||
echo ""; \
|
||||
echo " make k8s manifest [cmd] [preset] [url] - работа с манифестами"; \
|
||||
echo " 💡 Команды: apply, delete, update"; \
|
||||
echo " 💡 Команды: apply, delete"; \
|
||||
echo " 💡 Пример: make k8s manifest apply kubernetes https://example.com/deploy.yaml"; \
|
||||
echo ""; \
|
||||
echo " make k8s helm [cmd] [preset] [release] [chart] - работа с Helm"; \
|
||||
@@ -1406,6 +1415,10 @@ k8s:
|
||||
echo " make k8s helmrepo [cmd] [preset] [name] [url] - работа с Helm репозиториями"; \
|
||||
echo " 💡 Команды: add, list, delete, update, packages"; \
|
||||
echo " 💡 Пример: make k8s helmrepo add kubernetes stable https://charts.helm.sh/stable"; \
|
||||
echo ""; \
|
||||
echo " make k8s portforward [cmd] - управление port-forward"; \
|
||||
echo " 💡 Команды: create, list, clear, recreate, delete [port]"; \
|
||||
echo " 💡 Пример: make k8s portforward create"; \
|
||||
echo ""; \
|
||||
echo "💡 Примеры:"; \
|
||||
echo " make k8s create # создать минимальный кластер"; \
|
||||
@@ -1414,7 +1427,7 @@ k8s:
|
||||
echo " make k8s config kubernetes # получить kubeconfig для кластера"; \
|
||||
echo " export KUBECONFIG=kubeconfig # использовать конфиг"; \
|
||||
echo " kubectl get nodes # проверить узлы"; \
|
||||
echo " make k8s addon kubernetes https://example.com/manifest.yaml # установить аддон"; \
|
||||
echo " make k8s manifest apply kubernetes https://example.com/manifest.yaml # установить манифест"; \
|
||||
echo " make k8s stop kubernetes # остановить кластер"; \
|
||||
echo " make k8s start kubernetes # запустить кластер"; \
|
||||
echo " make k8s destroy kubernetes # удалить кластер с пресетом kubernetes";; \
|
||||
@@ -1425,7 +1438,7 @@ k8s:
|
||||
# =============================================================================
|
||||
help:
|
||||
@echo "=========================================="
|
||||
@echo "AnsibleLab - Универсальная система"
|
||||
@echo "DevOpsLab - Универсальная система"
|
||||
@echo "тестирования Ansible ролей"
|
||||
@echo "=========================================="
|
||||
@echo ""
|
||||
@@ -1461,7 +1474,7 @@ help:
|
||||
@echo " make presets info - подробная информация о preset'е"
|
||||
@echo " make presets test - запустить тест с preset'ом"
|
||||
@echo ""
|
||||
@echo "🖼️ СОБСТВЕННЫЕ ОБРАЗЫ (AnsibleLab):"
|
||||
@echo "🖼️ СОБСТВЕННЫЕ ОБРАЗЫ (DevOpsLab):"
|
||||
@echo " make custom-images test [minimal|full|performance] - тест с собственными образами"
|
||||
@echo " make custom-images check - проверить наличие собственных образов"
|
||||
@echo " make custom-images build - собрать все образы для тестирования"
|
||||
@@ -1518,10 +1531,13 @@ help:
|
||||
@echo " make k8s destroy [preset] - удалить Kind кластер"
|
||||
@echo " make k8s start [preset] - запустить Kind кластер"
|
||||
@echo " make k8s stop [preset] - остановить Kind кластер"
|
||||
@echo " make k8s status [preset] - показать статус кластера"
|
||||
@echo " make k8s status [preset] - детальный отчет о состоянии кластера"
|
||||
@echo " make k8s nodes [preset] - показать узлы кластера"
|
||||
@echo " make k8s config [preset] - получить kubeconfig для подключения"
|
||||
@echo " make k8s addon [preset] [url] - установить аддон из манифеста"
|
||||
@echo " make k8s manifest [cmd] [preset] [url] - работа с манифестами (apply, delete)"
|
||||
@echo " make k8s helm [cmd] [preset] [release] [chart] - работа с Helm"
|
||||
@echo " make k8s helmrepo [cmd] [preset] [name] [url] - управление Helm репозиториями"
|
||||
@echo " make k8s portforward [cmd] - управление port-forward (create, list, clear)"
|
||||
@echo " make k8s shell [preset] - открыть shell в контейнере k8s"
|
||||
@echo ""
|
||||
@echo "💡 ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:"
|
||||
@@ -1549,7 +1565,7 @@ help:
|
||||
custom-images:
|
||||
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||
test) \
|
||||
echo "🧪 Тестирование с собственными образами AnsibleLab..."; \
|
||||
echo "🧪 Тестирование с собственными образами DevOpsLab..."; \
|
||||
if [ -z "$(word 3, $(MAKECMDGOALS))" ]; then \
|
||||
echo "💡 Использование: make custom-images test [minimal|full|performance]"; \
|
||||
echo "💡 По умолчанию: minimal"; \
|
||||
@@ -1577,7 +1593,7 @@ custom-images:
|
||||
echo ""; \
|
||||
echo " 🔨 make custom-images build - собрать все образы для тестирования"; \
|
||||
echo " 💡 Выполняет: make docker build"; \
|
||||
echo " 💡 Собирает: все образы AnsibleLab"; \
|
||||
echo " 💡 Собирает: все образы DevOpsLab"; \
|
||||
echo ""; \
|
||||
echo "💡 Пресеты для тестирования:"; \
|
||||
echo " - custom-minimal.yml - минимальный тест (4 хоста)"; \
|
||||
|
||||
199
README.md
199
README.md
@@ -1,4 +1,4 @@
|
||||
# AnsibleLab - Универсальная система тестирования Ansible ролей
|
||||
# DevOpsLab - Универсальная система тестирования Ansible ролей
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
@@ -6,23 +6,41 @@
|
||||
|
||||
## 📋 Описание
|
||||
|
||||
AnsibleLab - это универсальная система для разработки, тестирования и развертывания Ansible ролей с использованием Docker, Molecule и preset конфигураций. Система поддерживает тестирование на различных ОС через Docker контейнеры.
|
||||
DevOpsLab - это универсальная DevOps платформа для разработки, тестирования и развертывания инфраструктуры. Система объединяет Ansible роли, Docker контейнеры и Kubernetes кластеры в единую среду для автоматизации и управления инфраструктурой.
|
||||
|
||||
**Ключевые компоненты:**
|
||||
- **Ansible** - автоматизация конфигурации и развертывания
|
||||
- **Docker** - контейнеризация для изоляции и переносимости
|
||||
- **Molecule** - тестирование Ansible ролей
|
||||
- **Kubernetes (Kind)** - локальные K8s кластеры для разработки
|
||||
- **Multi-arch поддержка** - сборка для amd64 и arm64 архитектур
|
||||
|
||||
## ✨ Ключевые возможности
|
||||
|
||||
### 🔧 Ansible
|
||||
- **Тестирование ролей** через Molecule с Docker
|
||||
- **Preset система** для быстрого выбора окружений тестирования
|
||||
- **Мультиплатформенное тестирование** (Ubuntu, Debian, CentOS, AlmaLinux, RHEL и другие)
|
||||
- **Автоматическая проверка** синтаксиса Ansible ролей
|
||||
- **Управление секретами** через Ansible Vault
|
||||
- **Готовые Docker образы** для разных ОС
|
||||
- **Kubernetes Kind кластеры** для тестирования в среде Kubernetes
|
||||
- **Автоматическая установка аддонов** (Istio, Prometheus, Grafana, Kiali и другие)
|
||||
|
||||
### 🐳 Docker
|
||||
- **Готовые Docker образы** для разных ОС с поддержкой systemd
|
||||
- **Multi-arch сборка** (amd64, arm64)
|
||||
- **Автоматическая публикация** в Docker Hub
|
||||
- **Контейнеры для тестирования** Ansible ролей
|
||||
|
||||
### ☸️ Kubernetes
|
||||
- **Kind кластеры** для локального тестирования
|
||||
- **Автоматическая установка аддонов** (Istio, Prometheus, Grafana, Kiali, Ingress, Metrics Server)
|
||||
- **Управление через Helm** и Kubernetes манифесты
|
||||
- **Port-forward** для доступа к сервисам
|
||||
- **Детальный мониторинг** состояния кластера
|
||||
|
||||
## 📁 Структура проекта
|
||||
|
||||
```
|
||||
AnsibleLab/
|
||||
DevOpsLab/
|
||||
├── molecule/ # Конфигурация Molecule
|
||||
│ ├── default/ # Основная конфигурация
|
||||
│ │ ├── create.yml # Создание контейнеров
|
||||
@@ -33,22 +51,65 @@ AnsibleLab/
|
||||
│ │ └── molecule.yml # Конфигурация Molecule
|
||||
│ └── presets/ # Preset конфигурации
|
||||
│ ├── default.yml # Стандартный preset
|
||||
│ ├── minimal.yml # Минимальный preset
|
||||
│ ├── mytest.yml # Кастомный preset
|
||||
│ ├── presets.yml # Основные preset'ы
|
||||
│ └── examples/ # Примеры preset'ов
|
||||
│ ├── all-images.yml # Все образы (16 хостов)
|
||||
│ ├── multi-os.yml # Multi-OS тестирование
|
||||
│ ├── performance.yml # Тест производительности
|
||||
│ ├── security.yml # Тест безопасности
|
||||
│ └── ...
|
||||
│ ├── examples/ # Примеры preset'ов
|
||||
│ │ ├── all-images.yml # Все образы (16 хостов)
|
||||
│ │ ├── centos-all.yml # CentOS 7/8/9
|
||||
│ │ ├── debian-all.yml # Debian 9/10/11/12
|
||||
│ │ ├── ubuntu-all.yml # Ubuntu 20/22/24
|
||||
│ │ ├── multi-os.yml # Multi-OS тестирование
|
||||
│ │ ├── performance.yml # Тест производительности
|
||||
│ │ ├── security.yml # Тест безопасности
|
||||
│ │ ├── minimal.yml # Минимальный preset
|
||||
│ │ └── ...
|
||||
│ └── k8s/ # Kubernetes preset'ы
|
||||
│ ├── kubernetes.yml # Полный K8s кластер с аддонами
|
||||
│ └── k8s-minimal.yml # Минимальный K8s кластер
|
||||
├── roles/ # Ansible роли
|
||||
│ ├── docker/ # Роль установки Docker
|
||||
│ │ ├── defaults/ # Переменные по умолчанию
|
||||
│ │ ├── handlers/ # Обработчики
|
||||
│ │ ├── meta/ # Метаданные
|
||||
│ │ ├── tasks/ # Задачи
|
||||
│ │ ├── templates/ # Шаблоны
|
||||
│ │ ├── tests/ # Тесты
|
||||
│ │ ├── vars/ # Переменные
|
||||
│ │ ├── README.md
|
||||
│ │ └── examples.yml
|
||||
│ ├── devops/ # Роль DevOps инструментов
|
||||
│ │ ├── defaults/
|
||||
│ │ ├── files/
|
||||
│ │ ├── handlers/
|
||||
│ │ ├── meta/
|
||||
│ │ ├── tasks/
|
||||
│ │ ├── templates/
|
||||
│ │ ├── tests/
|
||||
│ │ ├── vars/
|
||||
│ │ ├── README.md
|
||||
│ │ ├── QUICKSTART.md
|
||||
│ │ ├── examples.yml
|
||||
│ │ └── playbook.yml
|
||||
│ ├── ping/ # Роль для ping проверок
|
||||
│ │ ├── defaults/
|
||||
│ │ ├── handlers/
|
||||
│ │ ├── meta/
|
||||
│ │ ├── tasks/
|
||||
│ │ ├── templates/
|
||||
│ │ ├── README.md
|
||||
│ │ ├── QUICKSTART.md
|
||||
│ │ └── playbook.yml
|
||||
│ └── deploy.yml # Playbook для развертывания
|
||||
├── dockerfiles/ # Docker образы
|
||||
│ ├── ansible-controller/ # Ansible контроллер
|
||||
│ │ ├── Dockerfile
|
||||
│ │ ├── docker-compose.yml
|
||||
│ │ ├── requirements.txt
|
||||
│ │ └── requirements.yml
|
||||
│ ├── k8s/ # Kubernetes образ (Kind, kubectl, Helm, Istio)
|
||||
│ │ └── Dockerfile
|
||||
│ ├── k8s-portforward/ # Port-forward контейнер (устаревший)
|
||||
│ │ ├── Dockerfile
|
||||
│ │ └── portforward-container.py
|
||||
│ ├── ubuntu20/ # Ubuntu 20.04
|
||||
│ ├── ubuntu22/ # Ubuntu 22.04
|
||||
│ ├── ubuntu24/ # Ubuntu 24.04
|
||||
@@ -64,18 +125,51 @@ AnsibleLab/
|
||||
│ ├── rhel/ # RHEL 8
|
||||
│ ├── alt-linux/ # ALT Linux P9
|
||||
│ ├── astra-linux/ # Astra Linux 1.7
|
||||
│ └── redos/ # RED OS 9
|
||||
│ ├── redos/ # RED OS 9
|
||||
│ └── README.md
|
||||
├── cicd/ # CI/CD конфигурации
|
||||
│ ├── azure-devops/ # Azure DevOps
|
||||
│ │ └── azure-pipelines.yml
|
||||
│ ├── github/ # GitHub Actions
|
||||
│ │ └── workflows.yml
|
||||
│ ├── gitlab/ # GitLab CI
|
||||
│ │ ├── config.json
|
||||
│ │ ├── docker-compose.yaml
|
||||
│ │ └── runner/
|
||||
│ │ └── config.toml
|
||||
│ └── jenkins/ # Jenkins
|
||||
├── vault/ # Зашифрованные секреты
|
||||
├── inventory/ # Инвентори файлы
|
||||
│ └── Jenkinsfile
|
||||
├── scripts/ # Вспомогательные скрипты
|
||||
│ ├── create_k8s_cluster.py # Создание K8s кластера
|
||||
│ ├── delete_hosts.py # Удаление хостов
|
||||
│ ├── k8s_status.py # Статус K8s кластера
|
||||
│ ├── portforward.py # Управление port-forward
|
||||
│ ├── generate-role-docs.sh # Генерация документации
|
||||
│ ├── role-manager.sh # Управление ролями
|
||||
│ ├── setup-cicd.sh # Настройка CI/CD
|
||||
│ ├── test-custom-images.sh # Тестирование образов
|
||||
│ └── update-playbooks.sh # Обновление playbook'ов
|
||||
├── docs/ # Документация
|
||||
│ ├── kubernetes-kind.md # Руководство по Kubernetes
|
||||
│ ├── k8s-scripts.md # Описание K8s скриптов
|
||||
│ ├── kubernetes-commands.md # Команды Kubernetes
|
||||
│ ├── kubernetes-full-guide.md # Полное руководство K8s
|
||||
│ ├── k8s-ingress-fix.md # Исправление Ingress
|
||||
│ ├── getting-started.md # Быстрый старт
|
||||
│ ├── molecule-guide.md # Руководство по Molecule
|
||||
│ ├── creating-roles.md # Создание ролей
|
||||
│ ├── linting-guide.md # Руководство по линтингу
|
||||
│ ├── platform-support.md # Поддержка платформ
|
||||
│ ├── monitoring.md # Мониторинг
|
||||
│ └── ...
|
||||
├── manifests/ # Kubernetes манифесты
|
||||
│ └── test-grafana-ingress.yaml
|
||||
├── vault/ # Зашифрованные секреты
|
||||
│ └── secrets.yml
|
||||
├── inventory/ # Инвентори файлы
|
||||
│ └── hosts.ini
|
||||
├── Makefile # Основные команды
|
||||
└── requirements.yml # Ansible коллекции
|
||||
└── README.md # Этот файл
|
||||
```
|
||||
|
||||
## 🚀 Быстрый старт
|
||||
@@ -84,7 +178,7 @@ AnsibleLab/
|
||||
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd AnsibleLab
|
||||
cd DevOpsLab
|
||||
```
|
||||
|
||||
### 2. Тестирование ролей
|
||||
@@ -111,6 +205,27 @@ make role lint docker
|
||||
make role lint ping
|
||||
```
|
||||
|
||||
### 4. Работа с Kubernetes
|
||||
|
||||
```bash
|
||||
# Создание Kind кластера с аддонами
|
||||
make k8s create kubernetes
|
||||
|
||||
# Статус кластера (детальный отчет)
|
||||
make k8s status kubernetes
|
||||
|
||||
# Создание port-forward для доступа к сервисам
|
||||
make k8s portforward create
|
||||
|
||||
# Установка Helm чарта
|
||||
make k8s helm apply kubernetes nginx bitnami/nginx
|
||||
|
||||
# Удаление кластера
|
||||
make k8s destroy kubernetes
|
||||
```
|
||||
|
||||
**Подробная документация:** [docs/kubernetes-kind.md](docs/kubernetes-kind.md)
|
||||
|
||||
## 📚 Доступные роли
|
||||
|
||||
### Docker
|
||||
@@ -505,7 +620,51 @@ make custom-images # справка по собственным
|
||||
|
||||
### Kubernetes
|
||||
|
||||
- **[docs/kubernetes-kind.md](docs/kubernetes-kind.md)** - Документация по работе с Kind кластерами
|
||||
**Полная документация:** [docs/kubernetes-kind.md](docs/kubernetes-kind.md)
|
||||
|
||||
DevOpsLab предоставляет полную поддержку локальных Kubernetes кластеров на базе Kind:
|
||||
|
||||
#### Основные команды
|
||||
|
||||
```bash
|
||||
# Создание кластера с аддонами
|
||||
make k8s create kubernetes
|
||||
|
||||
# Детальный статус кластера
|
||||
make k8s status kubernetes
|
||||
|
||||
# Управление port-forward
|
||||
make k8s portforward create
|
||||
make k8s portforward list
|
||||
make k8s portforward clear
|
||||
|
||||
# Работа с Helm
|
||||
make k8s helm apply kubernetes nginx bitnami/nginx
|
||||
make k8s helm list kubernetes
|
||||
make k8s helm delete kubernetes nginx
|
||||
|
||||
# Работа с манифестами
|
||||
make k8s manifest apply kubernetes https://example.com/app.yaml
|
||||
|
||||
# Удаление кластера
|
||||
make k8s destroy kubernetes
|
||||
```
|
||||
|
||||
#### Доступные аддоны
|
||||
|
||||
- **Ingress NGINX** - маршрутизация трафика
|
||||
- **Metrics Server** - сбор метрик
|
||||
- **Istio** - Service Mesh
|
||||
- **Prometheus Stack** - мониторинг (Prometheus + Grafana)
|
||||
- **Kiali** - визуализация Service Mesh
|
||||
|
||||
#### Доступ к сервисам
|
||||
|
||||
- **Grafana**: http://localhost:3000 (admin/admin)
|
||||
- **Prometheus**: http://localhost:9090
|
||||
- **Kiali**: http://localhost:20001
|
||||
- **Ingress HTTP**: http://localhost:8081
|
||||
- **Ingress HTTPS**: https://localhost:8443
|
||||
|
||||
## 🐳 Docker образы
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# GitLab CI для AnsibleLab
|
||||
# GitLab CI для DevOpsLab
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Azure DevOps Pipeline для AnsibleLab
|
||||
# Azure DevOps Pipeline для DevOpsLab
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# GitHub Actions Workflow для AnsibleLab
|
||||
# GitHub Actions Workflow для DevOpsLab
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
name: AnsibleLab CI/CD Pipeline
|
||||
name: DevOpsLab CI/CD Pipeline
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# GitLab CI Pipeline для AnsibleLab
|
||||
# GitLab CI Pipeline для DevOpsLab
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
|
||||
2
cicd/jenkins/Jenkinsfile
vendored
2
cicd/jenkins/Jenkinsfile
vendored
@@ -1,4 +1,4 @@
|
||||
// Jenkins Pipeline для AnsibleLab
|
||||
// Jenkins Pipeline для DevOpsLab
|
||||
// Автор: Сергей Антропов
|
||||
// Сайт: https://devops.org.ru
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Docker образы для универсальной системы тестирования AnsibleLab
|
||||
# Docker образы для универсальной системы тестирования DevOpsLab
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
@@ -15,7 +15,13 @@ dockerfiles/
|
||||
├── ansible-controller/ # Ansible контроллер с предустановленными коллекциями
|
||||
│ ├── Dockerfile
|
||||
│ ├── docker-compose.yml
|
||||
│ └── requirements.txt
|
||||
│ ├── requirements.txt
|
||||
│ └── requirements.yml
|
||||
├── k8s/ # Kubernetes контроллер (Kind, kubectl, Helm, Istio)
|
||||
│ └── Dockerfile
|
||||
├── k8s-portforward/ # Port-forward контейнер (устаревший)
|
||||
│ ├── Dockerfile
|
||||
│ └── portforward-container.py
|
||||
├── alt-linux/ # ALT Linux P9 с systemd
|
||||
│ └── Dockerfile
|
||||
├── astra-linux/ # Astra Linux 1.7 с systemd
|
||||
@@ -48,7 +54,7 @@ dockerfiles/
|
||||
│ └── Dockerfile
|
||||
├── debian12/ # Debian 12 (bookworm) с systemd
|
||||
│ └── Dockerfile
|
||||
└── README.md # Документация
|
||||
└── README.md # Этот файл
|
||||
```
|
||||
|
||||
## 🚀 Доступные образы
|
||||
@@ -62,12 +68,11 @@ dockerfiles/
|
||||
#### Компоненты:
|
||||
- **Ansible Core** с последними коллекциями
|
||||
- **Docker CLI** для работы с контейнерами
|
||||
- **kubectl** для управления Kubernetes
|
||||
- **Helm** для управления пакетами Kubernetes
|
||||
- **Kind** для локального Kubernetes
|
||||
- **yq** для работы с YAML
|
||||
- **jq** для работы с JSON
|
||||
|
||||
**Примечание:** Kubernetes инструменты (kubectl, Helm, Kind, Istio) были перенесены в отдельный образ `k8s`.
|
||||
|
||||
#### Предустановленные коллекции:
|
||||
```yaml
|
||||
collections:
|
||||
@@ -109,7 +114,40 @@ docker run --rm \
|
||||
ansible-playbook site.yml
|
||||
```
|
||||
|
||||
### 2. Ubuntu
|
||||
### 2. k8s
|
||||
|
||||
**Базовый образ:** `ubuntu:22.04`
|
||||
**Тег:** `inecs/ansible-lab:k8s-latest`
|
||||
**Описание:** Kubernetes контроллер с инструментами для работы с Kubernetes, Helm, Istio и Kind кластерами
|
||||
|
||||
#### Компоненты:
|
||||
- **Docker CLI** (20.10.24) для работы с контейнерами
|
||||
- **kubectl** (1.34.1) для управления Kubernetes
|
||||
- **Helm** (latest) для управления пакетами Kubernetes
|
||||
- **Kind** (0.30.0) для локальных Kubernetes кластеров
|
||||
- **Istio CLI** (1.22.1) для управления Service Mesh
|
||||
- **Python 3** с модулем yaml для выполнения скриптов
|
||||
|
||||
#### Использование:
|
||||
```bash
|
||||
# Создание Kind кластера
|
||||
docker run -it --rm \
|
||||
--name k8s-controller \
|
||||
--network kind \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock:rw \
|
||||
inecs/ansible-lab:k8s-latest \
|
||||
kind create cluster --name lab
|
||||
|
||||
# Выполнение kubectl команд
|
||||
docker exec k8s-controller kubectl get nodes
|
||||
|
||||
# Установка Helm релиза
|
||||
docker exec k8s-controller helm install prometheus prometheus-community/kube-prometheus-stack
|
||||
```
|
||||
|
||||
**Примечание:** Этот образ используется автоматически при выполнении `make k8s` команд. Контейнер запускается с именем `k8s-controller` и подключен к Docker daemon хоста.
|
||||
|
||||
### 3. Ubuntu
|
||||
|
||||
#### Ubuntu 20.04 (focal)
|
||||
|
||||
@@ -157,7 +195,7 @@ docker run -d --privileged \
|
||||
inecs/ansible-lab:ubuntu22
|
||||
```
|
||||
|
||||
### 3. Debian
|
||||
### 4. Debian
|
||||
|
||||
#### Debian 9 (stretch)
|
||||
|
||||
@@ -216,7 +254,7 @@ docker run -d --privileged \
|
||||
inecs/ansible-lab:debian12
|
||||
```
|
||||
|
||||
### 4. RHEL (Red Hat Enterprise Linux)
|
||||
### 5. RHEL (Red Hat Enterprise Linux)
|
||||
|
||||
**Базовый образ:** `registry.access.redhat.com/ubi8/ubi`
|
||||
**Тег:** `inecs/ansible-lab:rhel-latest`
|
||||
@@ -240,7 +278,7 @@ docker run -d --privileged \
|
||||
inecs/ansible-lab:rhel-latest
|
||||
```
|
||||
|
||||
### 5. CentOS
|
||||
### 6. CentOS
|
||||
|
||||
#### CentOS 7
|
||||
|
||||
@@ -304,7 +342,7 @@ docker run -d --privileged \
|
||||
inecs/ansible-lab:centos-latest
|
||||
```
|
||||
|
||||
### 6. alma
|
||||
### 7. alma
|
||||
|
||||
**Базовый образ:** `almalinux:8`
|
||||
**Тег:** `inecs/ansible-lab:alma-latest`
|
||||
@@ -341,7 +379,7 @@ docker run -d --privileged \
|
||||
inecs/ansible-lab:alma-latest
|
||||
```
|
||||
|
||||
### 7. rocky
|
||||
### 8. rocky
|
||||
|
||||
**Базовый образ:** `rockylinux:8`
|
||||
**Тег:** `inecs/ansible-lab:rocky-latest`
|
||||
@@ -378,7 +416,7 @@ docker run -d --privileged \
|
||||
inecs/ansible-lab:rocky-latest
|
||||
```
|
||||
|
||||
### 8. alt-linux
|
||||
### 9. alt-linux
|
||||
|
||||
**Базовый образ:** `altlinux/p9`
|
||||
**Тег:** `inecs/ansible-lab:alt-linux-latest`
|
||||
@@ -415,7 +453,7 @@ docker run -d --privileged \
|
||||
inecs/ansible-lab:alt-linux-latest
|
||||
```
|
||||
|
||||
### 9. astra-linux
|
||||
### 10. astra-linux
|
||||
|
||||
**Базовый образ:** `astralinux/astra-1.7`
|
||||
**Тег:** `inecs/ansible-lab:astra-linux-latest`
|
||||
@@ -452,7 +490,7 @@ docker run -d --privileged \
|
||||
inecs/ansible-lab:astra-linux-latest
|
||||
```
|
||||
|
||||
### 10. redos
|
||||
### 11. redos
|
||||
|
||||
**Базовый образ:** `redos/redos:9`
|
||||
**Тег:** `inecs/ansible-lab:redos-latest`
|
||||
@@ -569,7 +607,7 @@ make docker reset-builder
|
||||
```yaml
|
||||
# molecule/presets/custom-images.yml
|
||||
---
|
||||
#description: Preset с собственными образами AnsibleLab
|
||||
#description: Preset с собственными образами DevOpsLab
|
||||
docker_network: labnet
|
||||
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
|
||||
|
||||
|
||||
43
dockerfiles/k8s-portforward/Dockerfile
Normal file
43
dockerfiles/k8s-portforward/Dockerfile
Normal file
@@ -0,0 +1,43 @@
|
||||
# Kubernetes Port-Forward Container
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
ARG TARGETARCH
|
||||
|
||||
FROM ubuntu:22.04
|
||||
|
||||
# Обновляем систему
|
||||
RUN apt-get update && apt-get upgrade -y && apt-get clean
|
||||
|
||||
# Устанавливаем базовые пакеты + socat для форвардинга портов
|
||||
RUN apt-get install -y \
|
||||
wget \
|
||||
curl \
|
||||
bash \
|
||||
ca-certificates \
|
||||
python3 \
|
||||
python3-yaml \
|
||||
socat \
|
||||
netcat-openbsd \
|
||||
&& apt-get clean
|
||||
|
||||
# Устанавливаем kubectl
|
||||
RUN if [ "${TARGETARCH}" = "amd64" ]; then \
|
||||
wget -O kubectl "https://dl.k8s.io/release/v1.34.1/bin/linux/amd64/kubectl"; \
|
||||
else \
|
||||
wget -O kubectl "https://dl.k8s.io/release/v1.34.1/bin/linux/arm64/kubectl"; \
|
||||
fi && \
|
||||
chmod +x kubectl && \
|
||||
mv kubectl /usr/local/bin/
|
||||
|
||||
# Создаем рабочий каталог
|
||||
WORKDIR /portforward
|
||||
|
||||
# Копируем скрипт порт-форвардинга
|
||||
COPY portforward-container.py /portforward/portforward-container.py
|
||||
|
||||
# Делаем скрипт исполняемым
|
||||
RUN chmod +x /portforward/portforward-container.py
|
||||
|
||||
# Команда по умолчанию
|
||||
CMD ["python3", "/portforward/portforward-container.py"]
|
||||
145
dockerfiles/k8s-portforward/portforward-container.py
Executable file
145
dockerfiles/k8s-portforward/portforward-container.py
Executable file
@@ -0,0 +1,145 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Скрипт для работы внутри контейнера k8s-portforward
|
||||
Автор: Сергей Антропов
|
||||
Сайт: https://devops.org.ru
|
||||
"""
|
||||
import sys
|
||||
import yaml
|
||||
import subprocess
|
||||
import time
|
||||
import os
|
||||
import signal
|
||||
import json
|
||||
|
||||
def run_kubectl_portforward(cluster_name, namespace, service, remote_port, local_port):
|
||||
"""Запускает kubectl port-forward внутри контейнера"""
|
||||
cmd = [
|
||||
"kubectl",
|
||||
f"--server=https://{cluster_name}-control-plane:6443",
|
||||
"--insecure-skip-tls-verify",
|
||||
"port-forward",
|
||||
"-n", namespace,
|
||||
service,
|
||||
f"{local_port}:{remote_port}"
|
||||
]
|
||||
|
||||
print(f"[portforward] Запуск: {' '.join(cmd)}")
|
||||
process = subprocess.Popen(
|
||||
cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True
|
||||
)
|
||||
|
||||
return process
|
||||
|
||||
def main():
|
||||
"""Главная функция"""
|
||||
# Загружаем preset
|
||||
preset_file = "/workspace/molecule/presets/k8s/kubernetes.yml"
|
||||
|
||||
if not os.path.exists(preset_file):
|
||||
print(f"❌ Файл {preset_file} не найден")
|
||||
print("💡 Убедитесь, что workspace подключен в контейнер")
|
||||
sys.exit(1)
|
||||
|
||||
with open(preset_file, 'r') as f:
|
||||
preset = yaml.safe_load(f)
|
||||
|
||||
cluster_name = preset['kind_clusters'][0]['name']
|
||||
addon_ports = preset['kind_clusters'][0].get('addon_ports', {})
|
||||
|
||||
print(f"🔌 Запуск порт-форвардинга для кластера: {cluster_name}")
|
||||
|
||||
processes = []
|
||||
|
||||
# Ingress HTTP
|
||||
if addon_ports.get('ingress_http'):
|
||||
port = addon_ports['ingress_http']
|
||||
print(f" - Ingress HTTP: {port} -> ingress-nginx-controller:80")
|
||||
proc = run_kubectl_portforward(
|
||||
cluster_name, "ingress-nginx",
|
||||
"svc/ingress-nginx-controller", 80, port
|
||||
)
|
||||
processes.append(proc)
|
||||
|
||||
# Ingress HTTPS
|
||||
if addon_ports.get('ingress_https'):
|
||||
port = addon_ports['ingress_https']
|
||||
print(f" - Ingress HTTPS: {port} -> ingress-nginx-controller:443")
|
||||
proc = run_kubectl_portforward(
|
||||
cluster_name, "ingress-nginx",
|
||||
"svc/ingress-nginx-controller", 443, port
|
||||
)
|
||||
processes.append(proc)
|
||||
|
||||
# Prometheus
|
||||
if addon_ports.get('prometheus'):
|
||||
port = addon_ports['prometheus']
|
||||
print(f" - Prometheus: {port} -> monitoring-kube-prometheus-prometheus:9090")
|
||||
proc = run_kubectl_portforward(
|
||||
cluster_name, "monitoring",
|
||||
"svc/monitoring-kube-prometheus-prometheus", 9090, port
|
||||
)
|
||||
processes.append(proc)
|
||||
|
||||
# Grafana
|
||||
if addon_ports.get('grafana'):
|
||||
port = addon_ports['grafana']
|
||||
print(f" - Grafana: {port} -> monitoring-grafana:80")
|
||||
proc = run_kubectl_portforward(
|
||||
cluster_name, "monitoring",
|
||||
"svc/monitoring-grafana", 80, port
|
||||
)
|
||||
processes.append(proc)
|
||||
|
||||
# Kiali
|
||||
if addon_ports.get('kiali'):
|
||||
port = addon_ports['kiali']
|
||||
print(f" - Kiali: {port} -> kiali:20001")
|
||||
proc = run_kubectl_portforward(
|
||||
cluster_name, "istio-system",
|
||||
"svc/kiali", 20001, port
|
||||
)
|
||||
processes.append(proc)
|
||||
|
||||
# Metrics Server
|
||||
if addon_ports.get('metrics_server'):
|
||||
port = addon_ports['metrics_server']
|
||||
print(f" - Metrics Server: {port} -> metrics-server:4443")
|
||||
proc = run_kubectl_portforward(
|
||||
cluster_name, "kube-system",
|
||||
"svc/metrics-server", 4443, port
|
||||
)
|
||||
processes.append(proc)
|
||||
|
||||
print("✅ Все порты запущены. Ожидание завершения...")
|
||||
print("💡 Контейнер будет работать, пока все port-forward активны")
|
||||
|
||||
# Ожидание завершения процессов
|
||||
try:
|
||||
while True:
|
||||
time.sleep(1)
|
||||
# Проверяем, что все процессы еще работают
|
||||
alive = [p for p in processes if p.poll() is None]
|
||||
if not alive:
|
||||
print("⚠️ Все port-forward завершились")
|
||||
break
|
||||
except KeyboardInterrupt:
|
||||
print("\n🛑 Получен сигнал завершения...")
|
||||
|
||||
# Завершаем все процессы
|
||||
print("🗑️ Завершение port-forward...")
|
||||
for proc in processes:
|
||||
if proc.poll() is None:
|
||||
proc.terminate()
|
||||
try:
|
||||
proc.wait(timeout=5)
|
||||
except subprocess.TimeoutExpired:
|
||||
proc.kill()
|
||||
|
||||
print("✅ Завершено")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,4 +1,4 @@
|
||||
# Настройка CI/CD для AnsibleLab
|
||||
# Настройка CI/CD для DevOpsLab
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
@@ -847,7 +847,7 @@ pipeline {
|
||||
# scripts/setup-cicd.sh
|
||||
# Автоматическая настройка CI/CD
|
||||
|
||||
echo "🔧 Настройка CI/CD для AnsibleLab..."
|
||||
echo "🔧 Настройка CI/CD для DevOpsLab..."
|
||||
|
||||
# Создание директории .github/workflows
|
||||
mkdir -p .github/workflows
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Создание и разработка ролей для AnsibleLab
|
||||
# Создание и разработка ролей для DevOpsLab
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
@@ -247,7 +247,7 @@ my_role_cache_dir: /var/cache/my-role
|
||||
|
||||
galaxy_info:
|
||||
author: Сергей Антропов
|
||||
description: Моя кастомная роль для AnsibleLab
|
||||
description: Моя кастомная роль для DevOpsLab
|
||||
company: https://devops.org.ru
|
||||
license: MIT
|
||||
min_ansible_version: "2.9"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Docker образы AnsibleLab
|
||||
# Docker образы DevOpsLab
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
@@ -6,13 +6,22 @@
|
||||
|
||||
## 🐳 Обзор
|
||||
|
||||
AnsibleLab использует предварительно собранные Docker образы для различных операционных систем с полной поддержкой systemd. Все образы поддерживают multi-arch сборку и автоматически публикуются в Docker Hub под namespace `inecs/ansible-lab`.
|
||||
DevOpsLab использует предварительно собранные Docker образы для различных операционных систем с полной поддержкой systemd. Все образы поддерживают multi-arch сборку и автоматически публикуются в Docker Hub под namespace `inecs/ansible-lab`.
|
||||
|
||||
## 📁 Структура dockerfiles/
|
||||
|
||||
```
|
||||
dockerfiles/
|
||||
├── ansible-controller/ # Ansible контроллер
|
||||
│ ├── Dockerfile
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── requirements.txt
|
||||
│ └── requirements.yml
|
||||
├── k8s/ # Kubernetes контроллер (Kind, kubectl, Helm, Istio)
|
||||
│ └── Dockerfile
|
||||
├── k8s-portforward/ # Port-forward контейнер (устаревший)
|
||||
│ ├── Dockerfile
|
||||
│ └── portforward-container.py
|
||||
├── alt-linux/ # ALT Linux P9
|
||||
├── astra-linux/ # Astra Linux 1.7
|
||||
├── redos/ # RED OS 9
|
||||
@@ -28,7 +37,8 @@ dockerfiles/
|
||||
├── debian9/ # Debian 9 Stretch
|
||||
├── debian10/ # Debian 10 Buster
|
||||
├── debian11/ # Debian 11 Bullseye
|
||||
└── debian12/ # Debian 12 Bookworm
|
||||
├── debian12/ # Debian 12 Bookworm
|
||||
└── README.md # Документация по Dockerfiles
|
||||
```
|
||||
|
||||
## 🚀 Доступные образы
|
||||
@@ -44,13 +54,12 @@ Ansible контроллер с предустановленными колле
|
||||
#### Компоненты:
|
||||
- Ansible Core с последними коллекциями
|
||||
- Docker CLI для работы с контейнерами
|
||||
- kubectl для управления Kubernetes
|
||||
- Helm для управления пакетами Kubernetes
|
||||
- Kind для локального Kubernetes
|
||||
- yq для работы с YAML
|
||||
- jq для работы с JSON
|
||||
- Molecule для тестирования ролей
|
||||
|
||||
**Примечание:** Kubernetes инструменты (kubectl, Helm, Kind, Istio) были перенесены в отдельный образ `k8s`.
|
||||
|
||||
#### Предустановленные коллекции:
|
||||
```yaml
|
||||
collections:
|
||||
@@ -82,6 +91,41 @@ docker run --rm \
|
||||
ansible-playbook site.yml
|
||||
```
|
||||
|
||||
### k8s
|
||||
|
||||
**Базовый образ:** `ubuntu:22.04`
|
||||
**Теги:** `inecs/ansible-lab:k8s-latest`
|
||||
**Платформы:** linux/amd64, linux/arm64
|
||||
|
||||
Kubernetes контроллер с инструментами для работы с Kubernetes, Helm, Istio и Kind кластерами.
|
||||
|
||||
#### Компоненты:
|
||||
- **Docker CLI** (20.10.24) для работы с контейнерами
|
||||
- **kubectl** (1.34.1) для управления Kubernetes
|
||||
- **Helm** (latest) для управления пакетами Kubernetes
|
||||
- **Kind** (0.30.0) для локальных Kubernetes кластеров
|
||||
- **Istio CLI** (1.22.1) для управления Service Mesh
|
||||
- Python 3 с модулем yaml для выполнения скриптов
|
||||
|
||||
#### Использование:
|
||||
```bash
|
||||
# Создание Kind кластера
|
||||
docker run -it --rm \
|
||||
--name k8s-controller \
|
||||
--network kind \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock:rw \
|
||||
inecs/ansible-lab:k8s-latest \
|
||||
kind create cluster --name lab
|
||||
|
||||
# Выполнение kubectl команд
|
||||
docker exec k8s-controller kubectl get nodes
|
||||
|
||||
# Установка Helm релиза
|
||||
docker exec k8s-controller helm install prometheus prometheus-community/kube-prometheus-stack
|
||||
```
|
||||
|
||||
**Примечание:** Этот образ используется автоматически при выполнении `make k8s` команд. Контейнер запускается с именем `k8s-controller` и подключен к Docker daemon хоста.
|
||||
|
||||
### Ubuntu
|
||||
|
||||
**Базовые образы:**
|
||||
@@ -348,18 +392,19 @@ docker run -d --privileged \
|
||||
|
||||
## 📋 Матрица совместимости
|
||||
|
||||
| Образ | Платформы | systemd | Docker | Python 3 |
|
||||
|-------|-----------|---------|--------|----------|
|
||||
| ansible-controller | amd64, arm64 | ✅ | ✅ | ✅ |
|
||||
| ubuntu20/22/24 | amd64, arm64 | ✅ | ✅ | ✅ |
|
||||
| debian9/10/11/12 | amd64, arm64 | ✅ | ✅ | ✅ |
|
||||
| centos7/8/9 | amd64, arm64 | ✅ | ✅ | ✅ |
|
||||
| alma | amd64, arm64 | ✅ | ✅ | ✅ |
|
||||
| rocky | amd64, arm64 | ✅ | ✅ | ✅ |
|
||||
| rhel | amd64, arm64 | ✅ | ✅ | ✅ |
|
||||
| alt-linux | amd64 | ✅ | ✅ | ✅ |
|
||||
| astra-linux | amd64 | ✅ | ✅ | ✅ |
|
||||
| redos | amd64 | ✅ | ✅ | ✅ |
|
||||
| Образ | Платформы | systemd | Docker | Python 3 | Kubernetes Tools |
|
||||
|-------|-----------|---------|--------|----------|------------------|
|
||||
| ansible-controller | amd64, arm64 | ✅ | ✅ | ✅ | ❌ |
|
||||
| k8s | amd64, arm64 | ❌ | ✅ | ✅ | ✅ (kubectl, Helm, Kind, Istio) |
|
||||
| ubuntu20/22/24 | amd64, arm64 | ✅ | ✅ | ✅ | ❌ |
|
||||
| debian9/10/11/12 | amd64, arm64 | ✅ | ✅ | ✅ | ❌ |
|
||||
| centos7/8/9 | amd64, arm64 | ✅ | ✅ | ✅ | ❌ |
|
||||
| alma | amd64, arm64 | ✅ | ✅ | ✅ | ❌ |
|
||||
| rocky | amd64, arm64 | ✅ | ✅ | ✅ | ❌ |
|
||||
| rhel | amd64, arm64 | ✅ | ✅ | ✅ | ❌ |
|
||||
| alt-linux | amd64 | ✅ | ✅ | ✅ | ❌ |
|
||||
| astra-linux | amd64 | ✅ | ✅ | ✅ | ❌ |
|
||||
| redos | amd64 | ✅ | ✅ | ✅ | ❌ |
|
||||
|
||||
## 🛠️ Управление образами
|
||||
|
||||
@@ -406,5 +451,5 @@ make docker purge
|
||||
## 🔗 Полезные ссылки
|
||||
|
||||
- **Docker Hub**: https://hub.docker.com/r/inecs/ansible-lab
|
||||
- **AnsibleLab**: https://devops.org.ru
|
||||
- **Документация**: https://github.com/AnsibleLab/docs
|
||||
- **DevOpsLab**: https://devops.org.ru
|
||||
- **Документация**: https://github.com/DevOpsLab/docs
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Примеры использования AnsibleLab
|
||||
# Примеры использования DevOpsLab
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
@@ -304,7 +304,7 @@ make vault check
|
||||
|
||||
## Заключение
|
||||
|
||||
Эти примеры демонстрируют основные возможности AnsibleLab:
|
||||
Эти примеры демонстрируют основные возможности DevOpsLab:
|
||||
|
||||
1. **Быстрое тестирование** с minimal preset
|
||||
2. **Полное тестирование** с all-images preset
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Быстрый старт с AnsibleLab
|
||||
# Быстрый старт с DevOpsLab
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
@@ -9,8 +9,8 @@
|
||||
### 1. Клонирование репозитория
|
||||
|
||||
```bash
|
||||
git clone ssh://git@git.antropoff.ru:222/Ansible/AnsibleLab.git
|
||||
cd AnsibleLab
|
||||
git clone ssh://git@git.antropoff.ru:222/Ansible/DevOpsLab.git
|
||||
cd DevOpsLab
|
||||
```
|
||||
|
||||
### 2. Проверка структуры проекта
|
||||
|
||||
110
docs/k8s-ingress-fix.md
Normal file
110
docs/k8s-ingress-fix.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Исправление проблемы с Ingress
|
||||
|
||||
## Проблема
|
||||
|
||||
После создания Kubernetes кластера Ingress ресурсы не доступны по доменным именам.
|
||||
|
||||
## Причина
|
||||
|
||||
1. **extraPortMappings не добавлялись в конфигурацию Kind** - порты 80 и 443 не пробрасывались на host
|
||||
2. **Записи в /etc/hosts не добавлялись автоматически** при применении манифестов
|
||||
|
||||
## Решение
|
||||
|
||||
### Вариант 1: Быстрое исправление (без пересоздания кластера)
|
||||
|
||||
1. **Добавьте запись в `/etc/hosts` вручную:**
|
||||
|
||||
```bash
|
||||
echo "127.0.0.1 grafana.local #k8s" | sudo tee -a /etc/hosts
|
||||
```
|
||||
|
||||
2. **Создайте port-forward для Ingress напрямую:**
|
||||
|
||||
```bash
|
||||
# Подключитесь к кластеру
|
||||
export KUBECONFIG=$(docker exec k8s-controller cat /root/.kube/config)
|
||||
|
||||
# Замените 0.0.0.0 на localhost в kubeconfig
|
||||
export KUBECONFIG=$(echo "$KUBECONFIG" | sed 's/0\.0\.0\.0:6443/localhost:6443/g' > /tmp/kubeconfig-local.yaml && echo /tmp/kubeconfig-local.yaml)
|
||||
|
||||
# Создайте port-forward для Ingress HTTP
|
||||
kubectl port-forward -n ingress-nginx svc/ingress-nginx-controller 8081:80 &
|
||||
|
||||
# Проверьте доступность
|
||||
curl -H "Host: grafana.local" http://localhost:8081
|
||||
```
|
||||
|
||||
3. **Откройте в браузере:**
|
||||
|
||||
```
|
||||
http://grafana.local:8081
|
||||
```
|
||||
|
||||
### Вариант 2: Пересоздание кластера (рекомендуется)
|
||||
|
||||
Исправления уже внесены в код. Просто пересоздайте кластер:
|
||||
|
||||
```bash
|
||||
# Удалите старый кластер
|
||||
make k8s destroy kubernetes
|
||||
|
||||
# Создайте новый (с исправлениями)
|
||||
make k8s create kubernetes
|
||||
|
||||
# Примените манифест с Ingress
|
||||
make k8s manifest apply kubernetes manifests/test-grafana-ingress.yaml
|
||||
|
||||
# Запись в /etc/hosts добавится автоматически
|
||||
# Проверьте
|
||||
cat /etc/hosts | grep k8s
|
||||
|
||||
# Откройте в браузере
|
||||
open http://grafana.local:8081
|
||||
```
|
||||
|
||||
## Проверка
|
||||
|
||||
```bash
|
||||
# 1. Проверьте Ingress
|
||||
docker exec k8s-controller kubectl --server=https://lab-control-plane:6443 --insecure-skip-tls-verify get ingress --all-namespaces
|
||||
|
||||
# 2. Проверьте ports control-plane
|
||||
docker port lab-control-plane
|
||||
|
||||
# Должны быть:
|
||||
# 6443/tcp -> 0.0.0.0:6443
|
||||
# 80/tcp -> 0.0.0.0:8081 <- после исправления
|
||||
# 443/tcp -> 0.0.0.0:8443 <- после исправления
|
||||
|
||||
# 3. Проверьте доступность
|
||||
curl -H "Host: grafana.local" http://localhost:8081
|
||||
```
|
||||
|
||||
## Что было исправлено
|
||||
|
||||
1. В `scripts/create_k8s_cluster.py` исправлена логика добавления `extraPortMappings` в конфигурацию Kind
|
||||
2. Порты 80 и 443 теперь правильно пробрасываются на host (8081 и 8443)
|
||||
3. Манифест Ingress можно применить и автоматически добавить запись в `/etc/hosts`
|
||||
|
||||
## Дополнительно
|
||||
|
||||
Если Ingress всё ещё не работает:
|
||||
|
||||
1. **Проверьте статус подов Ingress Controller:**
|
||||
|
||||
```bash
|
||||
docker exec k8s-controller kubectl --server=https://lab-control-plane:6443 --insecure-skip-tls-verify get pods -n ingress-nginx
|
||||
```
|
||||
|
||||
2. **Проверьте логи Ingress Controller:**
|
||||
|
||||
```bash
|
||||
docker exec k8s-controller kubectl --server=https://lab-control-plane:6443 --insecure-skip-tls-verify logs -n ingress-nginx -l app.kubernetes.io/component=controller
|
||||
```
|
||||
|
||||
3. **Проверьте события:**
|
||||
|
||||
```bash
|
||||
docker exec k8s-controller kubectl --server=https://lab-control-plane:6443 --insecure-skip-tls-verify get events -n monitoring
|
||||
```
|
||||
232
docs/k8s-scripts.md
Normal file
232
docs/k8s-scripts.md
Normal file
@@ -0,0 +1,232 @@
|
||||
# Скрипты управления Kubernetes
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
|
||||
## Обзор
|
||||
|
||||
В проекте используются несколько Python скриптов для автоматизации работы с Kubernetes кластерами на базе Kind. Все скрипты находятся в директории `scripts/`.
|
||||
|
||||
## Скрипты
|
||||
|
||||
### 1. `create_k8s_cluster.py`
|
||||
|
||||
**Назначение:** Создание Kind кластера, установка аддонов и создание Docker контейнеров из пресета.
|
||||
|
||||
**Принцип работы:**
|
||||
|
||||
1. **Парсинг пресета:** Читает YAML файл пресета (например, `molecule/presets/k8s/kubernetes.yml`)
|
||||
|
||||
2. **Создание Docker сети:**
|
||||
- Проверяет наличие сети (по умолчанию `labnet`)
|
||||
- Создает сеть если её нет
|
||||
|
||||
3. **Создание Docker контейнеров:**
|
||||
- Читает секцию `hosts` из пресета
|
||||
- Для каждого хоста создает Docker контейнер с настройками из `systemd_defaults`
|
||||
- Использует образы из секции `images`
|
||||
|
||||
4. **Создание Kind кластера:**
|
||||
- Генерирует конфигурацию Kind в формате YAML
|
||||
- Настраивает `extraPortMappings` для Ingress портов
|
||||
- Создает кластер через команду `kind create cluster`
|
||||
|
||||
5. **Установка аддонов:**
|
||||
- **Ingress NGINX:** Устанавливает ingress-nginx controller через kubectl apply
|
||||
- **Metrics Server:** Устанавливает metrics-server с патчем для insecure TLS
|
||||
- **Istio:** Устанавливает Istio через istioctl с профилем demo
|
||||
- **Kiali:** Устанавливает Kiali через Helm (использует Helm chart)
|
||||
- **Prometheus Stack:** Устанавливает Prometheus + Grafana через Helm (kube-prometheus-stack)
|
||||
|
||||
6. **Подключение к сети Kind:** Подключает контейнер `k8s-controller` к сети `kind` для доступа к API серверу
|
||||
|
||||
**Параметры:**
|
||||
```bash
|
||||
python3 scripts/create_k8s_cluster.py <preset_file> <container_name>
|
||||
```
|
||||
|
||||
**Пример:**
|
||||
```bash
|
||||
python3 scripts/create_k8s_cluster.py molecule/presets/k8s/kubernetes.yml k8s-controller
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. `delete_hosts.py`
|
||||
|
||||
**Назначение:** Удаление Docker контейнеров, созданных из секции `hosts` пресета.
|
||||
|
||||
**Принцип работы:**
|
||||
|
||||
1. **Парсинг пресета:** Читает YAML файл пресета
|
||||
2. **Получение списка хостов:** Извлекает секцию `hosts`
|
||||
3. **Удаление контейнеров:** Для каждого хоста выполняет `docker rm -f <host_name>`
|
||||
|
||||
**Параметры:**
|
||||
```bash
|
||||
python3 scripts/delete_hosts.py <preset_file>
|
||||
```
|
||||
|
||||
**Пример:**
|
||||
```bash
|
||||
python3 scripts/delete_hosts.py molecule/presets/k8s/kubernetes.yml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. `portforward.py`
|
||||
|
||||
**Назначение:** Управление port-forward для доступа к сервисам Kubernetes извне кластера.
|
||||
|
||||
**Принцип работы:**
|
||||
|
||||
1. **Загрузка пресета:** Читает файл `molecule/presets/k8s/kubernetes.yml`
|
||||
|
||||
2. **Получение kubeconfig:**
|
||||
- Копирует kubeconfig из контейнера `k8s-controller` через `docker exec`
|
||||
- Сохраняет во временный файл
|
||||
|
||||
3. **Модификация kubeconfig:**
|
||||
- Заменяет `server: https://0.0.0.0:6443` на `server: https://localhost:6443`
|
||||
- Это необходимо для доступа с локальной машины
|
||||
|
||||
4. **Создание port-forward:**
|
||||
- Запускает `kubectl port-forward` для каждого сервиса из `addon_ports`
|
||||
- Использует формат: `kubectl port-forward -n <namespace> svc/<service> <local_port>:<remote_port>`
|
||||
- Управляет процессами через PID
|
||||
|
||||
**Команды:**
|
||||
- `create` - создает port-forward для всех сервисов
|
||||
- `list` - показывает список активных портов
|
||||
- `clear` - останавливает все port-forward процессы
|
||||
- `recreate` - очищает и заново создает port-forward
|
||||
- `delete <port>` - удаляет конкретный port-forward
|
||||
|
||||
**Пример использования:**
|
||||
```bash
|
||||
python3 scripts/portforward.py create
|
||||
python3 scripts/portforward.py list
|
||||
python3 scripts/portforward.py delete 3000
|
||||
python3 scripts/portforward.py clear
|
||||
```
|
||||
|
||||
**Важно:** Скрипт должен запускаться на локальной машине, где установлены `kubectl` и Python 3.
|
||||
|
||||
---
|
||||
|
||||
### 4. `k8s_status.py`
|
||||
|
||||
**Назначение:** Детальный отчет о состоянии Kubernetes кластера.
|
||||
|
||||
**Принцип работы:**
|
||||
|
||||
1. **Подключение к кластеру:**
|
||||
- Получает имя кластера через `kind get clusters`
|
||||
- Формирует адрес API сервера: `https://<cluster_name>-control-plane:6443`
|
||||
- Выполняет все kubectl команды через `docker exec k8s-controller`
|
||||
|
||||
2. **Сбор информации:**
|
||||
- **Общая информация:** версия Kubernetes
|
||||
- **Узлы:** статус, ресурсы, описание каждого узла
|
||||
- **Namespaces:** список всех namespace
|
||||
- **Использование ресурсов:** метрики через metrics-server (если установлен)
|
||||
- **Pods:** поды по каждому namespace
|
||||
- **Deployments:** deployments по namespace
|
||||
- **DaemonSets:** daemonsets по namespace
|
||||
- **StatefulSets:** statefulsets по namespace
|
||||
- **Services:** сервисы по namespace
|
||||
- **Ingress:** ingress ресурсы
|
||||
- **PVC:** PersistentVolumeClaims
|
||||
- **События:** последние 20 событий по namespace
|
||||
- **Helm релизы:** список установленных через Helm
|
||||
|
||||
3. **Форматирование вывода:**
|
||||
- Использует секции с разделителями
|
||||
- Группирует информацию по namespace
|
||||
- Показывает только непустые секции
|
||||
|
||||
**Пример использования:**
|
||||
```bash
|
||||
python3 scripts/k8s_status.py
|
||||
```
|
||||
|
||||
**Интеграция:**
|
||||
- Автоматически вызывается командой `make k8s status [preset]`
|
||||
|
||||
**Особенности:**
|
||||
- Выполняет все команды внутри контейнера `k8s-controller`
|
||||
- Использует прямой адрес control-plane для подключения
|
||||
- Обходит проблемы с kubeconfig через `--insecure-skip-tls-verify`
|
||||
|
||||
---
|
||||
|
||||
## Архитектура взаимодействия
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Локальная машина │
|
||||
│ │
|
||||
│ Makefile → Python скрипты → Docker API │
|
||||
│ ↓ ↓ ↓ │
|
||||
│ make k8s scripts/*.py docker exec │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
│
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Docker контейнер │
|
||||
│ k8s-controller │
|
||||
│ ┌──────────────────────────────────────────┐ │
|
||||
│ │ kind, kubectl, helm, istioctl │ │
|
||||
│ └──────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
│
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Docker сеть: kind │
|
||||
│ ┌──────────────────────────────────────────┐ │
|
||||
│ │ Kind Kubernetes Cluster │ │
|
||||
│ │ • Control Plane (6443) │ │
|
||||
│ │ • Worker Nodes │ │
|
||||
│ │ • Services (ClusterIP) │ │
|
||||
│ │ • Ingress │ │
|
||||
│ └──────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Общие принципы
|
||||
|
||||
1. **Изоляция:** Все kubectl команды выполняются внутри контейнера `k8s-controller`
|
||||
2. **Безопасность:** Используется `--insecure-skip-tls-verify` для обхода проблем с сертификатами
|
||||
3. **Автоматизация:** Скрипты вызываются автоматически через Makefile
|
||||
4. **Логгирование:** Все скрипты выводят подробную информацию о своих действиях
|
||||
|
||||
## Требования
|
||||
|
||||
- Python 3 (на локальной машине)
|
||||
- kubectl (на локальной машине, для portforward.py)
|
||||
- Docker
|
||||
- Docker контейнер `k8s-controller` должен быть запущен
|
||||
|
||||
## Отладка
|
||||
|
||||
Если что-то не работает:
|
||||
|
||||
1. **Проверьте контейнер:**
|
||||
```bash
|
||||
docker ps | grep k8s-controller
|
||||
```
|
||||
|
||||
2. **Запустите скрипт вручную:**
|
||||
```bash
|
||||
python3 scripts/k8s_status.py
|
||||
```
|
||||
|
||||
3. **Посмотрите логи:**
|
||||
```bash
|
||||
docker logs k8s-controller
|
||||
```
|
||||
|
||||
4. **Проверьте кластер:**
|
||||
```bash
|
||||
docker exec k8s-controller kubectl get nodes
|
||||
```
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
## Введение
|
||||
|
||||
AnsibleLab предоставляет полную поддержку создания и управления локальными Kubernetes кластерами на основе Kind (Kubernetes in Docker). Kind позволяет запускать Kubernetes кластеры внутри Docker контейнеров, что идеально подходит для разработки, тестирования и обучения.
|
||||
DevOpsLab предоставляет полную поддержку создания и управления локальными Kubernetes кластерами на основе Kind (Kubernetes in Docker). Kind позволяет запускать Kubernetes кластеры внутри Docker контейнеров, что идеально подходит для разработки, тестирования и обучения.
|
||||
|
||||
### Основные возможности
|
||||
|
||||
@@ -891,7 +891,7 @@ make k8s manifest apply kubernetes ./network-policy.yaml
|
||||
|
||||
## Заключение
|
||||
|
||||
AnsibleLab предоставляет полный набор инструментов для работы с Kubernetes кластерами локально. Вы можете:
|
||||
DevOpsLab предоставляет полный набор инструментов для работы с Kubernetes кластерами локально. Вы можете:
|
||||
|
||||
- Создавать и управлять кластерами
|
||||
- Устанавливать и настраивать приложения
|
||||
|
||||
@@ -3,295 +3,792 @@
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Описание](#описание)
|
||||
- [Требования к системе](#требования-к-системе)
|
||||
- [Возможности](#возможности)
|
||||
- [Быстрый старт](#быстрый-старт)
|
||||
- [Команды управления](#команды-управления)
|
||||
- [Работа с Helm](#работа-с-helm)
|
||||
- [Работа с манифестами](#работа-с-манифестами)
|
||||
- [Управление Ingress](#управление-ingress)
|
||||
- [Проброс портов (Port-forward)](#проброс-портов-port-forward)
|
||||
- [Мониторинг и логи](#мониторинг-и-логи)
|
||||
- [Конфигурация](#конфигурация)
|
||||
- [Архитектура](#архитектура)
|
||||
- [Доступ к приложениям](#доступ-к-приложениям)
|
||||
- [Кроссплатформенность](#кроссплатформенность)
|
||||
- [Подробная документация по скриптам](#подробная-документация-по-скриптам)
|
||||
- [Best Practices](#best-practices)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
## Описание
|
||||
|
||||
Проект поддерживает автоматическое создание и управление Kubernetes кластерами на базе [Kind](https://kind.sigs.k8s.io/) для тестирования в изолированной лабораторной среде.
|
||||
|
||||
Kind позволяет создавать локальные Kubernetes кластеры внутри Docker контейнеров, что идеально подходит для разработки и тестирования без необходимости устанавливать полный Kubernetes.
|
||||
|
||||
## Требования к системе
|
||||
|
||||
### Обязательные требования
|
||||
|
||||
1. **Docker** - для запуска Kind кластеров
|
||||
2. **Python 3** - для управления port-forward
|
||||
3. **kubectl** - для работы с кластером
|
||||
|
||||
**Установка на macOS:**
|
||||
```bash
|
||||
brew install docker python3 kubectl
|
||||
```
|
||||
|
||||
**Установка на Ubuntu/Debian:**
|
||||
```bash
|
||||
sudo apt update && sudo apt install -y docker.io python3 python3-pip kubectl
|
||||
```
|
||||
|
||||
**Установка на CentOS/RHEL:**
|
||||
```bash
|
||||
sudo yum install -y docker python3 python3-pip kubectl
|
||||
sudo systemctl start docker
|
||||
sudo systemctl enable docker
|
||||
```
|
||||
|
||||
### Проверка установки
|
||||
|
||||
```bash
|
||||
docker --version
|
||||
python3 --version
|
||||
kubectl version --client
|
||||
```
|
||||
|
||||
### Docker группы
|
||||
|
||||
На Linux добавьте пользователя в группу docker:
|
||||
```bash
|
||||
sudo usermod -aG docker $USER
|
||||
# Выйдите и войдите заново
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Возможности
|
||||
|
||||
- Создание Kind кластеров с настраиваемым количеством worker-узлов
|
||||
- Автоматическая установка аддонов:
|
||||
- Ingress NGINX Controller
|
||||
- Metrics Server
|
||||
- Istio Service Mesh
|
||||
- Kiali (визуализация Istio)
|
||||
- Prometheus Stack (Prometheus + Grafana)
|
||||
- Настройка портов для внешнего доступа к аддонам
|
||||
- Интеграция с Docker контейнерами в одной лабораторной сети
|
||||
- ✅ Создание Kind кластеров с настраиваемым количеством worker-узлов
|
||||
- ✅ Автоматическая установка аддонов (Ingress NGINX, Metrics Server, Istio, Kiali, Prometheus Stack)
|
||||
- ✅ **Автоматический port-forward** для доступа к сервисам
|
||||
- ✅ Работа с Helm (установка, удаление, обновление, rollback)
|
||||
- ✅ Работа с Kubernetes манифестами
|
||||
- ✅ Управление Helm репозиториями
|
||||
- ✅ Автоматическое управление `/etc/hosts` для Ingress
|
||||
- ✅ Управление Docker контейнерами в лабораторной сети
|
||||
- ✅ Интеграция с Istio Service Mesh
|
||||
- ✅ Детальный отчет о состоянии кластера
|
||||
|
||||
## Команды
|
||||
---
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
### 1. Создание кластера
|
||||
|
||||
```bash
|
||||
# Создание кластера с полным набором аддонов
|
||||
make k8s create kubernetes
|
||||
```
|
||||
|
||||
### 2. Проверка статуса
|
||||
|
||||
```bash
|
||||
# Детальный отчет о кластере
|
||||
make k8s status kubernetes
|
||||
```
|
||||
|
||||
### 3. Доступ к аддонам
|
||||
|
||||
После создания кластера автоматически создаются port-forward:
|
||||
- Grafana: http://localhost:3000
|
||||
- Prometheus: http://localhost:9090
|
||||
- Kiali: http://localhost:20001
|
||||
|
||||
### 4. Удаление кластера
|
||||
|
||||
```bash
|
||||
make k8s destroy kubernetes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Команды управления
|
||||
|
||||
### Создание кластера
|
||||
|
||||
```bash
|
||||
# Создание минимального кластера (без аддонов)
|
||||
# Минимальный кластер (без аддонов)
|
||||
make k8s create
|
||||
|
||||
# Создание кластера с полным набором аддонов
|
||||
# Полный кластер с аддонами
|
||||
make k8s create kubernetes
|
||||
|
||||
# Использование пользовательского пресета
|
||||
# Пользовательский пресет
|
||||
make k8s create my-custom-preset
|
||||
```
|
||||
|
||||
### Управление кластером
|
||||
**Что происходит:**
|
||||
1. Создается контейнер `k8s-controller` с инструментами (Kind, kubectl, Helm, Istio CLI)
|
||||
2. Создаются Docker контейнеры из раздела `hosts` (если есть)
|
||||
3. Создается Kind кластер
|
||||
4. Устанавливаются аддоны
|
||||
5. Создается автоматический port-forward
|
||||
6. Добавляются записи в `/etc/hosts` для Ingress
|
||||
|
||||
### Управление жизненным циклом
|
||||
|
||||
```bash
|
||||
# Удаление кластера
|
||||
# Удаление кластера (с очисткой port-forward и /etc/hosts)
|
||||
make k8s destroy [preset]
|
||||
|
||||
# Остановка кластера (без удаления)
|
||||
make k8s stop [cluster]
|
||||
make k8s stop [preset]
|
||||
|
||||
# Запуск остановленного кластера
|
||||
make k8s start [cluster]
|
||||
make k8s start [preset]
|
||||
|
||||
# Проверка статуса кластера
|
||||
make k8s status [cluster]
|
||||
# Детальный отчет о состоянии
|
||||
make k8s status [preset]
|
||||
|
||||
# Получение kubeconfig для подключения
|
||||
make k8s config [cluster]
|
||||
|
||||
# Открытие shell в контейнере
|
||||
make k8s shell
|
||||
# Показать узлы кластера
|
||||
make k8s nodes [preset]
|
||||
```
|
||||
|
||||
### Получение kubeconfig
|
||||
|
||||
```bash
|
||||
# Сохранить kubeconfig для подключения
|
||||
make k8s config [preset]
|
||||
|
||||
# Использовать конфиг
|
||||
export KUBECONFIG=kubeconfig
|
||||
kubectl get nodes
|
||||
```
|
||||
|
||||
### Shell доступ
|
||||
|
||||
```bash
|
||||
# Открыть shell в контейнере k8s-controller
|
||||
make k8s shell [preset]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Работа с Helm
|
||||
|
||||
Helm - это менеджер пакетов для Kubernetes.
|
||||
|
||||
### Управление релизами
|
||||
|
||||
```bash
|
||||
# Установить чарт
|
||||
make k8s helm apply kubernetes nginx stable/nginx-ingress
|
||||
|
||||
# Обновить релиз
|
||||
make k8s helm update kubernetes nginx stable/nginx-ingress
|
||||
|
||||
# Откатить релиз
|
||||
make k8s helm rollback kubernetes nginx
|
||||
|
||||
# Посмотреть статус релиза
|
||||
make k8s helm status kubernetes nginx
|
||||
|
||||
# Удалить релиз
|
||||
make k8s helm delete kubernetes nginx
|
||||
|
||||
# Список всех релизов
|
||||
make k8s helm list kubernetes
|
||||
```
|
||||
|
||||
### Управление репозиториями
|
||||
|
||||
```bash
|
||||
# Добавить репозиторий
|
||||
make k8s helmrepo add kubernetes stable https://charts.helm.sh/stable
|
||||
|
||||
# Обновить репозиторий
|
||||
make k8s helmrepo update kubernetes stable
|
||||
|
||||
# Список репозиториев
|
||||
make k8s helmrepo list kubernetes
|
||||
|
||||
# Показать доступные чарты
|
||||
make k8s helmrepo packages kubernetes stable
|
||||
|
||||
# Удалить репозиторий
|
||||
make k8s helmrepo delete kubernetes stable
|
||||
```
|
||||
|
||||
### Пример: установка MySQL
|
||||
|
||||
```bash
|
||||
# Добавить репозиторий Bitnami
|
||||
make k8s helmrepo add kubernetes bitnami https://charts.bitnami.com/bitnami
|
||||
|
||||
# Установить MySQL
|
||||
make k8s helm apply kubernetes mysql bitnami/mysql
|
||||
|
||||
# Проверить статус
|
||||
make k8s helm status kubernetes mysql
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Работа с манифестами
|
||||
|
||||
Применение обычных Kubernetes манифестов (без Helm).
|
||||
|
||||
```bash
|
||||
# Применить манифест из URL
|
||||
make k8s manifest apply kubernetes https://example.com/deploy.yaml
|
||||
|
||||
# Применить манифест из файла
|
||||
make k8s manifest apply kubernetes /path/to/manifest.yaml
|
||||
|
||||
# Удалить манифест
|
||||
make k8s manifest delete kubernetes https://example.com/deploy.yaml
|
||||
```
|
||||
|
||||
### Пример: создание Deployment
|
||||
|
||||
```yaml
|
||||
# nginx-deployment.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:latest
|
||||
ports:
|
||||
- containerPort: 80
|
||||
```
|
||||
|
||||
```bash
|
||||
# Применить
|
||||
make k8s manifest apply kubernetes ./nginx-deployment.yaml
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Управление Ingress
|
||||
|
||||
### Доступ к приложениям через Ingress
|
||||
|
||||
Для доступа к приложениям по доменным именам нужно вручную добавить записи в `/etc/hosts`:
|
||||
|
||||
```bash
|
||||
# Добавить запись в /etc/hosts
|
||||
echo "127.0.0.1 grafana.local #k8s" | sudo tee -a /etc/hosts
|
||||
|
||||
# Очистить DNS кеш macOS
|
||||
sudo killall -HUP mDNSResponder
|
||||
```
|
||||
|
||||
После этого приложение будет доступно по адресу:
|
||||
```
|
||||
http://grafana.local:8081
|
||||
```
|
||||
|
||||
**Пример манифеста Ingress:**
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: grafana-ingress
|
||||
namespace: monitoring
|
||||
spec:
|
||||
rules:
|
||||
- host: grafana.local
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: monitoring-grafana
|
||||
port:
|
||||
number: 80
|
||||
```
|
||||
|
||||
**Важно:**
|
||||
- Записи в `/etc/hosts` нужно добавлять вручную
|
||||
- Используйте порт 8081 для HTTP и 8443 для HTTPS
|
||||
- Для удаления записей используйте sudo
|
||||
|
||||
---
|
||||
|
||||
## Проброс портов (Port-forward)
|
||||
|
||||
Port-forward позволяет получить доступ к ClusterIP сервисам извне кластера.
|
||||
|
||||
### Автоматический port-forward
|
||||
|
||||
После создания кластера автоматически создаются порты:
|
||||
- Ingress HTTP: `8081:80`
|
||||
- Ingress HTTPS: `8443:443`
|
||||
- Grafana: `3000:80`
|
||||
- Prometheus: `9090:9090`
|
||||
- Kiali: `20001:20001`
|
||||
|
||||
### Управление вручную
|
||||
|
||||
```bash
|
||||
# Создать port-forward
|
||||
make k8s portforward create
|
||||
|
||||
# Список активных портов
|
||||
make k8s portforward list
|
||||
|
||||
# Удалить конкретный порт
|
||||
make k8s portforward delete 3000
|
||||
|
||||
# Очистить все порты
|
||||
make k8s portforward clear
|
||||
|
||||
# Пересоздать порты
|
||||
make k8s portforward recreate
|
||||
```
|
||||
|
||||
### Ручной port-forward для своих сервисов
|
||||
|
||||
```bash
|
||||
# Подключиться к кластеру
|
||||
export KUBECONFIG=$(docker exec k8s-controller cat /root/.kube/config)
|
||||
|
||||
# Создать port-forward
|
||||
kubectl port-forward -n default svc/my-service 8080:80
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Мониторинг и логи
|
||||
|
||||
### Детальный статус кластера
|
||||
|
||||
```bash
|
||||
make k8s status kubernetes
|
||||
```
|
||||
|
||||
Показывает:
|
||||
- Узлы кластера
|
||||
- Namespaces
|
||||
- Pods
|
||||
- Services
|
||||
- Ingress
|
||||
- Deployments
|
||||
- DaemonSets
|
||||
- StatefulSets
|
||||
- PVC
|
||||
- События
|
||||
- Helm релизы
|
||||
- Использование ресурсов
|
||||
|
||||
### Доступ к аддонам
|
||||
|
||||
**Grafana:**
|
||||
```
|
||||
URL: http://localhost:3000
|
||||
Login: admin
|
||||
Password: admin
|
||||
```
|
||||
|
||||
**Prometheus:**
|
||||
```
|
||||
URL: http://localhost:9090
|
||||
```
|
||||
|
||||
**Kiali:**
|
||||
```
|
||||
URL: http://localhost:20001
|
||||
Login: admin
|
||||
Password: admin
|
||||
```
|
||||
|
||||
### Логи контейнера
|
||||
|
||||
```bash
|
||||
# Логи k8s-controller
|
||||
docker logs k8s-controller
|
||||
|
||||
# Логи в реальном времени
|
||||
docker logs -f k8s-controller
|
||||
```
|
||||
|
||||
### Логи кластера
|
||||
|
||||
```bash
|
||||
# Логи конкретного pod
|
||||
make k8s shell kubernetes
|
||||
kubectl logs -n monitoring <pod-name>
|
||||
|
||||
# Все логи в namespace
|
||||
kubectl logs -n monitoring --all-containers=true --tail=100
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Конфигурация
|
||||
|
||||
### Пресеты Kubernetes хранятся в `molecule/presets/k8s/`
|
||||
### Пресеты
|
||||
|
||||
#### Минимальный кластер (`k8s-minimal.yml`)
|
||||
Пресеты находятся в `molecule/presets/k8s/`:
|
||||
|
||||
**kubernetes.yml** - полный набор аддонов:
|
||||
- Ingress NGINX
|
||||
- Metrics Server
|
||||
- Istio
|
||||
- Kiali
|
||||
- Prometheus + Grafana
|
||||
|
||||
### Структура пресета
|
||||
|
||||
```yaml
|
||||
kind_clusters:
|
||||
- name: minimal
|
||||
workers: 0 # Только control-plane узел
|
||||
api_port: 6443
|
||||
```
|
||||
k8s_cluster:
|
||||
name: lab
|
||||
nodes: 1
|
||||
|
||||
#### Полный кластер с аддонами (`kubernetes.yml`)
|
||||
|
||||
```yaml
|
||||
kind_clusters:
|
||||
- name: lab
|
||||
workers: 2
|
||||
api_port: 6443
|
||||
addons:
|
||||
ingress_nginx: true
|
||||
addons:
|
||||
ingress: true
|
||||
metrics_server: true
|
||||
istio: true
|
||||
kiali: true
|
||||
prometheus_stack: true
|
||||
ingress_host_http_port: 8081
|
||||
ingress_host_https_port: 8443
|
||||
# Порты для внешнего доступа к аддонам
|
||||
addon_ports:
|
||||
|
||||
addon_ports:
|
||||
ingress_http: 8081
|
||||
ingress_https: 8443
|
||||
prometheus: 9090
|
||||
grafana: 3000
|
||||
kiali: 20001
|
||||
metrics_server: 4443
|
||||
|
||||
hosts:
|
||||
- name: test1
|
||||
image: centos8
|
||||
systemd_defaults:
|
||||
container: true
|
||||
|
||||
images:
|
||||
centos8:
|
||||
name: inecs/ansible-lab:centos8-latest
|
||||
```
|
||||
|
||||
## Доступ к аддонам
|
||||
### Пользовательский пресет
|
||||
|
||||
После создания кластера с аддонами, они доступны на следующих портах:
|
||||
Создайте файл `molecule/presets/k8s/my-preset.yml`:
|
||||
|
||||
### Prometheus
|
||||
```yaml
|
||||
k8s_cluster:
|
||||
name: my-cluster
|
||||
nodes: 2
|
||||
|
||||
addons:
|
||||
ingress: true
|
||||
metrics_server: false
|
||||
istio: false
|
||||
kiali: false
|
||||
prometheus_stack: false
|
||||
```
|
||||
|
||||
Использование:
|
||||
```bash
|
||||
# Web UI доступна на порту 9090
|
||||
http://localhost:9090
|
||||
make k8s create my-preset
|
||||
```
|
||||
|
||||
### Grafana
|
||||
```bash
|
||||
# Web UI доступна на порту 3000
|
||||
http://localhost:3000
|
||||
|
||||
# Пароль администратора
|
||||
kubectl get secret -n monitoring monitoring-grafana \
|
||||
-o jsonpath="{.data.admin-password}" | base64 -d
|
||||
|
||||
# Логин: admin
|
||||
# Пароль: (получен выше)
|
||||
```
|
||||
|
||||
### Kiali
|
||||
```bash
|
||||
# Web UI доступна на порту 20001
|
||||
http://localhost:20001
|
||||
|
||||
# Аутентификация: anonymous (отключена по умолчанию)
|
||||
```
|
||||
|
||||
### Istio Ingress
|
||||
```bash
|
||||
# HTTP доступен на порту 8081
|
||||
http://localhost:8081
|
||||
|
||||
# HTTPS доступен на порту 8443
|
||||
https://localhost:8443
|
||||
```
|
||||
|
||||
## Примеры использования
|
||||
|
||||
### Создание и настройка кластера
|
||||
|
||||
```bash
|
||||
# 1. Создать кластер с аддонами
|
||||
make k8s create kubernetes
|
||||
|
||||
# 2. Проверить статус
|
||||
make k8s status
|
||||
|
||||
# 3. Получить kubeconfig
|
||||
make k8s config lab
|
||||
|
||||
# 4. Использовать kubeconfig
|
||||
export KUBECONFIG=kubeconfig
|
||||
kubectl get nodes
|
||||
kubectl get pods -A
|
||||
|
||||
# 5. Открыть Grafana в браузере
|
||||
open http://localhost:3000
|
||||
# Логин: admin
|
||||
# Пароль: (получить командой выше)
|
||||
```
|
||||
|
||||
### Управление кластером
|
||||
|
||||
```bash
|
||||
# Остановить кластер (без удаления)
|
||||
make k8s stop lab
|
||||
|
||||
# Запустить остановленный кластер
|
||||
make k8s start lab
|
||||
|
||||
# Проверить конкретный кластер
|
||||
make k8s status lab
|
||||
|
||||
# Получить kubeconfig для конкретного кластера
|
||||
make k8s config lab
|
||||
|
||||
# Удалить кластер
|
||||
make k8s destroy kubernetes
|
||||
```
|
||||
|
||||
### Работа внутри контейнера
|
||||
|
||||
```bash
|
||||
# Открыть shell в контейнере ansible-controller
|
||||
make k8s shell
|
||||
|
||||
# Внутри контейнера:
|
||||
kind get clusters
|
||||
kubectl --context kind-lab get nodes
|
||||
istioctl --context kind-lab proxy-status
|
||||
kubectl --context kind-lab get pods -n monitoring
|
||||
```
|
||||
---
|
||||
|
||||
## Архитектура
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Docker Network: labnet │
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Локальная машина │
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ Ubuntu22 │ │ Debian12 │ │ Ansible │ │
|
||||
│ │ Container │ │ Container │ │ Controller │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────┐ │
|
||||
│ │ Kind Cluster: "lab" │ │
|
||||
│ │ ┌──────────────┐ ┌──────────────┐ │ │
|
||||
│ │ │ Control Plane│ │ Worker 1 │ │ │
|
||||
│ │ │ Port 6443 │ │ │ │ │
|
||||
│ │ └──────────────┘ └──────────────┘ │ │
|
||||
│ │ ┌──────────────┐ │ │
|
||||
│ │ │ Worker 2 │ │ │
|
||||
│ │ └──────────────┘ │ │
|
||||
│ │ │ │
|
||||
│ │ NodePort Services: │ │
|
||||
│ │ - Prometheus :9090 │ │
|
||||
│ │ - Grafana :3000 │ │
|
||||
│ │ - Kiali :20001 │ │
|
||||
│ │ - Ingress :8081 (HTTP), :8443 (HTTPS) │ │
|
||||
│ └──────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
│ ┌──────────────────────────────────────────────┐ │
|
||||
│ │ Makefile → Python скрипты → Docker API │ │
|
||||
│ │ kubectl (port-forward) │ │
|
||||
│ └──────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
│
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Docker: k8s-controller │
|
||||
│ ┌──────────────────────────────────────────────┐ │
|
||||
│ │ kind, kubectl, helm, istioctl │ │
|
||||
│ └──────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
│
|
||||
↓
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Docker сеть: kind │
|
||||
│ ┌──────────────────────────────────────────────┐ │
|
||||
│ │ Kind Kubernetes Cluster │ │
|
||||
│ │ • Control Plane (6443) │ │
|
||||
│ │ • Worker Nodes │ │
|
||||
│ │ • Services (ClusterIP) │ │
|
||||
│ │ • Ingress Controller │ │
|
||||
│ │ • Istio Service Mesh │ │
|
||||
│ └──────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Настройка портов аддонов
|
||||
### Компоненты
|
||||
|
||||
Вы можете настроить порты для внешнего доступа в пресете:
|
||||
1. **k8s-controller** - контейнер с инструментами управления
|
||||
2. **Kind кластер** - Kubernetes кластер в Docker контейнерах
|
||||
3. **Port-forward** - локальные процессы на хосте
|
||||
4. **Ingress** - маршрутизация трафика внутрь кластера
|
||||
|
||||
```yaml
|
||||
kind_clusters:
|
||||
- name: lab
|
||||
workers: 2
|
||||
addons:
|
||||
prometheus_stack: true
|
||||
kiali: true
|
||||
addon_ports:
|
||||
prometheus: 9090 # Prometheus UI
|
||||
grafana: 3000 # Grafana UI
|
||||
kiali: 20001 # Kiali UI
|
||||
---
|
||||
|
||||
## Доступ к приложениям
|
||||
|
||||
### Доступ через Ingress
|
||||
|
||||
1. Создайте Ingress манифест
|
||||
2. Примените через `make k8s manifest apply`
|
||||
3. Запись автоматически добавится в `/etc/hosts`
|
||||
4. Приложение доступно по доменному имени
|
||||
|
||||
### Доступ через port-forward
|
||||
|
||||
Для ClusterIP сервисов:
|
||||
```bash
|
||||
kubectl port-forward -n namespace svc/service-name 8080:80
|
||||
```
|
||||
|
||||
Доступ: http://localhost:8080
|
||||
|
||||
### Доступ внутри кластера
|
||||
|
||||
Из другого pod:
|
||||
```bash
|
||||
kubectl exec -it pod-name -- curl http://service-name.namespace:80
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Кроссплатформенность
|
||||
|
||||
### Поддерживаемые платформы
|
||||
|
||||
- **macOS (Intel & Apple Silicon)** - полная поддержка
|
||||
- **Linux (amd64 & arm64)** - полная поддержка
|
||||
- **Windows** - через WSL2
|
||||
|
||||
### Проблемы на разных платформах
|
||||
|
||||
**Apple Silicon (M1/M2):**
|
||||
- Используется ARM64 образы
|
||||
- Автоматическое определение архитектуры
|
||||
|
||||
**Linux:**
|
||||
- Требуются права на Docker socket
|
||||
- Возможны проблемы с selinux
|
||||
|
||||
---
|
||||
|
||||
## Подробная документация по скриптам
|
||||
|
||||
Для подробного описания работы всех скриптов управления Kubernetes смотрите:
|
||||
|
||||
📖 [Документация по скриптам Kubernetes](k8s-scripts.md)
|
||||
|
||||
Включает:
|
||||
- Описание каждого скрипта
|
||||
- Принцип работы
|
||||
- Примеры использования
|
||||
- Архитектура взаимодействия
|
||||
- Отладка
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Минимальные ресурсы:** Для быстрого тестирования используйте `workers: 0` (только control-plane)
|
||||
2. **Production-like:** Для реалистичных тестов используйте `workers: 2-3`
|
||||
3. **Аддоны:** Включайте только необходимые аддоны для уменьшения времени создания
|
||||
4. **Изоляция:** Каждый preset может иметь свой уникальный кластер с разными настройками
|
||||
5. **Порты:** Используйте разные порты для разных кластеров, если запускаете несколько
|
||||
### 1. Используйте пресеты
|
||||
|
||||
Не создавайте кластеры вручную, используйте пресеты для консистентности.
|
||||
|
||||
### 2. Очищайте после работы
|
||||
|
||||
```bash
|
||||
# После тестирования
|
||||
make k8s destroy kubernetes
|
||||
```
|
||||
|
||||
### 3. Проверяйте статус
|
||||
|
||||
```bash
|
||||
# Регулярно проверяйте статус
|
||||
make k8s status kubernetes
|
||||
```
|
||||
|
||||
### 4. Используйте Helm для сложных приложений
|
||||
|
||||
Для многослойных приложений лучше использовать Helm вместо сырых манифестов.
|
||||
|
||||
### 5. Логируйте изменения
|
||||
|
||||
Все изменения в кластере через `make k8s` автоматически логируются.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Кластер не создается
|
||||
|
||||
**Проблема:** `kind create cluster` завершается с ошибкой
|
||||
|
||||
**Решение:**
|
||||
```bash
|
||||
# Проверить логи
|
||||
docker logs ansible-controller
|
||||
# Проверьте Docker
|
||||
docker ps
|
||||
|
||||
# Проверить доступное место на диске
|
||||
df -h
|
||||
# Перезапустите Docker
|
||||
sudo systemctl restart docker
|
||||
|
||||
# Проверить Docker ресурсы
|
||||
docker system df
|
||||
# Очистите старые кластеры
|
||||
kind delete cluster --all
|
||||
```
|
||||
|
||||
### Проблемы с аддонами
|
||||
### Port-forward не работает
|
||||
|
||||
**Проблема:** Невозможно подключиться к порту
|
||||
|
||||
**Решение:**
|
||||
```bash
|
||||
# Проверить статус подов
|
||||
kubectl get pods -A
|
||||
# Проверьте процессы
|
||||
make k8s portforward list
|
||||
|
||||
# Проверить сервисы
|
||||
kubectl get svc -A
|
||||
# Пересоздайте порты
|
||||
make k8s portforward recreate
|
||||
|
||||
# Проверить порты
|
||||
kubectl get svc -n monitoring
|
||||
# Проверьте, что порт свободен
|
||||
lsof -i :3000
|
||||
```
|
||||
|
||||
### Проблемы с Istio
|
||||
### kubectl не подключается
|
||||
|
||||
**Проблема:** `kubectl get nodes` выдает ошибку
|
||||
|
||||
**Решение:**
|
||||
```bash
|
||||
# Переустановить Istio
|
||||
istioctl uninstall -y --context kind-lab
|
||||
istioctl install -y --set profile=demo --context kind-lab
|
||||
# Проверьте контейнер
|
||||
docker ps | grep k8s-controller
|
||||
|
||||
# Зайдите в контейнер
|
||||
make k8s shell kubernetes
|
||||
|
||||
# Проверьте кластер
|
||||
kubectl get nodes
|
||||
|
||||
# Если не работает, пересоздайте кластер
|
||||
make k8s destroy kubernetes
|
||||
make k8s create kubernetes
|
||||
```
|
||||
|
||||
### Проблемы с Prometheus Stack
|
||||
### Аддоны не устанавливаются
|
||||
|
||||
**Проблема:** Grafana/Prometheus/Kiali не доступны
|
||||
|
||||
**Решение:**
|
||||
```bash
|
||||
# Переустановить
|
||||
helm uninstall monitoring -n monitoring
|
||||
helm upgrade --install monitoring prometheus-community/kube-prometheus-stack \
|
||||
--namespace monitoring --kube-context kind-lab
|
||||
# Проверьте статус кластера
|
||||
make k8s status kubernetes
|
||||
|
||||
# Проверьте pods
|
||||
make k8s shell kubernetes
|
||||
kubectl get pods -n monitoring
|
||||
kubectl logs -n monitoring <pod-name>
|
||||
|
||||
# Пересоздайте кластер
|
||||
make k8s destroy kubernetes
|
||||
make k8s create kubernetes
|
||||
```
|
||||
|
||||
## Дополнительные ресурсы
|
||||
### Ingress не работает
|
||||
|
||||
- [Kind Documentation](https://kind.sigs.k8s.io/docs/)
|
||||
- [Istio Documentation](https://istio.io/latest/docs/)
|
||||
- [Kiali Documentation](https://kiali.io/documentation/)
|
||||
- [Prometheus Operator](https://prometheus-operator.dev/)
|
||||
**Проблема:** Доменные имена не резолвятся
|
||||
|
||||
**Решение:**
|
||||
```bash
|
||||
# Проверьте Ingress
|
||||
make k8s shell kubernetes
|
||||
kubectl get ingress --all-namespaces
|
||||
|
||||
# Добавьте запись в /etc/hosts вручную
|
||||
echo "127.0.0.1 grafana.local #k8s" | sudo tee -a /etc/hosts
|
||||
|
||||
# Очистите DNS кеш
|
||||
sudo killall -HUP mDNSResponder
|
||||
|
||||
# Проверьте доступность
|
||||
curl http://grafana.local:8081
|
||||
```
|
||||
|
||||
### Helm чарты не устанавливаются
|
||||
|
||||
**Проблема:** `helm install` завершается с ошибкой
|
||||
|
||||
**Решение:**
|
||||
```bash
|
||||
# Проверьте репозитории
|
||||
make k8s helmrepo list kubernetes
|
||||
|
||||
# Обновите репозитории
|
||||
make k8s helmrepo update kubernetes stable
|
||||
|
||||
# Проверьте логи
|
||||
make k8s shell kubernetes
|
||||
kubectl logs -l app=<release-name>
|
||||
```
|
||||
|
||||
### Контейнер k8s-controller не запускается
|
||||
|
||||
**Проблема:** `docker: Error response from daemon: ...`
|
||||
|
||||
**Решение:**
|
||||
```bash
|
||||
# Проверьте образ
|
||||
docker images | grep k8s
|
||||
|
||||
# Пересоберите образ
|
||||
make docker build-image IMAGE=k8s-amd64
|
||||
make docker build-image IMAGE=k8s-arm64
|
||||
|
||||
# Проверьте Docker
|
||||
docker system prune -f
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Контакты
|
||||
|
||||
- **Автор:** Сергей Антропов
|
||||
- **Сайт:** https://devops.org.ru
|
||||
- **GitHub:** https://github.com/your-repo
|
||||
|
||||
---
|
||||
|
||||
## Лицензия
|
||||
|
||||
MIT
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## Обзор
|
||||
|
||||
Линтинг ролей - это автоматическая проверка синтаксиса, стиля и соответствия лучшим практикам Ansible. В AnsibleLab используется `ansible-lint` для обеспечения качества кода.
|
||||
Линтинг ролей - это автоматическая проверка синтаксиса, стиля и соответствия лучшим практикам Ansible. В DevOpsLab используется `ansible-lint` для обеспечения качества кода.
|
||||
|
||||
## Команды линтинга
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
## 📋 Обзор
|
||||
|
||||
Molecule - это инструмент для тестирования Ansible ролей в изолированных окружениях. В проекте AnsibleLab используется универсальная конфигурация Molecule с поддержкой множества операционных систем и различных preset'ов для тестирования.
|
||||
Molecule - это инструмент для тестирования Ansible ролей в изолированных окружениях. В проекте DevOpsLab используется универсальная конфигурация Molecule с поддержкой множества операционных систем и различных preset'ов для тестирования.
|
||||
|
||||
### 🔧 Fallback значения
|
||||
|
||||
@@ -64,7 +64,7 @@ platforms:
|
||||
```
|
||||
- **Назначение:** Определяет доступные Docker образы для тестирования
|
||||
- **Поддерживаемые ОС:** Ubuntu, Debian, RHEL, CentOS, AlmaLinux, Rocky Linux, Alt Linux, Astra Linux, RedOS
|
||||
- **Собственные образы:** AnsibleLab создает собственные образы для тестирования
|
||||
- **Собственные образы:** DevOpsLab создает собственные образы для тестирования
|
||||
|
||||
**Provisioner (Провижнер):**
|
||||
```yaml
|
||||
@@ -154,7 +154,7 @@ vars:
|
||||
```
|
||||
- **Назначение:** Определение fallback значений для случаев когда preset файл не найден
|
||||
- **Функция:** Обеспечение работоспособности даже без preset файлов
|
||||
- **Образы:** Собственные образы AnsibleLab для всех поддерживаемых ОС
|
||||
- **Образы:** Собственные образы DevOpsLab для всех поддерживаемых ОС
|
||||
- **Systemd настройки:** Стандартные настройки для systemd контейнеров
|
||||
|
||||
#### Основные задачи:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Мониторинг и диагностика AnsibleLab
|
||||
# Мониторинг и диагностика DevOpsLab
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
@@ -15,7 +15,7 @@ docker info
|
||||
# Проверка запущенных контейнеров
|
||||
docker ps -a
|
||||
|
||||
# Проверка образов AnsibleLab
|
||||
# Проверка образов DevOpsLab
|
||||
docker images | grep inecs/ansible-lab
|
||||
|
||||
# Проверка сетей
|
||||
@@ -368,7 +368,7 @@ echo "✅ Диагностическая информация собрана в:
|
||||
```bash
|
||||
# Быстрая проверка состояния
|
||||
echo "=== Docker Status ===" && docker info | head -5
|
||||
echo "=== AnsibleLab Images ===" && docker images | grep inecs/ansible-lab
|
||||
echo "=== DevOpsLab Images ===" && docker images | grep inecs/ansible-lab
|
||||
echo "=== Roles ===" && ls -1 roles/ | grep -v "\.yml"
|
||||
echo "=== Presets ===" && ls -1 molecule/presets/*.yml 2>/dev/null | wc -l
|
||||
echo "=== Disk Usage ===" && df -h . | tail -1
|
||||
@@ -382,7 +382,7 @@ echo "=== Disk Usage ===" && df -h . | tail -1
|
||||
# Очистка контейнеров Molecule
|
||||
make clean-containers
|
||||
|
||||
# Очистка Docker образов AnsibleLab
|
||||
# Очистка Docker образов DevOpsLab
|
||||
make docker clean
|
||||
|
||||
# Очистка всего Docker
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## Описание
|
||||
|
||||
AnsibleLab поддерживает указание конкретных платформ для хостов в пресетах. Это позволяет автоматически фильтровать хосты, которые не поддерживаются на текущей архитектуре системы.
|
||||
DevOpsLab поддерживает указание конкретных платформ для хостов в пресетах. Это позволяет автоматически фильтровать хосты, которые не поддерживаются на текущей архитектуре системы.
|
||||
|
||||
## Обязательные требования
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
## Описание
|
||||
|
||||
Это руководство описывает работу с зашифрованными секретами в Ansible Vault для проекта AnsibleLab.
|
||||
Это руководство описывает работу с зашифрованными секретами в Ansible Vault для проекта DevOpsLab.
|
||||
|
||||
## Безопасность
|
||||
|
||||
|
||||
19
manifests/test-grafana-ingress.yaml
Normal file
19
manifests/test-grafana-ingress.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: grafana-ingress
|
||||
namespace: monitoring
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/rewrite-target: /
|
||||
spec:
|
||||
rules:
|
||||
- host: grafana.local
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: monitoring-grafana
|
||||
port:
|
||||
number: 80
|
||||
@@ -8,7 +8,7 @@ driver:
|
||||
|
||||
platforms:
|
||||
# Платформы будут созданы динамически через preset файлы
|
||||
# Поддержка собственных образов AnsibleLab
|
||||
# Поддержка собственных образов DevOpsLab
|
||||
- name: placeholder
|
||||
image: ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy
|
||||
pre_build_image: true
|
||||
|
||||
@@ -44,23 +44,23 @@ kind_clusters:
|
||||
istio: true
|
||||
kiali: true
|
||||
prometheus_stack: true
|
||||
ingress_host_http_port: 8081
|
||||
ingress_host_https_port: 8443
|
||||
# Порты для доступа к аддонам извне
|
||||
# Документация: https://devops.org.ru
|
||||
# Ingress HTTP: http://localhost:8081
|
||||
# Ingress HTTPS: https://localhost:8443
|
||||
# Prometheus: http://localhost:9090
|
||||
# Grafana: http://localhost:3000 (admin/admin)
|
||||
# Kiali: http://localhost:20001
|
||||
# Metrics Server: http://localhost:4443
|
||||
addon_ports:
|
||||
ingress_http: 8081
|
||||
ingress_https: 8443
|
||||
prometheus: 9090
|
||||
grafana: 3000
|
||||
kiali: 20001
|
||||
metrics_server: 4443
|
||||
|
||||
hosts:
|
||||
# Стандартный набор - 2 хоста для базового тестирования (стабильные ОС)
|
||||
- name: u1
|
||||
family: ubuntu22
|
||||
groups: [test, web]
|
||||
- name: u2
|
||||
family: debian12
|
||||
groups: [test, web]
|
||||
hosts: []
|
||||
# # Стандартный набор - 2 хоста для базового тестирования (стабильные ОС)
|
||||
# - name: u1
|
||||
# family: ubuntu22
|
||||
# groups: [test, web]
|
||||
|
||||
@@ -124,20 +124,29 @@ def main():
|
||||
}
|
||||
}
|
||||
|
||||
# Добавляем extraPortMappings для ingress если нужно
|
||||
if cluster.get('addons', {}).get('ingress_nginx'):
|
||||
config['nodes'][0]['extraPortMappings'] = [
|
||||
{
|
||||
# Добавляем extraPortMappings для всех портов из addon_ports
|
||||
addon_ports = cluster.get('addon_ports', {})
|
||||
|
||||
# Ingress порты для проброса на host
|
||||
if addon_ports.get('ingress_http') or addon_ports.get('ingress_https'):
|
||||
# Добавляем extraPortMappings к control-plane узлу
|
||||
if 'extraPortMappings' not in config['nodes'][0]:
|
||||
config['nodes'][0]['extraPortMappings'] = []
|
||||
|
||||
if addon_ports.get('ingress_http'):
|
||||
config['nodes'][0]['extraPortMappings'].append({
|
||||
'containerPort': 80,
|
||||
'hostPort': cluster.get('ingress_host_http_port', 8081),
|
||||
'hostPort': addon_ports['ingress_http'],
|
||||
'protocol': 'TCP'
|
||||
},
|
||||
{
|
||||
})
|
||||
if addon_ports.get('ingress_https'):
|
||||
config['nodes'][0]['extraPortMappings'].append({
|
||||
'containerPort': 443,
|
||||
'hostPort': cluster.get('ingress_host_https_port', 8443),
|
||||
'hostPort': addon_ports['ingress_https'],
|
||||
'protocol': 'TCP'
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
# Не добавляем extraPortMappings для портов аддонов - используем port-forward
|
||||
|
||||
# Добавляем worker nodes
|
||||
workers = cluster.get('workers', 0)
|
||||
@@ -160,6 +169,20 @@ def main():
|
||||
print(f"🚀 Создание кластера: {name}")
|
||||
run_cmd(f"kind create cluster --name {name} --config {config_file}")
|
||||
|
||||
# Подключаем контейнер k8s-controller к сети kind
|
||||
print(f"🔗 Подключение контейнера к сети kind...")
|
||||
result = subprocess.run(f"docker network inspect kind", shell=True, capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
# Получаем имя контейнера из аргументов (второй аргумент)
|
||||
controller_name = sys.argv[2] if len(sys.argv) > 2 else "k8s-controller"
|
||||
result = subprocess.run(f"docker network connect kind {controller_name}", shell=True, capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
print(f"✅ Контейнер {controller_name} подключен к сети kind")
|
||||
else:
|
||||
print(f"⚠️ Не удалось подключить контейнер к сети kind: {result.stderr}")
|
||||
else:
|
||||
print(f"⚠️ Сеть kind не найдена")
|
||||
|
||||
# Устанавливаем аддоны
|
||||
addons = cluster.get('addons', {})
|
||||
if not addons:
|
||||
@@ -169,56 +192,49 @@ def main():
|
||||
|
||||
if addons.get('ingress_nginx'):
|
||||
print(" - Installing ingress-nginx")
|
||||
run_cmd(f"kubectl --context kind-{name} apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml")
|
||||
run_cmd(f"kubectl --context kind-{name} -n ingress-nginx rollout status deploy/ingress-nginx-controller --timeout=180s")
|
||||
run_cmd(f"kubectl --server=https://{name}-control-plane:6443 --insecure-skip-tls-verify apply --validate=false -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml")
|
||||
run_cmd(f"kubectl --server=https://{name}-control-plane:6443 --insecure-skip-tls-verify -n ingress-nginx rollout status deploy/ingress-nginx-controller --timeout=180s")
|
||||
|
||||
if addons.get('metrics_server'):
|
||||
print(" - Installing metrics-server")
|
||||
run_cmd(f"kubectl --context kind-{name} apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml")
|
||||
run_cmd(f"kubectl --server=https://{name}-control-plane:6443 --insecure-skip-tls-verify apply --validate=false -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml")
|
||||
patch_json = '{"spec":{"template":{"spec":{"containers":[{"name":"metrics-server","args":["--kubelet-insecure-tls","--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname"]}]}}}}'
|
||||
run_cmd(f"kubectl --context kind-{name} -n kube-system patch deploy metrics-server -p '{patch_json}'")
|
||||
run_cmd(f"kubectl --server=https://{name}-control-plane:6443 --insecure-skip-tls-verify -n kube-system patch deploy metrics-server -p '{patch_json}'")
|
||||
|
||||
if addons.get('istio'):
|
||||
print(" - Installing Istio")
|
||||
run_cmd(f"istioctl install -y --set profile=demo --context kind-{name}")
|
||||
run_cmd(f"kubectl --context kind-{name} -n istio-system rollout status deploy/istiod --timeout=180s")
|
||||
run_cmd(f"kubectl --context kind-{name} -n istio-system rollout status deploy/istio-ingressgateway --timeout=180s")
|
||||
# Генерируем kubeconfig и заменяем 0.0.0.0 на IP control-plane узла
|
||||
run_cmd(f"kind get kubeconfig --name {name} > /tmp/istio-kubeconfig-{name}.yaml")
|
||||
# Получаем IP control-plane узла и заменяем в kubeconfig
|
||||
result = subprocess.run(f"docker inspect {name}-control-plane --format='{{{{.NetworkSettings.Networks.kind.IPAddress}}}}'",
|
||||
shell=True, capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
control_plane_ip = result.stdout.strip()
|
||||
# Заменяем 0.0.0.0 на IP control-plane
|
||||
subprocess.run(f"sed -i 's/0\\.0\\.0\\.0:6443/{control_plane_ip}:6443/g' /tmp/istio-kubeconfig-{name}.yaml", shell=True)
|
||||
# Устанавливаем Istio используя kubeconfig
|
||||
run_cmd(f"KUBECONFIG=/tmp/istio-kubeconfig-{name}.yaml istioctl install -y --set profile=demo")
|
||||
run_cmd(f"kubectl --server=https://{name}-control-plane:6443 --insecure-skip-tls-verify -n istio-system rollout status deploy/istiod --timeout=180s")
|
||||
run_cmd(f"kubectl --server=https://{name}-control-plane:6443 --insecure-skip-tls-verify -n istio-system rollout status deploy/istio-ingressgateway --timeout=180s")
|
||||
|
||||
if addons.get('kiali'):
|
||||
print(" - Installing Kiali")
|
||||
run_cmd(f"kubectl --context kind-{name} create ns istio-system")
|
||||
run_cmd(f"helm upgrade --install kiali-server kiali/kiali-server --namespace istio-system --kube-context kind-{name} --set auth.strategy=anonymous --wait --timeout 180s")
|
||||
subprocess.run(f"kubectl --server=https://{name}-control-plane:6443 --insecure-skip-tls-verify create ns istio-system", shell=True, capture_output=True)
|
||||
# Добавляем Helm репозиторий Kiali
|
||||
run_cmd(f"helm repo add kiali https://kiali.org/helm-charts")
|
||||
run_cmd(f"helm repo update")
|
||||
# Используем исправленный kubeconfig
|
||||
run_cmd(f"KUBECONFIG=/tmp/istio-kubeconfig-{name}.yaml helm upgrade --install kiali-server kiali/kiali-server --namespace istio-system --set auth.strategy=anonymous --wait --timeout 180s")
|
||||
|
||||
if addons.get('prometheus_stack'):
|
||||
print(" - Installing Prometheus Stack")
|
||||
run_cmd(f"helm repo add prometheus-community https://prometheus-community.github.io/helm-charts")
|
||||
run_cmd(f"helm repo update")
|
||||
run_cmd(f"kubectl --context kind-{name} create ns monitoring")
|
||||
run_cmd(f"helm upgrade --install monitoring prometheus-community/kube-prometheus-stack --namespace monitoring --kube-context kind-{name} --set grafana.adminPassword=admin --set grafana.defaultDashboardsTimezone=browser --wait --timeout 600s")
|
||||
run_cmd(f"kubectl --context kind-{name} -n monitoring rollout status deploy/monitoring-grafana --timeout=300s")
|
||||
|
||||
# Настраиваем NodePort для аддонов
|
||||
addon_ports = cluster.get('addon_ports', {})
|
||||
if addon_ports:
|
||||
print("\n🔌 Настройка NodePort для аддонов")
|
||||
|
||||
if 'prometheus' in addon_ports:
|
||||
port = addon_ports['prometheus']
|
||||
print(f" - Prometheus: {port}")
|
||||
patch_json = f'[{{"op": "replace", "path": "/spec/type", "value":"NodePort"}},{{"op": "replace", "path": "/spec/ports/0/nodePort", "value":{port}}}]'
|
||||
run_cmd(f"kubectl --context kind-{name} patch svc -n monitoring monitoring-kube-prom-prometheus --type='json' -p='{patch_json}'")
|
||||
|
||||
if 'grafana' in addon_ports:
|
||||
port = addon_ports['grafana']
|
||||
print(f" - Grafana: {port}")
|
||||
patch_json = f'[{{"op": "replace", "path": "/spec/type", "value":"NodePort"}},{{"op": "replace", "path": "/spec/ports/0/nodePort", "value":{port}}}]'
|
||||
run_cmd(f"kubectl --context kind-{name} patch svc -n monitoring monitoring-grafana --type='json' -p='{patch_json}'")
|
||||
|
||||
if 'kiali' in addon_ports:
|
||||
port = addon_ports['kiali']
|
||||
print(f" - Kiali: {port}")
|
||||
patch_json = f'[{{"op": "replace", "path": "/spec/type", "value":"NodePort"}},{{"op": "replace", "path": "/spec/ports/0/nodePort", "value":{port}}}]'
|
||||
run_cmd(f"kubectl --context kind-{name} patch svc -n istio-system kiali --type='json' -p='{patch_json}'")
|
||||
# Добавляем Helm репозиторий Prometheus
|
||||
subprocess.run(f"helm repo add prometheus-community https://prometheus-community.github.io/helm-charts", shell=True, capture_output=True)
|
||||
subprocess.run(f"helm repo update", shell=True, capture_output=True)
|
||||
subprocess.run(f"kubectl --server=https://{name}-control-plane:6443 --insecure-skip-tls-verify create ns monitoring", shell=True, capture_output=True)
|
||||
# Используем исправленный kubeconfig
|
||||
run_cmd(f"KUBECONFIG=/tmp/istio-kubeconfig-{name}.yaml helm upgrade --install monitoring prometheus-community/kube-prometheus-stack --namespace monitoring --set grafana.adminPassword=admin --set grafana.defaultDashboardsTimezone=browser --wait --timeout 600s")
|
||||
run_cmd(f"kubectl --server=https://{name}-control-plane:6443 --insecure-skip-tls-verify -n monitoring rollout status deploy/monitoring-grafana --timeout=300s")
|
||||
|
||||
print(f"✅ Кластер '{name}' готов!")
|
||||
|
||||
|
||||
300
scripts/k8s_status.py
Executable file
300
scripts/k8s_status.py
Executable file
@@ -0,0 +1,300 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Скрипт для детального отчета о состоянии Kubernetes кластера
|
||||
Автор: Сергей Антропов
|
||||
Сайт: https://devops.org.ru
|
||||
"""
|
||||
import sys
|
||||
import subprocess
|
||||
import json
|
||||
|
||||
def get_cluster_name():
|
||||
"""Получает имя кластера"""
|
||||
result = subprocess.run("docker exec k8s-controller kind get clusters | head -1", shell=True, capture_output=True, text=True)
|
||||
if result.returncode == 0:
|
||||
return result.stdout.strip()
|
||||
return None
|
||||
|
||||
def run_kubectl_cmd(cmd):
|
||||
"""Выполняет команду kubectl внутри контейнера k8s-controller"""
|
||||
cluster_name = get_cluster_name()
|
||||
if cluster_name:
|
||||
# Используем прямой адрес control-plane
|
||||
server = f"https://{cluster_name}-control-plane:6443"
|
||||
cmd_with_server = f"--server={server} --insecure-skip-tls-verify {cmd}"
|
||||
else:
|
||||
cmd_with_server = cmd
|
||||
|
||||
full_cmd = f"docker exec k8s-controller kubectl {cmd_with_server}"
|
||||
result = subprocess.run(full_cmd, shell=True, capture_output=True, text=True)
|
||||
return result.stdout
|
||||
|
||||
def print_section(title):
|
||||
"""Выводит заголовок секции"""
|
||||
print(f"\n{'='*70}")
|
||||
print(f" {title}")
|
||||
print(f"{'='*70}\n")
|
||||
|
||||
def print_subsection(title):
|
||||
"""Выводит подзаголовок"""
|
||||
print(f"\n{'─'*70}")
|
||||
print(f" {title}")
|
||||
print(f"{'─'*70}\n")
|
||||
|
||||
def get_cluster_info():
|
||||
"""Получает информацию о кластере"""
|
||||
print_section("📊 ОБЩАЯ ИНФОРМАЦИЯ О КЛАСТЕРЕ")
|
||||
|
||||
# Версия Kubernetes
|
||||
version = run_kubectl_cmd("version --short")
|
||||
print(version)
|
||||
|
||||
def get_nodes_status():
|
||||
"""Получает статус узлов"""
|
||||
print_section("🖥️ УЗЛЫ КЛАСТЕРА")
|
||||
|
||||
nodes = run_kubectl_cmd("get nodes -o wide")
|
||||
print(nodes)
|
||||
|
||||
# Детальная информация о каждом узле
|
||||
node_names = run_kubectl_cmd("get nodes -o jsonpath='{.items[*].metadata.name}'")
|
||||
if node_names.strip():
|
||||
for node in node_names.strip().split():
|
||||
print_subsection(f"Узел: {node}")
|
||||
node_info = run_kubectl_cmd(f"describe node {node}")
|
||||
print(node_info)
|
||||
|
||||
def get_namespaces():
|
||||
"""Получает список namespace"""
|
||||
print_section("📁 NAMESPACES")
|
||||
|
||||
namespaces = run_kubectl_cmd("get namespaces")
|
||||
print(namespaces)
|
||||
|
||||
def get_pods_by_namespace():
|
||||
"""Получает поды по namespace"""
|
||||
print_section("🪟 PODS")
|
||||
|
||||
# Получаем список namespace
|
||||
namespaces_output = run_kubectl_cmd("get namespaces -o json")
|
||||
try:
|
||||
namespaces_data = json.loads(namespaces_output)
|
||||
namespaces = [ns['metadata']['name'] for ns in namespaces_data['items']]
|
||||
except:
|
||||
namespaces = ['default', 'kube-system', 'kube-public', 'kube-node-lease']
|
||||
|
||||
for ns in namespaces:
|
||||
print_subsection(f"Namespace: {ns}")
|
||||
pods = run_kubectl_cmd(f"get pods -n {ns} -o wide")
|
||||
if pods.strip():
|
||||
print(pods)
|
||||
else:
|
||||
print(" (пусто)")
|
||||
|
||||
def get_services():
|
||||
"""Получает сервисы"""
|
||||
print_section("🔗 SERVICES")
|
||||
|
||||
namespaces_output = run_kubectl_cmd("get namespaces -o json")
|
||||
try:
|
||||
namespaces_data = json.loads(namespaces_output)
|
||||
namespaces = [ns['metadata']['name'] for ns in namespaces_data['items']]
|
||||
except:
|
||||
namespaces = ['default', 'kube-system', 'kube-public', 'kube-node-lease']
|
||||
|
||||
for ns in namespaces:
|
||||
print_subsection(f"Namespace: {ns}")
|
||||
services = run_kubectl_cmd(f"get services -n {ns}")
|
||||
if services.strip():
|
||||
print(services)
|
||||
else:
|
||||
print(" (пусто)")
|
||||
|
||||
def get_ingress():
|
||||
"""Получает Ingress ресурсы"""
|
||||
print_section("🌐 INGRESS")
|
||||
|
||||
namespaces_output = run_kubectl_cmd("get namespaces -o json")
|
||||
try:
|
||||
namespaces_data = json.loads(namespaces_output)
|
||||
namespaces = [ns['metadata']['name'] for ns in namespaces_data['items']]
|
||||
except:
|
||||
namespaces = ['default', 'kube-system', 'kube-public', 'kube-node-lease']
|
||||
|
||||
ingress_found = False
|
||||
for ns in namespaces:
|
||||
ingress = run_kubectl_cmd(f"get ingress -n {ns} 2>/dev/null")
|
||||
if ingress.strip() and "No resources found" not in ingress:
|
||||
ingress_found = True
|
||||
print_subsection(f"Namespace: {ns}")
|
||||
print(ingress)
|
||||
|
||||
if not ingress_found:
|
||||
print(" Ingress ресурсы не найдены")
|
||||
|
||||
def get_pvcs():
|
||||
"""Получает PersistentVolumeClaims"""
|
||||
print_section("💾 VOLUMES (PVC)")
|
||||
|
||||
namespaces_output = run_kubectl_cmd("get namespaces -o json")
|
||||
try:
|
||||
namespaces_data = json.loads(namespaces_output)
|
||||
namespaces = [ns['metadata']['name'] for ns in namespaces_data['items']]
|
||||
except:
|
||||
namespaces = ['default', 'kube-system', 'kube-public', 'kube-node-lease']
|
||||
|
||||
pvc_found = False
|
||||
for ns in namespaces:
|
||||
pvcs = run_kubectl_cmd(f"get pvc -n {ns} 2>/dev/null")
|
||||
if pvcs.strip() and "No resources found" not in pvcs:
|
||||
pvc_found = True
|
||||
print_subsection(f"Namespace: {ns}")
|
||||
print(pvcs)
|
||||
|
||||
if not pvc_found:
|
||||
print(" PVC не найдены")
|
||||
|
||||
def get_deployments():
|
||||
"""Получает Deployments"""
|
||||
print_section("🚀 DEPLOYMENTS")
|
||||
|
||||
namespaces_output = run_kubectl_cmd("get namespaces -o json")
|
||||
try:
|
||||
namespaces_data = json.loads(namespaces_output)
|
||||
namespaces = [ns['metadata']['name'] for ns in namespaces_data['items']]
|
||||
except:
|
||||
namespaces = ['default', 'kube-system', 'kube-public', 'kube-node-lease']
|
||||
|
||||
for ns in namespaces:
|
||||
print_subsection(f"Namespace: {ns}")
|
||||
deployments = run_kubectl_cmd(f"get deployments -n {ns}")
|
||||
if deployments.strip():
|
||||
print(deployments)
|
||||
else:
|
||||
print(" (пусто)")
|
||||
|
||||
def get_daemonsets():
|
||||
"""Получает DaemonSets"""
|
||||
print_section("🔧 DAEMONSETS")
|
||||
|
||||
namespaces_output = run_kubectl_cmd("get namespaces -o json")
|
||||
try:
|
||||
namespaces_data = json.loads(namespaces_output)
|
||||
namespaces = [ns['metadata']['name'] for ns in namespaces_data['items']]
|
||||
except:
|
||||
namespaces = ['default', 'kube-system', 'kube-public', 'kube-node-lease']
|
||||
|
||||
for ns in namespaces:
|
||||
print_subsection(f"Namespace: {ns}")
|
||||
daemonsets = run_kubectl_cmd(f"get daemonsets -n {ns}")
|
||||
if daemonsets.strip():
|
||||
print(daemonsets)
|
||||
else:
|
||||
print(" (пусто)")
|
||||
|
||||
def get_statefulsets():
|
||||
"""Получает StatefulSets"""
|
||||
print_section("🗄️ STATEFULSETS")
|
||||
|
||||
namespaces_output = run_kubectl_cmd("get namespaces -o json")
|
||||
try:
|
||||
namespaces_data = json.loads(namespaces_output)
|
||||
namespaces = [ns['metadata']['name'] for ns in namespaces_data['items']]
|
||||
except:
|
||||
namespaces = ['default', 'kube-system', 'kube-public', 'kube-node-lease']
|
||||
|
||||
statefulsets_found = False
|
||||
for ns in namespaces:
|
||||
statefulsets = run_kubectl_cmd(f"get statefulsets -n {ns} 2>/dev/null")
|
||||
if statefulsets.strip() and "No resources found" not in statefulsets:
|
||||
statefulsets_found = True
|
||||
print_subsection(f"Namespace: {ns}")
|
||||
print(statefulsets)
|
||||
|
||||
if not statefulsets_found:
|
||||
print(" StatefulSets не найдены")
|
||||
|
||||
def get_events():
|
||||
"""Получает события"""
|
||||
print_section("📅 СОБЫТИЯ (EVENTS)")
|
||||
|
||||
namespaces_output = run_kubectl_cmd("get namespaces -o json")
|
||||
try:
|
||||
namespaces_data = json.loads(namespaces_output)
|
||||
namespaces = [ns['metadata']['name'] for ns in namespaces_data['items']]
|
||||
except:
|
||||
namespaces = ['default', 'kube-system', 'kube-public', 'kube-node-lease']
|
||||
|
||||
for ns in namespaces:
|
||||
print_subsection(f"Namespace: {ns}")
|
||||
events = run_kubectl_cmd(f"get events -n {ns} --sort-by='.lastTimestamp' | tail -20")
|
||||
if events.strip():
|
||||
print(events)
|
||||
else:
|
||||
print(" (пусто)")
|
||||
|
||||
def get_helm_releases():
|
||||
"""Получает Helm релизы"""
|
||||
print_section("📦 HELM RELEASES")
|
||||
|
||||
helm_output = run_kubectl_cmd("helm list --all-namespaces 2>/dev/null")
|
||||
if helm_output.strip():
|
||||
print(helm_output)
|
||||
else:
|
||||
print(" Helm релизы не найдены")
|
||||
|
||||
def get_resource_usage():
|
||||
"""Получает использование ресурсов"""
|
||||
print_section("📈 ИСПОЛЬЗОВАНИЕ РЕСУРСОВ")
|
||||
|
||||
try:
|
||||
# Проверяем наличие metrics-server
|
||||
top_nodes = run_kubectl_cmd("top nodes 2>/dev/null")
|
||||
if top_nodes.strip():
|
||||
print_subsection("Узлы:")
|
||||
print(top_nodes)
|
||||
except:
|
||||
print(" metrics-server не установлен или недоступен")
|
||||
|
||||
try:
|
||||
top_pods = run_kubectl_cmd("top pods --all-namespaces 2>/dev/null")
|
||||
if top_pods.strip():
|
||||
print_subsection("Pods (топ-20):")
|
||||
# Берем только первые 20 строк
|
||||
lines = top_pods.strip().split('\n')
|
||||
print('\n'.join(lines[:21])) # + заголовок
|
||||
except:
|
||||
pass
|
||||
|
||||
def main():
|
||||
"""Главная функция"""
|
||||
# Проверяем доступность контейнера
|
||||
result = subprocess.run("docker ps | grep k8s-controller", shell=True, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
print("❌ Контейнер k8s-controller не запущен")
|
||||
sys.exit(1)
|
||||
|
||||
print("="*70)
|
||||
print(" ДЕТАЛЬНЫЙ ОТЧЕТ О СОСТОЯНИИ KUBERNETES КЛАСТЕРА")
|
||||
print("="*70)
|
||||
|
||||
get_cluster_info()
|
||||
get_nodes_status()
|
||||
get_namespaces()
|
||||
get_resource_usage()
|
||||
get_pods_by_namespace()
|
||||
get_deployments()
|
||||
get_daemonsets()
|
||||
get_statefulsets()
|
||||
get_services()
|
||||
get_ingress()
|
||||
get_pvcs()
|
||||
get_events()
|
||||
get_helm_releases()
|
||||
|
||||
print("\n" + "="*70)
|
||||
print(" ОТЧЕТ ЗАВЕРШЕН")
|
||||
print("="*70 + "\n")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
253
scripts/portforward.py
Executable file
253
scripts/portforward.py
Executable file
@@ -0,0 +1,253 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Скрипт для управления port-forward для Kubernetes сервисов
|
||||
Автор: Сергей Антропов
|
||||
Сайт: https://devops.org.ru
|
||||
"""
|
||||
import sys
|
||||
import yaml
|
||||
import subprocess
|
||||
import os
|
||||
import signal
|
||||
import time
|
||||
|
||||
def get_cluster_name():
|
||||
"""Получаем имя кластера из preset файла"""
|
||||
preset_file = "molecule/presets/k8s/kubernetes.yml"
|
||||
with open(preset_file, 'r') as f:
|
||||
preset = yaml.safe_load(f)
|
||||
return preset['kind_clusters'][0]['name']
|
||||
|
||||
def run_cmd(cmd):
|
||||
"""Выполняет команду и возвращает результат"""
|
||||
print(f"[run] {cmd}")
|
||||
result = subprocess.run(cmd, shell=True, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
print(f"[error] {result.stderr}")
|
||||
else:
|
||||
print(result.stdout)
|
||||
return result
|
||||
|
||||
def get_portforward_pids():
|
||||
"""Получает PID процессов port-forward"""
|
||||
result = subprocess.run("ps aux | grep 'kubectl.*port-forward' | grep -v grep", shell=True, capture_output=True, text=True)
|
||||
pids = []
|
||||
for line in result.stdout.split('\n'):
|
||||
if line.strip():
|
||||
pids.append(int(line.split()[1]))
|
||||
return pids
|
||||
|
||||
def list_portforwards():
|
||||
"""Показывает список всех активных port-forward"""
|
||||
pids = get_portforward_pids()
|
||||
if not pids:
|
||||
print("❌ Нет активных port-forward")
|
||||
return
|
||||
|
||||
print("📋 Активные port-forward:")
|
||||
result = subprocess.run("ps aux | grep 'kubectl.*port-forward' | grep -v grep", shell=True, capture_output=True, text=True)
|
||||
for line in result.stdout.split('\n'):
|
||||
if line.strip():
|
||||
print(f" {line}")
|
||||
|
||||
def clear_portforwards():
|
||||
"""Завершает все процессы port-forward"""
|
||||
pids = get_portforward_pids()
|
||||
if not pids:
|
||||
print("❌ Нет активных port-forward")
|
||||
return
|
||||
|
||||
print(f"🗑️ Завершение {len(pids)} процессов port-forward...")
|
||||
for pid in pids:
|
||||
try:
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
print(f"✅ Процесс {pid} завершен")
|
||||
except ProcessLookupError:
|
||||
print(f"⚠️ Процесс {pid} уже не существует")
|
||||
|
||||
# Ждем завершения процессов
|
||||
time.sleep(2)
|
||||
|
||||
# Принудительно убиваем оставшиеся
|
||||
remaining_pids = get_portforward_pids()
|
||||
if remaining_pids:
|
||||
print("⚠️ Принудительное завершение оставшихся процессов...")
|
||||
for pid in remaining_pids:
|
||||
try:
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
print(f"✅ Процесс {pid} принудительно завершен")
|
||||
except ProcessLookupError:
|
||||
pass
|
||||
|
||||
def create_portforwards():
|
||||
"""Создает port-forward для всех сервисов из preset на локальном компьютере"""
|
||||
# Загружаем preset
|
||||
preset_file = "molecule/presets/k8s/kubernetes.yml"
|
||||
with open(preset_file, 'r') as f:
|
||||
preset = yaml.safe_load(f)
|
||||
|
||||
cluster_name = preset['kind_clusters'][0]['name']
|
||||
addon_ports = preset['kind_clusters'][0].get('addon_ports', {})
|
||||
|
||||
# Получаем kubeconfig из контейнера k8s-controller
|
||||
print(f"🔌 Создание port-forward для кластера: {cluster_name}")
|
||||
print("📋 Получение kubeconfig из контейнера k8s-controller...")
|
||||
|
||||
# Копируем kubeconfig из контейнера
|
||||
result = subprocess.run(
|
||||
f"docker exec k8s-controller kind get kubeconfig --name {cluster_name}",
|
||||
shell=True, capture_output=True, text=True
|
||||
)
|
||||
|
||||
if result.returncode != 0:
|
||||
print(f"❌ Ошибка получения kubeconfig: {result.stderr}")
|
||||
return
|
||||
|
||||
# Сохраняем kubeconfig во временный файл
|
||||
kubeconfig_file = "/tmp/kubeconfig-lab.yaml"
|
||||
with open(kubeconfig_file, 'w') as f:
|
||||
f.write(result.stdout)
|
||||
|
||||
# Меняем server с 0.0.0.0 на localhost для локального доступа
|
||||
subprocess.run(f"sed -i.bak 's|server: https://0.0.0.0:6443|server: https://localhost:6443|g' {kubeconfig_file}", shell=True)
|
||||
|
||||
print("✅ Kubeconfig подготовлен")
|
||||
|
||||
# Ingress HTTP (80)
|
||||
if addon_ports.get('ingress_http'):
|
||||
port = addon_ports['ingress_http']
|
||||
print(f" - Ingress HTTP: localhost:{port} -> ingress-nginx-controller:80")
|
||||
subprocess.Popen([
|
||||
"kubectl",
|
||||
f"--kubeconfig={kubeconfig_file}",
|
||||
"port-forward",
|
||||
"-n", "ingress-nginx",
|
||||
"svc/ingress-nginx-controller",
|
||||
f"{port}:80"
|
||||
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
|
||||
# Ingress HTTPS (443)
|
||||
if addon_ports.get('ingress_https'):
|
||||
port = addon_ports['ingress_https']
|
||||
print(f" - Ingress HTTPS: localhost:{port} -> ingress-nginx-controller:443")
|
||||
subprocess.Popen([
|
||||
"kubectl",
|
||||
f"--kubeconfig={kubeconfig_file}",
|
||||
"port-forward",
|
||||
"-n", "ingress-nginx",
|
||||
"svc/ingress-nginx-controller",
|
||||
f"{port}:443"
|
||||
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
|
||||
# Prometheus
|
||||
if addon_ports.get('prometheus'):
|
||||
port = addon_ports['prometheus']
|
||||
print(f" - Prometheus: localhost:{port} -> monitoring/monitoring-kube-prometheus-prometheus:9090")
|
||||
subprocess.Popen([
|
||||
"kubectl",
|
||||
f"--kubeconfig={kubeconfig_file}",
|
||||
"port-forward",
|
||||
"-n", "monitoring",
|
||||
"svc/monitoring-kube-prometheus-prometheus",
|
||||
f"{port}:9090"
|
||||
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
|
||||
# Grafana
|
||||
if addon_ports.get('grafana'):
|
||||
port = addon_ports['grafana']
|
||||
print(f" - Grafana: localhost:{port} -> monitoring/monitoring-grafana:80")
|
||||
subprocess.Popen([
|
||||
"kubectl",
|
||||
f"--kubeconfig={kubeconfig_file}",
|
||||
"port-forward",
|
||||
"-n", "monitoring",
|
||||
"svc/monitoring-grafana",
|
||||
f"{port}:80"
|
||||
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
|
||||
# Kiali
|
||||
if addon_ports.get('kiali'):
|
||||
port = addon_ports['kiali']
|
||||
print(f" - Kiali: localhost:{port} -> istio-system/kiali:20001")
|
||||
subprocess.Popen([
|
||||
"kubectl",
|
||||
f"--kubeconfig={kubeconfig_file}",
|
||||
"port-forward",
|
||||
"-n", "istio-system",
|
||||
"svc/kiali",
|
||||
f"{port}:20001"
|
||||
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
|
||||
# Metrics Server
|
||||
if addon_ports.get('metrics_server'):
|
||||
port = addon_ports['metrics_server']
|
||||
print(f" - Metrics Server: localhost:{port} -> kube-system/metrics-server:4443")
|
||||
subprocess.Popen([
|
||||
"kubectl",
|
||||
f"--kubeconfig={kubeconfig_file}",
|
||||
"port-forward",
|
||||
"-n", "kube-system",
|
||||
"svc/metrics-server",
|
||||
f"{port}:4443"
|
||||
], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
|
||||
time.sleep(2)
|
||||
print("✅ Port-forward создан")
|
||||
list_portforwards()
|
||||
|
||||
def delete_portforward(port):
|
||||
"""Удаляет port-forward для конкретного порта"""
|
||||
pids = get_portforward_pids()
|
||||
if not pids:
|
||||
print(f"❌ Нет активных port-forward на порту {port}")
|
||||
return
|
||||
|
||||
# Находим процесс с нужным портом
|
||||
result = subprocess.run(f"ps aux | grep 'kubectl.*port-forward.*:{port}' | grep -v grep", shell=True, capture_output=True, text=True)
|
||||
if not result.stdout.strip():
|
||||
print(f"❌ Не найден port-forward на порту {port}")
|
||||
return
|
||||
|
||||
# Извлекаем PID
|
||||
pid = int(result.stdout.split()[1])
|
||||
print(f"🗑️ Завершение port-forward на порту {port} (PID: {pid})...")
|
||||
try:
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
print(f"✅ Port-forward на порту {port} завершен")
|
||||
except ProcessLookupError:
|
||||
print(f"⚠️ Процесс {pid} уже не существует")
|
||||
|
||||
def recreate_portforwards():
|
||||
"""Пересоздает port-forward: удаляет существующие и создает заново"""
|
||||
print("🔄 Пересоздание port-forward...")
|
||||
clear_portforwards()
|
||||
time.sleep(1)
|
||||
create_portforwards()
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: portforward.py <create|list|delete|clear|recreate> [port]")
|
||||
sys.exit(1)
|
||||
|
||||
command = sys.argv[1]
|
||||
|
||||
if command == "create":
|
||||
create_portforwards()
|
||||
elif command == "list":
|
||||
list_portforwards()
|
||||
elif command == "clear":
|
||||
clear_portforwards()
|
||||
elif command == "recreate":
|
||||
recreate_portforwards()
|
||||
elif command == "delete":
|
||||
if len(sys.argv) < 3:
|
||||
print("Usage: portforward.py delete <port>")
|
||||
sys.exit(1)
|
||||
port = sys.argv[2]
|
||||
delete_portforward(port)
|
||||
else:
|
||||
print(f"❌ Неизвестная команда: {command}")
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,11 +1,11 @@
|
||||
#!/bin/bash
|
||||
# Автоматическая настройка CI/CD для AnsibleLab
|
||||
# Автоматическая настройка CI/CD для DevOpsLab
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
echo "🔧 Настройка CI/CD для AnsibleLab..."
|
||||
echo "🔧 Настройка CI/CD для DevOpsLab..."
|
||||
|
||||
# Создание директории .github/workflows
|
||||
mkdir -p .github/workflows
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
# Скрипт для тестирования собственных образов AnsibleLab
|
||||
# Скрипт для тестирования собственных образов DevOpsLab
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
@@ -190,7 +190,7 @@ cleanup() {
|
||||
|
||||
# Основная функция
|
||||
main() {
|
||||
log "🚀 Тестирование собственных образов AnsibleLab"
|
||||
log "🚀 Тестирование собственных образов DevOpsLab"
|
||||
echo "=========================================="
|
||||
|
||||
# Проверки
|
||||
|
||||
Reference in New Issue
Block a user