CommunityProgramación y desarrollogithub.com

seaworld008/centos7-almalinux-upgrade

Actualiza servidores CentOS 7/8 (y RHEL 7/8) antiguos a AlmaLinux 10 de manera segura e in situ, preservando aplicaciones, contenedores, nginx, kubectl, etc. Utiliza ELevate/Leapp para la ruta 7→8→9→10 y almalinux-deploy para CentOS 8.

¿Qué es centos7-almalinux-upgrade?

Este skill automatiza la migración in situ de servidores CentOS 7/8 (y derivados de RHEL) a AlmaLinux 10, garantizando que los servicios y aplicaciones existentes (nginx, Docker, kubectl, bases de datos, etc.) sigan funcionando tras la actualización. Está diseñado para entornos de producción reales, con énfasis en la seguridad, reversibilidad y verificación en cada paso. El flujo típico es 7→8, 8→9, 9→10, utilizando las herramientas ELevate y Leapp. Para servidores CentOS 8, primero se convierte a AlmaLinux 8 con almalinux-deploy. Incluye scripts de diagnóstico (survey), backup, verificación de línea base, preparación del sistema, ejecución de saltos, y finalización/post-procesamiento. Soporta operaciones tanto en un solo servidor como en flotas completas, con clasificación automática de riesgos y recomendaciones de lotes. Además, documenta en detalle los bloqueos conocidos, pasos de recuperación y compatibilidad de aplicaciones, basándose en ejecuciones reales en producción.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/seaworld008/centos7-lighthouse/tree/HEAD/skills/centos7-almalinux-upgrade

Installed? Explore more Programación y desarrollo skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

CentOS 7 → AlmaLinux 10 — Actualización in situ

Este es un flujo consolidado a partir de una migración real de producción (servidor bastión de Huawei Cloud, CentOS 7.7 → AlmaLinux 10.2, manteniendo nginx/Docker/xxl-job/MySQL/NetBird/kubectl). Su objetivo es que cada máquina pueda actualizarse de forma segura, reversible y verificable, y que se pueda realizar en lote.

Idea central: Evaluar primero → instantánea de respaldo → pasos pequeños (preverificar→actualizar→reiniciar→comparar línea base→finalizar) → modernizar al final. La mayoría de los problemas surgen de elementos "no oficiales" (programas compilados manualmente, paquetes pip, repositorios de terceros, OpenSSH compilado manualmente, políticas de reinicio de contenedores, rutas de acceso VPN), por lo que la fase de diagnóstico es la más valiosa.

Cuándo NO actualizar in situ

Primero revise los BLOQUEOS de survey.sh. En los siguientes casos se recomienda crear una nueva máquina con AlmaLinux 10 y migrar los servicios, en lugar de actualizar in situ:

  • Es un nodo de Kubernetes (kubelet en ejecución) — debe tratarse como un cambio a nivel de clúster, siguiendo references/kubernetes.md (ya probado: kubeadm 1.21 + dockershim + flannel/ipvs funciona en EL10, clúster 3m3w ~6 horas); también se puede drenar y reemplazar el nodo.
  • La base de datos instalada desde rpm debe saltar múltiples versiones principales (MariaDB 5.5→10.11, PostgreSQL 9.2→16) y tiene grandes volúmenes de datos.
  • No es x86_64, usa btrfs, o el disco del sistema es extremadamente pequeño y no se puede ampliar.
  • La CPU no es compatible con x86-64-v3 (la edición estándar de AlmaLinux 10 no funcionará; solo se puede actualizar a 9, o usar la variante x86_64_v2 de AlmaLinux 10).
  • Los servicios ya están contenerizados y la configuración está en compose/k8s — crear una nueva máquina y redesplegar suele ser más rápido que actualizar in situ.

Si no está seguro, proporcione al usuario los criterios de evaluación y deje que él decida.

Kit de herramientas

El directorio scripts/ del skill (todo se sube a la máquina de destino mediante SSH a /root/os-upgrade-kit/ para su ejecución):

