Compare commits

..

8 Commits

Author SHA1 Message Date
Сергей Антропов
591cdaf831 refactor: переименовать контейнер Kubernetes в k8s-controller
Some checks failed
Ansible Testing / lint (push) Has been cancelled
Ansible Testing / test (default) (push) Has been cancelled
Ansible Testing / test (minimal) (push) Has been cancelled
Ansible Testing / test (performance) (push) Has been cancelled
Ansible Testing / deploy-check (push) Has been cancelled
- Все команды make k8s теперь используют единый контейнер k8s-controller
- Упрощена логика именования контейнеров
- Контейнер k8s-controller используется для всех операций с Kubernetes
2025-10-26 08:28:19 +03:00
Сергей Антропов
377e15119a refactor: запуск Python скриптов через контейнер k8s
Some checks failed
Ansible Testing / lint (push) Has been cancelled
Ansible Testing / test (default) (push) Has been cancelled
Ansible Testing / test (minimal) (push) Has been cancelled
Ansible Testing / test (performance) (push) Has been cancelled
Ansible Testing / deploy-check (push) Has been cancelled
- Команда destroy теперь запускает delete_hosts.py через контейнер k8s
- Все Python скрипты выполняются внутри Docker контейнера для единообразия
- Если контейнер не запущен, скрипты выполняются на хосте (fallback)
2025-10-26 08:26:20 +03:00
Сергей Антропов
4ed9c2e0eb feat: добавлена поддержка создания и удаления контейнеров из пресета
Some checks failed
Ansible Testing / lint (push) Has been cancelled
Ansible Testing / test (default) (push) Has been cancelled
Ansible Testing / test (minimal) (push) Has been cancelled
Ansible Testing / test (performance) (push) Has been cancelled
Ansible Testing / deploy-check (push) Has been cancelled
- Добавлено создание контейнеров из секции hosts в create_k8s_cluster.py
- Добавлено удаление контейнеров в команде make k8s destroy
- Создан скрипт scripts/delete_hosts.py для удаления контейнеров
- Контейнеры автоматически создаются в Docker сети из пресета
- Контейнеры удаляются вместе с Kind кластером при make k8s destroy
2025-10-26 08:23:43 +03:00
Сергей Антропов
60c2623fbc refactor: удалить лишние задачи Kind из create.yml и destroy.yml
Some checks failed
Ansible Testing / lint (push) Has been cancelled
Ansible Testing / test (default) (push) Has been cancelled
Ansible Testing / test (minimal) (push) Has been cancelled
Ansible Testing / test (performance) (push) Has been cancelled
Ansible Testing / deploy-check (push) Has been cancelled
- Удалены все задачи по созданию Kind кластеров из create.yml
- Удалены все задачи по удалению Kind кластеров из destroy.yml
- Добавлены комментарии о том, что все операции с Kind выполняются через make k8s
- Теперь Kind кластеры полностью управляются через Python скрипт create_k8s_cluster.py
2025-10-26 08:15:44 +03:00
Сергей Антропов
1b6c83d941 docs: добавить полное руководство по работе с Kubernetes
Some checks failed
Ansible Testing / lint (push) Has been cancelled
Ansible Testing / test (default) (push) Has been cancelled
Ansible Testing / test (minimal) (push) Has been cancelled
Ansible Testing / test (performance) (push) Has been cancelled
Ansible Testing / deploy-check (push) Has been cancelled
- Создано подробное руководство docs/kubernetes-full-guide.md
- Описаны все аспекты работы с Kubernetes кластерами
- Добавлены примеры использования манифестов, Helm, Ingress
- Подробно описана работа с мониторингом (Prometheus, Grafana)
- Документирована работа с Service Mesh (Istio, Kiali)
- Добавлены примеры полных развертываний
- Включены разделы по безопасности и отладке
- Документация на русском языке с большим количеством примеров
2025-10-26 03:37:12 +03:00
Сергей Антропов
714ca43d38 feat: добавить команды для работы с манифестами, Helm и Helm репозиториями
Some checks failed
Ansible Testing / lint (push) Has been cancelled
Ansible Testing / test (default) (push) Has been cancelled
Ansible Testing / test (minimal) (push) Has been cancelled
Ansible Testing / test (performance) (push) Has been cancelled
Ansible Testing / deploy-check (push) Has been cancelled
- Добавлены команды make k8s manifest для работы с манифестами YAML
- Добавлены команды make k8s helm для управления Helm чартами
- Добавлены команды make k8s helmrepo для управления Helm репозиториями
- Создана подробная документация docs/kubernetes-commands.md
- Обновлена справка в Makefile

