Skip to content

Instantly share code, notes, and snippets.

@regispires
Last active February 9, 2026 19:37
Show Gist options
  • Select an option

  • Save regispires/8ee955d790f7c652147a0b0efb27893e to your computer and use it in GitHub Desktop.

Select an option

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
#!/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