ScriptFunción
remote.pySe ejecuta localmente: toma credenciales de una tabla de activos (xlsx/csv), ejecuta comandos SSH, sube/descarga archivos, espera reinicios; mantiene keepalive; no muestra contraseñas
survey.shDiagnóstico de solo lectura, genera BANDERAS DE RIESGO (BLOQUEADOR/ALTO/MEDIO/INFO) al final
backup.shRespaldar configuración + generar línea base de servicios baseline.tsv (servicios, puertos, contenedores, códigos HTTP de cada dominio, kubectl)
state.sh / verify.shGenerar estado actual / comparar con línea base, reportar FALLO/ADVERTENCIA
prep-el7.shPreparación para EL7: repos (ajustar repositorios), update (a 7.9), pipfix, inhibitors
convert-el8.shCuando el sistema origen es CentOS 8: prep → run (almalinux-deploy oficial) → post, convertir a AlmaLinux 8
swap-openssh.shReemplazar OpenSSH compilado manualmente por el paquete oficial (con respaldo automático)
hop.shCada salto: prep→pre→report/answer→up→reboot→post
nginx-static-build.shRecompilación estática de nginx compilado manualmente con la misma versión (para mantenerlo funcional durante la transición)
fleet_summary.pySe ejecuta localmente: resume los resultados de survey de múltiples máquinas → clasificación A/B/C/D, marcas VPN/EL8, sugerencias de canario y lotes (--groups para que servidores principal y de respaldo del mismo servicio no estén en el mismo lote)
finalize.shFinalización de EL10: empaquetado de compose, alineación de kubectl con el clúster, helm, postfix lmdb, fuente nginx.org, compatibilidad cgroup v1, empaquetado SysV, módulos iptables legacy, redis→valkey, convertir procesos iniciados manualmente a servicios systemd
k8s.shPara nodos K8s: backup (snapshot de etcd/configuración/binarios/lista de pods, pin automático de versiones), stop, nfs-off/nfs-on, nm, fix, check, pods (comparar con antes de la actualización), jvm-maxram (OOM en cgroup v2 con JDK antiguo)

Al invocarlo desde Windows Git Bash, remote.py ya maneja automáticamente la reescritura de MSYS que convierte /root/... en C:/Program Files/Git/root/....

Uso común:

export FLEET_INVENTORY="/path/to/servers.xlsx"   # Columnas: name, host, port, username, password (incluye contraseña, ¡no subir al repositorio!)
S=<directorio del skill>/scripts
python $S/remote.py HOST put $S /root/os-upgrade-kit
python $S/remote.py HOST run "bash /root/os-upgrade-kit/survey.sh > /root/os-upgrade-kit/survey.txt; sed -n '/RISK FLAGS/,\$p' /root/os-upgrade-kit/survey.txt"
python $S/remote.py HOST wait-ssh --timeout 3600

Flujo de trabajo

Fase 0: Confirmaciones obligatorias con el usuario antes de comenzar (no negociables)

Estas son "decisiones del usuario", no asuma por él:

  1. Instantánea de nube/respaldo completo de la máquina ya realizado (disco del sistema + discos de datos). Es el único medio confiable de reversión; Claude no puede hacerlo desde dentro de la máquina.
  2. Ventana de inactividad: cada salto requiere un reinicio, todo el proceso dura aproximadamente 2~4 horas (la mayor parte del tiempo se descargan paquetes; depende de la velocidad del espejo de repositorio); el servicio se interrumpirá varias veces.
  3. Consola fuera de banda disponible: VNC de Alibaba Cloud / VNC de Huawei Cloud / AWS EC2 Serial Console (requisitos previos en references/cloud-providers.md). Si la actualización se detiene en initramfs, solo se puede rescatar desde aquí.
  4. Ruta de acceso: ¿Cómo te conectas a esta máquina desde tu máquina local? Si es a través de VPN/túnel, ejecuta los comandos en esa máquina (survey reportará BLOQUEADOR). Ten especial cuidado con reinicios y operaciones de contenedores — en nuestro incidente real, docker stop de todos los contenedores provocó que el contenedor de ruta NetBird no se iniciara al arrancar, perdiendo conectividad en toda la VPC.
  5. Qué elementos ya no se usan: Después del diagnóstico, pasa la lista al usuario y pídele que confirme qué componentes/sitios se pueden dar de baja (por ejemplo, PHP, sitios antiguos). Antes de eliminar, explica claramente el impacto (p. ej., "eliminar PHP provocará que el sitio xxx devuelva 404") y que el usuario decida.

Fase 1: Diagnóstico + Respaldo + Línea base

  1. Sube el kit de herramientas, ejecuta survey.sh, revisa cada BANDERA DE RIESGO, y determina un plan de tratamiento para cada una consultando references/app-compat.md.
  2. Ejecuta backup.sh (por defecto en un disco que no sea del sistema, como /data) y anota el BACKUP_DIR. baseline.tsv será la base para comparar en cada salto — los elementos que ya estaban anómalos antes de la actualización (p. ej., 502) deben indicarse en el informe como "ya anómalo antes de la actualización" para evitar confusiones posteriores.
  3. Comunica al usuario de una sola vez las conclusiones del diagnóstico, los planes de tratamiento y los elementos que requieren su decisión (ver Fase 0).

Fase 2: Preparación de EL7

bash prep-el7.sh repos <MIRROR>      # Recomendado en China: https://mirrors.aliyun.com; red interna de Alibaba Cloud: http://mirrors.cloud.aliyuncs.com; en el extranjero: upstream
bash prep-el7.sh update              # Actualizar a 7.9; los paquetes que fallen suelen ser conflictos con pip
bash prep-el7.sh pipfix
bash prep-el7.sh inhibitors
bash swap-openssh.sh                 # Solo si survey reporta OpenSSH no oficial; después de hacerlo, verificar con una [nueva conexión]

Programas que dependen de bibliotecas de EL7 (como nginx compilado manualmente): recompílelos estáticamente en EL7 usando nginx-static-build.sh (o acepte desactivarlos durante la transición e instale el paquete oficial al final). Bases de datos en el servidor: realice primero un respaldo lógico.

Cuando el sistema de origen es CentOS Linux 8 / CentOS Stream 8 (survey reportará BLOQUEADOR): ELevate no lo admite como origen, así que omita la preparación de EL7 anterior y primero realice la conversión a la misma versión, luego comience desde el salto 8→9 en la Fase 3:

bash convert-el8.sh prep <MIRROR>                    # Ajustar repos (vault, EPEL8), conflictos con pip, kernel-devel sobrante
bash convert-el8.sh update                           # Actualizar a 8.5 (almalinux-deploy requiere ≥8.4)
bash convert-el8.sh run  <MIRROR> <almalinux-deploy.sh>   # almalinux-deploy oficial: -d permite degradar, -l usa espejo
bash hop.sh reboot && python remote.py HOST wait-ssh   # Reiniciar para entrar al kernel de AlmaLinux
bash convert-el8.sh post                             # Eliminar kernels que no sean de AlmaLinux, dnf upgrade

Los servidores en China generalmente no pueden acceder a GitHub raw, por lo que primero debe descargar almalinux-deploy.sh en su máquina local y luego subirlo.

Fase 3: Cada salto (7→8, 8→9, 9→10 — repetir cada uno)

bash hop.sh prep <MIRROR>     # Instalar ELevate para este salto, usar espejos para el repositorio de destino y repos de proveedores (docker-ce/epel), deshabilitar secciones test/nightly, limpiar pip, verificar conectividad
bash hop.sh pre               # Ejecutar preupgrade en segundo plano y esperar → reporte automático
bash hop.sh answer            # Responder automáticamente a problemas de seguridad conocidos; para el resto de elementos bloqueantes, usar los comandos de reparación del reporte y volver a hacer pre hasta que no haya bloqueos
bash hop.sh report            # Revisar especialmente "paquetes que serán eliminados" y "destino de paquetes críticos" — si un servicio depende de ellos, hay que buscar solución primero
bash hop.sh up                # Descargar en segundo plano + generar entorno de actualización
bash hop.sh reboot [nombres_de_contenedores_adicionales_a_detener]   # Detener solo contenedores con estado restart=always; no tocar contenedores VPN ni los con unless-stopped; si el negocio dice "no toques", usa --no-stop
python remote.py HOST wait-ssh --timeout 3600   # Esperar desde la máquina local; si hay timeout → consola, ver references/recovery.md
bash hop.sh post <MIRROR>     # Verificar marcas de fallo, limpiar leapp/kernels antiguos/repos residuales, dnf upgrade
bash verify.sh <BACKUP_DIR>   # FALLO debe corregirse; ADVERTENCIA evaluar si es esperado

Después de cada salto, corrija los problemas de servicio antes de pasar al siguiente; no los acumule para el final. Los bloqueos específicos de cada salto y su manejo están en references/pitfalls.md bajo "clasificación por salto".

Las tareas largas deben ejecutarse siempre en segundo plano: los scripts ya usan systemd-run para ejecutar leapp/dnf, por lo que si se corta la conexión SSH no se ven afectados; solo debes consultar periódicamente. Cuando escribas tus propios comandos, haz lo mismo; no dejes una sesión SSH colgada durante decenas de minutos.

Fase 4: Finalización y modernización en EL10

Según las necesidades del usuario, usa los subcomandos de finalize.sh y consulta references/app-compat.md:

  • nginx compilado manualmente → paquete oficial estable de nginx.org (ssl on; cambiar a listen 443 ssl;, TLS 1.2/1.3, certificados en /etc/nginx/ssl, systemd autoarranque)
  • docker-compose v1 → empaquetar como compose v2; aplicaciones antiguas con cgroup v1 añadir shim
  • kubectl → fuente pkgs.k8s.io, misma minor que el clúster; helm → última v3
  • postfix hash → lmdb; elementos de inicio en rc.local convertirlos a unidades systemd
  • dnf -y upgrade para actualizar todo, confirmar que dnf check-update esté vacío
  • Finalmente, reiniciar una vez más para probar el arranque automático, ejecutar verify.sh, todos los servicios deben iniciarse solos para considerar la tarea completa

Fase 5: Informe de entrega

Usa la estructura de assets/report-template.md para escribir al usuario: comparación de versiones, tabla de comparación de servicios (antes/después de la actualización), cambios de compatibilidad realizados, elementos pendientes que requieren acción del usuario (certificados expirados, plugins de proveedores de nube no reparados, etc.), ubicación del respaldo. En escenarios por lotes, actualiza también la tabla de seguimiento de activos (assets/fleet-tracker.csv).

Fase 6: Consolidar la experiencia (retroalimentar al repositorio del skill)

Este skill evoluciona con ejecuciones reales. Dirección del proyecto: https://github.com/seaworld008/centos7-lighthouse . Después de cada ejecución real (ya sea exitosa, fallida o con reversión):

  • Sigue la field-reports/TEMPLATE.md del repositorio para escribir un informe de campo desinfectado (sin IP reales, dominios, nombres de host ni credenciales).
  • Los nuevos problemas escríbelos en references/pitfalls.md; los que puedan detectarse automáticamente, agrégalos a survey.sh; los que puedan manejarse automáticamente, mejora los scripts.
  • Si el directorio de trabajo actual es ese repositorio, sigue su AGENTS.md; de lo contrario, entrega el informe al usuario y sugiérele que cree un issue o PR.

Principios clave (cada uno corresponde a un incidente real)

  • Nunca ejecutes docker stop $(docker ps -q) antes de reiniciar: los contenedores con unless-stopped que se detengan manualmente no se reiniciarán solos; si se detiene un contenedor VPN, perderás la conexión. Usa hop.sh reboot.
  • Los elementos instalados por pip en site-packages del sistema deben eliminarse antes de cada salto: si entran en conflicto con archivos rpm, la actualización fallará a medio camino en initramfs, dejando el sistema en modo de emergencia y en estado "semi-actualizado".
  • Todo lo que no sea oficial y no se reconozca debe tratarse primero: OpenSSH compilado manualmente, nginx compilado manualmente, repositorios de terceros, mysql-community-libs reemplazando a mariadb-libs... leapp no los maneja y se romperán tras la actualización.
  • En China, usa espejos locales y desactiva las secciones test/nightly de los repositorios de proveedores: mirrorlist/metalink son a menudo lentos o dan timeout; la fuente nightly de docker puede hacer que leapp falle por timeout. Los espejos de Huawei Cloud pueden limitar la tasa (429); Alibaba Cloud es el más estable.
  • Los patrones de pkill -f / pgrep -f no deben aparecer en tu propia línea de comandos; de lo contrario, podrías matar tu propia sesión SSH (nos pasó dos veces). Usa PID, archivos de script o la notación [l]eapp.
  • Compara la línea base en cada salto: detecta y corrige problemas de servicio en el mismo salto, como la rotura de Yearning con cgroup v2 o la falla de docker-compose v1.
  • Las decisiones que cambien el comportamiento del negocio deben dejarlas al usuario: eliminar componentes, dar de baja sitios, deshabilitar TLS 1.0/1.1, cambiar a una versión principal de base de datos.

Documentos de referencia (leer según necesidad)

  • references/pitfalls.md — Todos los problemas: fenómeno → causa → solución, clasificados por salto + generales. Si encuentras un error, consulta esto primero.
  • references/app-compat.md — Manejo de compatibilidad de diversas aplicaciones al migrar de EL7 a EL10: nginx, Docker/compose/cgroup v2, Java, Python, PHP, bases de datos, postfix, red, SSH, kubectl/helm, SysV, políticas de cifrado TLS.
  • references/cloud-providers.md — Diferencias entre Alibaba Cloud/Huawei Cloud/AWS: instantáneas, requisitos previos de consola fuera de banda, espejos de repositorio, agentes de proveedores de nube, cloud-init.
  • references/recovery.md — Cómo rescatar si el sistema se queda en modo de emergencia de initramfs, no se conecta al arrancar, o está en estado semi-actualizado (incluye trucos de operación en VNC).
  • references/fleet.md — Gestión de lotes de decenas o cientos de máquinas: tabla de activos, diagnóstico paralelo, clasificación, canario, lotes, registro.
  • references/kubernetes.md — Actualización in situ de nodos K8s: cosas que deben aclararse antes de empezar (ruta de acceso/punto de entrada del plano de control/etcd/almacenamiento), conclusiones de compatibilidad, orden recomendado, problemas encontrados, lista de verificación de recuperación.

Skills relacionados