Compare commits
42 Commits
43ded4dde0
...
1ab2353280
| Author | SHA1 | Date | |
|---|---|---|---|
| 1ab2353280 | |||
|
|
37ff18c91b | ||
|
|
4e86b7f0c3 | ||
|
|
85b68dc4d0 | ||
|
|
a56de6183a | ||
|
|
d8e1052e7b | ||
|
|
c2ab17b7b6 | ||
|
|
c2a84a3aee | ||
|
|
0ffe1f1a90 | ||
|
|
df7473fbd9 | ||
|
|
eca556cca7 | ||
|
|
fcf3f33e80 | ||
|
|
6ef4090fb2 | ||
|
|
9677aea281 | ||
|
|
fd80db220a | ||
|
|
4ca882b5f7 | ||
|
|
3b8c6e52ea | ||
|
|
02eab55d73 | ||
|
|
e3d393ef91 | ||
|
|
6d55f924e5 | ||
|
|
69a589974e | ||
|
|
3238b3903a | ||
|
|
ab1231fce5 | ||
|
|
44fff158ce | ||
|
|
604c7816be | ||
|
|
06bfc00b5a | ||
|
|
ebed1f76ab | ||
|
|
69b547dda6 | ||
|
|
d48c273e50 | ||
|
|
87002cb9b3 | ||
|
|
e2b9d94075 | ||
|
|
791504abf6 | ||
|
|
33e329c091 | ||
|
|
5c8862e9bf | ||
|
|
591cdaf831 | ||
|
|
377e15119a | ||
|
|
4ed9c2e0eb | ||
|
|
60c2623fbc | ||
|
|
1b6c83d941 | ||
|
|
714ca43d38 | ||
|
|
881502ad69 | ||
|
|
c1655d2674 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -180,3 +180,6 @@ cython_debug/
|
|||||||
# Cursor IDE
|
# Cursor IDE
|
||||||
.cursor/
|
.cursor/
|
||||||
|
|
||||||
|
# Kubernetes kubeconfig
|
||||||
|
kubeconfig
|
||||||
|
|
||||||
|
|||||||
459
Makefile
459
Makefile
@@ -1,5 +1,5 @@
|
|||||||
# =============================================================================
|
# =============================================================================
|
||||||
# AnsibleLab - Универсальная система тестирования Ansible ролей
|
# DevOpsLab - Универсальная система тестирования Ansible ролей
|
||||||
# Автор: Сергей Антропов
|
# Автор: Сергей Антропов
|
||||||
# Сайт: https://devops.org.ru
|
# Сайт: https://devops.org.ru
|
||||||
# =============================================================================
|
# =============================================================================
|
||||||
@@ -20,11 +20,12 @@ WHITE := \033[0;37m
|
|||||||
RESET := \033[0m
|
RESET := \033[0m
|
||||||
|
|
||||||
# Глобальные переменные
|
# Глобальные переменные
|
||||||
PROJECT_NAME ?= ansible-lab
|
PROJECT_NAME ?= devops-lab
|
||||||
VERSION ?= 0.1.0
|
VERSION ?= 0.1.0
|
||||||
AUTHOR ?= "Сергей Антропов"
|
AUTHOR ?= "Сергей Антропов"
|
||||||
SITE ?= "https://devops.org.ru"
|
SITE ?= "https://devops.org.ru"
|
||||||
DOCKER_IMAGE ?= inecs/ansible-lab:ansible-controller-latest
|
DOCKER_IMAGE ?= inecs/ansible-lab:ansible-controller-latest
|
||||||
|
DOCKER_K8S_IMAGE ?= inecs/ansible-lab:k8s-latest
|
||||||
DOCKER_DIND_IMAGE ?= docker:27-dind
|
DOCKER_DIND_IMAGE ?= docker:27-dind
|
||||||
CONTAINER_NAME ?= ansible-controller
|
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
|
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");; \
|
TAG=$$(docker inspect --format='{{.RepoTags}}' $$BASE_IMAGE 2>/dev/null | tr -d '[]' | cut -d',' -f1 | cut -d':' -f2 | tr -d ' ' || echo "latest");; \
|
||||||
ansible-controller) \
|
ansible-controller) \
|
||||||
TAG="latest";; \
|
TAG="latest";; \
|
||||||
*) \
|
k8s) \
|
||||||
echo "❌ Неизвестный образ: $(IMAGE)"; \
|
TAG="latest";; \
|
||||||
exit 1;; \
|
k8s-portforward) \
|
||||||
esac; \
|
TAG="latest";; \
|
||||||
echo "$$TAG"
|
*) \
|
||||||
|
echo "❌ Неизвестный образ: $(IMAGE)"; \
|
||||||
|
exit 1;; \
|
||||||
|
esac; \
|
||||||
|
echo "$$TAG"
|
||||||
|
|
||||||
# Сборка одного образа с multi-arch
|
# Сборка одного образа с multi-arch
|
||||||
docker-build-image:
|
docker-build-image:
|
||||||
@@ -1012,12 +1017,428 @@ controller:
|
|||||||
echo " 💡 Удаляет: контейнеры и сети";; \
|
echo " 💡 Удаляет: контейнеры и сети";; \
|
||||||
esac
|
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:
|
help:
|
||||||
@echo "=========================================="
|
@echo "=========================================="
|
||||||
@echo "AnsibleLab - Универсальная система"
|
@echo "DevOpsLab - Универсальная система"
|
||||||
@echo "тестирования Ansible ролей"
|
@echo "тестирования Ansible ролей"
|
||||||
@echo "=========================================="
|
@echo "=========================================="
|
||||||
@echo ""
|
@echo ""
|
||||||
@@ -1053,7 +1474,7 @@ help:
|
|||||||
@echo " make presets info - подробная информация о preset'е"
|
@echo " make presets info - подробная информация о preset'е"
|
||||||
@echo " make presets test - запустить тест с preset'ом"
|
@echo " make presets test - запустить тест с preset'ом"
|
||||||
@echo ""
|
@echo ""
|
||||||
@echo "🖼️ СОБСТВЕННЫЕ ОБРАЗЫ (AnsibleLab):"
|
@echo "🖼️ СОБСТВЕННЫЕ ОБРАЗЫ (DevOpsLab):"
|
||||||
@echo " make custom-images test [minimal|full|performance] - тест с собственными образами"
|
@echo " make custom-images test [minimal|full|performance] - тест с собственными образами"
|
||||||
@echo " make custom-images check - проверить наличие собственных образов"
|
@echo " make custom-images check - проверить наличие собственных образов"
|
||||||
@echo " make custom-images build - собрать все образы для тестирования"
|
@echo " make custom-images build - собрать все образы для тестирования"
|
||||||
@@ -1105,6 +1526,20 @@ help:
|
|||||||
@echo " make controller run - запустить ansible-controller"
|
@echo " make controller run - запустить ansible-controller"
|
||||||
@echo " make controller stop - остановить ansible-controller"
|
@echo " make controller stop - остановить ansible-controller"
|
||||||
@echo ""
|
@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 "💡 ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ:"
|
||||||
@echo " make presets list # показать все preset'ы"
|
@echo " make presets list # показать все preset'ы"
|
||||||
@echo " make presets test PRESET=etcd-patroni # тест с etcd-patroni"
|
@echo " make presets test PRESET=etcd-patroni # тест с etcd-patroni"
|
||||||
@@ -1130,7 +1565,7 @@ help:
|
|||||||
custom-images:
|
custom-images:
|
||||||
@case "$(word 2, $(MAKECMDGOALS))" in \
|
@case "$(word 2, $(MAKECMDGOALS))" in \
|
||||||
test) \
|
test) \
|
||||||
echo "🧪 Тестирование с собственными образами AnsibleLab..."; \
|
echo "🧪 Тестирование с собственными образами DevOpsLab..."; \
|
||||||
if [ -z "$(word 3, $(MAKECMDGOALS))" ]; then \
|
if [ -z "$(word 3, $(MAKECMDGOALS))" ]; then \
|
||||||
echo "💡 Использование: make custom-images test [minimal|full|performance]"; \
|
echo "💡 Использование: make custom-images test [minimal|full|performance]"; \
|
||||||
echo "💡 По умолчанию: minimal"; \
|
echo "💡 По умолчанию: minimal"; \
|
||||||
@@ -1158,7 +1593,7 @@ custom-images:
|
|||||||
echo ""; \
|
echo ""; \
|
||||||
echo " 🔨 make custom-images build - собрать все образы для тестирования"; \
|
echo " 🔨 make custom-images build - собрать все образы для тестирования"; \
|
||||||
echo " 💡 Выполняет: make docker build"; \
|
echo " 💡 Выполняет: make docker build"; \
|
||||||
echo " 💡 Собирает: все образы AnsibleLab"; \
|
echo " 💡 Собирает: все образы DevOpsLab"; \
|
||||||
echo ""; \
|
echo ""; \
|
||||||
echo "💡 Пресеты для тестирования:"; \
|
echo "💡 Пресеты для тестирования:"; \
|
||||||
echo " - custom-minimal.yml - минимальный тест (4 хоста)"; \
|
echo " - custom-minimal.yml - минимальный тест (4 хоста)"; \
|
||||||
|
|||||||
202
README.md
202
README.md
@@ -1,26 +1,46 @@
|
|||||||
# AnsibleLab - Универсальная система тестирования Ansible ролей
|
# DevOpsLab - Универсальная система тестирования Ansible ролей
|
||||||
|
|
||||||
**Автор:** Сергей Антропов
|
**Автор:** Сергей Антропов
|
||||||
**Сайт:** https://devops.org.ru
|
**Сайт:** 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
|
- **Тестирование ролей** через Molecule с Docker
|
||||||
- **Preset система** для быстрого выбора окружений тестирования
|
- **Preset система** для быстрого выбора окружений тестирования
|
||||||
- **Мультиплатформенное тестирование** (Ubuntu, Debian, CentOS, AlmaLinux, RHEL и другие)
|
- **Мультиплатформенное тестирование** (Ubuntu, Debian, CentOS, AlmaLinux, RHEL и другие)
|
||||||
- **Автоматическая проверка** синтаксиса Ansible ролей
|
- **Автоматическая проверка** синтаксиса Ansible ролей
|
||||||
- **Управление секретами** через Ansible Vault
|
- **Управление секретами** через 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
|
├── molecule/ # Конфигурация Molecule
|
||||||
│ ├── default/ # Основная конфигурация
|
│ ├── default/ # Основная конфигурация
|
||||||
│ │ ├── create.yml # Создание контейнеров
|
│ │ ├── create.yml # Создание контейнеров
|
||||||
@@ -31,22 +51,65 @@ AnsibleLab/
|
|||||||
│ │ └── molecule.yml # Конфигурация Molecule
|
│ │ └── molecule.yml # Конфигурация Molecule
|
||||||
│ └── presets/ # Preset конфигурации
|
│ └── presets/ # Preset конфигурации
|
||||||
│ ├── default.yml # Стандартный preset
|
│ ├── default.yml # Стандартный preset
|
||||||
│ ├── minimal.yml # Минимальный preset
|
|
||||||
│ ├── mytest.yml # Кастомный preset
|
│ ├── mytest.yml # Кастомный preset
|
||||||
│ ├── presets.yml # Основные preset'ы
|
│ ├── examples/ # Примеры preset'ов
|
||||||
│ └── examples/ # Примеры preset'ов
|
│ │ ├── all-images.yml # Все образы (16 хостов)
|
||||||
│ ├── all-images.yml # Все образы (16 хостов)
|
│ │ ├── centos-all.yml # CentOS 7/8/9
|
||||||
│ ├── multi-os.yml # Multi-OS тестирование
|
│ │ ├── debian-all.yml # Debian 9/10/11/12
|
||||||
│ ├── performance.yml # Тест производительности
|
│ │ ├── ubuntu-all.yml # Ubuntu 20/22/24
|
||||||
│ ├── security.yml # Тест безопасности
|
│ │ ├── multi-os.yml # Multi-OS тестирование
|
||||||
│ └── ...
|
│ │ ├── performance.yml # Тест производительности
|
||||||
|
│ │ ├── security.yml # Тест безопасности
|
||||||
|
│ │ ├── minimal.yml # Минимальный preset
|
||||||
|
│ │ └── ...
|
||||||
|
│ └── k8s/ # Kubernetes preset'ы
|
||||||
|
│ ├── kubernetes.yml # Полный K8s кластер с аддонами
|
||||||
|
│ └── k8s-minimal.yml # Минимальный K8s кластер
|
||||||
├── roles/ # Ansible роли
|
├── roles/ # Ansible роли
|
||||||
│ ├── docker/ # Роль установки Docker
|
│ ├── docker/ # Роль установки Docker
|
||||||
|
│ │ ├── defaults/ # Переменные по умолчанию
|
||||||
|
│ │ ├── handlers/ # Обработчики
|
||||||
|
│ │ ├── meta/ # Метаданные
|
||||||
|
│ │ ├── tasks/ # Задачи
|
||||||
|
│ │ ├── templates/ # Шаблоны
|
||||||
|
│ │ ├── tests/ # Тесты
|
||||||
|
│ │ ├── vars/ # Переменные
|
||||||
|
│ │ ├── README.md
|
||||||
|
│ │ └── examples.yml
|
||||||
│ ├── devops/ # Роль DevOps инструментов
|
│ ├── devops/ # Роль DevOps инструментов
|
||||||
|
│ │ ├── defaults/
|
||||||
|
│ │ ├── files/
|
||||||
|
│ │ ├── handlers/
|
||||||
|
│ │ ├── meta/
|
||||||
|
│ │ ├── tasks/
|
||||||
|
│ │ ├── templates/
|
||||||
|
│ │ ├── tests/
|
||||||
|
│ │ ├── vars/
|
||||||
|
│ │ ├── README.md
|
||||||
|
│ │ ├── QUICKSTART.md
|
||||||
|
│ │ ├── examples.yml
|
||||||
|
│ │ └── playbook.yml
|
||||||
│ ├── ping/ # Роль для ping проверок
|
│ ├── ping/ # Роль для ping проверок
|
||||||
|
│ │ ├── defaults/
|
||||||
|
│ │ ├── handlers/
|
||||||
|
│ │ ├── meta/
|
||||||
|
│ │ ├── tasks/
|
||||||
|
│ │ ├── templates/
|
||||||
|
│ │ ├── README.md
|
||||||
|
│ │ ├── QUICKSTART.md
|
||||||
|
│ │ └── playbook.yml
|
||||||
│ └── deploy.yml # Playbook для развертывания
|
│ └── deploy.yml # Playbook для развертывания
|
||||||
├── dockerfiles/ # Docker образы
|
├── dockerfiles/ # Docker образы
|
||||||
│ ├── ansible-controller/ # Ansible контроллер
|
│ ├── 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
|
│ ├── ubuntu20/ # Ubuntu 20.04
|
||||||
│ ├── ubuntu22/ # Ubuntu 22.04
|
│ ├── ubuntu22/ # Ubuntu 22.04
|
||||||
│ ├── ubuntu24/ # Ubuntu 24.04
|
│ ├── ubuntu24/ # Ubuntu 24.04
|
||||||
@@ -62,18 +125,51 @@ AnsibleLab/
|
|||||||
│ ├── rhel/ # RHEL 8
|
│ ├── rhel/ # RHEL 8
|
||||||
│ ├── alt-linux/ # ALT Linux P9
|
│ ├── alt-linux/ # ALT Linux P9
|
||||||
│ ├── astra-linux/ # Astra Linux 1.7
|
│ ├── astra-linux/ # Astra Linux 1.7
|
||||||
│ └── redos/ # RED OS 9
|
│ ├── redos/ # RED OS 9
|
||||||
|
│ └── README.md
|
||||||
├── cicd/ # CI/CD конфигурации
|
├── cicd/ # CI/CD конфигурации
|
||||||
│ ├── azure-devops/ # Azure DevOps
|
│ ├── azure-devops/ # Azure DevOps
|
||||||
|
│ │ └── azure-pipelines.yml
|
||||||
│ ├── github/ # GitHub Actions
|
│ ├── github/ # GitHub Actions
|
||||||
|
│ │ └── workflows.yml
|
||||||
│ ├── gitlab/ # GitLab CI
|
│ ├── gitlab/ # GitLab CI
|
||||||
|
│ │ ├── config.json
|
||||||
|
│ │ ├── docker-compose.yaml
|
||||||
|
│ │ └── runner/
|
||||||
|
│ │ └── config.toml
|
||||||
│ └── jenkins/ # Jenkins
|
│ └── jenkins/ # Jenkins
|
||||||
├── vault/ # Зашифрованные секреты
|
│ └── Jenkinsfile
|
||||||
├── inventory/ # Инвентори файлы
|
|
||||||
├── scripts/ # Вспомогательные скрипты
|
├── 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/ # Документация
|
├── 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 # Основные команды
|
├── Makefile # Основные команды
|
||||||
└── requirements.yml # Ansible коллекции
|
└── README.md # Этот файл
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🚀 Быстрый старт
|
## 🚀 Быстрый старт
|
||||||
@@ -82,7 +178,7 @@ AnsibleLab/
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone <repository-url>
|
git clone <repository-url>
|
||||||
cd AnsibleLab
|
cd DevOpsLab
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Тестирование ролей
|
### 2. Тестирование ролей
|
||||||
@@ -109,6 +205,27 @@ make role lint docker
|
|||||||
make role lint ping
|
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
|
### Docker
|
||||||
@@ -501,6 +618,54 @@ make custom-images # справка по собственным
|
|||||||
|
|
||||||
- **[docs/dockerfiles.md](docs/dockerfiles.md)** - Полная документация по Docker образам
|
- **[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 образы
|
||||||
|
|
||||||
Проект использует готовые Docker образы для различных ОС:
|
Проект использует готовые Docker образы для различных ОС:
|
||||||
@@ -620,6 +785,7 @@ MIT License
|
|||||||
- ✅ Управление секретами через Ansible Vault
|
- ✅ Управление секретами через Ansible Vault
|
||||||
- ✅ Готовые Docker образы для разных ОС
|
- ✅ Готовые Docker образы для разных ОС
|
||||||
- ✅ CI/CD интеграция
|
- ✅ CI/CD интеграция
|
||||||
|
- ✅ Kubernetes Kind кластеры для тестирования
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# GitLab CI для AnsibleLab
|
# GitLab CI для DevOpsLab
|
||||||
# Автор: Сергей Антропов
|
# Автор: Сергей Антропов
|
||||||
# Сайт: https://devops.org.ru
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Azure DevOps Pipeline для AnsibleLab
|
# Azure DevOps Pipeline для DevOpsLab
|
||||||
# Автор: Сергей Антропов
|
# Автор: Сергей Антропов
|
||||||
# Сайт: https://devops.org.ru
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# GitHub Actions Workflow для AnsibleLab
|
# GitHub Actions Workflow для DevOpsLab
|
||||||
# Автор: Сергей Антропов
|
# Автор: Сергей Антропов
|
||||||
# Сайт: https://devops.org.ru
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
name: AnsibleLab CI/CD Pipeline
|
name: DevOpsLab CI/CD Pipeline
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# GitLab CI Pipeline для AnsibleLab
|
# GitLab CI Pipeline для DevOpsLab
|
||||||
# Автор: Сергей Антропов
|
# Автор: Сергей Антропов
|
||||||
# Сайт: https://devops.org.ru
|
# Сайт: 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
|
// Сайт: https://devops.org.ru
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Docker образы для универсальной системы тестирования AnsibleLab
|
# Docker образы для универсальной системы тестирования DevOpsLab
|
||||||
|
|
||||||
**Автор:** Сергей Антропов
|
**Автор:** Сергей Антропов
|
||||||
**Сайт:** https://devops.org.ru
|
**Сайт:** https://devops.org.ru
|
||||||
**Версия:** 2.0.0
|
**Версия:** 3.0.0
|
||||||
|
|
||||||
## 🐳 Обзор
|
## 🐳 Обзор
|
||||||
|
|
||||||
@@ -15,7 +15,13 @@ dockerfiles/
|
|||||||
├── ansible-controller/ # Ansible контроллер с предустановленными коллекциями
|
├── ansible-controller/ # Ansible контроллер с предустановленными коллекциями
|
||||||
│ ├── Dockerfile
|
│ ├── Dockerfile
|
||||||
│ ├── docker-compose.yml
|
│ ├── 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
|
├── alt-linux/ # ALT Linux P9 с systemd
|
||||||
│ └── Dockerfile
|
│ └── Dockerfile
|
||||||
├── astra-linux/ # Astra Linux 1.7 с systemd
|
├── astra-linux/ # Astra Linux 1.7 с systemd
|
||||||
@@ -48,7 +54,7 @@ dockerfiles/
|
|||||||
│ └── Dockerfile
|
│ └── Dockerfile
|
||||||
├── debian12/ # Debian 12 (bookworm) с systemd
|
├── debian12/ # Debian 12 (bookworm) с systemd
|
||||||
│ └── Dockerfile
|
│ └── Dockerfile
|
||||||
└── README.md # Документация
|
└── README.md # Этот файл
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🚀 Доступные образы
|
## 🚀 Доступные образы
|
||||||
@@ -62,12 +68,11 @@ dockerfiles/
|
|||||||
#### Компоненты:
|
#### Компоненты:
|
||||||
- **Ansible Core** с последними коллекциями
|
- **Ansible Core** с последними коллекциями
|
||||||
- **Docker CLI** для работы с контейнерами
|
- **Docker CLI** для работы с контейнерами
|
||||||
- **kubectl** для управления Kubernetes
|
|
||||||
- **Helm** для управления пакетами Kubernetes
|
|
||||||
- **Kind** для локального Kubernetes
|
|
||||||
- **yq** для работы с YAML
|
- **yq** для работы с YAML
|
||||||
- **jq** для работы с JSON
|
- **jq** для работы с JSON
|
||||||
|
|
||||||
|
**Примечание:** Kubernetes инструменты (kubectl, Helm, Kind, Istio) были перенесены в отдельный образ `k8s`.
|
||||||
|
|
||||||
#### Предустановленные коллекции:
|
#### Предустановленные коллекции:
|
||||||
```yaml
|
```yaml
|
||||||
collections:
|
collections:
|
||||||
@@ -109,7 +114,40 @@ docker run --rm \
|
|||||||
ansible-playbook site.yml
|
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)
|
#### Ubuntu 20.04 (focal)
|
||||||
|
|
||||||
@@ -157,7 +195,7 @@ docker run -d --privileged \
|
|||||||
inecs/ansible-lab:ubuntu22
|
inecs/ansible-lab:ubuntu22
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Debian
|
### 4. Debian
|
||||||
|
|
||||||
#### Debian 9 (stretch)
|
#### Debian 9 (stretch)
|
||||||
|
|
||||||
@@ -216,7 +254,7 @@ docker run -d --privileged \
|
|||||||
inecs/ansible-lab:debian12
|
inecs/ansible-lab:debian12
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. RHEL (Red Hat Enterprise Linux)
|
### 5. RHEL (Red Hat Enterprise Linux)
|
||||||
|
|
||||||
**Базовый образ:** `registry.access.redhat.com/ubi8/ubi`
|
**Базовый образ:** `registry.access.redhat.com/ubi8/ubi`
|
||||||
**Тег:** `inecs/ansible-lab:rhel-latest`
|
**Тег:** `inecs/ansible-lab:rhel-latest`
|
||||||
@@ -240,7 +278,7 @@ docker run -d --privileged \
|
|||||||
inecs/ansible-lab:rhel-latest
|
inecs/ansible-lab:rhel-latest
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5. CentOS
|
### 6. CentOS
|
||||||
|
|
||||||
#### CentOS 7
|
#### CentOS 7
|
||||||
|
|
||||||
@@ -304,7 +342,7 @@ docker run -d --privileged \
|
|||||||
inecs/ansible-lab:centos-latest
|
inecs/ansible-lab:centos-latest
|
||||||
```
|
```
|
||||||
|
|
||||||
### 6. alma
|
### 7. alma
|
||||||
|
|
||||||
**Базовый образ:** `almalinux:8`
|
**Базовый образ:** `almalinux:8`
|
||||||
**Тег:** `inecs/ansible-lab:alma-latest`
|
**Тег:** `inecs/ansible-lab:alma-latest`
|
||||||
@@ -341,7 +379,7 @@ docker run -d --privileged \
|
|||||||
inecs/ansible-lab:alma-latest
|
inecs/ansible-lab:alma-latest
|
||||||
```
|
```
|
||||||
|
|
||||||
### 7. rocky
|
### 8. rocky
|
||||||
|
|
||||||
**Базовый образ:** `rockylinux:8`
|
**Базовый образ:** `rockylinux:8`
|
||||||
**Тег:** `inecs/ansible-lab:rocky-latest`
|
**Тег:** `inecs/ansible-lab:rocky-latest`
|
||||||
@@ -378,7 +416,7 @@ docker run -d --privileged \
|
|||||||
inecs/ansible-lab:rocky-latest
|
inecs/ansible-lab:rocky-latest
|
||||||
```
|
```
|
||||||
|
|
||||||
### 8. alt-linux
|
### 9. alt-linux
|
||||||
|
|
||||||
**Базовый образ:** `altlinux/p9`
|
**Базовый образ:** `altlinux/p9`
|
||||||
**Тег:** `inecs/ansible-lab:alt-linux-latest`
|
**Тег:** `inecs/ansible-lab:alt-linux-latest`
|
||||||
@@ -415,7 +453,7 @@ docker run -d --privileged \
|
|||||||
inecs/ansible-lab:alt-linux-latest
|
inecs/ansible-lab:alt-linux-latest
|
||||||
```
|
```
|
||||||
|
|
||||||
### 9. astra-linux
|
### 10. astra-linux
|
||||||
|
|
||||||
**Базовый образ:** `astralinux/astra-1.7`
|
**Базовый образ:** `astralinux/astra-1.7`
|
||||||
**Тег:** `inecs/ansible-lab:astra-linux-latest`
|
**Тег:** `inecs/ansible-lab:astra-linux-latest`
|
||||||
@@ -452,7 +490,7 @@ docker run -d --privileged \
|
|||||||
inecs/ansible-lab:astra-linux-latest
|
inecs/ansible-lab:astra-linux-latest
|
||||||
```
|
```
|
||||||
|
|
||||||
### 10. redos
|
### 11. redos
|
||||||
|
|
||||||
**Базовый образ:** `redos/redos:9`
|
**Базовый образ:** `redos/redos:9`
|
||||||
**Тег:** `inecs/ansible-lab:redos-latest`
|
**Тег:** `inecs/ansible-lab:redos-latest`
|
||||||
@@ -569,7 +607,7 @@ make docker reset-builder
|
|||||||
```yaml
|
```yaml
|
||||||
# molecule/presets/custom-images.yml
|
# molecule/presets/custom-images.yml
|
||||||
---
|
---
|
||||||
#description: Preset с собственными образами AnsibleLab
|
#description: Preset с собственными образами DevOpsLab
|
||||||
docker_network: labnet
|
docker_network: labnet
|
||||||
generated_inventory: "{{ molecule_ephemeral_directory }}/inventory/hosts.ini"
|
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
|
**Сайт:** https://devops.org.ru
|
||||||
@@ -847,7 +847,7 @@ pipeline {
|
|||||||
# scripts/setup-cicd.sh
|
# scripts/setup-cicd.sh
|
||||||
# Автоматическая настройка CI/CD
|
# Автоматическая настройка CI/CD
|
||||||
|
|
||||||
echo "🔧 Настройка CI/CD для AnsibleLab..."
|
echo "🔧 Настройка CI/CD для DevOpsLab..."
|
||||||
|
|
||||||
# Создание директории .github/workflows
|
# Создание директории .github/workflows
|
||||||
mkdir -p .github/workflows
|
mkdir -p .github/workflows
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Создание и разработка ролей для AnsibleLab
|
# Создание и разработка ролей для DevOpsLab
|
||||||
|
|
||||||
**Автор:** Сергей Антропов
|
**Автор:** Сергей Антропов
|
||||||
**Сайт:** https://devops.org.ru
|
**Сайт:** https://devops.org.ru
|
||||||
**Версия:** 2.0.0
|
**Версия:** 3.0.0
|
||||||
|
|
||||||
## 🚀 Быстрый старт
|
## 🚀 Быстрый старт
|
||||||
|
|
||||||
@@ -247,7 +247,7 @@ my_role_cache_dir: /var/cache/my-role
|
|||||||
|
|
||||||
galaxy_info:
|
galaxy_info:
|
||||||
author: Сергей Антропов
|
author: Сергей Антропов
|
||||||
description: Моя кастомная роль для AnsibleLab
|
description: Моя кастомная роль для DevOpsLab
|
||||||
company: https://devops.org.ru
|
company: https://devops.org.ru
|
||||||
license: MIT
|
license: MIT
|
||||||
min_ansible_version: "2.9"
|
min_ansible_version: "2.9"
|
||||||
|
|||||||
@@ -1,18 +1,27 @@
|
|||||||
# Docker образы AnsibleLab
|
# Docker образы DevOpsLab
|
||||||
|
|
||||||
**Автор:** Сергей Антропов
|
**Автор:** Сергей Антропов
|
||||||
**Сайт:** https://devops.org.ru
|
**Сайт:** 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/
|
||||||
|
|
||||||
```
|
```
|
||||||
dockerfiles/
|
dockerfiles/
|
||||||
├── ansible-controller/ # Ansible контроллер
|
├── 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
|
├── alt-linux/ # ALT Linux P9
|
||||||
├── astra-linux/ # Astra Linux 1.7
|
├── astra-linux/ # Astra Linux 1.7
|
||||||
├── redos/ # RED OS 9
|
├── redos/ # RED OS 9
|
||||||
@@ -28,7 +37,8 @@ dockerfiles/
|
|||||||
├── debian9/ # Debian 9 Stretch
|
├── debian9/ # Debian 9 Stretch
|
||||||
├── debian10/ # Debian 10 Buster
|
├── debian10/ # Debian 10 Buster
|
||||||
├── debian11/ # Debian 11 Bullseye
|
├── debian11/ # Debian 11 Bullseye
|
||||||
└── debian12/ # Debian 12 Bookworm
|
├── debian12/ # Debian 12 Bookworm
|
||||||
|
└── README.md # Документация по Dockerfiles
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🚀 Доступные образы
|
## 🚀 Доступные образы
|
||||||
@@ -44,13 +54,12 @@ Ansible контроллер с предустановленными колле
|
|||||||
#### Компоненты:
|
#### Компоненты:
|
||||||
- Ansible Core с последними коллекциями
|
- Ansible Core с последними коллекциями
|
||||||
- Docker CLI для работы с контейнерами
|
- Docker CLI для работы с контейнерами
|
||||||
- kubectl для управления Kubernetes
|
|
||||||
- Helm для управления пакетами Kubernetes
|
|
||||||
- Kind для локального Kubernetes
|
|
||||||
- yq для работы с YAML
|
- yq для работы с YAML
|
||||||
- jq для работы с JSON
|
- jq для работы с JSON
|
||||||
- Molecule для тестирования ролей
|
- Molecule для тестирования ролей
|
||||||
|
|
||||||
|
**Примечание:** Kubernetes инструменты (kubectl, Helm, Kind, Istio) были перенесены в отдельный образ `k8s`.
|
||||||
|
|
||||||
#### Предустановленные коллекции:
|
#### Предустановленные коллекции:
|
||||||
```yaml
|
```yaml
|
||||||
collections:
|
collections:
|
||||||
@@ -82,6 +91,41 @@ docker run --rm \
|
|||||||
ansible-playbook site.yml
|
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
|
### Ubuntu
|
||||||
|
|
||||||
**Базовые образы:**
|
**Базовые образы:**
|
||||||
@@ -348,18 +392,19 @@ docker run -d --privileged \
|
|||||||
|
|
||||||
## 📋 Матрица совместимости
|
## 📋 Матрица совместимости
|
||||||
|
|
||||||
| Образ | Платформы | systemd | Docker | Python 3 |
|
| Образ | Платформы | systemd | Docker | Python 3 | Kubernetes Tools |
|
||||||
|-------|-----------|---------|--------|----------|
|
|-------|-----------|---------|--------|----------|------------------|
|
||||||
| ansible-controller | amd64, arm64 | ✅ | ✅ | ✅ |
|
| ansible-controller | amd64, arm64 | ✅ | ✅ | ✅ | ❌ |
|
||||||
| ubuntu20/22/24 | amd64, arm64 | ✅ | ✅ | ✅ |
|
| k8s | amd64, arm64 | ❌ | ✅ | ✅ | ✅ (kubectl, Helm, Kind, Istio) |
|
||||||
| debian9/10/11/12 | amd64, arm64 | ✅ | ✅ | ✅ |
|
| ubuntu20/22/24 | amd64, arm64 | ✅ | ✅ | ✅ | ❌ |
|
||||||
| centos7/8/9 | amd64, arm64 | ✅ | ✅ | ✅ |
|
| debian9/10/11/12 | amd64, arm64 | ✅ | ✅ | ✅ | ❌ |
|
||||||
| alma | amd64, arm64 | ✅ | ✅ | ✅ |
|
| centos7/8/9 | amd64, arm64 | ✅ | ✅ | ✅ | ❌ |
|
||||||
| rocky | amd64, arm64 | ✅ | ✅ | ✅ |
|
| alma | amd64, arm64 | ✅ | ✅ | ✅ | ❌ |
|
||||||
| rhel | amd64, arm64 | ✅ | ✅ | ✅ |
|
| rocky | amd64, arm64 | ✅ | ✅ | ✅ | ❌ |
|
||||||
| alt-linux | amd64 | ✅ | ✅ | ✅ |
|
| rhel | amd64, arm64 | ✅ | ✅ | ✅ | ❌ |
|
||||||
| astra-linux | amd64 | ✅ | ✅ | ✅ |
|
| alt-linux | amd64 | ✅ | ✅ | ✅ | ❌ |
|
||||||
| redos | amd64 | ✅ | ✅ | ✅ |
|
| astra-linux | amd64 | ✅ | ✅ | ✅ | ❌ |
|
||||||
|
| redos | amd64 | ✅ | ✅ | ✅ | ❌ |
|
||||||
|
|
||||||
## 🛠️ Управление образами
|
## 🛠️ Управление образами
|
||||||
|
|
||||||
@@ -406,5 +451,5 @@ make docker purge
|
|||||||
## 🔗 Полезные ссылки
|
## 🔗 Полезные ссылки
|
||||||
|
|
||||||
- **Docker Hub**: https://hub.docker.com/r/inecs/ansible-lab
|
- **Docker Hub**: https://hub.docker.com/r/inecs/ansible-lab
|
||||||
- **AnsibleLab**: https://devops.org.ru
|
- **DevOpsLab**: https://devops.org.ru
|
||||||
- **Документация**: https://github.com/AnsibleLab/docs
|
- **Документация**: https://github.com/DevOpsLab/docs
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Примеры использования AnsibleLab
|
# Примеры использования DevOpsLab
|
||||||
|
|
||||||
**Автор:** Сергей Антропов
|
**Автор:** Сергей Антропов
|
||||||
**Сайт:** https://devops.org.ru
|
**Сайт:** https://devops.org.ru
|
||||||
**Версия:** 2.0.0
|
**Версия:** 3.0.0
|
||||||
|
|
||||||
## Быстрый старт
|
## Быстрый старт
|
||||||
|
|
||||||
@@ -304,7 +304,7 @@ make vault check
|
|||||||
|
|
||||||
## Заключение
|
## Заключение
|
||||||
|
|
||||||
Эти примеры демонстрируют основные возможности AnsibleLab:
|
Эти примеры демонстрируют основные возможности DevOpsLab:
|
||||||
|
|
||||||
1. **Быстрое тестирование** с minimal preset
|
1. **Быстрое тестирование** с minimal preset
|
||||||
2. **Полное тестирование** с all-images preset
|
2. **Полное тестирование** с all-images preset
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
# Быстрый старт с AnsibleLab
|
# Быстрый старт с DevOpsLab
|
||||||
|
|
||||||
**Автор:** Сергей Антропов
|
**Автор:** Сергей Антропов
|
||||||
**Сайт:** https://devops.org.ru
|
**Сайт:** https://devops.org.ru
|
||||||
**Версия:** 2.0.0
|
**Версия:** 3.0.0
|
||||||
|
|
||||||
## 🚀 Установка и настройка
|
## 🚀 Установка и настройка
|
||||||
|
|
||||||
### 1. Клонирование репозитория
|
### 1. Клонирование репозитория
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone ssh://git@git.antropoff.ru:222/Ansible/AnsibleLab.git
|
git clone ssh://git@git.antropoff.ru:222/Ansible/DevOpsLab.git
|
||||||
cd AnsibleLab
|
cd DevOpsLab
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Проверка структуры проекта
|
### 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 значения
|
### 🔧 Fallback значения
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ platforms:
|
|||||||
```
|
```
|
||||||
- **Назначение:** Определяет доступные Docker образы для тестирования
|
- **Назначение:** Определяет доступные Docker образы для тестирования
|
||||||
- **Поддерживаемые ОС:** Ubuntu, Debian, RHEL, CentOS, AlmaLinux, Rocky Linux, Alt Linux, Astra Linux, RedOS
|
- **Поддерживаемые ОС:** Ubuntu, Debian, RHEL, CentOS, AlmaLinux, Rocky Linux, Alt Linux, Astra Linux, RedOS
|
||||||
- **Собственные образы:** AnsibleLab создает собственные образы для тестирования
|
- **Собственные образы:** DevOpsLab создает собственные образы для тестирования
|
||||||
|
|
||||||
**Provisioner (Провижнер):**
|
**Provisioner (Провижнер):**
|
||||||
```yaml
|
```yaml
|
||||||
@@ -154,7 +154,7 @@ vars:
|
|||||||
```
|
```
|
||||||
- **Назначение:** Определение fallback значений для случаев когда preset файл не найден
|
- **Назначение:** Определение fallback значений для случаев когда preset файл не найден
|
||||||
- **Функция:** Обеспечение работоспособности даже без preset файлов
|
- **Функция:** Обеспечение работоспособности даже без preset файлов
|
||||||
- **Образы:** Собственные образы AnsibleLab для всех поддерживаемых ОС
|
- **Образы:** Собственные образы DevOpsLab для всех поддерживаемых ОС
|
||||||
- **Systemd настройки:** Стандартные настройки для systemd контейнеров
|
- **Systemd настройки:** Стандартные настройки для systemd контейнеров
|
||||||
|
|
||||||
#### Основные задачи:
|
#### Основные задачи:
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# Мониторинг и диагностика AnsibleLab
|
# Мониторинг и диагностика DevOpsLab
|
||||||
|
|
||||||
**Автор:** Сергей Антропов
|
**Автор:** Сергей Антропов
|
||||||
**Сайт:** https://devops.org.ru
|
**Сайт:** https://devops.org.ru
|
||||||
**Версия:** 2.0.0
|
**Версия:** 3.0.0
|
||||||
|
|
||||||
## 🔍 Диагностика Docker
|
## 🔍 Диагностика Docker
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ docker info
|
|||||||
# Проверка запущенных контейнеров
|
# Проверка запущенных контейнеров
|
||||||
docker ps -a
|
docker ps -a
|
||||||
|
|
||||||
# Проверка образов AnsibleLab
|
# Проверка образов DevOpsLab
|
||||||
docker images | grep inecs/ansible-lab
|
docker images | grep inecs/ansible-lab
|
||||||
|
|
||||||
# Проверка сетей
|
# Проверка сетей
|
||||||
@@ -368,7 +368,7 @@ echo "✅ Диагностическая информация собрана в:
|
|||||||
```bash
|
```bash
|
||||||
# Быстрая проверка состояния
|
# Быстрая проверка состояния
|
||||||
echo "=== Docker Status ===" && docker info | head -5
|
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 "=== Roles ===" && ls -1 roles/ | grep -v "\.yml"
|
||||||
echo "=== Presets ===" && ls -1 molecule/presets/*.yml 2>/dev/null | wc -l
|
echo "=== Presets ===" && ls -1 molecule/presets/*.yml 2>/dev/null | wc -l
|
||||||
echo "=== Disk Usage ===" && df -h . | tail -1
|
echo "=== Disk Usage ===" && df -h . | tail -1
|
||||||
@@ -382,7 +382,7 @@ echo "=== Disk Usage ===" && df -h . | tail -1
|
|||||||
# Очистка контейнеров Molecule
|
# Очистка контейнеров Molecule
|
||||||
make clean-containers
|
make clean-containers
|
||||||
|
|
||||||
# Очистка Docker образов AnsibleLab
|
# Очистка Docker образов DevOpsLab
|
||||||
make docker clean
|
make docker clean
|
||||||
|
|
||||||
# Очистка всего Docker
|
# Очистка всего Docker
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
|
|
||||||
**Автор:** Сергей Антропов
|
**Автор:** Сергей Антропов
|
||||||
**Сайт:** https://devops.org.ru
|
**Сайт:** 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:
|
vars:
|
||||||
# Получаем preset из переменной окружения или используем default
|
# Получаем preset из переменной окружения или используем default
|
||||||
preset_name: "{{ lookup('env', 'MOLECULE_PRESET') | default('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 файл не найден
|
# Fallback значения если preset файл не найден
|
||||||
docker_network: labnet
|
docker_network: labnet
|
||||||
@@ -30,6 +31,7 @@
|
|||||||
- name: u1
|
- name: u1
|
||||||
family: debian
|
family: debian
|
||||||
groups: [test]
|
groups: [test]
|
||||||
|
kind_clusters: []
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
# - name: Install required collections
|
# - name: Install required collections
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
vars:
|
vars:
|
||||||
# Получаем preset из переменной окружения или используем default
|
# Получаем preset из переменной окружения или используем default
|
||||||
preset_name: "{{ lookup('env', 'MOLECULE_PRESET') | default('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 файл не найден
|
# Fallback значения если preset файл не найден
|
||||||
docker_network: labnet
|
docker_network: labnet
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
- name: u1
|
- name: u1
|
||||||
family: debian
|
family: debian
|
||||||
groups: [test]
|
groups: [test]
|
||||||
|
kind_clusters: []
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Load preset configuration
|
- name: Load preset configuration
|
||||||
@@ -81,3 +83,4 @@
|
|||||||
- Removed containers: {{ hosts | length }}
|
- Removed containers: {{ hosts | length }}
|
||||||
- Removed DinD volumes: {{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list | 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:
|
platforms:
|
||||||
# Платформы будут созданы динамически через preset файлы
|
# Платформы будут созданы динамически через preset файлы
|
||||||
# Поддержка собственных образов AnsibleLab
|
# Поддержка собственных образов DevOpsLab
|
||||||
- name: placeholder
|
- name: placeholder
|
||||||
image: ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy
|
image: ghcr.io/ansible-community/molecule-ubuntu-systemd:jammy
|
||||||
pre_build_image: true
|
pre_build_image: true
|
||||||
|
|||||||
@@ -33,6 +33,20 @@ systemd_defaults:
|
|||||||
tmpfs: ["/run", "/run/lock"]
|
tmpfs: ["/run", "/run/lock"]
|
||||||
capabilities: ["SYS_ADMIN"]
|
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:
|
hosts:
|
||||||
# Стандартный набор - 3 хоста
|
# Стандартный набор - 3 хоста
|
||||||
- name: u1
|
- 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
|
**Сайт:** https://devops.org.ru
|
||||||
**Версия:** 2.0.0
|
**Версия:** 3.0.0
|
||||||
|
|
||||||
## Что делает роль
|
## Что делает роль
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
**Автор:** Сергей Антропов
|
**Автор:** Сергей Антропов
|
||||||
**Сайт:** https://devops.org.ru
|
**Сайт:** 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
|
#!/bin/bash
|
||||||
# Автоматическая настройка CI/CD для AnsibleLab
|
# Автоматическая настройка CI/CD для DevOpsLab
|
||||||
# Автор: Сергей Антропов
|
# Автор: Сергей Антропов
|
||||||
# Сайт: https://devops.org.ru
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
echo "🔧 Настройка CI/CD для AnsibleLab..."
|
echo "🔧 Настройка CI/CD для DevOpsLab..."
|
||||||
|
|
||||||
# Создание директории .github/workflows
|
# Создание директории .github/workflows
|
||||||
mkdir -p .github/workflows
|
mkdir -p .github/workflows
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Скрипт для тестирования собственных образов AnsibleLab
|
# Скрипт для тестирования собственных образов DevOpsLab
|
||||||
# Автор: Сергей Антропов
|
# Автор: Сергей Антропов
|
||||||
# Сайт: https://devops.org.ru
|
# Сайт: https://devops.org.ru
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ cleanup() {
|
|||||||
|
|
||||||
# Основная функция
|
# Основная функция
|
||||||
main() {
|
main() {
|
||||||
log "🚀 Тестирование собственных образов AnsibleLab"
|
log "🚀 Тестирование собственных образов DevOpsLab"
|
||||||
echo "=========================================="
|
echo "=========================================="
|
||||||
|
|
||||||
# Проверки
|
# Проверки
|
||||||
|
|||||||
Reference in New Issue
Block a user