Parcheas una flota. El kernel sube de versión. Unos minutos después tu monitor se enciende: GPUs desaparecidas, pools ZFS protestando, offloads de NIC perdidos, quizá una tela de InfiniBand inestable. Los servicios siguen activos… por ahora. Entonces lo ves: DKMS no compiló los módulos para el kernel nuevo, así que el próximo reinicio es una trampa.
Esta es la realidad de correr Ubuntu 24.04 en producción. Las actualizaciones del kernel son rutinarias; los fallos de DKMS son el precio de usar controladores fuera del kernel mainline. El objetivo aquí no es “arreglarlo después de que se rompa”. El objetivo es: arreglarlo mientras el sistema sigue en línea y hacer que la próxima actualización del kernel sea aburrida.
Cómo DKMS realmente falla tras una actualización del kernel
DKMS (Dynamic Kernel Module Support) existe porque los proveedores siguen entregando módulos de kernel que no están en el kernel mainline. NVIDIA, ZFS-on-Linux, algunos controladores NIC y RAID, VirtualBox, algunos agentes de seguridad—cualquier cosa que compile contra los headers del kernel es candidata.
Cuando Ubuntu instala un kernel nuevo, los scripts del paquete intentan recompilar los módulos DKMS para ese kernel. Si esa recompilación falla, puede que no lo notes de inmediato porque el kernel que se está ejecutando todavía tiene módulos cargados y funcionales. La rotura aparece cuando:
- Reinicias y el kernel nuevo arranca sin el módulo.
- initramfs se generó sin el módulo, provocando fallos en el arranque temprano (almacenamiento, root-on-ZFS, cifrado, etc.).
- Secure Boot bloquea el módulo sin firmar, y obtienes el caso “compilado pero no cargable”.
- Los headers del kernel nuevo no estaban instalados, así que DKMS no tuvo nada contra qué compilar.
La mayoría de los incidentes “DKMS roto” son uno de estos cuatro. La solución rara vez es misteriosa; suele ser laboriosa y operacionalmente aterradora. El truco es reducir el riesgo: diagnosticar con precisión, compilar para el kernel al que vas a arrancar, validar la capacidad de carga y solo entonces permitir reinicios.
Verdad seca: DKMS no es “dinámico” en el sentido que la gerencia imagina. Es “dinámico” como lo es un formulario en papel: puedes volver a rellenarlo cada vez que cambia el kernel.
Guion de diagnóstico rápido
Cuando intentas evitar tiempo de inactividad, la velocidad importa. El camino más rápido es: identificar el kernel objetivo, confirmar si el módulo existe para él, confirmar si puede cargarse y luego validar los artefactos de arranque (initramfs). Todo lo demás es guarnición.
Primero: ¿qué kernel estás ejecutando y qué kernels están instalados?
- Si todavía ejecutas el kernel antiguo, puedes reconstruir con calma antes de reiniciar.
- Si ya estás en el kernel nuevo y faltan módulos, necesitas restaurar la funcionalidad en el kernel en vivo (a veces posible, a veces no).
Segundo: ¿DKMS muestra “built” para el kernel objetivo?
- Si no está compilado: estás en modo “reconstruir y arreglar dependencias de construcción”.
- Si está compilado: comprueba si se instaló en
/lib/modules/<kernel>y simodprobetiene éxito.
Tercero: ¿Secure Boot está bloqueando el módulo?
- Secure Boot activado + módulo sin firmar = compilará bien y luego fallará al cargar con errores de firma.
- Este es el bucle número uno de “lo recompilé tres veces y nada cambió”.
Cuarto: ¿incluye initramfs lo que necesitas?
- Si el módulo es necesario para el arranque temprano (almacenamiento/root en ZFS, criptografía), “compilado” no basta.
- Regenera initramfs para el kernel objetivo y verifica que contenga el módulo.
Quinto: bloquea cambios riesgosos mientras lo arreglas
- Retén paquetes del kernel si unattended upgrades sigue descargando nuevos kernels mientras estás en mitad de la recuperación.
- Fija un kernel conocido bueno como opción de reversión.
Datos y contexto interesantes (por qué esto sigue ocurriendo)
- DKMS se originó en el ecosistema Dell a mediados de los 2000 para mantener los controladores de proveedores compilables tras actualizaciones del kernel, especialmente en flotas empresariales.
- Ubuntu ha incluido integración de DKMS durante años, pero aún depende de scripts de empaquetado y de la presencia de headers—sin headers, no hay módulo.
- La aplicación de Secure Boot convirtió “errores de compilación” en “errores de carga”. El módulo puede compilar perfectamente y aun así ser rechazado por el kernel.
- ZFS on Linux vivió fuera del árbol durante mucho tiempo por fricciones de licencia; esa historia explica por qué muchas instalaciones de Ubuntu todavía dependen de DKMS para los módulos ZFS.
- La estabilidad del ABI del kernel no es una promesa para módulos fuera del árbol. Pequeños saltos de kernel pueden romper compilaciones si el módulo usa APIs internas.
- La cadencia HWE y SRU de Ubuntu puede sorprenderte: una actualización del kernel puede llegar vía unattended upgrades aunque “no cambiaste nada”.
- initramfs es a menudo el verdadero dominio de fallo. El sistema arranca un kernel; luego el userspace temprano no encuentra el módulo de almacenamiento que necesita.
- Las compilaciones DKMS pueden verse afectadas por cambios en la toolchain (gcc, make, binutils). “Kernel actualizado” a veces es atajo para “tu compilador también avanzó”.
- Algunos proveedores entregan módulos precompilados para versiones concretas de kernel, pero las versiones de kernel de Ubuntu derivan; DKMS se convierte en la solución de respaldo—hasta que deja de serlo.
Una cita que ha sobrevivido más postmortems de los que cualquier persona merece: “La esperanza no es una estrategia.”
— Gene Kranz. También aplica a las recompilaciones DKMS.
Tareas prácticas: comandos, salidas y decisiones (12+)
Estos no son “ejecuta todo”. Son una caja de herramientas. Cada tarea incluye: el comando, salida de ejemplo, qué significa y la decisión que tomas a partir de ello.
Tarea 1: Confirmar el kernel en ejecución
cr0x@server:~$ uname -r
6.8.0-51-generic
Qué significa: Este es el kernel que se está ejecutando actualmente. Si DKMS falló durante la instalación de un kernel más nuevo, por lo general puedes arreglarlo sin corte inmediato, porque no estás usando aún ese kernel nuevo.
Decisión: Si el kernel en ejecución sigue siendo el conocido bueno, reconstruye DKMS para el kernel nuevo ahora y programa un reinicio controlado más tarde.
Tarea 2: Listar kernels instalados y ver cuál usará el próximo reinicio
cr0x@server:~$ dpkg -l 'linux-image-*generic' | awk '/^ii/{print $2,$3}'
linux-image-6.8.0-51-generic 6.8.0-51.52
linux-image-6.8.0-52-generic 6.8.0-52.53
Qué significa: Tienes al menos dos kernels instalados; la versión más alta suele seleccionarse al arranque.
Decisión: Identifica el kernel “objetivo” para el que debes tener módulos DKMS (aquí: 6.8.0-52-generic).
Tarea 3: Comprobar el estado de DKMS en los kernels
cr0x@server:~$ dkms status
zfs/2.2.2, 6.8.0-51-generic, x86_64: installed
zfs/2.2.2, 6.8.0-52-generic, x86_64: built
nvidia/550.90.07, 6.8.0-51-generic, x86_64: installed
nvidia/550.90.07, 6.8.0-52-generic, x86_64: added
Qué significa: “installed” significa que el módulo está compilado y copiado en /lib/modules/<kernel>. “built” está compilado pero puede que no esté instalado. “added” significa que DKMS conoce el módulo pero no lo ha compilado para ese kernel.
Decisión: Para el kernel objetivo, cualquier estado que no sea “installed” es un riesgo. Compila+instala ahora.
Tarea 4: Verificar que existen los headers del kernel objetivo
cr0x@server:~$ dpkg -l | awk '/linux-headers-6.8.0-52-generic/{print $1,$2,$3}'
ii linux-headers-6.8.0-52-generic 6.8.0-52.53
Qué significa: DKMS necesita headers. Si faltan, DKMS fallará con errores como “Kernel headers for target not found”.
Decisión: Si faltan headers, instálalos antes de reconstruir los módulos DKMS.
Tarea 5: Instalar los headers faltantes (si procede)
cr0x@server:~$ sudo apt-get update
Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Reading package lists... Done
cr0x@server:~$ sudo apt-get install -y linux-headers-6.8.0-52-generic
Reading package lists... Done
Building dependency tree... Done
The following NEW packages will be installed:
linux-headers-6.8.0-52-generic
Setting up linux-headers-6.8.0-52-generic (6.8.0-52.53) ...
Qué significa: Los headers ya están presentes; DKMS tiene una oportunidad justa.
Decisión: Reconstruye los módulos DKMS para el kernel objetivo.
Tarea 6: Forzar la instalación automática DKMS para el kernel objetivo
cr0x@server:~$ sudo dkms autoinstall -k 6.8.0-52-generic
Sign command: /lib/modules/6.8.0-52-generic/build/scripts/sign-file
Signing key: /var/lib/shim-signed/mok/MOK.priv
Public certificate (MOK): /var/lib/shim-signed/mok/MOK.der
Building module:
Cleaning build area... done.
Building module(s).... done.
Installing /lib/modules/6.8.0-52-generic/updates/dkms/zfs.ko
Installing /lib/modules/6.8.0-52-generic/updates/dkms/nvidia.ko
depmod... done.
Qué significa: DKMS compiló e instaló módulos para ese kernel específico, y depmod actualizó los mapas de dependencias de módulos.
Decisión: Si esto tuvo éxito, pasa a la validación: ¿puede cargarse el módulo (o al menos está presente y firmado)?
Tarea 7: Si falla, lee el log de compilación DKMS en serio
cr0x@server:~$ sudo tail -n 40 /var/lib/dkms/nvidia/550.90.07/build/make.log
CONFTEST: drm_prime_pages_to_sg_has_drm_device_arg
CONFTEST: drm_gem_object_put_unlocked
error: implicit declaration of function ‘drm_gem_object_put_unlocked’
make[2]: *** [scripts/Makefile.build:243: /var/lib/dkms/nvidia/550.90.07/build/nvidia-drm/nvidia-drm-gem.o] Error 1
make[1]: *** [Makefile:1926: /var/lib/dkms/nvidia/550.90.07/build] Error 2
make: *** [Makefile:234: __sub-make] Error 2
Qué significa: Esto es un desajuste de API en tiempo de compilación. No es un paquete que falte; es que el código fuente del módulo no soporta esta API del kernel.
Decisión: Deja de intentar reconstrucciones al azar. Necesitas una versión del controlador/módulo compatible con ese kernel (p. ej., actualizar el paquete del controlador NVIDIA), o debes arrancar el kernel anterior hasta que puedas.
Tarea 8: Validar la presencia del módulo para el kernel objetivo sin reiniciar
cr0x@server:~$ ls -l /lib/modules/6.8.0-52-generic/updates/dkms/ | egrep 'zfs|nvidia' | head
-rw-r--r-- 1 root root 8532480 Dec 29 10:12 nvidia.ko
-rw-r--r-- 1 root root 17362944 Dec 29 10:12 zfs.ko
Qué significa: Los archivos existen donde DKMS los coloca para ese kernel.
Decisión: Valida la capacidad de carga y el estado de firma (especialmente si Secure Boot está activo).
Tarea 9: Comprobar el estado de Secure Boot (el detector “compilado pero bloqueado”)
cr0x@server:~$ mokutil --sb-state
SecureBoot enabled
Qué significa: El kernel aplicará verificación de firma de módulos. Los DKMS sin firmar fallarán al cargarse.
Decisión: Si Secure Boot está habilitado, asegúrate de que los módulos DKMS estén firmados con una clave inscrita, o planifica un flujo controlado de inscripción MOK.
Tarea 10: Intentar cargar el módulo en el kernel en ejecución (solo cuando sea seguro)
cr0x@server:~$ sudo modprobe -v zfs
insmod /lib/modules/6.8.0-51-generic/updates/dkms/spl.ko
insmod /lib/modules/6.8.0-51-generic/updates/dkms/zfs.ko
Qué significa: En el kernel en ejecución, la carga del módulo tiene éxito. Esto es una comprobación de cordura de que tu instalación DKMS no está rota globalmente.
Decisión: Si modprobe falla con “Required key not available”, tienes problemas de firma con Secure Boot. Si falla con “Unknown symbol”, tienes un desajuste kernel/módulo.
Tarea 11: Inspeccionar los logs del kernel por errores de firma o símbolos
cr0x@server:~$ sudo dmesg -T | tail -n 20
[Mon Dec 29 10:19:02 2025] Lockdown: modprobe: unsigned module loading is restricted; see man kernel_lockdown.7
[Mon Dec 29 10:19:02 2025] nvidia: module verification failed: signature and/or required key missing - tainting kernel
Qué significa: Secure Boot o la política de lockdown están bloqueando o marcando como tainted. Algunos entornos toleran el taint; otros lo tratan como incumplimiento.
Decisión: Si tu política requiere módulos firmados, arregla el firmado y la inscripción ahora, antes de reiniciar en un kernel que rechazará el módulo por completo.
Tarea 12: Verificar que initramfs se reconstruyó para el kernel objetivo
cr0x@server:~$ ls -lh /boot/initrd.img-6.8.0-52-generic
-rw-r--r-- 1 root root 98M Dec 29 10:14 /boot/initrd.img-6.8.0-52-generic
Qué significa: El initramfs existe y se actualizó recientemente, pero eso no garantiza que contenga tu módulo.
Decisión: Si el módulo es necesario en el arranque (ZFS root, HBA de almacenamiento, NIC especial), debes verificar su presencia dentro del initramfs.
Tarea 13: Confirmar que el módulo está dentro del initramfs (el paso “confía pero verifica”)
cr0x@server:~$ lsinitramfs /boot/initrd.img-6.8.0-52-generic | egrep '/zfs\.ko|/nvidia\.ko' | head
usr/lib/modules/6.8.0-52-generic/updates/dkms/zfs.ko
Qué significa: ZFS está incluido en el userspace temprano para ese kernel. Para GPUs, por lo general no es necesario incluirlas en initramfs; para escenarios de arranque por red/almacenamiento puede ser obligatorio.
Decisión: Si falta, regenera initramfs después de arreglar la instalación DKMS.
Tarea 14: Reconstruir initramfs para un kernel específico (dirigido, no a lo loco)
cr0x@server:~$ sudo update-initramfs -u -k 6.8.0-52-generic
update-initramfs: Generating /boot/initrd.img-6.8.0-52-generic
Qué significa: Forzaste la regeneración de initramfs para el kernel que te importa.
Decisión: Vuelve a ejecutar las comprobaciones con lsinitramfs; solo entonces considera reiniciar.
Tarea 15: Asegurar que el mapa de dependencias de módulos es correcto para el kernel objetivo
cr0x@server:~$ sudo depmod -a 6.8.0-52-generic
Qué significa: modules.dep y amigos se actualizan. Algunos scripts postinst hacen esto; algunos fallos lo omiten. Ejecutarlo manualmente es barato.
Decisión: Si modprobe después se queja de que no puede encontrar dependencias, probablemente omitiste depmod o los módulos quedaron en una ruta no estándar.
Tarea 16: Retener actualizaciones del kernel mientras estabilizas (opcional pero frecuentemente sensato)
cr0x@server:~$ sudo apt-mark hold linux-image-generic linux-headers-generic
linux-image-generic set on hold.
linux-headers-generic set on hold.
Qué significa: Estás evitando que los meta-paquetes tiren nuevos kernels automáticamente.
Decisión: Usa esto durante la respuesta a incidentes. Quita los hold cuando tengas una canalización DKMS repetible y una puerta de validación.
Tarea 17: Confirmar cuál será la entrada de arranque por defecto (para no reiniciar en la trampa)
cr0x@server:~$ grep -E 'GRUB_DEFAULT|GRUB_TIMEOUT|GRUB_SAVEDEFAULT' /etc/default/grub
GRUB_DEFAULT=0
GRUB_TIMEOUT=5
Qué significa: El valor por defecto es la primera entrada del menú, típicamente el kernel más nuevo.
Decisión: Si el kernel más nuevo no tiene módulos funcionales, o arreglas DKMS para él o temporalmente configuras GRUB para arrancar el kernel conocido bueno.
Tarea 18: Detectar paquetes “medio configurados” tras una actualización desordenada
cr0x@server:~$ sudo dpkg --audit
The following packages are in a mess due to serious problems during installation. They must be reinstalled for them to work properly:
linux-image-6.8.0-52-generic
Qué significa: La instalación del paquete del kernel no terminó correctamente, lo que puede saltarse los triggers DKMS y la generación de initramfs.
Decisión: Arregla el estado del empaquetado antes de depurar DKMS sin fin.
Tarea 19: Reparar el estado de paquetes y volver a ejecutar triggers postinst
cr0x@server:~$ sudo apt-get -f install
Reading package lists... Done
Building dependency tree... Done
Correcting dependencies... Done
Setting up linux-image-6.8.0-52-generic (6.8.0-52.53) ...
update-initramfs: Generating /boot/initrd.img-6.8.0-52-generic
Qué significa: Los hooks post-install del kernel se ejecutaron. Eso a menudo incluye triggers de reconstrucción DKMS.
Decisión: Revisa de nuevo dkms status para el kernel objetivo; valida la presencia de módulos y el contenido del initramfs otra vez.
Broma 1: DKMS es como una suscripción al gimnasio: solo notas que no funciona cuando realmente intentas usarla.
Recuperar controladores sin tiempo de inactividad: estrategia que funciona
“Sin tiempo de inactividad” no significa magia. Significa que evitas reiniciar en un kernel que no puede cargar módulos críticos y evitas reiniciar hardware en medio del tráfico. Para la mayoría de incidentes DKMS, el sistema sigue ejecutándose en el kernel anterior y todo está bien—hasta que reinicias. Esa es tu ventana.
Paso 1: Decide qué significa “controlador crítico” en este equipo
No trates todos los módulos DKMS por igual. Un módulo VirtualBox faltante en un servidor es molesto; un módulo de almacenamiento faltante en un nodo root-on-ZFS es catastrófico. Clasifica el host:
- Crítico para almacenamiento: ZFS root, pools ZFS, controladores HBA, dependencias de dm-crypt.
- Crítico para red: controladores NIC fuera del árbol (raro en Ubuntu, pero ocurre), módulos DPDK, pilas SR-IOV, offloads de proveedor.
- Crítico para cómputo: nodos con NVIDIA GPU, clusters ML, transcodificadores de vídeo.
- “Deseable”: controladores de estaciones de trabajo y módulos no esenciales.
Crítico significa: no reiniciar hasta que el kernel objetivo tenga un módulo validado y cargable y un initramfs sano.
Paso 2: Compila para el kernel al que vas a arrancar, no para el que estás ejecutando
Los valores por defecto de DKMS pueden engañar. Si solo ejecutas dkms autoinstall sin -k, a menudo apunta al kernel en ejecución. Eso no es lo que necesitas durante la recuperación. Necesitas el kernel que se usará en el próximo arranque.
Compila explícitamente para la versión de kernel objetivo. Siempre.
Paso 3: Prefiere empaquetado del proveedor que siga tu línea de kernel
Cuando un módulo DKMS falla por desajustes de API, tienes dos opciones realistas:
- Actualizar el paquete del controlador/módulo a una versión compatible con el kernel nuevo.
- Aplazar el reinicio y fijar la versión del kernel hasta que exista un controlador compatible.
Intentar parchear el código del módulo en una caja de producción a las 2am es un hobby, no una práctica SRE.
Paso 4: Valida con “puede cargar” y “está en initramfs”
La presencia en disco no basta. Necesitas al menos uno de:
- Prueba de carga en el kernel objetivo (difícil sin reiniciar).
- Validación de firma (si Secure Boot está habilitado).
- Verificación de inclusión en initramfs para módulos críticos en arranque temprano.
Un compromiso práctico: valida la ruta del artefacto DKMS, ejecuta comprobaciones modinfo, verifica el estado de firmado del módulo y valida initramfs. Luego reinicia en una ventana de mantenimiento controlada con un kernel de reversión conocido listo.
Paso 5: No rompas tu propia red mientras arreglas un controlador
La mayoría de las recuperaciones DKMS son intensivas en CPU y disco pero no perturban el tráfico. La zona de peligro es cuando descargas/cargas módulos en vivo. A menos que tengas redundancia (bonding, multipath, clustering), evita descargar/cargar controladores de red/almacenamiento en un host crítico sin redundancia durante horas de negocio.
Reconstruir e instalar es seguro. Descargar/cargar es un cambio.
Paso 6: Crea una “puerta de reinicio”
En producción, el control más simple para no tener tiempo de inactividad es la política: no permitir reiniciar si los módulos DKMS no están instalados para el kernel más reciente instalado. Puedes aplicarlo con un script local que compruebe:
dkms statuspara el kernel objetivo muestra “installed” para los módulos críticoslsinitramfscontiene los módulos de arranque tempranomokutil --sb-statey el estado de firma están alineados
Luego lo integras en tu proceso de cambios. Aburrido. Funciona.
Secure Boot y firmado de módulos (MOK): el rompedor silencioso
Si ejecutas Ubuntu 24.04 en hardware con Secure Boot habilitado—y muchas organizaciones lo hacen porque cumplimiento ama las casillas—DKMS puede “tener éxito” y aun así perder funcionalidad. He aquí por qué:
- DKMS compila un módulo.
- El kernel se niega a cargarlo si no está firmado (o está firmado con una clave no inscrita).
- Lo descubres solo cuando el controlador se necesita por primera vez, a menudo después de un reinicio.
Cómo reconocer fallos de firma de Secure Boot rápidamente
Síntomas típicos:
modprobe: ERROR: could not insert '...': Required key not availabledmesgmuestra “module verification failed” o restricciones de lockdowndkms statusdice “installed” pero la funcionalidad está ausente
Qué hacer al respecto (opciones pragmáticas)
- Firmar módulos DKMS e inscribir la clave (MOK). Esta es la opción limpia cuando Secure Boot debe permanecer habilitado.
- Deshabilitar Secure Boot en firmware. Es operativamente la más simple pero puede violar políticas.
- Usar controladores firmados y en-tree cuando sea posible. A largo plazo es lo mejor, no siempre disponible.
Comprobar si DKMS está firmando módulos
cr0x@server:~$ sudo grep -R "sign-file" -n /etc/dkms /etc/modprobe.d 2>/dev/null | head
Qué significa: Puede que no haya una configuración explícita. En Ubuntu, el firmado de módulos para DKMS a menudo se integra con la herramienta shim/MOK y los scripts de empaquetado.
Decisión: Si Secure Boot está activo y ves fallos de firma, no adivines. Verifica el firmado del módulo con modinfo.
Inspeccionar metadatos de firma en un módulo
cr0x@server:~$ modinfo -F signer /lib/modules/6.8.0-52-generic/updates/dkms/zfs.ko
Canonical Ltd. Secure Boot Signing
Qué significa: El módulo lleva una cadena de firmante. Si está vacía, puede que esté sin firmar (o sin metadatos).
Decisión: Si falta el firmante y Secure Boot está activo, necesitas firmar e inscribir, o aceptar que el módulo no se cargará.
Verificar claves MOK inscritas
cr0x@server:~$ sudo mokutil --list-enrolled | head
[key 1]
SHA1 Fingerprint: 12:34:56:78:90:...
Subject: CN=Canonical Ltd. Secure Boot Signing
Qué significa: El sistema confía en un conjunto de claves. Si tu firmado DKMS usa una clave diferente, el kernel la rechazará.
Decisión: Alinea tu clave de firmado con las claves inscritas, o inscribe la clave correcta vía MOK (lo cual normalmente requiere un reinicio al gestor MOK).
Broma 2: Secure Boot es el portero en la discoteca del kernel: tu módulo puede estar perfecto y aun así no estar en la lista.
initramfs, arranque temprano y por qué “se compiló” no basta
initramfs es la imagen comprimida de userspace temprano que el kernel carga para pasar de “kernel iniciado” a “sistema raíz montado”. Si tu módulo crítico no está en initramfs, la presencia del módulo en disco es irrelevante porque el disco podría no estar accesible todavía.
Esto importa para:
- Sistemas root-on-ZFS
- Root cifrado que necesita módulos específicos temprano
- Algunos flujos exóticos de arranque por red o almacenamiento
Modo de fallo: DKMS instaló módulos, pero initramfs se generó antes de la instalación
Esto ocurre durante actualizaciones interrumpidas, operaciones de paquetes en paralelo o cuando DKMS corre tarde y initramfs se ejecutó antes. Arrancas y descubres que el userspace temprano no encuentra ZFS/SPL, o que tu controlador de almacenamiento no está presente.
Arreglo: reconstruye initramfs después de la instalación DKMS para el kernel objetivo y verifica contenidos con lsinitramfs.
Modo de fallo: múltiples kernels, initramfs obsoleto
Puedes tener un initramfs correcto para el kernel en ejecución pero no para el kernel más nuevo instalado. Así es como se arma la trampa del reinicio. Siempre valida el initramfs que coincide con el kernel al que vas a reiniciar.
Tres mini-historias corporativas (realistas, anonimizadas)
Mini-historia 1: El incidente causado por una suposición equivocada
Gestionaban un pequeño clúster GPU para inferencia por lotes. Nada exótico: hosts Ubuntu, controlador NVIDIA DKMS, un scheduler de trabajos y una ventana de cambios los martes. El ritmo de actualizaciones era “kernels automáticamente, controladores cuando alguien se queja”. Funcionó hasta que dejó de funcionar.
Una actualización del kernel llegó el viernes por la noche vía unattended upgrades. Nadie lo notó porque los nodos seguían ejecutando el kernel antiguo y las GPUs seguían disponibles. El lunes por la mañana drenaron un nodo para mantenimiento no relacionado y lo reiniciaron. Volvió sin cargar los módulos NVIDIA.
La suposición equivocada fue sutil: “Si el controlador está instalado, está instalado.” Nunca comprobaron si el controlador se había compilado para el kernel nuevo instalado. El nodo arrancó en el kernel más nuevo (como debía) y DKMS había fallado silenciosamente días antes.
Intentaron la solución clásica: reinstalar el paquete del controlador. Todavía no cargó. Finalmente alguien miró dmesg y encontró un mensaje de aplicación de firma de Secure Boot. Secure Boot se había habilitado en firmware tras una renovación de hardware reciente, pero nadie actualizó el runbook.
La solución fue sencilla—firmar e inscribir la clave correctamente—pero requirió reinicios hacia el gestor MOK. Perdieron un día coordinando reinicios entre nodos, algo evitable si hubieran tenido una puerta de reinicio y una comprobación “DKMS instalado para el kernel más nuevo”.
Mini-historia 2: La optimización que salió mal
Una firma financiera se cansó de parches lentos. Decidieron “optimizar” quitando herramientas de compilación de servidores de producción: sin gcc, sin make, sin headers, solo paquetes mínimos. A seguridad le gustó. La imagen era más pequeña, los escaneos más limpios y los servidores parecían más tipo appliance.
Luego se desplegó una actualización del kernel. DKMS intentó recompilar el módulo NIC fuera del árbol que necesitaban para las funciones de una tarjeta en particular. Sin compilador, sin headers, sin construcción. DKMS falló, pero el kernel actual siguió funcionando. El fallo permaneció invisible.
La siguiente oleada de reinicios ocurrió durante un mantenimiento de energía en el centro de datos. Los reinicios fueron obligatorios. Varios hosts arrancaron en el kernel nuevo sin el módulo NIC. El controlador incluido en el kernel funcionó lo suficiente para arrancar, pero carecía de las funciones de offload que habían afinado para la latencia. El síntoma no fue “sin red”. Fue peor: colapso de rendimiento intermitente y timeouts bajo carga.
Revirtieron la decisión de “imagen mínima” para esa flota y movieron las compilaciones DKMS a una canalización controlada: precompilan módulos para el kernel objetivo en un entorno de construcción, distribuyen los artefactos y verifican antes de reiniciar. La optimización no estaba mal en principio. Estaba mal sin reemplazar la construcción implícita de DKMS en el host por una cadena de suministro explícita.
La lección: si quitas compiladores de hosts, te responsabilizas por el proceso de construcción de módulos de extremo a extremo. Si no lo haces, solo pospones el fallo hasta el momento del reinicio.
Mini-historia 3: La práctica aburrida pero correcta que salvó el día
Una compañía de medios ejecutaba muchos servidores con intensivo uso de almacenamiento, algunos con pools ZFS. Su práctica era dolorosamente aburrida: cada actualización del kernel iba seguida de una comprobación automatizada de “preparación para reinicio”. Verificaba el estado DKMS para ZFS contra el kernel más nuevo instalado, comprobaba que initramfs contuviera ZFS y confirmaba que permanecía instalado un kernel conocido bueno como reversión.
Una mañana, la comprobación señaló un fallo en un subconjunto de hosts. DKMS mostraba ZFS “built” pero no “installed” para el kernel más nuevo. Los hosts aún funcionaban, así que no entraron en pánico. Bloquearon reinicios vía su orquestador y abrieron un ticket.
La causa raíz fue una carrera de empaquetado durante una actualización unattended anterior: la generación de initramfs ocurrió, luego la instalación DKMS falló y se reintentó, dejando un estado inconsistente. La comprobación aburrida lo detectó antes de cualquier reinicio. Ejecutaron dkms autoinstall -k, reconstruyeron initramfs para el kernel objetivo y limpiaron la puerta.
Cero tiempo de inactividad, sin drama, sin fin de semana. Así es la “excelencia operacional” cuando quitas la diapositiva de PowerPoint.
Errores comunes: síntoma → causa raíz → solución
1) Síntoma: dkms status muestra “added” para el kernel nuevo
Causa raíz: El módulo DKMS está registrado pero no compilado para ese kernel; faltan headers o la compilación falló antes.
Solución: Instala los headers para el kernel objetivo y luego ejecuta sudo dkms autoinstall -k <kernel>. Valida que los archivos existan bajo /lib/modules/<kernel>/updates/dkms.
2) Síntoma: La compilación DKMS falla con “Kernel headers not found”
Causa raíz: Falta el paquete linux-headers-<kernel>, o el enlace simbólico /lib/modules/<kernel>/build está roto.
Solución: Instala los headers coincidentes; verifica que ls -l /lib/modules/<kernel>/build apunte a los headers.
3) Síntoma: El módulo se compila, pero modprobe falla con “Required key not available”
Causa raíz: Secure Boot habilitado; módulo sin firmar o firmado con clave no inscrita.
Solución: Asegura que los módulos DKMS estén firmados con una clave de confianza e inscríbela vía MOK, o deshabilita Secure Boot si la política lo permite.
4) Síntoma: Al arrancar en el kernel nuevo se pierde ZFS/almacenamiento raíz
Causa raíz: initramfs para el kernel nuevo carece de los módulos requeridos, a menudo por el orden de triggers DKMS/postinst.
Solución: Tras la instalación DKMS, ejecuta update-initramfs -u -k <kernel> y confirma con lsinitramfs.
5) Síntoma: Errores de compilación DKMS sobre símbolos faltantes / declaraciones implícitas
Causa raíz: Cambio en la API del kernel; la versión del controlador no es compatible con el kernel nuevo.
Solución: Actualiza el paquete del controlador/módulo (p. ej., versión más nueva de NVIDIA/ZFS), o mantén el kernel y arranca en el anterior hasta disponer de paquetes compatibles.
6) Síntoma: Todo parece instalado, pero el hardware no funciona después del reinicio
Causa raíz: Compilaste para la versión de kernel equivocada (kernel en ejecución en lugar del instalado más nuevo), o arrancaste un kernel distinto al esperado.
Solución: Confirma los kernels instalados, confirma la selección de arranque por defecto, reconstruye explícitamente para el kernel de arranque con dkms autoinstall -k.
7) Síntoma: Las actualizaciones de paquetes cuelgan o dejan estado “medio configurado”
Causa raíz: Actualización interrumpida, contención del lock de dpkg, disco lleno o fallos en scripts postinst (a menudo DKMS).
Solución: Repara el estado de dpkg: apt-get -f install, comprueba espacio en disco y vuelve a ejecutar compilaciones DKMS después de que la capa de empaquetado esté sana.
Listas de verificación / plan paso a paso
Lista A: Recuperación sin tiempo de inactividad en un host que aún ejecuta el kernel antiguo
- Identificar el kernel objetivo (el más nuevo instalado): usa
dpkg -lpara imágenes instaladas. - Comprobar estado DKMS para módulos críticos contra ese kernel:
dkms status. - Instalar headers para el kernel objetivo si faltan:
apt-get install linux-headers-<kernel>. - Reconstruir módulos para el kernel objetivo:
dkms autoinstall -k <kernel>. - Validar artefactos existentes en
/lib/modules/<kernel>/updates/dkms. - Comprobación Secure Boot:
mokutil --sb-statey confirmar firmante del módulo conmodinfo. - Reconstruir initramfs para el kernel objetivo (hosts críticos de almacenamiento):
update-initramfs -u -k <kernel>. - Verificar contenido de initramfs:
lsinitramfsincluye los módulos requeridos. - Mantener reversión disponible: confirmar que un kernel antiguo conocido bueno sigue instalado.
- Programar reinicio con plan de reversión (acceso por consola, selección GRUB, manos remotas si es necesario).
Lista B: Si ya reiniciaste en el kernel roto
- Confirmar qué falta:
lsmod,modprobeydmesg. - Comprobar Secure Boot de inmediato; no pierdas tiempo reconstruyendo módulos sin firmar si Secure Boot los bloqueará.
- Instalar prerequisitos de compilación (temporalmente): headers, toolchain de compilación si DKMS lo necesita.
- Reconstruir DKMS para el kernel en ejecución:
dkms autoinstall -k $(uname -r). - Si la compilación falla por desajuste de API: detente y elige una versión de controlador compatible o revierte al kernel anterior vía GRUB.
- Arregla initramfs si hay módulos de arranque temprano implicados, y luego prueba el reinicio.
Lista C: Evitarlo la próxima vez (higiene de producción)
- Crear una “puerta de reinicio” que verifique DKMS instalado para el kernel más nuevo y valide initramfs donde haga falta.
- Escalar actualizaciones de kernel en hosts canarios con hardware representativo.
- Tratar la política de Secure Boot como una restricción de primera clase, no como una nota en la BIOS.
- Mantener al menos un kernel de reversión instalado y arrancable en todo momento.
- Controlar unattended upgrades para que los kernels no cambien sin validación.
Preguntas frecuentes
1) ¿Por qué DKMS “falló” solo después de la actualización del kernel?
Porque los módulos DKMS se compilan contra los headers de una versión específica del kernel. Cuando el kernel cambia, el módulo debe recompilarse. Si esa recompilación falla, no lo notarás hasta que arranques el kernel nuevo o intentes cargar el módulo para él.
2) ¿Puedo arreglar DKMS sin reiniciar?
Puedes recompilar e instalar módulos para el kernel siguiente sin reiniciar, sí. Normalmente no puedes probar cargarlos en ese kernel sin arrancarlo realmente. Por eso validas artefactos, firmas e initramfs antes del reinicio.
3) ¿Qué significan “added” vs “built” vs “installed” en dkms status?
added: DKMS conoce el código fuente del módulo pero no lo ha compilado para ese kernel. built: compilado pero no necesariamente instalado en el árbol de módulos del kernel. installed: colocado en /lib/modules/<kernel> y depmod se ha ejecutado (o debería haberse ejecutado).
4) ¿Realmente necesito headers que coincidan con el kernel?
Sí. DKMS compila contra los headers de la versión de kernel que apuntas. “Suficientemente cercano” no existe aquí; instala linux-headers-<versión exacta>.
5) ¿Por qué Secure Boot empeora tanto esto?
Porque convierte un problema de compilación en un problema de cumplimiento en tiempo de ejecución. Puedes compilar el módulo con éxito y aun así no poder cargarlo. El kernel rechazará módulos no firmados por una clave de confianza cuando Secure Boot y las políticas de lockdown lo requieran.
6) Si Secure Boot está habilitado, ¿debo desactivarlo?
Solo si tu política lo permite. Deshabilitar Secure Boot puede ser la solución operativamente más simple, pero la corrección adecuada en entornos regulados es firmar los módulos DKMS con una clave que controles e inscribirla vía MOK.
7) ¿Por qué mi sistema arrancó pero luego el almacenamiento o la red estaban rotos?
A menudo porque el controlador se carga más tarde de lo que crees, o existe un controlador in-tree de reserva que carece de funciones. Otra causa común: initramfs carece de un módulo necesario temprano, así que el arranque tiene éxito parcialmente y luego los dispositivos aparecen tarde o incorrectamente.
8) ¿Cuál es la reversión más segura si no puedo conseguir que DKMS compile para el kernel nuevo?
Arranca el kernel anterior conocido bueno y fija temporalmente los meta-paquetes del kernel. Luego actualiza el paquete del controlador/módulo a una versión que soporte el kernel nuevo antes de probar el reinicio de nuevo.
9) ¿Debería mantener compiladores fuera de los servidores de producción?
Depende. Si dependes de compilaciones DKMS en el host, necesitas la toolchain y los headers. Si los quitas, debes reemplazar la construcción on-host de DKMS con una canalización que produzca y distribuya módulos compatibles para cada kernel que despliegues.
10) ¿Cómo evito que se acumulen kernels “trampa de reinicio”?
Tener un paso de validación después de la instalación del kernel que compruebe el estado DKMS para módulos críticos en el kernel más nuevo instalado. Si falla, bloquea la automatización de reinicios y alerta. Esto es más barato que la respuesta a incidentes.
Próximos pasos que puedes hacer hoy
Si ejecutas Ubuntu 24.04 con controladores gestionados por DKMS, deja de tratar las actualizaciones del kernel como “solo parches de seguridad”. También son eventos de reconstrucción de controladores. El camino práctico hacia cero tiempo de inactividad es corto:
- Elige tus módulos DKMS críticos por rol de host (almacenamiento, red, GPU).
- Después de cada instalación de kernel, reconstruye módulos para el kernel más nuevo instalado (
dkms autoinstall -k). - Valida firmas si Secure Boot está habilitado; no asumas que el éxito de compilación implica éxito de carga.
- Regenera y verifica initramfs para módulos críticos en arranque temprano.
- Sólo entonces reinicia. Mantén un kernel de reversión instalado y arrancable.
Haz eso, y “DKMS falló tras la actualización del kernel” dejará de ser un incidente. Será un ítem de la lista de verificación que se completa antes de que alguien lo note.