Last active
February 9, 2026 19:37
-
-
Save regispires/8ee955d790f7c652147a0b0efb27893e to your computer and use it in GitHub Desktop.
microk8s-worker-rejoin - Uso não-interativo para automação: sudo bash microk8s-worker-rejoin.sh --yes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # ============================================================================= | |
| # microk8s-worker-rejoin.sh (v3) | |
| # Script seguro para rejoin de um worker node no cluster MicroK8s | |
| # | |
| # Uso: | |
| # sudo bash microk8s-worker-rejoin.sh [--yes] | |
| # | |
| # Flags: | |
| # --yes Pula todas as confirmações interativas (modo não-interativo) | |
| # ============================================================================= | |
| set -euo pipefail | |
| # ── Cores e formatação ─────────────────────────────────────────────────────── | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| CYAN='\033[0;36m' | |
| BOLD='\033[1m' | |
| NC='\033[0m' | |
| # ── Variáveis globais ──────────────────────────────────────────────────────── | |
| AUTO_YES=false | |
| LOG_FILE="/tmp/microk8s-rejoin-$(date +%Y%m%d-%H%M%S).log" | |
| HOSTNAME=$(hostname) | |
| STEP=0 | |
| # Diretórios-alvo de limpeza | |
| CLEAN_DIRS=( | |
| "/var/snap/microk8s/common/run" | |
| "/var/snap/microk8s/current/args/cni-network" | |
| "/var/snap/microk8s/common/var/lib/cni" | |
| "/var/snap/microk8s/common/var/lib/calico" | |
| ) | |
| CRED_DIR="/var/snap/microk8s/current/credentials" | |
| # ── Funções utilitárias ────────────────────────────────────────────────────── | |
| log() { echo -e "$(date '+%H:%M:%S') ${GREEN}[INFO]${NC} $*" | tee -a "$LOG_FILE"; } | |
| warn() { echo -e "$(date '+%H:%M:%S') ${YELLOW}[WARN]${NC} $*" | tee -a "$LOG_FILE"; } | |
| err() { echo -e "$(date '+%H:%M:%S') ${RED}[ERRO]${NC} $*" | tee -a "$LOG_FILE"; } | |
| step() { STEP=$((STEP + 1)); echo -e "\n${CYAN}${BOLD}══ Passo ${STEP}: $* ══${NC}" | tee -a "$LOG_FILE"; } | |
| confirm() { | |
| if $AUTO_YES; then | |
| log "Auto-confirmado (--yes): $1" | |
| return 0 | |
| fi | |
| echo "" | |
| read -rp "$(echo -e "${YELLOW}⚠ $1 [s/N]: ${NC}")" resp | |
| case "$resp" in | |
| [sS]|[sS][iI][mM]) return 0 ;; | |
| *) err "Operação cancelada pelo usuário."; exit 1 ;; | |
| esac | |
| } | |
| run_cmd() { | |
| local desc="$1"; shift | |
| log "Executando: $*" | |
| if "$@" >> "$LOG_FILE" 2>&1; then | |
| log "✔ ${desc} — OK" | |
| else | |
| local rc=$? | |
| warn "✘ ${desc} — código de saída: ${rc} (continuando...)" | |
| return 0 | |
| fi | |
| } | |
| run_cmd_strict() { | |
| local desc="$1"; shift | |
| log "Executando: $*" | |
| if "$@" >> "$LOG_FILE" 2>&1; then | |
| log "✔ ${desc} — OK" | |
| else | |
| local rc=$? | |
| err "✘ ${desc} — código de saída: ${rc}" | |
| err "Verifique o log em: ${LOG_FILE}" | |
| exit "$rc" | |
| fi | |
| } | |
| # ── Parse de argumentos ────────────────────────────────────────────────────── | |
| for arg in "$@"; do | |
| case "$arg" in | |
| --yes|-y) AUTO_YES=true ;; | |
| --help|-h) | |
| echo "Uso: sudo bash $0 [--yes]" | |
| echo " --yes, -y Pula confirmações interativas" | |
| exit 0 | |
| ;; | |
| *) err "Argumento desconhecido: $arg"; exit 1 ;; | |
| esac | |
| done | |
| # ── Pré-verificações ───────────────────────────────────────────────────────── | |
| echo -e "${BOLD}" | |
| echo "╔══════════════════════════════════════════════════════════════╗" | |
| echo "║ MicroK8s Worker — Procedimento de Rejoin (v3) ║" | |
| echo "╚══════════════════════════════════════════════════════════════╝" | |
| echo -e "${NC}" | |
| log "Host: ${HOSTNAME}" | |
| log "Log: ${LOG_FILE}" | |
| log "Data: $(date '+%Y-%m-%d %H:%M:%S')" | |
| # Exige root | |
| if [[ $EUID -ne 0 ]]; then | |
| err "Este script deve ser executado como root (sudo)." | |
| exit 1 | |
| fi | |
| # Verifica se microk8s está instalado | |
| if ! command -v microk8s &>/dev/null; then | |
| err "microk8s não encontrado no PATH. Verifique a instalação." | |
| exit 1 | |
| fi | |
| # Detecta se é um nó control-plane (segurança extra) | |
| if microk8s status 2>/dev/null | grep -q "datastore master nodes" && \ | |
| microk8s kubectl get nodes 2>/dev/null | grep -q "$(hostname).*control-plane"; then | |
| err "ATENÇÃO: Este nó parece ser um control-plane, NÃO um worker!" | |
| err "Este script é destinado APENAS a workers. Abortando." | |
| exit 1 | |
| fi | |
| echo "" | |
| warn "Este procedimento irá:" | |
| warn " • Desconectar este nó do cluster (microk8s leave)" | |
| warn " • Resetar workloads e configurações (microk8s reset)" | |
| warn " • Limpar CNI, runtime e credenciais (preservando client.config)" | |
| warn " • Reiniciar o microk8s limpo" | |
| echo "" | |
| confirm "Deseja prosseguir com o rejoin do worker '${HOSTNAME}'?" | |
| # ============================================================================= | |
| # PASSO 1 — Sair do cluster | |
| # ============================================================================= | |
| step "Sair do cluster (microk8s leave)" | |
| run_cmd "microk8s leave" microk8s leave | |
| log "Se já estava desconectado, o erro acima é esperado." | |
| # ============================================================================= | |
| # PASSO 2 — Reset do microk8s | |
| # ============================================================================= | |
| step "Reset do microk8s (limpa workloads, certificados gerados, etc.)" | |
| confirm "Executar 'microk8s reset'? Isso remove todos os workloads locais." | |
| run_cmd "microk8s reset" microk8s reset | |
| # ============================================================================= | |
| # PASSO 3 — Parar o microk8s | |
| # ============================================================================= | |
| step "Parar o microk8s" | |
| run_cmd_strict "microk8s stop" microk8s stop | |
| log "Verificando status..." | |
| if microk8s status 2>&1 | grep -q "microk8s is not running"; then | |
| log "✔ Status confirmado: microk8s is not running" | |
| else | |
| STATUS_OUT=$(microk8s status 2>&1 || true) | |
| warn "Status inesperado após stop:" | |
| warn "${STATUS_OUT}" | |
| confirm "O microk8s pode não ter parado completamente. Continuar mesmo assim?" | |
| fi | |
| # ============================================================================= | |
| # PASSO 4 — Limpeza pesada (CNI + runtime) | |
| # ============================================================================= | |
| step "Limpeza pesada (desmontagem + remoção de CNI/runtime)" | |
| # 4a. Desmontar filesystems residuais (match exato com ^ no início do path) | |
| log "Desmontando filesystems residuais..." | |
| umount $(mount | awk '{print $3}' | grep -E '^/var/snap/microk8s/(common/run|current/args/cni-network|common/var/lib/cni|common/var/lib/calico|current/credentials)/') 2>/dev/null || true | |
| log "✔ Desmontagem concluída." | |
| # 4b. Remover conteúdo dos diretórios de CNI e runtime | |
| for dir in "${CLEAN_DIRS[@]}"; do | |
| if [[ -d "$dir" ]]; then | |
| log "Limpando: ${dir}/*" | |
| rm -rf "${dir:?}"/* 2>/dev/null || warn "Falha parcial ao limpar: ${dir}" | |
| else | |
| log "Diretório não existe (OK): ${dir}" | |
| fi | |
| done | |
| log "✔ Limpeza de CNI/runtime concluída." | |
| # ============================================================================= | |
| # PASSO 5 — Limpeza de credenciais (preserva client.config) | |
| # ============================================================================= | |
| step "Limpeza de credenciais (resolve x509 unknown authority)" | |
| if [[ -d "$CRED_DIR" ]]; then | |
| # client.config é necessário para o wrapper 'microk8s' verificar permissões. | |
| # Sem ele, qualquer comando 'microk8s' falha com "Insufficient permissions". | |
| if [[ -f "${CRED_DIR}/client.config" ]]; then | |
| log "client.config encontrado — será preservado." | |
| else | |
| warn "client.config NÃO encontrado! O wrapper 'microk8s' pode falhar após a limpeza." | |
| warn "Se isso ocorrer, use: sudo snap refresh microk8s --channel=1.32/stable" | |
| fi | |
| CRED_COUNT=$(find "$CRED_DIR" -type f ! -name 'client.config' 2>/dev/null | wc -l) | |
| log "Arquivos de credenciais a remover: ${CRED_COUNT} (excluindo client.config)" | |
| confirm "Remover credenciais em ${CRED_DIR} (preservando client.config)?" | |
| find "${CRED_DIR}/" -type f ! -name 'client.config' -delete 2>/dev/null || \ | |
| warn "Falha parcial ao limpar credenciais" | |
| log "Arquivos restantes em credentials:" | |
| ls -la "${CRED_DIR}/" 2>/dev/null | tee -a "$LOG_FILE" | |
| log "✔ Credenciais removidas (client.config preservado)." | |
| else | |
| log "Diretório de credenciais não existe (OK)." | |
| fi | |
| # ============================================================================= | |
| # PASSO 6 — Subir microk8s limpo | |
| # ============================================================================= | |
| step "Iniciar microk8s limpo" | |
| run_cmd_strict "microk8s start" microk8s start | |
| log "Aguardando microk8s ficar pronto (até 120s)..." | |
| TIMEOUT=120 | |
| ELAPSED=0 | |
| while [[ $ELAPSED -lt $TIMEOUT ]]; do | |
| if microk8s status 2>&1 | grep -q "microk8s is running"; then | |
| break | |
| fi | |
| sleep 5 | |
| ELAPSED=$((ELAPSED + 5)) | |
| printf "." | |
| done | |
| echo "" | |
| if microk8s status 2>&1 | grep -q "microk8s is running"; then | |
| log "✔ microk8s está rodando!" | |
| else | |
| warn "microk8s não reportou 'running' após ${TIMEOUT}s." | |
| warn "Verifique manualmente com: sudo microk8s status" | |
| fi | |
| # ============================================================================= | |
| # RESUMO FINAL | |
| # ============================================================================= | |
| echo "" | |
| echo -e "${BOLD}" | |
| echo "╔══════════════════════════════════════════════════════════════╗" | |
| echo "║ Rejoin — Concluído ║" | |
| echo "╚══════════════════════════════════════════════════════════════╝" | |
| echo -e "${NC}" | |
| log "Procedimento de limpeza finalizado em ${HOSTNAME}." | |
| echo "" | |
| echo -e "${CYAN}${BOLD}Próximos passos:${NC}" | |
| echo -e " 1. No ${BOLD}control-plane${NC}, gere o token de join:" | |
| echo -e " ${GREEN}sudo microk8s add-node${NC}" | |
| echo "" | |
| echo -e " 2. Neste ${BOLD}worker${NC}, execute o comando fornecido:" | |
| echo -e " ${GREEN}sudo microk8s join <IP-CONTROL-PLANE>:<PORT>/<TOKEN> --worker${NC}" | |
| echo "" | |
| echo -e " 3. Verifique no control-plane:" | |
| echo -e " ${GREEN}sudo microk8s kubectl get nodes${NC}" | |
| echo "" | |
| echo -e "Log completo: ${YELLOW}${LOG_FILE}${NC}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment