Skip to content

Instantly share code, notes, and snippets.

@dmi3mis
Last active June 11, 2026 12:31
Show Gist options
  • Select an option

  • Save dmi3mis/d49113874be6cdfd0394c8968eda9c94 to your computer and use it in GitHub Desktop.

Select an option

Save dmi3mis/d49113874be6cdfd0394c8968eda9c94 to your computer and use it in GitHub Desktop.
Этот скрипт предназначен для аварийного восстановления кластера Kubernetes после истечения срока действия TLS-сертификатов.
#!/bin/bash
# Восстановление кластера Kubernetes (через пользователя kadm + sudo с паролем)
MASTER="k8s-master.techedu.lab"
WORKERS=("k8s-worker1.techedu.lab" "k8s-worker2.techedu.lab")
ALL_NODES=("$MASTER" "${WORKERS[@]}")
SSH_USER="kadm"
if [ -n "$1" ]; then
PASSWORD=$1
else
read -sp "Введите пароль пользователя $SSH_USER для серверов: " PASSWORD
echo ""
fi
if [ -z "$PASSWORD" ]; then
echo "Ошибка: пароль не может быть пустым."
exit 1
fi
# Универсальная функция выполнения команд от root через sudo (пароль передаётся в stdin)
run_ssh() {
local host=$1
local cmd=$2
printf '%s\n%s\n' "$PASSWORD" "$cmd" | \
sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -T "$SSH_USER@$host" "sudo -S bash -s"
}
echo "--- 0. Предварительные проверки ---"
# Проверка сети
echo "Проверка пинга..."
for node in "${ALL_NODES[@]}"; do
if ! ping -c 1 -W 2 "$node" > /dev/null; then
echo "[ ERROR ] $node не отвечает на ping."
exit 1
fi
done
echo "[ OK ] Все узлы доступны."
# Установка sshpass (при необходимости)
if ! command -v sshpass &> /dev/null; then
echo "Установка sshpass..."
sudo apt-get update && sudo apt-get install -y sshpass || sudo yum install -y sshpass
fi
# Проверка подключения и sudo (через реальную команду)
echo "Проверка пароля SSH и прав sudo..."
if ! run_ssh "$MASTER" "true"; then
echo "[ ERROR ] Не удалось выполнить команду через sudo на $MASTER."
echo " Проверьте пароль и права sudo для пользователя $SSH_USER."
exit 1
fi
echo "[ OK ] Подключение и sudo работают корректно."
echo -e "\n--- 1. Восстановление Master-ноды ($MASTER) ---"
run_ssh "$MASTER" "kubeadm certs renew all"
run_ssh "$MASTER" "kubeadm init phase kubeconfig all"
run_ssh "$MASTER" "cp /etc/kubernetes/admin.conf /root/.kube/config"
run_ssh "$MASTER" "cp /etc/kubernetes/admin.conf /etc/kubernetes/bootstrap-kubelet.conf"
echo "Перезапуск компонентов Control Plane..."
run_ssh "$MASTER" "mkdir -p /tmp/k8s_manifests_backup && mv /etc/kubernetes/manifests/*.yaml /tmp/k8s_manifests_backup/"
sleep 5
run_ssh "$MASTER" "mv /tmp/k8s_manifests_backup/*.yaml /etc/kubernetes/manifests/"
run_ssh "$MASTER" "systemctl restart kubelet"
echo "Ожидание готовности API-сервера..."
until run_ssh "$MASTER" "kubectl get nodes &>/dev/null"; do
printf "."
sleep 2
done
echo " API запущен."
echo "Генерация токена присоединения..."
JOIN_CMD=$(run_ssh "$MASTER" "kubeadm token create --print-join-command")
echo "Команда: $JOIN_CMD"
echo -e "\n--- 2. Переподключение Worker-нод ---"
for WORKER in "${WORKERS[@]}"; do
echo "Обработка $WORKER..."
run_ssh "$WORKER" "kubeadm reset -f"
run_ssh "$WORKER" "rm -rf /etc/kubernetes/pki /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /var/lib/kubelet/pki"
run_ssh "$WORKER" "$JOIN_CMD"
done
echo -e "\n--- 3. Одобрение CSR и ожидание Ready ---"
for i in {1..20}; do
PENDING_CSR=$(run_ssh "$MASTER" "kubectl get csr | grep -i Pending | awk '{print \$1}'")
if [ -n "$PENDING_CSR" ]; then
echo "Одобрение запросов: $PENDING_CSR"
run_ssh "$MASTER" "echo '$PENDING_CSR' | xargs -r kubectl certificate approve"
fi
NOT_READY_COUNT=$(run_ssh "$MASTER" "kubectl get nodes --no-headers | grep -v 'Ready' | wc -l")
if [ "$NOT_READY_COUNT" -eq "0" ]; then
echo -e "\nВсе ноды в статусе Ready."
break
fi
printf "Ожидание (попытка %d/20)...\r" "$i"
sleep 5
done
echo -e "\n--- 4. Настройка локального kubectl ---"
mkdir -p "$HOME/.kube"
sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no "$SSH_USER@$MASTER" "sudo cat /etc/kubernetes/admin.conf" > "$HOME/.kube/config"
chown "$(id -u)":"$(id -g)" "$HOME/.kube/config"
echo -e "\n--- 5. Очистка временных файлов ---"
run_ssh "$MASTER" "rm -rf /tmp/k8s_manifests_backup"
echo -e "\n--- 6. Сроки сертификатов ---"
run_ssh "$MASTER" "kubeadm certs check-expiration"
echo -e "\n--- 7. Статус кластера ---"
kubectl get nodes
echo "Скрипт успешно завершен!"
#!/bin/bash
# Вот краткое описание работы скрипта.
# Предварительная проверка:
# * Проверяет доступность узлов по сети (ping) и
# наличие утилиты sshpass (устанавливает её при необходимости).
# Реанимация Master-ноды:
# * Обновляет истекшие сертификаты через kubeadm certs renew
# * пересоздает конфигурационные файлы
# * перезапускает компоненты Control Plane (API-server, etcd и др.)
# Оживление API:
# * Использует curl для ожидания готовности API-сервера, прежде чем переходить к следующим шагам.
# Переподключение Worker-нод:
# * Сбрасывает настройки на рабочих узлах через kubeadm reset и
# заново вводит их в кластер с использованием свежего токена.
# Автоматизация CSR:
# * В цикле находит и одобряет запросы на подпись сертификатов
# (Certificate Signing Requests) чтобы ноды могли перейти в статус Ready.
# Настройка доступа:
# * Копирует обновленный admin.conf с мастера
# в локальную папку ~/.kube/config для управления кластером без SSH.
# Очистка и аудит:
# * Удаляет временные файлы на мастере и выводит итоговую таблицу
# сроков действия сертификатов и статус всех узлов.
# Параметры подключения
MASTER="k8s-master.techedu.lab"
WORKERS=("k8s-worker1.techedu.lab" "k8s-worker2.techedu.lab")
ALL_NODES=("$MASTER" "${WORKERS[@]}")
# Проверка наличия пароля
# 1. Проверка или запрос пароля
if [ -n "$1" ]; then
PASSWORD=$1
else
read -sp "Введите пароль root для серверов: " PASSWORD
echo ""
fi
if [ -z "$PASSWORD" ]; then
echo "Ошибка: пароль не может быть пустым."
exit 1
fi
echo "--- 0. Предварительные проверки ---"
# 2. Проверка доступности серверов пингом
echo "Проверка пинга..."
for node in "${ALL_NODES[@]}"; do
if ! ping -c 1 -W 2 "$node" > /dev/null; then
echo "[ ERROR ] $node не отвечает на ping."
exit 1
fi
done
echo "[ OK ] Все узлы доступны по сети."
# 3. Проверка и установка sshpass
if ! command -v sshpass &> /dev/null; then
echo "Установка sshpass..."
sudo apt-get update && sudo apt-get install -y sshpass || sudo yum install -y sshpass
fi
# 4. Проверка корректности пароля (пробное подключение)
echo "Проверка пароля SSH..."
if ! sshpass -p "$PASSWORD" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=5 root@"$MASTER" "exit" &>/dev/null; then
echo "[ ERROR ] Не удалось подключиться к $MASTER. Неверный пароль или доступ по SSH ограничен."
exit 1
fi
echo "[ OK ] Пароль подтвержден."
run_ssh() {
local host=$1
local cmd=$2
sshpass -p"$PASSWORD" ssh -o StrictHostKeyChecking=no root@"$host" "$cmd"
}
echo -e "\n--- 1. Восстановление Master-ноды ($MASTER) ---"
run_ssh "$MASTER" "kubeadm certs renew all"
run_ssh "$MASTER" "kubeadm init phase kubeconfig all"
run_ssh "$MASTER" "cp /etc/kubernetes/admin.conf /root/.kube/config"
run_ssh "$MASTER" "cp /etc/kubernetes/admin.conf /etc/kubernetes/bootstrap-kubelet.conf"
# Перезапуск статик-подов control plane через временную папку
echo "Перезапуск компонентов управления..."
run_ssh "$MASTER" "mkdir -p /tmp/k8s_manifests_backup && mv /etc/kubernetes/manifests/*.yaml /tmp/k8s_manifests_backup/"
sleep 5
run_ssh "$MASTER" "mv /tmp/k8s_manifests_backup/*.yaml /etc/kubernetes/manifests/"
run_ssh "$MASTER" "systemctl restart kubelet"
echo "Ожидание готовности API-сервера (curl)..."
until run_ssh "$MASTER" "kubectl get nodes &>/dev/null "; do
printf "."
sleep 2
done
echo " API запущен."
echo "Создание токена и вывод команды для присоединения нод к кластеру"
JOIN_CMD=$(run_ssh "$MASTER" "kubeadm token create --print-join-command")
echo "Команда для присоединения:"
echo $JOIN_CMD
echo -e "\n--- 2. Переподключение Worker-нод ---"
for WORKER in "${WORKERS[@]}"; do
echo "Обработка $WORKER..."
run_ssh "$WORKER" "kubeadm reset -f"
run_ssh "$WORKER" "rm -rf /etc/kubernetes/pki /etc/kubernetes/kubelet.conf /etc/kubernetes/bootstrap-kubelet.conf /var/lib/kubelet/pki"
run_ssh "$WORKER" "$JOIN_CMD"
done
echo -e "\n--- 3. Одобрение CSR и ожидание Ready ---"
for i in {1..20}; do
# Поиск и одобрение всех Pending CSR
PENDING_CSR=$(run_ssh "$MASTER" "kubectl get csr | grep -i Pending | awk '{print \$1}'")
if [ ! -z "$PENDING_CSR" ]; then
echo "Одобрение запросов: $PENDING_CSR"
run_ssh "$MASTER" "echo '$PENDING_CSR' | xargs -r kubectl certificate approve"
fi
# Проверка статуса нод
NOT_READY_COUNT=$(run_ssh "$MASTER" "kubectl get nodes --no-headers | grep -v 'Ready' | wc -l")
if [ "$NOT_READY_COUNT" -eq "0" ]; then
echo -e "\nВсе ноды в статусе Ready."
break
fi
printf "Ожидание статуса Ready (попытка $i/20)...\r"
sleep 5
done
echo -e "\n--- 4. Настройка локального доступа ---"
mkdir -p "$HOME/.kube"
sshpass -p "$PASSWORD" scp -o StrictHostKeyChecking=no root@"$MASTER":/etc/kubernetes/admin.conf "$HOME/.kube/config"
chown $(id -u):$(id -g) "$HOME/.kube/config"
echo -e "\n--- 5. Очистка временных файлов на мастере ---"
run_ssh "$MASTER" "rm -rf /tmp/k8s_manifests_backup"
echo "Временные файлы удалены."
echo -e "\n--- 6. Проверка сертификатов ---"
run_ssh "$MASTER" "kubeadm certs check-expiration"
echo -e "\n--- 7. Итоговый статус нод кластера ---"
kubectl get nodes
echo "Скрипт успешно завершен!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment