- Добавлен скрипт scripts/manage_hosts.py для управления /etc/hosts - Автоматическое добавление Ingress хостов при создании кластера - Автоматическое удаление Ingress хостов при удалении кластера - Записи помечаются меткой #k8s для разделения со статическими - Команды: add, remove, cleanup, list
191 lines
6.6 KiB
Python
Executable File
191 lines
6.6 KiB
Python
Executable File
#!/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()
|