feat: автоматическое управление Ingress хостами в /etc/hosts

- Добавлен скрипт scripts/manage_hosts.py для управления /etc/hosts
- Автоматическое добавление Ingress хостов при создании кластера
- Автоматическое удаление Ingress хостов при удалении кластера
- Записи помечаются меткой #k8s для разделения со статическими
- Команды: add, remove, cleanup, list
This commit is contained in:
Сергей Антропов
2025-10-26 10:03:59 +03:00
parent 4ca882b5f7
commit fd80db220a
2 changed files with 194 additions and 0 deletions

View File

@@ -1053,6 +1053,8 @@ k8s:
echo "✅ Kind кластер создан"; \ echo "✅ Kind кластер создан"; \
echo "🔌 Автоматическое создание port-forward..."; \ echo "🔌 Автоматическое создание port-forward..."; \
python3 scripts/portforward.py create || echo "⚠️ Не удалось создать port-forward автоматически"; \ python3 scripts/portforward.py create || echo "⚠️ Не удалось создать port-forward автоматически"; \
echo "📝 Добавление Ingress хостов в /etc/hosts..."; \
sudo python3 scripts/manage_hosts.py add 2>/dev/null || echo "⚠️ Не удалось добавить Ingress хосты (требуется sudo)"; \
echo "💡 Для подключения используйте: make k8s kubeconfig"; \ echo "💡 Для подключения используйте: make k8s kubeconfig"; \
echo "💡 Для остановки используйте: make k8s stop";; \ echo "💡 Для остановки используйте: make k8s stop";; \
destroy) \ destroy) \
@@ -1062,6 +1064,8 @@ k8s:
CONTAINER_NAME=k8s-controller; \ CONTAINER_NAME=k8s-controller; \
echo "🔌 Очистка port-forward..."; \ echo "🔌 Очистка port-forward..."; \
python3 scripts/portforward.py clear || echo "⚠️ Не удалось очистить port-forward"; \ python3 scripts/portforward.py clear || echo "⚠️ Не удалось очистить port-forward"; \
echo "📝 Удаление Ingress хостов из /etc/hosts..."; \
sudo python3 scripts/manage_hosts.py remove 2>/dev/null || echo "⚠️ Не удалось удалить Ingress хосты (требуется sudo)"; \
if docker ps | grep -q $$CONTAINER_NAME; then \ if docker ps | grep -q $$CONTAINER_NAME; then \
echo "🗑️ Удаление Kind кластеров..."; \ echo "🗑️ Удаление Kind кластеров..."; \
docker exec $$CONTAINER_NAME bash -c "kind delete clusters --all" 2>/dev/null || true; \ docker exec $$CONTAINER_NAME bash -c "kind delete clusters --all" 2>/dev/null || true; \

190
scripts/manage_hosts.py Executable file
View File

