mantenimiento.sh
#!/usr/bin/env bash
# Lanza los playbooks de mantenimiento de los nodos desde el master-1, en un contenedor.
# Hasta que esté el portal (Semaphore), es la forma de usarlos.
#
# Uso: ./scripts/mantenimiento.sh <revisar|actualizar|tailscale|reiniciar|k3s> [opciones de ansible-playbook]
# ./scripts/mantenimiento.sh revisar
# ./scripts/mantenimiento.sh actualizar --check simulación
# ./scripts/mantenimiento.sh actualizar -e nodos=workers solo los workers
# ./scripts/mantenimiento.sh tailscale -e nodos=worker-3
# ./scripts/mantenimiento.sh k3s -e version=v1.34.12+k3s1 --check
#
# Necesita, solo para root y fuera de git, en $CLAVES (por defecto /root/.config/mantenimiento):
# mantenimiento_ed25519 clave SSH del usuario `ansible` de los nodos
# known_hosts huellas de los nodos (ver ansible/README.md)
# kubeconfig de la ServiceAccount `mantenimiento-nodos` (ansible/kubernetes/)
set -euo pipefail
RAIZ="$(cd "$(dirname "$0")/.." && pwd)"
CLAVES="${CLAVES:-/root/.config/mantenimiento}"
IMAGEN="mantenimiento-ansible:$(sha256sum "$RAIZ/ansible/Dockerfile" "$RAIZ/ansible/requirements.txt" | sha256sum | cut -c1-12)"
PLAYBOOK="${1:-}"
case "$PLAYBOOK" in
revisar|actualizar|tailscale|reiniciar|k3s) shift ;;
*) sed -n '2,15p' "$0"; exit 64 ;;
esac
for f in mantenimiento_ed25519 known_hosts kubeconfig; do
[ -r "$CLAVES/$f" ] || { echo "Falta $CLAVES/$f (ver ansible/README.md)" >&2; exit 1; }
done
if ! docker image inspect "$IMAGEN" >/dev/null 2>&1; then
echo "Construyendo $IMAGEN…"
docker build -q -t "$IMAGEN" "$RAIZ/ansible" >/dev/null
fi
# Red del host: los nodos ven llegar la conexión desde 192.0.2.112, la única IP
# que acepta la clave del usuario `ansible`. Corre como root del contenedor para
# poder leer $CLAVES (0600 de root), pero sin ninguna capacidad y en solo lectura.
TTY=(); [ -t 1 ] && TTY=(-t)
exec docker run --rm "${TTY[@]}" --network host --read-only --tmpfs /tmp:exec \
--user 0:0 -e HOME=/tmp --cap-drop ALL --security-opt no-new-privileges \
-v "$RAIZ/ansible:/ansible:ro" \
-v "$CLAVES:/claves:ro" \
"$IMAGEN" "playbooks/$PLAYBOOK.yml" "$@"