Поддерживаемые операции:
- manifest: apply, delete, update
- helm: apply, delete, update, rollback, list, status
- helmrepo: add, list, delete, update, packages
2025-10-26 03:33:47 +03:00
Сергей Антропов
881502ad69 feat: добавить поддержку Kubernetes Kind кластеров
Some checks failed
Ansible Testing / lint (push) Has been cancelled
Ansible Testing / test (default) (push) Has been cancelled
Ansible Testing / test (minimal) (push) Has been cancelled
Ansible Testing / test (performance) (push) Has been cancelled
Ansible Testing / deploy-check (push) Has been cancelled
- Создан новый Docker образ k8s для работы с Kind, kubectl, Helm, Istio CLI
- Добавлены команды make k8s: create, destroy, stop, start, status, config, nodes, addon, shell
- Добавлена поддержка пресетов Kubernetes в molecule/presets/k8s/
- Создан скрипт create_k8s_cluster.py для автоматического создания кластеров и установки аддонов
- Добавлена документация docs/kubernetes-kind.md
- Команды kubectl выполняются внутри контейнера k8s, не требуют локальной установки
2025-10-26 03:30:58 +03:00
Сергей Антропов
c1655d2674 chore: обновлена версия проекта с 2.0.0 на 3.0.0
Some checks failed
Ansible Testing / lint (push) Has been cancelled
Ansible Testing / test (default) (push) Has been cancelled
Ansible Testing / test (minimal) (push) Has been cancelled
Ansible Testing / test (performance) (push) Has been cancelled
Ansible Testing / deploy-check (push) Has been cancelled
- Обновлена версия в README.md
- Обновлена версия во всех файлах docs/
- Обновлена версия в dockerfiles/README.md
- Обновлена версия в roles/*/QUICKSTART.md
- Подготовка к версии 3.0.0 с Kubernetes поддержкой

Автор: Сергей Антропов
Сайт: https://devops.org.ru
2025-10-26 01:36:54 +03:00
23 changed files with 2514 additions and 15 deletions

3
.gitignore vendored
View File

@@ -180,3 +180,6 @@ cython_debug/
# Cursor IDE
.cursor/
# Kubernetes kubeconfig
kubeconfig

421
Makefile
View File

@@ -25,6 +25,7 @@ VERSION ?= 0.1.0
AUTHOR ?= "Сергей Антропов"
SITE ?= "https://devops.org.ru"
DOCKER_IMAGE ?= inecs/ansible-lab:ansible-controller-latest
DOCKER_K8S_IMAGE ?= inecs/ansible-lab:k8s-latest
DOCKER_DIND_IMAGE ?= docker:27-dind
CONTAINER_NAME ?= ansible-controller
@@ -40,7 +41,7 @@ DOCKER_BUILDX_BUILDER ?= multiarch-builder
# Базовые образы и их теги
BASE_IMAGES := altlinux/p9 astralinux/astra-1.7 redos/redos:9 registry.access.redhat.com/ubi8/ubi centos:7 quay.io/centos/centos:8 quay.io/centos/centos:stream9 almalinux:8 rockylinux:8 ubuntu:20.04 ubuntu:22.04 ubuntu:24.04 debian:9 debian:10 debian:11 debian:bookworm
.PHONY: role vault git docker presets controller help update-playbooks generate-docs setup-cicd list create delete
.PHONY: role vault git docker presets controller k8s help update-playbooks generate-docs setup-cicd list create delete
# =============================================================================
# КОМАНДЫ ДЛЯ РАБОТЫ С РОЛЯМИ
@@ -904,6 +905,8 @@ docker-get-base-tag:
TAG=$$(docker inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
ansible-controller) \
TAG="latest";; \
k8s) \
TAG="latest";; \
*) \
echo "❌ Неизвестный образ: $(IMAGE)"; \
exit 1;; \
@@ -1012,6 +1015,411 @@ controller:
echo " 💡 Удаляет: контейнеры и сети";; \
esac
# =============================================================================
# КОМАНДЫ ДЛЯ РАБОТЫ С KUBERNETES KIND
# =============================================================================
k8s:
@case "$(word 2, $(MAKECMDGOALS))" in \
create) \
echo "☸️ Создание Kind кластера..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$PRESET_ARG" ]; then \
PRESET=k8s-minimal; \
echo "📋 Используется preset по умолчанию: $$PRESET (минимальный без аддонов)"; \
else \
PRESET=$$PRESET_ARG; \
echo "📋 Используется preset: $$PRESET"; \
fi; \
if [ ! -f "molecule/presets/k8s/$$PRESET.yml" ]; then \
echo "❌ Ошибка: Пресет '$$PRESET' не найден!"; \
echo "💡 Доступные пресеты:"; \
ls -1 molecule/presets/k8s/*.yml 2>/dev/null | sed 's|molecule/presets/k8s/||g' | sed 's|\.yml||g' | sed 's/^/ - /' || echo " - k8s-minimal"; \
exit 1; \
fi; \
CONTAINER_NAME=k8s-controller; \
docker run -d --name $$CONTAINER_NAME --rm \
-v "$(PWD):/workspace" -w /workspace \
-v /var/run/docker.sock:/var/run/docker.sock \
-u root \
-e ANSIBLE_FORCE_COLOR=1 \
-e MOLECULE_PRESET=$$PRESET \
-e MOLECULE_EPHEMERAL_DIRECTORY=/tmp/molecule_workspace \
$(DOCKER_K8S_IMAGE) \
/bin/bash -c 'sleep infinity'; \
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 "💡 Для подключения используйте: make k8s kubeconfig"; \
echo "💡 Для остановки используйте: make k8s stop";; \
destroy) \
echo "🗑️ Удаление Kind кластера и контейнеров..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
PRESET=$${PRESET_ARG:-k8s-minimal}; \
CONTAINER_NAME=k8s-controller; \
if docker ps | grep -q $$CONTAINER_NAME; then \
echo "🗑️ Удаление Kind кластеров..."; \
docker exec $$CONTAINER_NAME bash -c "kind delete clusters --all" 2>/dev/null || true; \
else \
echo "⚠️ Контейнер $$CONTAINER_NAME не запущен"; \
fi; \
docker rm -f $$CONTAINER_NAME 2>/dev/null || true; \
echo "🗑️ Удаление контейнеров из пресета..."; \
if [ -f "molecule/presets/k8s/$$PRESET.yml" ]; then \
if docker ps | grep -q $$CONTAINER_NAME; then \
docker exec $$CONTAINER_NAME bash -c "python3 /workspace/scripts/delete_hosts.py /workspace/molecule/presets/k8s/$$PRESET.yml" 2>/dev/null || true; \
else \
python3 scripts/delete_hosts.py molecule/presets/k8s/$$PRESET.yml 2>/dev/null || true; \
fi; \
fi; \
echo "✅ Удаление завершено";; \
stop) \
echo "🛑 Остановка Kind кластера..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$PRESET_ARG" ]; then \
echo "❌ Ошибка: Укажите пресет"; \
echo "💡 Пример: make k8s stop kubernetes"; \
exit 1; \
fi; \
CONTAINER_NAME=k8s-controller; \
if docker ps | grep -q $$CONTAINER_NAME; then \
docker exec $$CONTAINER_NAME bash -c "kind get clusters | xargs -I {} kind stop cluster --name {}" 2>/dev/null || true; \
echo "✅ Kind кластер остановлен"; \
else \
echo "⚠️ Контейнер $$CONTAINER_NAME не запущен"; \
fi; \
echo "💡 Кластер остановлен, но не удален"; \
echo "💡 Для перезапуска: make k8s start $$PRESET_ARG"; \
echo "💡 Для полного удаления: make k8s destroy $$PRESET_ARG";; \
start) \
echo "🚀 Запуск Kind кластера..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$PRESET_ARG" ]; then \
echo "❌ Ошибка: Укажите пресет"; \
echo "💡 Пример: make k8s start kubernetes"; \
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; \
docker exec $$CONTAINER_NAME bash -c "kind get clusters | xargs -I {} kind start cluster --name {}" 2>/dev/null || true; \
echo "✅ Kind кластер запущен";; \
status) \
echo "📊 Статус Kind кластеров:"; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$PRESET_ARG" ]; then \
echo "❌ Ошибка: Укажите пресет"; \
echo "💡 Пример: make k8s status kubernetes"; \
exit 1; \
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; \
else \
echo "⚠️ Контейнер $$CONTAINER_NAME не запущен"; \
echo "💡 Запустите: make k8s create $$PRESET_ARG"; \
fi;; \
config) \
echo "📋 Получение kubeconfig..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$PRESET_ARG" ]; then \
echo "❌ Ошибка: Укажите пресет"; \
echo "💡 Пример: make k8s config kubernetes"; \
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; \
KUBECONFIG_FILE="$$(pwd)/kubeconfig"; \
docker exec $$CONTAINER_NAME bash -c "kind get kubeconfig" > $$KUBECONFIG_FILE 2>/dev/null || true; \
if [ -f $$KUBECONFIG_FILE ] && [ -s $$KUBECONFIG_FILE ]; then \
echo "✅ kubeconfig сохранен в: $$KUBECONFIG_FILE"; \
echo ""; \
echo "💡 Для использования:"; \
echo " export KUBECONFIG=$$KUBECONFIG_FILE"; \
echo " kubectl get nodes"; \
echo ""; \
echo "💡 Или для однократного использования:"; \
echo " kubectl --kubeconfig=$$KUBECONFIG_FILE get nodes"; \
else \
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))"; \
if [ -z "$$PRESET_ARG" ]; then \
echo "❌ Ошибка: Укажите пресет"; \
echo "💡 Пример: make k8s nodes kubernetes"; \
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); \
docker exec $$CONTAINER_NAME bash -c "CLUSTER_NAME=$$CLUSTER_NAME; kubectl --server=https://\$${CLUSTER_NAME}-control-plane:6443 --insecure-skip-tls-verify get nodes";; \
shell) \
echo "🐚 Открытие shell в контейнере..."; \
PRESET_ARG="$(word 3, $(MAKECMDGOALS))"; \
if [ -z "$$PRESET_ARG" ]; then \
echo "❌ Ошибка: Укажите пресет"; \
echo "💡 Пример: make k8s shell kubernetes"; \
exit 1; \
fi; \
CONTAINER_NAME=k8s-controller; \
if docker ps | grep -q $$CONTAINER_NAME; then \
docker exec -it $$CONTAINER_NAME bash; \
else \
echo "❌ Контейнер $$CONTAINER_NAME не запущен"; \
echo "💡 Запустите: make k8s create $$PRESET_ARG"; \
fi;; \
manifest) \
echo "📄 Работа с манифестами..."; \
MANIFEST_CMD="$(word 3, $(MAKECMDGOALS))"; \
PRESET_ARG="$(word 4, $(MAKECMDGOALS))"; \
MANIFEST_ARG="$(word 5, $(MAKECMDGOALS))"; \
if [ -z "$$MANIFEST_CMD" ] || [ -z "$$PRESET_ARG" ] || [ -z "$$MANIFEST_ARG" ]; then \
echo "❌ Ошибка: Укажите команду, пресет и путь к манифесту"; \
echo "💡 Пример: make k8s manifest apply 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); \
case "$$MANIFEST_CMD" in \
apply) \
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";; \
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"; \
exit 1;; \
esac;; \
helm) \
echo "📦 Работа с Helm..."; \
HELM_CMD="$(word 3, $(MAKECMDGOALS))"; \
PRESET_ARG="$(word 4, $(MAKECMDGOALS))"; \
RELEASE_ARG="$(word 5, $(MAKECMDGOALS))"; \
CHART_ARG="$(word 6, $(MAKECMDGOALS))"; \
if [ -z "$$HELM_CMD" ] || [ -z "$$PRESET_ARG" ]; then \
echo "❌ Ошибка: Укажите команду и пресет"; \
echo "💡 Пример: make k8s helm list kubernetes"; \
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); \
case "$$HELM_CMD" in \
apply) \
if [ -z "$$RELEASE_ARG" ] || [ -z "$$CHART_ARG" ]; then \
echo "❌ Ошибка: Укажите имя релиза и чарт"; \
echo "💡 Пример: make k8s helm apply kubernetes my-release stable/nginx-ingress"; \
exit 1; \
fi; \
echo "📦 Установка Helm чарта: $$CHART_ARG как $$RELEASE_ARG"; \
docker exec $$CONTAINER_NAME bash -c "CLUSTER_NAME=$$CLUSTER_NAME; helm upgrade --install $$RELEASE_ARG $$CHART_ARG --kube-apiserver=https://\$${CLUSTER_NAME}-control-plane:6443 --kube-token=dummy --kube-context=dummy 2>&1 | grep -v '^WARNING' || true";; \
delete) \
if [ -z "$$RELEASE_ARG" ]; then \
echo "❌ Ошибка: Укажите имя релиза"; \
echo "💡 Пример: make k8s helm delete kubernetes my-release"; \
exit 1; \
fi; \
echo "🗑️ Удаление Helm релиза: $$RELEASE_ARG"; \
docker exec $$CONTAINER_NAME bash -c "CLUSTER_NAME=$$CLUSTER_NAME; helm uninstall $$RELEASE_ARG --kube-apiserver=https://\$${CLUSTER_NAME}-control-plane:6443 --kube-token=dummy --kube-context=dummy 2>&1 | grep -v '^WARNING' || true";; \
update) \
if [ -z "$$RELEASE_ARG" ] || [ -z "$$CHART_ARG" ]; then \
echo "❌ Ошибка: Укажите имя релиза и чарт"; \
echo "💡 Пример: make k8s helm update kubernetes my-release stable/nginx-ingress"; \
exit 1; \
fi; \
echo "🔄 Обновление Helm релиза: $$RELEASE_ARG"; \
docker exec $$CONTAINER_NAME bash -c "CLUSTER_NAME=$$CLUSTER_NAME; helm upgrade $$RELEASE_ARG $$CHART_ARG --kube-apiserver=https://\$${CLUSTER_NAME}-control-plane:6443 --kube-token=dummy --kube-context=dummy 2>&1 | grep -v '^WARNING' || true";; \
rollback) \
if [ -z "$$RELEASE_ARG" ]; then \
echo "❌ Ошибка: Укажите имя релиза"; \
echo "💡 Пример: make k8s helm rollback kubernetes my-release"; \
exit 1; \
fi; \
echo "⏪ Откат Helm релиза: $$RELEASE_ARG"; \
docker exec $$CONTAINER_NAME bash -c "CLUSTER_NAME=$$CLUSTER_NAME; helm rollback $$RELEASE_ARG --kube-apiserver=https://\$${CLUSTER_NAME}-control-plane:6443 --kube-token=dummy --kube-context=dummy 2>&1 | grep -v '^WARNING' || true";; \
list) \
echo "📋 Список Helm релизов:"; \
docker exec $$CONTAINER_NAME bash -c "CLUSTER_NAME=$$CLUSTER_NAME; helm list --kube-apiserver=https://\$${CLUSTER_NAME}-control-plane:6443 --kube-token=dummy --kube-context=dummy --all-namespaces 2>&1 | grep -v '^WARNING' || true";; \
status) \
if [ -z "$$RELEASE_ARG" ]; then \
echo "❌ Ошибка: Укажите имя релиза"; \
echo "💡 Пример: make k8s helm status kubernetes my-release"; \
exit 1; \
fi; \
echo "📊 Статус Helm релиза: $$RELEASE_ARG"; \
docker exec $$CONTAINER_NAME bash -c "CLUSTER_NAME=$$CLUSTER_NAME; helm status $$RELEASE_ARG --kube-apiserver=https://\$${CLUSTER_NAME}-control-plane:6443 --kube-token=dummy --kube-context=dummy 2>&1 | grep -v '^WARNING' || true";; \
*) \
echo "❌ Неизвестная команда: $$HELM_CMD"; \
echo "💡 Доступные команды: apply, delete, update, rollback, list, status"; \
exit 1;; \
esac;; \
helmrepo) \
echo "🏪 Работа с Helm репозиториями..."; \
REPO_CMD="$(word 3, $(MAKECMDGOALS))"; \
PRESET_ARG="$(word 4, $(MAKECMDGOALS))"; \
NAME_ARG="$(word 5, $(MAKECMDGOALS))"; \
URL_ARG="$(word 6, $(MAKECMDGOALS))"; \
if [ -z "$$REPO_CMD" ] || [ -z "$$PRESET_ARG" ]; then \
echo "❌ Ошибка: Укажите команду и пресет"; \
echo "💡 Пример: make k8s helmrepo list kubernetes"; \
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; \
case "$$REPO_CMD" in \
add) \
if [ -z "$$NAME_ARG" ] || [ -z "$$URL_ARG" ]; then \
echo "❌ Ошибка: Укажите имя и URL репозитория"; \
echo "💡 Пример: make k8s helmrepo add kubernetes stable https://charts.helm.sh/stable"; \
exit 1; \
fi; \
echo " Добавление Helm репозитория: $$NAME_ARG"; \
docker exec $$CONTAINER_NAME bash -c "helm repo add $$NAME_ARG $$URL_ARG 2>&1 | grep -v '^WARNING' || true; helm repo update";; \
list) \
echo "📋 Список Helm репозиториев:"; \
docker exec $$CONTAINER_NAME bash -c "helm repo list 2>&1 | grep -v '^WARNING' || true";; \
delete) \
if [ -z "$$NAME_ARG" ]; then \
echo "❌ Ошибка: Укажите имя репозитория"; \
echo "💡 Пример: make k8s helmrepo delete kubernetes stable"; \
exit 1; \
fi; \
echo "🗑️ Удаление Helm репозитория: $$NAME_ARG"; \
docker exec $$CONTAINER_NAME bash -c "helm repo remove $$NAME_ARG 2>&1 | grep -v '^WARNING' || true";; \
update) \
echo "🔄 Обновление Helm репозиториев"; \
docker exec $$CONTAINER_NAME bash -c "helm repo update 2>&1 | grep -v '^WARNING' || true";; \
packages) \
if [ -z "$$NAME_ARG" ]; then \
echo "❌ Ошибка: Укажите имя репозитория"; \
echo "💡 Пример: make k8s helmrepo packages kubernetes stable"; \
exit 1; \
fi; \
echo "📦 Пакеты в репозитории: $$NAME_ARG"; \
docker exec $$CONTAINER_NAME bash -c "helm search repo $$NAME_ARG 2>&1 | grep -v '^WARNING' || true";; \
*) \
echo "❌ Неизвестная команда: $$REPO_CMD"; \
echo "💡 Доступные команды: add, list, delete, update, packages"; \
exit 1;; \
esac;; \
*) \
echo "☸️ Доступные команды:"; \
echo ""; \
echo " make k8s create [preset] - создать Kind кластер"; \
echo " 💡 Без параметра: используется k8s-minimal (без аддонов)"; \
echo " 💡 С параметром: используется указанный пресет"; \
echo " 💡 Кластер НЕ удаляется автоматически"; \
echo ""; \
echo " make k8s destroy [preset] - удалить Kind кластер полностью"; \
echo " 💡 Удалит: кластер и контейнер ansible-controller"; \
echo ""; \
echo " make k8s stop [cluster] - остановить Kind кластер (без удаления)"; \
echo " 💡 Можно указать имя кластера или остановить все"; \
echo " 💡 Для перезапуска: make k8s start"; \
echo ""; \
echo " make k8s start [cluster] - запустить остановленный кластер"; \
echo " 💡 Можно указать имя кластера или запустить все"; \
echo ""; \
echo " make k8s status [cluster] - показать статус кластеров"; \
echo " 💡 Можно указать имя конкретного кластера"; \
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"; \
echo ""; \
echo " make k8s shell [preset] - открыть shell в контейнере"; \
echo " 💡 Для: ручного управления kubectl/kind"; \
echo " 💡 Пример: make k8s shell kubernetes"; \
echo ""; \
echo " make k8s manifest [cmd] [preset] [url] - работа с манифестами"; \
echo " 💡 Команды: apply, delete, update"; \
echo " 💡 Пример: make k8s manifest apply kubernetes https://example.com/deploy.yaml"; \
echo ""; \
echo " make k8s helm [cmd] [preset] [release] [chart] - работа с Helm"; \
echo " 💡 Команды: apply, delete, update, rollback, list, status"; \
echo " 💡 Пример: make k8s helm apply kubernetes nginx stable/nginx-ingress"; \
echo ""; \
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 "💡 Примеры:"; \
echo " make k8s create # создать минимальный кластер"; \
echo " make k8s create kubernetes # создать кластер с аддонами"; \
echo " make k8s nodes kubernetes # показать узлы кластера"; \
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 stop kubernetes # остановить кластер"; \
echo " make k8s start kubernetes # запустить кластер"; \
echo " make k8s destroy kubernetes # удалить кластер с пресетом kubernetes";; \
esac
# =============================================================================
# СПРАВКА
# =============================================================================
@@ -1105,6 +1513,17 @@ help:
@echo " make controller run - запустить ansible-controller"
@echo " make controller stop - остановить ansible-controller"
@echo ""
@echo "☸️ KUBERNETES (Kind кластеры):"
@echo " make k8s create [preset] - создать Kind кластер (по умолчанию: k8s-minimal)"
@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 nodes [preset] - показать узлы кластера"
@echo " make k8s config [preset] - получить kubeconfig для подключения"
@echo " make k8s addon [preset] [url] - установить аддон из манифеста"
@echo " make k8s shell [preset] - открыть shell в контейнере k8s"
@echo ""
@echo "💡 ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:"
@echo " make presets list # показать все preset'ы"
@echo " make presets test PRESET=etcd-patroni # тест с etcd-patroni"

View File

@@ -2,7 +2,7 @@
**Автор:** Сергей Антропов
**Сайт:** https://devops.org.ru
**Версия:** 2.0.0
**Версия:** 3.0.0
## 📋 Описание
@@ -16,6 +16,8 @@ AnsibleLab - это универсальная система для разра
- **Автоматическая проверка** синтаксиса Ansible ролей
- **Управление секретами** через Ansible Vault
- **Готовые Docker образы** для разных ОС
- **Kubernetes Kind кластеры** для тестирования в среде Kubernetes
- **Автоматическая установка аддонов** (Istio, Prometheus, Grafana, Kiali и другие)
## 📁 Структура проекта
@@ -501,6 +503,10 @@ make custom-images # справка по собственным
- **[docs/dockerfiles.md](docs/dockerfiles.md)** - Полная документация по Docker образам
### Kubernetes
- **[docs/kubernetes-kind.md](docs/kubernetes-kind.md)** - Документация по работе с Kind кластерами
## 🐳 Docker образы
Проект использует готовые Docker образы для различных ОС:
@@ -620,6 +626,7 @@ MIT License
- ✅ Управление секретами через Ansible Vault
- ✅ Готовые Docker образы для разных ОС
- ✅ CI/CD интеграция
- ✅ Kubernetes Kind кластеры для тестирования
---

View File

@@ -2,7 +2,7 @@
**Автор:** Сергей Антропов
**Сайт:** https://devops.org.ru
**Версия:** 2.0.0
**Версия:** 3.0.0
## 🐳 Обзор

View File

@@ -0,0 +1,73 @@
# Kubernetes Kind Container - Multi-Arch
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
ARG TARGETARCH
FROM ubuntu:22.04
# Обновляем систему
RUN apt-get update && apt-get upgrade -y && apt-get clean
# Устанавливаем базовые пакеты
RUN apt-get install -y \
wget \
curl \
git \
vim \
bash \
ca-certificates \
python3 \
python3-yaml \
file \
apt-transport-https \
gnupg \
lsb-release \
&& apt-get clean
# Устанавливаем Docker CLI
RUN DOCKER_VERSION=20.10.24 && \
if [ "${TARGETARCH}" = "amd64" ]; then \
wget -O /tmp/docker-cli.tgz "https://download.docker.com/linux/static/stable/x86_64/docker-${DOCKER_VERSION}.tgz" && \
tar -xz -C /tmp -f /tmp/docker-cli.tgz && \
mv /tmp/docker/docker /usr/local/bin/ && \
rm -rf /tmp/docker-cli.tgz /tmp/docker; \
else \
wget -O /tmp/docker-cli.tgz "https://download.docker.com/linux/static/stable/aarch64/docker-${DOCKER_VERSION}.tgz" && \
tar -xz -C /tmp -f /tmp/docker-cli.tgz && \
mv /tmp/docker/docker /usr/local/bin/ && \
rm -rf /tmp/docker-cli.tgz /tmp/docker; \
fi && \
chmod +x /usr/local/bin/docker
# Устанавливаем 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/
# Устанавливаем Helm
RUN wget https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 -O - | bash
# Устанавливаем Kind v0.30.0
RUN if [ "${TARGETARCH}" = "amd64" ]; then \
wget -O /usr/local/bin/kind "https://github.com/kubernetes-sigs/kind/releases/download/v0.30.0/kind-linux-amd64"; \
else \
wget -O /usr/local/bin/kind "https://github.com/kubernetes-sigs/kind/releases/download/v0.30.0/kind-linux-arm64"; \
fi && \
chmod +x /usr/local/bin/kind && \
ls -lh /usr/local/bin/kind && \
file /usr/local/bin/kind
# Устанавливаем Istio CLI
RUN ARCH=$(echo ${TARGETARCH} | sed 's/amd64/x86_64/; s/arm64/aarch64/') && \
ISTIO_VERSION=1.22.1 && \
wget -qO- https://istio.io/downloadIstio | ISTIO_VERSION=${ISTIO_VERSION} TARGET_ARCH=${ARCH} sh - && \
mv istio-${ISTIO_VERSION}/bin/istioctl /usr/local/bin/ && \
rm -rf istio-${ISTIO_VERSION}
# Команда по умолчанию
CMD ["sleep", "infinity"]

View File

@@ -2,7 +2,7 @@
**Автор:** Сергей Антропов
**Сайт:** https://devops.org.ru
**Версия:** 2.0.0
**Версия:** 3.0.0
## 🚀 Быстрый старт

View File

@@ -2,7 +2,7 @@
**Автор:** Сергей Антропов
**Сайт:** https://devops.org.ru
**Версия:** 2.0.0
**Версия:** 3.0.0
## 🐳 Обзор

View File

@@ -2,7 +2,7 @@
**Автор:** Сергей Антропов
**Сайт:** https://devops.org.ru
**Версия:** 2.0.0
**Версия:** 3.0.0
## Быстрый старт

View File

@@ -2,7 +2,7 @@
**Автор:** Сергей Антропов
**Сайт:** https://devops.org.ru
**Версия:** 2.0.0
**Версия:** 3.0.0
## 🚀 Установка и настройка

395
docs/kubernetes-commands.md Normal file
View File

@@ -0,0 +1,395 @@
# Команды для работы с Kubernetes
Автор: Сергей Антропов
Сайт: https://devops.org.ru
## Содержание
- [Работа с манифестами](#работа-с-манифестами)
- [Работа с Helm](#работа-с-helm)
- [Работа с Helm репозиториями](#работа-с-helm-репозиториями)
## Работа с манифестами
Команды для применения, удаления и обновления манифестов YAML в кластере.
### Синтаксис
```bash
make k8s manifest [команда] [пресет] [URL_или_путь_к_файлу]
```
### Команды
#### `apply` - Применение манифеста
Применяет манифест YAML к кластеру.
```bash
make k8s manifest apply kubernetes https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
```
**Примеры:**
```bash
# Применение манифеста из URL
make k8s manifest apply kubernetes https://example.com/deploy.yaml
# Применение локального манифеста
make k8s manifest apply kubernetes ./manifests/my-app.yaml
```
#### `delete` - Удаление ресурсов
Удаляет ресурсы из кластера по манифесту.
```bash
make k8s manifest delete kubernetes https://example.com/deploy.yaml
```
#### `update` - Обновление манифеста
Обновляет ресурсы в кластере, используя манифест.
```bash
make k8s manifest update kubernetes https://example.com/deploy.yaml
```
### Примеры использования
```bash
# Установка NGINX Ingress Controller
make k8s manifest apply kubernetes https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
# Удаление ресурсов
make k8s manifest delete kubernetes https://example.com/deploy.yaml
# Обновление конфигурации
make k8s manifest update kubernetes https://example.com/deploy.yaml --force
```
## Работа с Helm
Команды для установки, обновления и управления Helm чартами в кластере.
### Синтаксис
```bash
make k8s helm [команда] [пресет] [релиз] [чант]
```
### Команды
#### `apply` - Установка/обновление чарта
Устанавливает новый релиз или обновляет существующий.
```bash
make k8s helm apply kubernetes my-nginx nginx/nginx-ingress
```
**Параметры:**
- `пресет` - имя пресета кластера
- `релиз` - имя релиза (например: my-nginx)
- `чарт` - имя чарта (например: nginx/nginx-ingress)
**Примеры:**
```bash
# Установка nginx-ingress
make k8s helm apply kubernetes nginx-ingress nginx/nginx-ingress
# Установка с указанием репозитория
make k8s helm apply kubernetes prometheus prometheus-community/prometheus
```
#### `delete` - Удаление релиза
Удаляет Helm релиз из кластера.
```bash
make k8s helm delete kubernetes my-nginx
```
**Примеры:**
```bash
# Удаление релиза
make k8s helm delete kubernetes nginx-ingress
# Удаление с флагом --keep-history
# (не поддерживается в текущей реализации)
```
#### `update` - Обновление релиза
Обновляет существующий Helm релиз.
```bash
make k8s helm update kubernetes my-nginx nginx/nginx-ingress
```
#### `rollback` - Откат релиза
Откатывает релиз к предыдущей версии.
```bash
make k8s helm rollback kubernetes my-nginx
```
**Примеры:**
```bash
# Откат к предыдущей ревизии
make k8s helm rollback kubernetes my-nginx
# Откат к конкретной ревизии (не поддерживается в текущей реализации)
```
#### `list` - Список релизов
Показывает список всех установленных Helm релизов.
```bash
make k8s helm list kubernetes
```
**Пример вывода:**
```
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
nginx-ingress default 1 2024-01-15 12:00:00.000000 +0000 UTC deployed nginx-ingress-0.1.0 1.0.0
```
#### `status` - Статус релиза
Показывает подробную информацию о статусе релиза.
```bash
make k8s helm status kubernetes my-nginx
```
### Примеры использования
```bash
# 1. Установка NGINX Ingress Controller
make k8s helm apply kubernetes nginx-ingress nginx/nginx-ingress
# 2. Проверка статуса
make k8s helm status kubernetes nginx-ingress
# 3. Обновление релиза
make k8s helm update kubernetes nginx-ingress nginx/nginx-ingress
# 4. Просмотр списка релизов
make k8s helm list kubernetes
# 5. Откат релиза
make k8s helm rollback kubernetes nginx-ingress
# 6. Удаление релиза
make k8s helm delete kubernetes nginx-ingress
```
## Работа с Helm репозиториями
Команды для управления Helm репозиториями.
### Синтаксис
```bash
make k8s helmrepo [команда] [пресет] [имя] [URL]
```
### Команды
#### `add` - Добавление репозитория
Добавляет новый Helm репозиторий.
```bash
make k8s helmrepo add kubernetes stable https://charts.helm.sh/stable
```
**Примеры:**
```bash
# Добавление официального репозитория Helm
make k8s helmrepo add kubernetes stable https://charts.helm.sh/stable
# Добавление репозитория Bitnami
make k8s helmrepo add kubernetes bitnami https://charts.bitnami.com/bitnami
# Добавление репозитория NGINX
make k8s helmrepo add kubernetes nginx https://helm.nginx.com/stable
# Добавление репозитория Prometheus
make k8s helmrepo add kubernetes prometheus-community https://prometheus-community.github.io/helm-charts
# Добавление пользовательского репозитория
make k8s helmrepo add kubernetes my-repo https://charts.example.com
```
#### `list` - Список репозиториев
Показывает список всех добавленных Helm репозиториев.
```bash
make k8s helmrepo list kubernetes
```
**Пример вывода:**
```
NAME URL
stable https://charts.helm.sh/stable
bitnami https://charts.bitnami.com/bitnami
nginx https://helm.nginx.com/stable
```
#### `delete` - Удаление репозитория
Удаляет Helm репозиторий.
```bash
make k8s helmrepo delete kubernetes stable
```
**Примеры:**
```bash
# Удаление репозитория
make k8s helmrepo delete kubernetes stable
```
#### `update` - Обновление репозиториев
Обновляет информацию о всех Helm репозиториях.
```bash
make k8s helmrepo update kubernetes
```
**Примеры:**
```bash
# Обновление всех репозиториев
make k8s helmrepo update kubernetes
```
#### `packages` - Список пакетов
Показывает список пакетов в указанном репозитории.
```bash
make k8s helmrepo packages kubernetes stable
```
**Примеры:**
```bash
# Просмотр пакетов в репозитории stable
make k8s helmrepo packages kubernetes stable
# Просмотр пакетов в репозитории nginx
make k8s helmrepo packages kubernetes nginx
# Поиск конкретного пакета
make k8s helmrepo packages kubernetes stable | grep nginx
```
### Примеры использования
```bash
# 1. Добавление нескольких репозиториев
make k8s helmrepo add kubernetes stable https://charts.helm.sh/stable
make k8s helmrepo add kubernetes bitnami https://charts.bitnami.com/bitnami
make k8s helmrepo add kubernetes nginx https://helm.nginx.com/stable
# 2. Просмотр списка репозиториев
make k8s helmrepo list kubernetes
# 3. Обновление репозиториев
make k8s helmrepo update kubernetes
# 4. Поиск пакетов в репозитории
make k8s helmrepo packages kubernetes stable
# 5. Удаление репозитория
make k8s helmrepo delete kubernetes my-custom-repo
# 6. Установка пакета из добавленного репозитория
make k8s helm apply kubernetes my-nginx nginx/nginx-ingress
```
## Полный рабочий пример
```bash
# 1. Создание кластера
make k8s create kubernetes
# 2. Добавление Helm репозиториев
make k8s helmrepo add kubernetes nginx https://helm.nginx.com/stable
make k8s helmrepo add kubernetes bitnami https://charts.bitnami.com/bitnami
# 3. Обновление репозиториев
make k8s helmrepo update kubernetes
# 4. Просмотр доступных пакетов
make k8s helmrepo packages kubernetes nginx
# 5. Установка NGINX Ingress Controller
make k8s helm apply kubernetes nginx-ingress nginx/nginx-ingress
# 6. Проверка статуса
make k8s helm status kubernetes nginx-ingress
# 7. Просмотр списка релизов
make k8s helm list kubernetes
# 8. Применение манифеста
make k8s manifest apply kubernetes https://example.com/deploy.yaml
# 9. Откат релиза (если нужно)
make k8s helm rollback kubernetes nginx-ingress
# 10. Удаление релиза
make k8s helm delete kubernetes nginx-ingress
# 11. Удаление репозитория
make k8s helmrepo delete kubernetes nginx
# 12. Удаление кластера
make k8s destroy kubernetes
```
## Обработка ошибок
### Ошибка: Контейнер не запущен
```
❌ Контейнер k8s-kubernetes не запущен
💡 Запустите: make k8s create kubernetes
```
**Решение:** Запустите кластер перед выполнением команд.
### Ошибка: Неизвестная команда
```
❌ Неизвестная команда: unknown
💡 Доступные команды: apply, delete, update
```
**Решение:** Используйте правильную команду из списка доступных.
### Ошибка: Не указаны параметры
```
❌ Ошибка: Укажите имя релиза и чарт
💡 Пример: make k8s helm apply kubernetes my-release stable/nginx-ingress
```
**Решение:** Укажите все необходимые параметры команды.
## Дополнительная информация
- Все команды kubectl и helm выполняются внутри контейнера `k8s-[пресет]`
- Вам не нужно устанавливать kubectl или helm локально
- Подключение к кластеру происходит через имя узла control-plane
- Используется флаг `--insecure-skip-tls-verify` для обхода проблем с сертификатами
## Автор
Сергей Антропов
Сайт: https://devops.org.ru

View File

@@ -0,0 +1,906 @@
# Полное руководство по работе с Kubernetes кластерами
Автор: Сергей Антропов
Сайт: https://devops.org.ru
## Содержание
- [Введение](#введение)
- [Создание кластера](#создание-кластера)
- [Управление кластером](#управление-кластером)
- [Работа с манифестами](#работа-с-манифестами)
- [Работа с Helm](#работа-с-helm)
- [Настройка Ingress](#настройка-ingress)
- [Мониторинг и аддоны](#мониторинг-и-аддоны)
- [Service Mesh с Istio](#service-mesh-с-istio)
- [Примеры полных развертываний](#примеры-полных-развертываний)
## Введение
AnsibleLab предоставляет полную поддержку создания и управления локальными Kubernetes кластерами на основе Kind (Kubernetes in Docker). Kind позволяет запускать Kubernetes кластеры внутри Docker контейнеров, что идеально подходит для разработки, тестирования и обучения.
### Основные возможности
- Создание многоузловых Kubernetes кластеров
- Установка и управление Helm чартами
- Работа с манифестами YAML
- Настройка Ingress контроллеров
- Установка систем мониторинга (Prometheus, Grafana)
- Развертывание Service Mesh (Istio, Kiali)
- Изоляция сети и безопасность
### Преимущества
- Не требует установки локального Kubernetes
- Быстрое создание и удаление кластеров
- Поддержка многоузловых конфигураций
- Полная совместимость с production окружениями
- Контейнеризация всех инструментов
## Создание кластера
### Базовое создание
Простое создание минимального кластера без дополнительных компонентов:
```bash
make k8s create
```
Создаст кластер с пресетом `k8s-minimal` - один control-plane узел без дополнительных компонентов.
### Создание полнофункционального кластера
Создание кластера с предустановленными компонентами:
```bash
make k8s create kubernetes
```
Этот пресет создает кластер со следующими компонентами:
- 1 control-plane узел
- 2 worker узла
- Ingress NGINX Controller
- Metrics Server
- Istio Service Mesh
- Kiali для визуализации Istio
- Prometheus Stack (Prometheus + Grafana)
### Конфигурация пресета
Пресеты находятся в `molecule/presets/k8s/`. Пример конфигурации:
```yaml
kind_clusters:
- name: lab
workers: 2
api_port: 6443
addons:
ingress_nginx: true
metrics_server: true
istio: true
kiali: true
prometheus_stack: true
ingress_host_http_port: 8081
ingress_host_https_port: 8443
addon_ports:
prometheus: 9090
grafana: 3000
kiali: 20001
```
### Проверка статуса кластера
```bash
# Показать узлы кластера
make k8s nodes kubernetes
# Вывод:
# NAME STATUS ROLES AGE VERSION
# lab-control-plane Ready control-plane 5m v1.34.0
# lab-worker Ready <none> 4m v1.34.0
# lab-worker2 Ready <none> 4m v1.34.0
# Показать подробный статус
make k8s status kubernetes
```
### Подключение к кластеру
```bash
# Получить kubeconfig
make k8s config kubernetes
# Использовать kubeconfig
export KUBECONFIG=$(pwd)/kubeconfig
kubectl get nodes
```
## Управление кластером
### Остановка и запуск
```bash
# Остановить кластер (без удаления)
make k8s stop kubernetes
# Запустить остановленный кластер
make k8s start kubernetes
# Перезапустить кластер
make k8s stop kubernetes && make k8s start kubernetes
```
### Удаление кластера
```bash
# Полное удаление кластера и контейнера
make k8s destroy kubernetes
```
### Получение shell в контейнере
```bash
# Открыть интерактивный shell
make k8s shell kubernetes
# Теперь доступны все команды kubectl, helm, kind внутри контейнера
kubectl get nodes
helm list
kind get clusters
```
## Работа с манифестами
### Применение манифеста
Применение манифеста из URL:
```bash
make k8s manifest apply kubernetes https://example.com/deploy.yaml
```
Применение локального манифеста:
```bash
# Создайте файл example-deployment.yaml
cat > example-deployment.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort
EOF
# Применить манифест
make k8s manifest apply kubernetes ./example-deployment.yaml
```
### Удаление ресурсов
```bash
make k8s manifest delete kubernetes https://example.com/deploy.yaml
```
### Обновление ресурсов
```bash
make k8s manifest update kubernetes https://example.com/deploy.yaml
```
## Работа с Helm
### Добавление Helm репозиториев
Список популярных репозиториев:
```bash
# Официальный Helm репозиторий
make k8s helmrepo add kubernetes stable https://charts.helm.sh/stable
# Bitnami (большая коллекция чартов)
make k8s helmrepo add kubernetes bitnami https://charts.bitnami.com/bitnami
# NGINX Inc
make k8s helmrepo add kubernetes nginx https://helm.nginx.com/stable
# Prometheus Community
make k8s helmrepo add kubernetes prometheus-community https://prometheus-community.github.io/helm-charts
# Istio
make k8s helmrepo add kubernetes istio https://istio-release.storage.googleapis.com/charts
# Информация о репозиториях
make k8s helmrepo list kubernetes
```
### Обновление репозиториев
```bash
make k8s helmrepo update kubernetes
```
### Поиск чартов
```bash
# Просмотр всех чартов в репозитории
make k8s helmrepo packages kubernetes bitnami
# Поиск конкретного чарта
make k8s helmrepo packages kubernetes bitnami | grep nginx
# Поиск в нескольких репозиториях
make k8s helmrepo packages kubernetes bitnami | grep redis
make k8s helmrepo packages kubernetes stable | grep postgresql
```
### Установка Helm чартов
#### Пример 1: Установка Redis
```bash
# Добавить репозиторий
make k8s helmrepo add kubernetes bitnami https://charts.bitnami.com/bitnami
# Обновить индекс
make k8s helmrepo update kubernetes
# Установить Redis
make k8s helm apply kubernetes redis bitnami/redis
# Проверить статус
make k8s helm status kubernetes redis
# Посмотреть список релизов
make k8s helm list kubernetes
```
#### Пример 2: Установка PostgreSQL
```bash
make k8s helm apply kubernetes postgres bitnami/postgresql
make k8s helm status kubernetes postgres
```
#### Пример 3: Установка Nginx Ingress через Helm
```bash
# Добавить репозиторий (если еще не добавлен)
make k8s helmrepo add kubernetes nginx https://helm.nginx.com/stable
# Обновить индекс
make k8s helmrepo update kubernetes
# Установить NGINX Ingress
make k8s helm apply kubernetes nginx-ingress nginx/nginx-ingress-controller
# Проверить
make k8s helm status kubernetes nginx-ingress
```
### Обновление Helm релизов
```bash
# Обновить релиз до последней версии
make k8s helm update kubernetes redis bitnami/redis
# Проверить после обновления
make k8s helm status kubernetes redis
```
### Откат Helm релизов
```bash
# Откатить к предыдущей версии
make k8s helm rollback kubernetes redis
# Проверить статус после отката
make k8s helm status kubernetes redis
```
### Удаление Helm релизов
```bash
# Удалить релиз
make k8s helm delete kubernetes redis
make k8s helm delete kubernetes postgres
```
## Настройка Ingress
### Установка NGINX Ingress Controller
Ingress контроллер обычно устанавливается при создании кластера с пресетом `kubernetes`. Если нужна переустановка:
```bash
# Через манифест
make k8s manifest apply kubernetes \
https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
# Или через Helm
make k8s helmrepo add kubernetes nginx https://helm.nginx.com/stable
make k8s helm apply kubernetes nginx-ingress nginx/nginx-ingress-controller
```
### Создание Ingress ресурса
Создайте файл `example-ingress.yaml`:
```yaml
apiVersion: v1
kind: Service
metadata:
name: hello-service
spec:
selector:
app: hello
ports:
- port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-deployment
spec:
replicas: 2
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
spec:
containers:
- name: hello
image: hashicorp/http-echo:latest
args:
- "-text=Hello from Kubernetes!"
ports:
- containerPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: hello.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello-service
port:
number: 80
```
Примените манифест:
```bash
make k8s manifest apply kubernetes ./example-ingress.yaml
```
Проверьте доступность:
```bash
# Добавьте запись в /etc/hosts
echo "127.0.0.1 hello.local" | sudo tee -a /etc/hosts
# Откройте в браузере или проверьте через curl
curl http://hello.local:8081
```
### TLS Ingress
Создайте TLS сертификат и добавьте в Ingress:
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-tls-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- hello.local
secretName: tls-secret
rules:
- host: hello.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: hello-service
port:
number: 80
```
## Мониторинг и аддоны
### Prometheus Stack
Prometheus Stack устанавливается автоматически при создании кластера с пресетом `kubernetes`.
#### Доступ к Grafana
```bash
# 1. Получите пароль администратора
kubectl --kubeconfig kubeconfig get secret monitoring-grafana \
-n monitoring -o jsonpath="{.data.admin-password}" | base64 -d
# 2. Откройте браузер
# URL: http://localhost:3000
# Username: admin
# Password: [результат из команды выше]
```
#### Доступ к Prometheus
```bash
# URL: http://localhost:9090
# Откройте в браузере для просмотра метрик
```
#### Просмотр метрик
```bash
# Получить список метрик
curl http://localhost:9090/api/v1/label/__name__/values
# Запрос конкретной метрики
curl 'http://localhost:9090/api/v1/query?query=up'
```
### Установка дополнительных инструментов мониторинга
#### Loki для логов
```bash
# Добавить репозиторий Grafana
make k8s helmrepo add kubernetes grafana https://grafana.github.io/helm-charts
# Установить Loki
make k8s helm apply kubernetes loki grafana/loki-stack
# Проверить статус
make k8s helm status kubernetes loki
```
#### Jaeger для трейсинга
```bash
# Добавить репозиторий Jaeger
make k8s helmrepo add kubernetes jaegertracing https://jaegertracing.github.io/helm-charts
# Установить Jaeger
make k8s helm apply kubernetes jaeger jaegertracing/jaeger
# Проверить статус
make k8s helm status kubernetes jaeger
```
## Service Mesh с Istio
### Установка Istio
Istio устанавливается автоматически при создании кластера с пресетом `kubernetes`.
### Ручная установка Istio
```bash
# Добавить репозиторий Istio
make k8s helmrepo add kubernetes istio https://istio-release.storage.googleapis.com/charts
# Установить Istio base
make k8s helm apply kubernetes istio-base istio/base
# Установить Istiod (control plane)
make k8s helm apply kubernetes istiod istio/istiod \
--set values.global.istiod.enableAnalysis=true
# Установить Istio Ingress Gateway
make k8s helm apply kubernetes istio-ingress istio/gateway
```
### Kiali для визуализации Istio
Kiali устанавливается автоматически с пресетом `kubernetes`.
#### Доступ к Kiali
```bash
# URL: http://localhost:20001
# Откройте в браузере для визуализации Service Mesh
# Настройки доступа
# Username: admin
# Password: admin (если используется анонимный доступ)
```
#### Ручная установка Kiali
```bash
# Добавить репозиторий Kiali
make k8s helmrepo add kubernetes kiali https://kiali.org/helm-charts
# Установить Kiali
make k8s helm apply kubernetes kiali-server kiali/kiali-server \
--set auth.strategy=anonymous \
--set deployment.ingress.enabled=true \
--set server.web_root="/"
# Проверить статус
make k8s helm status kubernetes kiali-server
```
### Пример приложения с Istio
Создайте файл `istio-app.yaml`:
```yaml
apiVersion: v1
kind: Namespace
metadata:
name: bookinfo
labels:
istio-injection: enabled
---
apiVersion: v1
kind: Service
metadata:
name: productpage
namespace: bookinfo
spec:
ports:
- port: 9080
name: http
targetPort: 9080
selector:
app: productpage
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: productpage
namespace: bookinfo
spec:
replicas: 1
selector:
matchLabels:
app: productpage
template:
metadata:
labels:
app: productpage
spec:
containers:
- name: productpage
image: istio/examples-bookinfo-productpage-v1:latest
ports:
- containerPort: 9080
```
Примените:
```bash
make k8s manifest apply kubernetes ./istio-app.yaml
```
## Примеры полных развертываний
### Пример 1: WordPress с MySQL
```bash
# 1. Установить MySQL через Helm
make k8s helmrepo add kubernetes bitnami https://charts.bitnami.com/bitnami
make k8s helm apply kubernetes mysql bitnami/mysql \
--set auth.rootPassword=secretpassword
# 2. Создать манифест для WordPress
cat > wordpress.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress
spec:
replicas: 2
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
containers:
- name: wordpress
image: wordpress:latest
env:
- name: WORDPRESS_DB_HOST
value: mysql.default.svc.cluster.local
- name: WORDPRESS_DB_USER
value: root
- name: WORDPRESS_DB_PASSWORD
value: secretpassword
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: wordpress
spec:
selector:
app: wordpress
ports:
- port: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: wordpress-ingress
spec:
rules:
- host: wordpress.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: wordpress
port:
number: 80
EOF
# 3. Применить манифест
make k8s manifest apply kubernetes ./wordpress.yaml
```
### Пример 2: Многоуровневое приложение с мониторингом
```bash
# 1. Установить Redis
make k8s helmrepo add kubernetes bitnami https://charts.bitnami.com/bitnami
make k8s helm apply kubernetes redis bitnami/redis
# 2. Установить PostgreSQL
make k8s helm apply kubernetes postgres bitnami/postgresql
# 3. Создать приложение
cat > app.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
spec:
replicas: 3
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
version: v1
spec:
containers:
- name: api
image: nginx:alpine
ports:
- containerPort: 80
env:
- name: REDIS_HOST
value: redis-master.default.svc.cluster.local
- name: POSTGRES_HOST
value: postgresql-postgresql.default.svc.cluster.local
---
apiVersion: v1
kind: Service
metadata:
name: api-service
spec:
selector:
app: api
ports:
- port: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
spec:
rules:
- host: api.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
EOF
# 4. Применить
make k8s manifest apply kubernetes ./app.yaml
```
### Пример 3: CI/CD с Jenkins в Kubernetes
```bash
# 1. Установить Jenkins
make k8s helmrepo add kubernetes jenkins https://charts.jenkins.io
make k8s helm apply kubernetes jenkins jenkins/jenkins \
--set persistence.enabled=true \
--set controller.installPlugins.enabled=true
# 2. Получить пароль администратора
kubectl --kubeconfig kubeconfig exec \
-n default svc/jenkins -c jenkins -- \
cat /run/secrets/additional/chart-admin-password
```
## Полезные команды и советы
### Мониторинг ресурсов
```bash
# Просмотр использования ресурсов узлами
kubectl --kubeconfig kubeconfig top nodes
# Просмотр использования ресурсов подами
kubectl --kubeconfig kubeconfig top pods
# Детальная информация о узле
kubectl --kubeconfig kubeconfig describe node lab-control-plane
```
### Отладка
```bash
# Просмотр логов пода
kubectl --kubeconfig kubeconfig logs <pod-name>
# Просмотр логов с follow
kubectl --kubeconfig kubeconfig logs -f <pod-name>
# Выполнить команду в поде
kubectl --kubeconfig kubeconfig exec -it <pod-name> -- /bin/sh
# Описание ресурса
kubectl --kubeconfig kubeconfig describe pod <pod-name>
kubectl --kubeconfig kubeconfig describe service <service-name>
```
### Масштабирование
```bash
# Масштабировать Deployment
kubectl --kubeconfig kubeconfig scale deployment <deployment-name> --replicas=5
# Автомасштабирование (требует metrics-server)
kubectl --kubeconfig kubeconfig autoscale deployment <deployment-name> \
--cpu-percent=70 --min=2 --max=10
```
### Экспорт конфигурации
```bash
# Экспортировать ресурс в YAML
kubectl --kubeconfig kubeconfig get deployment <name> -o yaml > exported.yaml
# Экспортировать все ресурсы namespace
kubectl --kubeconfig kubeconfig get all -n <namespace> -o yaml > all-resources.yaml
```
## Безопасность
### Использование Secrets
```bash
# Создать Secret из файла
kubectl --kubeconfig kubeconfig create secret generic my-secret \
--from-file=username=./username.txt \
--from-file=password=./password.txt
# Создать Secret из литерала
kubectl --kubeconfig kubeconfig create secret generic my-secret \
--from-literal=username=admin \
--from-literal=password=secret123
```
### Network Policies
Создайте файл `network-policy.yaml`:
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
role: api
ports:
- protocol: TCP
port: 5432
egress:
- to:
- podSelector:
matchLabels:
role: api
ports:
- protocol: TCP
port: 5432
```
Примените:
```bash
make k8s manifest apply kubernetes ./network-policy.yaml
```
## Заключение
AnsibleLab предоставляет полный набор инструментов для работы с Kubernetes кластерами локально. Вы можете:
- Создавать и управлять кластерами
- Устанавливать и настраивать приложения
- Работать с мониторингом и Service Mesh
- Тестировать перед развертыванием в production
Все инструменты работают внутри Docker контейнеров, что обеспечивает изоляцию и переносимость.
## Автор
Сергей Антропов
Сайт: https://devops.org.ru

297
docs/kubernetes-kind.md Normal file
View File

@@ -0,0 +1,297 @@
# Kubernetes Kind Кластеры
**Автор:** Сергей Антропов
**Сайт:** https://devops.org.ru
## Описание
Проект поддерживает автоматическое создание и управление Kubernetes кластерами на базе [Kind](https://kind.sigs.k8s.io/) для тестирования в изолированной лабораторной среде.
## Возможности
- Создание Kind кластеров с настраиваемым количеством worker-узлов
- Автоматическая установка аддонов:
- Ingress NGINX Controller
- Metrics Server
- Istio Service Mesh
- Kiali (визуализация Istio)
- Prometheus Stack (Prometheus + Grafana)
- Настройка портов для внешнего доступа к аддонам
- Интеграция с Docker контейнерами в одной лабораторной сети
## Команды
### Создание кластера
```bash
# Создание минимального кластера (без аддонов)
make k8s create
# Создание кластера с полным набором аддонов
make k8s create kubernetes
# Использование пользовательского пресета
make k8s create my-custom-preset
```
### Управление кластером
```bash
# Удаление кластера
make k8s destroy [preset]
# Остановка кластера (без удаления)
make k8s stop [cluster]
# Запуск остановленного кластера
make k8s start [cluster]
# Проверка статуса кластера
make k8s status [cluster]
# Получение kubeconfig для подключения
make k8s config [cluster]
# Открытие shell в контейнере
make k8s shell
```
## Конфигурация
### Пресеты Kubernetes хранятся в `molecule/presets/k8s/`
#### Минимальный кластер (`k8s-minimal.yml`)
```yaml
kind_clusters:
- name: minimal
workers: 0 # Только control-plane узел
api_port: 6443
```
#### Полный кластер с аддонами (`kubernetes.yml`)
```yaml
kind_clusters:
- name: lab
workers: 2
api_port: 6443
addons:
ingress_nginx: true
metrics_server: true
istio: true
kiali: true
prometheus_stack: true
ingress_host_http_port: 8081
ingress_host_https_port: 8443
# Порты для внешнего доступа к аддонам
addon_ports:
prometheus: 9090
grafana: 3000
kiali: 20001
```
## Доступ к аддонам
После создания кластера с аддонами, они доступны на следующих портах:
### Prometheus
```bash
# Web UI доступна на порту 9090
http://localhost:9090
```
### 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) │ │
│ └──────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
```
## Настройка портов аддонов
Вы можете настроить порты для внешнего доступа в пресете:
```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
```
## Best Practices
1. **Минимальные ресурсы:** Для быстрого тестирования используйте `workers: 0` (только control-plane)
2. **Production-like:** Для реалистичных тестов используйте `workers: 2-3`
3. **Аддоны:** Включайте только необходимые аддоны для уменьшения времени создания
4. **Изоляция:** Каждый preset может иметь свой уникальный кластер с разными настройками
5. **Порты:** Используйте разные порты для разных кластеров, если запускаете несколько
## Troubleshooting
### Кластер не создается
```bash
# Проверить логи
docker logs ansible-controller
# Проверить доступное место на диске
df -h
# Проверить Docker ресурсы
docker system df
```
### Проблемы с аддонами
```bash
# Проверить статус подов
kubectl get pods -A
# Проверить сервисы
kubectl get svc -A
# Проверить порты
kubectl get svc -n monitoring
```
### Проблемы с Istio
```bash
# Переустановить Istio
istioctl uninstall -y --context kind-lab
istioctl install -y --set profile=demo --context kind-lab
```
### Проблемы с Prometheus Stack
```bash
# Переустановить
helm uninstall monitoring -n monitoring
helm upgrade --install monitoring prometheus-community/kube-prometheus-stack \
--namespace monitoring --kube-context kind-lab
```
## Дополнительные ресурсы
- [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/)

View File

@@ -2,7 +2,7 @@
**Автор:** Сергей Антропов
**Сайт:** https://devops.org.ru
**Версия:** 2.0.0
**Версия:** 3.0.0
## 🔍 Диагностика Docker

View File

@@ -2,7 +2,7 @@
**Автор:** Сергей Антропов
**Сайт:** https://devops.org.ru
**Версия:** 2.0.0
**Версия:** 3.0.0
## Описание

View File

@@ -4,7 +4,8 @@
vars:
# Получаем preset из переменной окружения или используем default
preset_name: "{{ lookup('env', 'MOLECULE_PRESET') | default('default') }}"
preset_file: "/workspace/molecule/presets/{{ preset_name }}.yml"
# Проверяем сначала в папке k8s, затем в основной папке presets
preset_file: "{{ '/workspace/molecule/presets/k8s/' + preset_name + '.yml' if (preset_name in ['k8s-minimal', 'kubernetes', 'k8s-full'] or preset_name.startswith('k8s-')) else '/workspace/molecule/presets/' + preset_name + '.yml' }}"
# Fallback значения если preset файл не найден
docker_network: labnet
@@ -30,6 +31,7 @@
- name: u1
family: debian
groups: [test]
kind_clusters: []
tasks:
# - name: Install required collections
@@ -281,4 +283,4 @@
- Groups: {{ groups_map.keys() | list | join(', ') }}
- Systemd nodes: {{ hosts | selectattr('type','undefined') | list | length }}
- DinD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list | length }}
- DOoD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list | length }}
- DOoD nodes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list | length }}

View File

@@ -4,7 +4,8 @@
vars:
# Получаем preset из переменной окружения или используем default
preset_name: "{{ lookup('env', 'MOLECULE_PRESET') | default('default') }}"
preset_file: "/workspace/molecule/presets/{{ preset_name }}.yml"
# Проверяем сначала в папке k8s, затем в основной папке presets
preset_file: "{{ '/workspace/molecule/presets/k8s/' + preset_name + '.yml' if (preset_name in ['k8s-minimal', 'kubernetes', 'k8s-full'] or preset_name.startswith('k8s-')) else '/workspace/molecule/presets/' + preset_name + '.yml' }}"
# Fallback значения если preset файл не найден
docker_network: labnet
@@ -12,6 +13,7 @@
- name: u1
family: debian
groups: [test]
kind_clusters: []
tasks:
- name: Load preset configuration
@@ -80,4 +82,5 @@
🧹 Cleanup Summary:
- Removed containers: {{ hosts | length }}
- Removed DinD volumes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list | length }}
- Network: {{ docker_network }}
- Network: {{ docker_network }}
- Removed kind clusters: {{ kind_clusters | default([]) | length }}

View File

@@ -33,6 +33,20 @@ systemd_defaults:
tmpfs: ["/run", "/run/lock"]
capabilities: ["SYS_ADMIN"]
# Kind кластеры (опционально)
# kind_clusters:
# - name: lab
# workers: 2
# api_port: 6443
# addons:
# ingress_nginx: true
# metrics_server: true
# istio: true
# kiali: true
# prometheus_stack: true
# ingress_host_http_port: 8081
# ingress_host_https_port: 8443
hosts:
# Стандартный набор - 3 хоста
- name: u1

View File

@@ -0,0 +1,42 @@
---
#description: Минимальный Kind кластер без аддонов
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
docker_network: labnet
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
# systemd-ready образы
images:
alt: "inecs/ansible-lab:alt-linux-latest"
astra: "inecs/ansible-lab:astra-linux-latest"
rhel: "inecs/ansible-lab:rhel-latest"
centos7: "inecs/ansible-lab:centos7-latest"
centos8: "inecs/ansible-lab:centos8-latest"
centos9: "inecs/ansible-lab:centos9-latest"
alma: "inecs/ansible-lab:alma-latest"
rocky: "inecs/ansible-lab:rocky-latest"
redos: "inecs/ansible-lab:redos-latest"
ubuntu20: "inecs/ansible-lab:ubuntu20-latest"
ubuntu22: "inecs/ansible-lab:ubuntu22-latest"
ubuntu24: "inecs/ansible-lab:ubuntu24-latest"
debian9: "inecs/ansible-lab:debian9-latest"
debian10: "inecs/ansible-lab:debian10-latest"
debian11: "inecs/ansible-lab:debian11-latest"
debian12: "inecs/ansible-lab:debian12-latest"
systemd_defaults:
privileged: true
command: "/sbin/init"
volumes:
- "/sys/fs/cgroup:/sys/fs/cgroup:rw"
tmpfs: ["/run", "/run/lock"]
capabilities: ["SYS_ADMIN"]
# Минимальный Kind кластер без аддонов
kind_clusters:
- name: minimal
workers: 0 # Только control-plane
api_port: 6443
hosts: []

View File

@@ -0,0 +1,66 @@
---
#description: Пресет для тестирования с Kubernetes Kind кластером
# Автор: Сергей Антропов
# Сайт: https://devops.org.ru
docker_network: labnet
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
# systemd-ready образы
images:
alt: "inecs/ansible-lab:alt-linux-latest"
astra: "inecs/ansible-lab:astra-linux-latest"
rhel: "inecs/ansible-lab:rhel-latest"
centos7: "inecs/ansible-lab:centos7-latest"
centos8: "inecs/ansible-lab:centos8-latest"
centos9: "inecs/ansible-lab:centos9-latest"
alma: "inecs/ansible-lab:alma-latest"
rocky: "inecs/ansible-lab:rocky-latest"
redos: "inecs/ansible-lab:redos-latest"
ubuntu20: "inecs/ansible-lab:ubuntu20-latest"
ubuntu22: "inecs/ansible-lab:ubuntu22-latest"
ubuntu24: "inecs/ansible-lab:ubuntu24-latest"
debian9: "inecs/ansible-lab:debian9-latest"
debian10: "inecs/ansible-lab:debian10-latest"
debian11: "inecs/ansible-lab:debian11-latest"
debian12: "inecs/ansible-lab:debian12-latest"
systemd_defaults:
privileged: true
command: "/sbin/init"
volumes:
- "/sys/fs/cgroup:/sys/fs/cgroup:rw"
tmpfs: ["/run", "/run/lock"]
capabilities: ["SYS_ADMIN"]
# Kind кластеры с полным набором аддонов
kind_clusters:
- name: lab
workers: 2
api_port: 6443
addons:
ingress_nginx: true
metrics_server: true
istio: true
kiali: true
prometheus_stack: true
ingress_host_http_port: 8081
ingress_host_https_port: 8443
# Порты для доступа к аддонам извне
# Документация: https://devops.org.ru
# Prometheus: http://localhost:9090
# Grafana: http://localhost:3000 (admin/admin)
# Kiali: http://localhost:20001
addon_ports:
prometheus: 9090
grafana: 3000
kiali: 20001
hosts:
# Стандартный набор - 2 хоста для базового тестирования (стабильные ОС)
- name: u1
family: ubuntu22
groups: [test, web]
- name: u2
family: debian12
groups: [test, web]

View File

@@ -2,7 +2,7 @@
**Автор:** Сергей Антропов
**Сайт:** https://devops.org.ru
**Версия:** 2.0.0
**Версия:** 3.0.0
## Что делает роль

View File

@@ -2,7 +2,7 @@
**Автор:** Сергей Антропов
**Сайт:** https://devops.org.ru
**Версия:** 2.0.0
**Версия:** 3.0.0
## Что делает роль?

228
scripts/create_k8s_cluster.py Executable file
View File

@@ -0,0 +1,228 @@
#!/usr/bin/env python3
"""
Скрипт для создания Kind кластеров
Автор: Сергей Антропов
Сайт: https://devops.org.ru
"""
import sys
import yaml
import subprocess
import os
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}")
sys.exit(1)
print(result.stdout)
return result.stdout
def main():
if len(sys.argv) < 3:
print("Usage: create_k8s_cluster.py <preset_file> <container_name>")
sys.exit(1)
preset_file = sys.argv[1]
container_name = sys.argv[2]
print(f"📋 Читаю пресет: {preset_file}")
with open(preset_file, 'r') as f:
preset = yaml.safe_load(f)
# Создаем Docker сеть если её нет
docker_network = preset.get('docker_network', 'labnet')
print(f"\n🌐 Проверка Docker сети: {docker_network}")
result = subprocess.run(f"docker network ls --format '{{{{.Name}}}}' | grep -x {docker_network}",
shell=True, capture_output=True, text=True)
if not result.stdout.strip():
print(f"📡 Создание Docker сети: {docker_network}")
run_cmd(f"docker network create {docker_network}")
else:
print(f"✅ Сеть {docker_network} уже существует")
# Получаем конфигурацию для hosts
hosts = preset.get('hosts', [])
images = preset.get('images', {})
systemd_defaults = preset.get('systemd_defaults', {})
# Создаем контейнеры если определены hosts
if hosts:
print(f"\n🐳 Создание контейнеров (всего: {len(hosts)})")
for host in hosts:
host_name = host['name']
family = host['family']
# Проверяем существование контейнера
result = subprocess.run(f"docker ps -a --format '{{{{.Names}}}}' | grep -x {host_name}",
shell=True, capture_output=True, text=True)
if result.stdout.strip():
print(f"⚠️ Контейнер '{host_name}' уже существует, удаляем старый")
run_cmd(f"docker rm -f {host_name}")
# Получаем образ
image = images.get(family, f"inecs/ansible-lab:{family}-latest")
# Формируем команду docker run
cmd_parts = [
"docker run -d",
f"--name {host_name}",
f"--network {docker_network}",
"--restart=unless-stopped"
]
# Добавляем systemd настройки
if systemd_defaults.get('privileged'):
cmd_parts.append("--privileged")
for vol in systemd_defaults.get('volumes', []):
cmd_parts.append(f"-v {vol}")
for tmpfs in systemd_defaults.get('tmpfs', []):
cmd_parts.append(f"--tmpfs {tmpfs}")
if systemd_defaults.get('capabilities'):
for cap in systemd_defaults['capabilities']:
cmd_parts.append(f"--cap-add {cap}")
cmd_parts.append(image)
# Добавляем command в конец если задан
if systemd_defaults.get('command'):
cmd_parts.append(systemd_defaults['command'])
cmd = " ".join(cmd_parts)
print(f"🚀 Создание контейнера: {host_name}")
run_cmd(cmd)
print(f"✅ Контейнер '{host_name}' создан")
kind_clusters = preset.get('kind_clusters', [])
if not kind_clusters:
print("\n⚠️ В пресете не определены kind кластеры")
print("✅ Создание контейнеров завершено")
sys.exit(0)
os.makedirs("/ansible/.kind", exist_ok=True)
for cluster in kind_clusters:
name = cluster['name']
config_file = f"/ansible/.kind/{name}.yaml"
print(f"\n☸️ Создание конфигурации для кластера: {name}")
# Создаем конфигурацию Kind
config = {
'kind': 'Cluster',
'apiVersion': 'kind.x-k8s.io/v1alpha4',
'nodes': [
{'role': 'control-plane'}
],
'networking': {
'apiServerAddress': '0.0.0.0',
'apiServerPort': cluster.get('api_port', 0)
}
}
# Добавляем extraPortMappings для ingress если нужно
if cluster.get('addons', {}).get('ingress_nginx'):
config['nodes'][0]['extraPortMappings'] = [
{
'containerPort': 80,
'hostPort': cluster.get('ingress_host_http_port', 8081),
'protocol': 'TCP'
},
{
'containerPort': 443,
'hostPort': cluster.get('ingress_host_https_port', 8443),
'protocol': 'TCP'
}
]
# Добавляем worker nodes
workers = cluster.get('workers', 0)
for i in range(workers):
config['nodes'].append({'role': 'worker'})
# Записываем конфигурацию
with open(config_file, 'w') as f:
yaml.dump(config, f)
print(f"✅ Конфигурация сохранена: {config_file}")
# Проверяем существование кластера
result = subprocess.run(f"kind get clusters", shell=True, capture_output=True, text=True)
existing = result.stdout.strip().split('\n') if result.returncode == 0 else []
if name in existing:
print(f"⚠️ Кластер '{name}' уже существует, пропускаю")
else:
print(f"🚀 Создание кластера: {name}")
run_cmd(f"kind create cluster --name {name} --config {config_file}")
# Устанавливаем аддоны
addons = cluster.get('addons', {})
if not addons:
continue
print(f"\n📦 Установка аддонов для кластера: {name}")
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")
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")
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}'")
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")
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")
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}'")
print(f"✅ Кластер '{name}' готов!")
print("\n🎉 Все кластеры созданы!")
if __name__ == '__main__':
main()

44
scripts/delete_hosts.py Normal file
View File

@@ -0,0 +1,44 @@
#!/usr/bin/env python3
"""
Скрипт для удаления контейнеров из секции hosts пресета
Автор: Сергей Антропов
Сайт: https://devops.org.ru
"""
import sys
import yaml
import subprocess
def main():
if len(sys.argv) < 2:
print("Usage: delete_hosts.py <preset_file>")
sys.exit(1)
preset_file = sys.argv[1]
print(f"📋 Читаю пресет: {preset_file}")
with open(preset_file, 'r') as f:
preset = yaml.safe_load(f)
hosts = preset.get('hosts', [])
if not hosts:
print("⚠️ В пресете нет контейнеров для удаления")
sys.exit(0)
print(f"🗑️ Удаление контейнеров (всего: {len(hosts)})")
for host in hosts:
host_name = host['name']
# Проверяем существование контейнера
result = subprocess.run(f"docker ps -a --format '{{{{.Names}}}}' | grep -x {host_name}",
shell=True, capture_output=True, text=True)
if result.stdout.strip():
print(f"🗑️ Удаление контейнера: {host_name}")
subprocess.run(f"docker rm -f {host_name}", shell=True, capture_output=True, text=True)
print(f"✅ Контейнер '{host_name}' удален")
else:
print(f"⚠️ Контейнер '{host_name}' не найден")
print("✅ Удаление завершено")
if __name__ == "__main__":
main()