k8s #1
3
.gitignore
vendored
3
.gitignore
vendored
@@ -180,3 +180,6 @@ cython_debug/
|
||||
# Cursor IDE
|
||||
.cursor/
|
||||
|
||||
# Kubernetes kubeconfig
|
||||
kubeconfig
|
||||
|
||||
|
||||
459
Makefile
459
Makefile
@@ -1,5 +1,5 @@
|
||||
# =============================================================================
|
||||
# AnsibleLab - Универсальная система тестирования Ansible ролей
|
||||
# DevOpsLab - Универсальная система тестирования Ansible ролей
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
# =============================================================================
|
||||
@@ -20,11 +20,12 @@ 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"
|
||||
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,11 +905,15 @@ 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";; \
|
||||
*) \
|
||||
echo "❌ Неизвестный образ: $(IMAGE)"; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
echo "$$TAG"
|
||||
k8s) \
|
||||
TAG="latest";; \
|
||||
k8s-portforward) \
|
||||
TAG="latest";; \
|
||||
*) \
|
||||
echo "❌ Неизвестный образ: $(IMAGE)"; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
echo "$$TAG"
|
||||
|
||||
# Сборка одного образа с multi-arch
|
||||
docker-build-image:
|
||||
@@ -1012,12 +1017,428 @@ 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 "💡 Для создания port-forward: make k8s portforward create"; \
|
||||
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; \
|
||||
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; \
|
||||
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 "📊 Детальный отчет о состоянии кластера..."; \
|
||||
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 \
|
||||
python3 scripts/k8s_status.py; \
|
||||
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;; \
|
||||
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";; \
|
||||
*) \
|
||||
echo "❌ Неизвестная команда: $$MANIFEST_CMD"; \
|
||||
echo "💡 Доступные команды: apply, delete"; \
|
||||
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;; \
|
||||
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 ""; \
|
||||
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 [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 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"; \
|
||||
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 " make k8s portforward [cmd] - управление port-forward"; \
|
||||
echo " 💡 Команды: create, list, clear, recreate, delete [port]"; \
|
||||
echo " 💡 Пример: make k8s portforward create"; \
|
||||
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 manifest apply kubernetes https://example.com/manifest.yaml # установить манифест"; \
|
||||
echo " make k8s stop kubernetes # остановить кластер"; \
|
||||
echo " make k8s start kubernetes # запустить кластер"; \
|
||||
echo " make k8s destroy kubernetes # удалить кластер с пресетом kubernetes";; \
|
||||
esac
|
||||
|
||||
# =============================================================================
|
||||
# СПРАВКА
|
||||
# =============================================================================
|
||||
help:
|
||||
@echo "=========================================="
|
||||
@echo "AnsibleLab - Универсальная система"
|
||||
@echo "DevOpsLab - Универсальная система"
|
||||
@echo "тестирования Ansible ролей"
|
||||
@echo "=========================================="
|
||||
@echo ""
|
||||
@@ -1053,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 - собрать все образы для тестирования"
|
||||
@@ -1105,6 +1526,20 @@ 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 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 "💡 ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:"
|
||||
@echo " make presets list # показать все preset'ы"
|
||||
@echo " make presets test PRESET=etcd-patroni # тест с etcd-patroni"
|
||||
@@ -1130,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"; \
|
||||
@@ -1158,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 хоста)"; \
|
||||
|
||||
202
README.md
202
README.md
@@ -1,26 +1,46 @@
|
||||
# AnsibleLab - Универсальная система тестирования Ansible ролей
|
||||
# DevOpsLab - Универсальная система тестирования Ansible ролей
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
**Версия:** 2.0.0
|
||||
**Версия:** 3.0.0
|
||||
|
||||
## 📋 Описание
|
||||
|
||||
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 образы** для разных ОС
|
||||
|
||||
### 🐳 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 # Создание контейнеров
|
||||
@@ -31,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
|
||||
@@ -62,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 # Этот файл
|
||||
```
|
||||
|
||||
## 🚀 Быстрый старт
|
||||
@@ -82,7 +178,7 @@ AnsibleLab/
|
||||
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd AnsibleLab
|
||||
cd DevOpsLab
|
||||
```
|
||||
|
||||
### 2. Тестирование ролей
|
||||
@@ -109,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
|
||||
@@ -501,6 +618,54 @@ make custom-images # справка по собственным
|
||||
|
||||
- **[docs/dockerfiles.md](docs/dockerfiles.md)** - Полная документация по Docker образам
|
||||
|
||||
### Kubernetes
|
||||
|
||||
**Полная документация:** [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 образы
|
||||
|
||||
Проект использует готовые Docker образы для различных ОС:
|
||||
@@ -620,6 +785,7 @@ MIT License
|
||||
- ✅ Управление секретами через Ansible Vault
|
||||
- ✅ Готовые Docker образы для разных ОС
|
||||
- ✅ CI/CD интеграция
|
||||
- ✅ Kubernetes Kind кластеры для тестирования
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -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,8 +1,8 @@
|
||||
# Docker образы для универсальной системы тестирования AnsibleLab
|
||||
# Docker образы для универсальной системы тестирования DevOpsLab
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
**Версия:** 2.0.0
|
||||
**Версия:** 3.0.0
|
||||
|
||||
## 🐳 Обзор
|
||||
|
||||
@@ -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()
|
||||
73
dockerfiles/k8s/Dockerfile
Normal file
73
dockerfiles/k8s/Dockerfile
Normal 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"]
|
||||
@@ -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,8 +1,8 @@
|
||||
# Создание и разработка ролей для AnsibleLab
|
||||
# Создание и разработка ролей для DevOpsLab
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
**Версия:** 2.0.0
|
||||
**Версия:** 3.0.0
|
||||
|
||||
## 🚀 Быстрый старт
|
||||
|
||||
@@ -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,18 +1,27 @@
|
||||
# Docker образы AnsibleLab
|
||||
# Docker образы DevOpsLab
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
**Версия:** 2.0.0
|
||||
**Версия:** 3.0.0
|
||||
|
||||
## 🐳 Обзор
|
||||
|
||||
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,8 +1,8 @@
|
||||
# Примеры использования AnsibleLab
|
||||
# Примеры использования DevOpsLab
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
**Версия:** 2.0.0
|
||||
**Версия:** 3.0.0
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
@@ -304,7 +304,7 @@ make vault check
|
||||
|
||||
## Заключение
|
||||
|
||||
Эти примеры демонстрируют основные возможности AnsibleLab:
|
||||
Эти примеры демонстрируют основные возможности DevOpsLab:
|
||||
|
||||
1. **Быстрое тестирование** с minimal preset
|
||||
2. **Полное тестирование** с all-images preset
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
# Быстрый старт с AnsibleLab
|
||||
# Быстрый старт с DevOpsLab
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
**Версия:** 2.0.0
|
||||
**Версия:** 3.0.0
|
||||
|
||||
## 🚀 Установка и настройка
|
||||
|
||||
### 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
|
||||
```
|
||||
395
docs/kubernetes-commands.md
Normal file
395
docs/kubernetes-commands.md
Normal 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
|
||||
906
docs/kubernetes-full-guide.md
Normal file
906
docs/kubernetes-full-guide.md
Normal file
@@ -0,0 +1,906 @@
|
||||
# Полное руководство по работе с Kubernetes кластерами
|
||||
|
||||
Автор: Сергей Антропов
|
||||
Сайт: https://devops.org.ru
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Введение](#введение)
|
||||
- [Создание кластера](#создание-кластера)
|
||||
- [Управление кластером](#управление-кластером)
|
||||
- [Работа с манифестами](#работа-с-манифестами)
|
||||
- [Работа с Helm](#работа-с-helm)
|
||||
- [Настройка Ingress](#настройка-ingress)
|
||||
- [Мониторинг и аддоны](#мониторинг-и-аддоны)
|
||||
- [Service Mesh с Istio](#service-mesh-с-istio)
|
||||
- [Примеры полных развертываний](#примеры-полных-развертываний)
|
||||
|
||||
## Введение
|
||||
|
||||
DevOpsLab предоставляет полную поддержку создания и управления локальными 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
|
||||
```
|
||||
|
||||
## Заключение
|
||||
|
||||
DevOpsLab предоставляет полный набор инструментов для работы с Kubernetes кластерами локально. Вы можете:
|
||||
|
||||
- Создавать и управлять кластерами
|
||||
- Устанавливать и настраивать приложения
|
||||
- Работать с мониторингом и Service Mesh
|
||||
- Тестировать перед развертыванием в production
|
||||
|
||||
Все инструменты работают внутри Docker контейнеров, что обеспечивает изоляцию и переносимость.
|
||||
|
||||
## Автор
|
||||
|
||||
Сергей Антропов
|
||||
Сайт: https://devops.org.ru
|
||||
794
docs/kubernetes-kind.md
Normal file
794
docs/kubernetes-kind.md
Normal file
@@ -0,0 +1,794 @@
|
||||
# Kubernetes Kind Кластеры
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** 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, 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 [preset]
|
||||
|
||||
# Запуск остановленного кластера
|
||||
make k8s start [preset]
|
||||
|
||||
# Детальный отчет о состоянии
|
||||
make k8s status [preset]
|
||||
|
||||
# Показать узлы кластера
|
||||
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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Конфигурация
|
||||
|
||||
### Пресеты
|
||||
|
||||
Пресеты находятся в `molecule/presets/k8s/`:
|
||||
|
||||
**kubernetes.yml** - полный набор аддонов:
|
||||
- Ingress NGINX
|
||||
- Metrics Server
|
||||
- Istio
|
||||
- Kiali
|
||||
- Prometheus + Grafana
|
||||
|
||||
### Структура пресета
|
||||
|
||||
```yaml
|
||||
k8s_cluster:
|
||||
name: lab
|
||||
nodes: 1
|
||||
|
||||
addons:
|
||||
ingress: true
|
||||
metrics_server: true
|
||||
istio: true
|
||||
kiali: true
|
||||
prometheus_stack: true
|
||||
|
||||
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`:
|
||||
|
||||
```yaml
|
||||
k8s_cluster:
|
||||
name: my-cluster
|
||||
nodes: 2
|
||||
|
||||
addons:
|
||||
ingress: true
|
||||
metrics_server: false
|
||||
istio: false
|
||||
kiali: false
|
||||
prometheus_stack: false
|
||||
```
|
||||
|
||||
Использование:
|
||||
```bash
|
||||
make k8s create my-preset
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Архитектура
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Локальная машина │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────┐ │
|
||||
│ │ 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** - маршрутизация трафика внутрь кластера
|
||||
|
||||
---
|
||||
|
||||
## Доступ к приложениям
|
||||
|
||||
### Доступ через 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. Используйте пресеты
|
||||
|
||||
Не создавайте кластеры вручную, используйте пресеты для консистентности.
|
||||
|
||||
### 2. Очищайте после работы
|
||||
|
||||
```bash
|
||||
# После тестирования
|
||||
make k8s destroy kubernetes
|
||||
```
|
||||
|
||||
### 3. Проверяйте статус
|
||||
|
||||
```bash
|
||||
# Регулярно проверяйте статус
|
||||
make k8s status kubernetes
|
||||
```
|
||||
|
||||
### 4. Используйте Helm для сложных приложений
|
||||
|
||||
Для многослойных приложений лучше использовать Helm вместо сырых манифестов.
|
||||
|
||||
### 5. Логируйте изменения
|
||||
|
||||
Все изменения в кластере через `make k8s` автоматически логируются.
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Кластер не создается
|
||||
|
||||
**Проблема:** `kind create cluster` завершается с ошибкой
|
||||
|
||||
**Решение:**
|
||||
```bash
|
||||
# Проверьте Docker
|
||||
docker ps
|
||||
|
||||
# Перезапустите Docker
|
||||
sudo systemctl restart docker
|
||||
|
||||
# Очистите старые кластеры
|
||||
kind delete cluster --all
|
||||
```
|
||||
|
||||
### Port-forward не работает
|
||||
|
||||
**Проблема:** Невозможно подключиться к порту
|
||||
|
||||
**Решение:**
|
||||
```bash
|
||||
# Проверьте процессы
|
||||
make k8s portforward list
|
||||
|
||||
# Пересоздайте порты
|
||||
make k8s portforward recreate
|
||||
|
||||
# Проверьте, что порт свободен
|
||||
lsof -i :3000
|
||||
```
|
||||
|
||||
### kubectl не подключается
|
||||
|
||||
**Проблема:** `kubectl get nodes` выдает ошибку
|
||||
|
||||
**Решение:**
|
||||
```bash
|
||||
# Проверьте контейнер
|
||||
docker ps | grep k8s-controller
|
||||
|
||||
# Зайдите в контейнер
|
||||
make k8s shell kubernetes
|
||||
|
||||
# Проверьте кластер
|
||||
kubectl get nodes
|
||||
|
||||
# Если не работает, пересоздайте кластер
|
||||
make k8s destroy kubernetes
|
||||
make k8s create kubernetes
|
||||
```
|
||||
|
||||
### Аддоны не устанавливаются
|
||||
|
||||
**Проблема:** Grafana/Prometheus/Kiali не доступны
|
||||
|
||||
**Решение:**
|
||||
```bash
|
||||
# Проверьте статус кластера
|
||||
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 не работает
|
||||
|
||||
**Проблема:** Доменные имена не резолвятся
|
||||
|
||||
**Решение:**
|
||||
```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,8 +1,8 @@
|
||||
# Мониторинг и диагностика AnsibleLab
|
||||
# Мониторинг и диагностика DevOpsLab
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
**Версия:** 2.0.0
|
||||
**Версия:** 3.0.0
|
||||
|
||||
## 🔍 Диагностика Docker
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
**Версия:** 2.0.0
|
||||
**Версия:** 3.0.0
|
||||
|
||||
## Описание
|
||||
|
||||
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
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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 }}
|
||||
@@ -8,7 +8,7 @@ driver:
|
||||
|
||||
platforms:
|
||||
# Платформы будут созданы динамически через preset файлы
|
||||
# Поддержка собственных образов AnsibleLab
|
||||
# Поддержка собственных образов DevOpsLab
|
||||
- name: placeholder
|
||||
image: ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy
|
||||
pre_build_image: true
|
||||
|
||||
@@ -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
|
||||
|
||||
42
molecule/presets/k8s/k8s-minimal.yml
Normal file
42
molecule/presets/k8s/k8s-minimal.yml
Normal 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: []
|
||||
66
molecule/presets/k8s/kubernetes.yml
Normal file
66
molecule/presets/k8s/kubernetes.yml
Normal 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 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]
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
**Версия:** 2.0.0
|
||||
**Версия:** 3.0.0
|
||||
|
||||
## Что делает роль
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Автор:** Сергей Антропов
|
||||
**Сайт:** https://devops.org.ru
|
||||
**Версия:** 2.0.0
|
||||
**Версия:** 3.0.0
|
||||
|
||||
## Что делает роль?
|
||||
|
||||
|
||||
244
scripts/create_k8s_cluster.py
Executable file
244
scripts/create_k8s_cluster.py
Executable file
@@ -0,0 +1,244 @@
|
||||
#!/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 для всех портов из 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': addon_ports['ingress_http'],
|
||||
'protocol': 'TCP'
|
||||
})
|
||||
if addon_ports.get('ingress_https'):
|
||||
config['nodes'][0]['extraPortMappings'].append({
|
||||
'containerPort': 443,
|
||||
'hostPort': addon_ports['ingress_https'],
|
||||
'protocol': 'TCP'
|
||||
})
|
||||
|
||||
# Не добавляем extraPortMappings для портов аддонов - используем port-forward
|
||||
|
||||
# Добавляем 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}")
|
||||
|
||||
# Подключаем контейнер 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:
|
||||
continue
|
||||
|
||||
print(f"\n📦 Установка аддонов для кластера: {name}")
|
||||
|
||||
if addons.get('ingress_nginx'):
|
||||
print(" - Installing ingress-nginx")
|
||||
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 --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 --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")
|
||||
# Генерируем 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")
|
||||
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")
|
||||
# Добавляем 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}' готов!")
|
||||
|
||||
print("\n🎉 Все кластеры созданы!")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
44
scripts/delete_hosts.py
Normal file
44
scripts/delete_hosts.py
Normal 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()
|
||||
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