@@ -0,0 +1,190 @@
#!/usr/bin/env python3
"""
Скрипт для управления записями в /etc/hosts для Ingress ресурсов
Автор: Сергей Антропов
Сайт: https://devops.org.ru
"""
import sys
import subprocess
import re
import os
HOSTS_FILE = "/etc/hosts"
K8S_MARKER = "#k8s"
def is_root():
"""Проверяет, запущен ли скрипт от root"""
return os.geteuid() == 0
def get_ingress_hosts():
"""Получает список Ingress хостов из кластера"""
# Получаем kubeconfig из контейнера k8s-controller
result = subprocess.run(
"docker exec k8s-controller kind get kubeconfig",
shell=True, capture_output=True, text=True
)
if result.returncode != 0:
print("⚠️ Кластер недоступен")
return []
# Сохраняем kubeconfig во временный файл
import tempfile
with tempfile.NamedTemporaryFile(mode='w', delete=False, suffix='.yaml') as f:
f.write(result.stdout)
kubeconfig_file = f.name
try:
# Получаем все Ingress ресурсы
result = subprocess.run(
f"kubectl --kubeconfig {kubeconfig_file} get ingress --all-namespaces -o jsonpath='{{range .items}}{{range .spec.rules}}{{.host}}{{\"\\n\"}}{{end}}{{end}}'",
shell=True, capture_output=True, text=True
)
hosts = []
if result.returncode == 0:
hosts = [h.strip() for h in result.stdout.split('\n') if h.strip()]
return hosts
finally:
# Удаляем временный файл
os.unlink(kubeconfig_file)
def get_current_k8s_entries():
"""Получает текущие k8s записи из /etc/hosts"""
if not os.path.exists(HOSTS_FILE):
return []
entries = []
with open(HOSTS_FILE, 'r') as f:
for line in f:
if K8S_MARKER in line:
# Извлекаем IP и hostname
parts = line.split()
if len(parts) >= 2:
ip = parts[0]
hostname = parts[1]
entries.append((ip, hostname))
return entries
def remove_k8s_entries():
"""Удаляет все записи с меткой #k8s из /etc/hosts"""
if not os.path.exists(HOSTS_FILE):
print("⚠️ Файл /etc/hosts не существует")
return
print("🗑️ Удаление k8s записей из /etc/hosts...")
# Читаем файл
with open(HOSTS_FILE, 'r') as f:
lines = f.readlines()
# Фильтруем строки с меткой #k8s
new_lines = []
removed_count = 0
for line in lines:
if K8S_MARKER in line:
removed_count += 1
print(f" ❌ Удалено: {line.strip()}")
else:
new_lines.append(line)
# Записываем обратно
with open(HOSTS_FILE, 'w') as f:
f.writelines(new_lines)
print(f"✅ Удалено {removed_count} записей")
def add_ingress_entries():
"""Добавляет записи Ingress в /etc/hosts"""
if not is_root():
print("❌ Ошибка: скрипт должен быть запущен от root")
print("💡 Используйте: sudo python3 scripts/manage_hosts.py add")
sys.exit(1)
# Проверяем доступность кластера
result = subprocess.run("docker ps | grep k8s-controller", shell=True, capture_output=True, text=True)
if result.returncode != 0:
print("❌ Контейнер k8s-controller не запущен")
return
print("🔍 Поиск Ingress ресурсов в кластере...")
hosts = get_ingress_hosts()
if not hosts:
print(" Не найдено Ingress ресурсов в кластере")
return
print(f"📋 Найдено {len(hosts)} Ingress хостов: {', '.join(hosts)}")
# Получаем текущие записи
current_entries = get_current_k8s_entries()
current_hosts = [e[1] for e in current_entries]
# Удаляем старые записи
if current_entries:
print("🗑️ Удаление старых k8s записей...")
remove_k8s_entries()
# Добавляем новые записи
print(" Добавление новых записей в /etc/hosts...")
with open(HOSTS_FILE, 'a') as f:
for host in hosts:
entry = f"127.0.0.1 {host} {K8S_MARKER}\n"
f.write(entry)
print(f" ✅ Добавлено: 127.0.0.1 {host}")
print(f"✅ Добавлено {len(hosts)} записей в /etc/hosts")
def cleanup_k8s_entries():
"""Очищает k8s записи если кластер недоступен"""
print("🔍 Проверка доступности кластера...")
# Проверяем доступность контейнера
result = subprocess.run("docker ps | grep k8s-controller", shell=True, capture_output=True, text=True)
if result.returncode == 0:
print("✅ Кластер доступен")
return
print("⚠️ Кластер недоступен, очищаем k8s записи...")
remove_k8s_entries()
def list_k8s_entries():
"""Выводит список текущих k8s записей"""
entries = get_current_k8s_entries()
if not entries:
print(" Нет k8s записей в /etc/hosts")
return
print("📋 Текущие k8s записи в /etc/hosts:")
for ip, hostname in entries:
print(f" {ip} {hostname}")
def main():
if len(sys.argv) < 2:
print("Usage: manage_hosts.py <add|remove|cleanup|list>")
print(" add - добавить Ingress хосты в /etc/hosts")
print(" remove - удалить все k8s записи из /etc/hosts")
print(" cleanup - удалить k8s записи если кластер недоступен")
print(" list - показать текущие k8s записи")
sys.exit(1)
command = sys.argv[1]
if command == "add":
add_ingress_entries()
elif command == "remove":
remove_k8s_entries()
elif command == "cleanup":
cleanup_k8s_entries()
elif command == "list":
list_k8s_entries()
else:
print(f"❌ Неизвестная команда: {command}")
sys.exit(1)
if __name__ == '__main__':
main()