La optimización energética en el centro de datos hace tiempo que dejó de ser solo una cuestión de costes. Afecta a la estabilidad térmica, a la vida útil del hardware, a la densidad por rack y, no menos importante, a la previsibilidad del rendimiento. En la práctica, a menudo decide una combinación discreta de regulación de la frecuencia de la CPU (CPU-Freq-Governors) y estados de sueño de la CPU (C-States, es decir, Idle-States) si los sistemas funcionan “satisfechos” y previsibles o si de repente aparecen picos de latencia que resultan difíciles de reproducir.
Este artículo sitúa los mecanismos con claridad y los traduce en decisiones operativas: ¿qué se puede ahorrar sin riesgo? ¿dónde aumenta el riesgo de jitter (variaciones en los tiempos de respuesta)? ¿Y cómo debe proceder especialmente en entornos Kubernetes, donde muchos workloads comparten hosts pero aplicaciones individuales siguen teniendo requisitos estrictos de latencia?
Optimización energética en el centro de datos en la práctica
En las CPU de servidor modernas hay dos palancas centrales:
- Escalado de frecuencia/tensión mediante P-States (Performance-States): la CPU acelera o reduce la frecuencia, a menudo acoplada al voltaje de alimentación. Un CPU-Freq-Governor es la política que decide con qué agresividad se sube o baja la frecuencia.
- Estados de sueño (idle) mediante C-States: cuando un core no tiene trabajo, puede entrar en estados de sueño cada vez más profundos. Cuanto más profundo es el C-State, más energía ahorra, pero normalmente más tiempo tarda en despertarse (exit latency).
El malentendido en operación: “más ahorro = siempre más lento”. En realidad es más matizado. Muchos workloads no están limitados por CPU de forma promedio, pero se benefician de una alta eficiencia siempre que las latencias tail (p. ej., percentil 99) no se descontrolen. Se vuelve crítico sobre todo cuando la carga es bursty (picos cortos y frecuentes), o cuando hilos/requests individuales deben servirse muy rápido y la transición desde un C-State profundo o desde una frecuencia baja hasta el “modo pleno” cae justo en ese intervalo.
Otros amplificadores típicos en centros de datos son: NUMA (Non-Uniform Memory Access, es decir, tiempos de acceso a memoria distintos según el zócalo de la CPU), interrupciones compartidas, Hyper-Threading/SMT (dos hilos comparten recursos de un core) y virtualización/containerización con asignación de CPU variable.
CPU-Freq-Governors, P-States y controladores: lo que los administradores deben saber de verdad
Bajo Linux el subsistema de frecuencia de la CPU ha crecido históricamente. Lo decisivo es qué controlador está activo, porque el controlador define las posibilidades reales de actuación y la observabilidad. Variantes comunes:
- intel_pstate: controlador específico de Intel, a menudo el predeterminado. Utiliza DVFS interno del hardware/CPU (Dynamic Voltage and Frequency Scaling) y ofrece políticas como “performance”/“powersave”. Los nombres pueden inducir a error: “powersave” suele significar aquí “gestionado por hardware, eficiente” y no es necesariamente “lento”.
- amd_pstate: equivalente de AMD en plataformas más recientes, con grados de madurez variables según kernel/BIOS.
- acpi-cpufreq: controlador genérico basado en ACPI, que ofrece governors clásicos como “ondemand”, “conservative”, etc.
La política del governor decide con qué rapidez se reacciona ante la carga. En muchas configuraciones de centro de datos los tiempos de reacción (ramp-up) son más importantes que la frecuencia máxima. Es decir: una política que escala hacia arriba con rapidez puede estabilizar las latencias tail sin mantener permanentemente la frecuencia máxima.
Inventario rápido en hosts Linux
Para una línea base fiable debe recopilar primero controladores, governor y límites de frecuencia. Use para ello cpupower (nombre del paquete según la distribución):
# Überblick: Treiber, Governor, aktuelle Frequenz, Grenzen
cpupower frequency-info
# Kurzstatus pro CPU (je nach Distribution verfügbar)
cpupower frequency-info -p
Además, vale la pena consultar sysfs (para automatización/CMDB):
# Treiber und Governor pro CPU (CPU0 als Beispiel)
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
# Grenzen (kHz)
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq
Trampa típica: Ajustes del BIOS pueden sobreescribir o limitar Linux (p. ej. „Energy Efficient Turbo“, „C-State Control“, „Package C-State Limit“, „Power Regulator“). Si ajusta a nivel de SO pero el BIOS/controlador de gestión impone límites rígidos, verá políticas aparentemente „correctas“ pero sin efecto.
Entender los C-States: Core vs. Package y la latencia de salida
Los C-States son estados de inactividad. Un core puede cambiar desde C1 (muy superficial) hasta estados más profundos. Además existen los Package C-States, en los que todo el zócalo de CPU (el „Package“) duerme más profundamente cuando suficientes núcleos están inactivos. Precisamente estos Package-States suelen ser el origen de picos de latencia difíciles de explicar, porque el despertar afecta a más componentes (Uncore, jerarquía de caché, interconexión).
La pregunta operativa relevante no es «¿Qué C-States están activados?», sino: ¿Con qué frecuencia y durante cuánto tiempo reside la CPU en qué C-States, y ¿correlacionan las latencias de salida con sus SLOs (Service Level Objectives)?
Medir la residencia en C-States
En Linux turbostat (de los linux-tools) ofrece indicaciones muy útiles. Muestra, entre otras cosas, el porcentaje de residencia en C-States y comportamiento de frecuencia/turbo. Ejemplo:
# 10 Messzyklen à 1 Sekunde, kompakt
turbostat --quiet --Summary --interval 1 --num_iterations 10
Si en las fases con picos de latencia observa alta residencia en Package-States profundos, es un indicio fuerte. Al contrario: si la CPU rara vez baja más allá de C1/C2 (p. ej. por carga en segundo plano, interrupts, agentes de monitorización), un ajuste agresivo de C-States suele aportar poco — y la causa estará en otro lado (scheduler, tormentas de IRQ, almacenamiento, red).
Síntomas típicos de latencia relacionados con governors/C-States
No toda latencia está relacionada con la gestión de energía. No obstante, los siguientes patrones suelen corresponder a temas de frecuencia e inactividad:
- Picos en el rango de milisegundos con una latencia media por lo demás estable, frecuentemente en solicitudes en ráfaga (API-Gateways, Ingress, Auth, rutas de fallo de caché).
- Clusters de jitter periódicos a intervalos de segundos, que correlacionan con ciclos de inactividad/activación.
- Sólo ciertos nodos están afectados (otro perfil de BIOS, otra versión de microcode/kernel, otros límites de potencia).
- El problema desaparece bajo carga continua (porque la CPU ya no está en estado profundo de inactividad) y aparece en fases ‚tranquilas‘.
Importante: Estos síntomas también pueden ser causados por IRQ-Balancing, accesos remotos NUMA, cgroup-CPU-Quota, CPU-Steal (en virtualización) o pausas del Garbage-Collector. Por ello, una estrategia de medición y descarte es fundamental.
Flujo de trabajo práctico: de la hipótesis a la decisión fundamentada
Un proceso viable en el centro de datos requiere reproducibilidad, telemetría y rollback. Un procedimiento probado:
- Clasificar la carga de trabajo: sensible a la latencia (p. ej. servicios cercanos a tiempo real), orientada al rendimiento (batch), mixta (APIs con picos).
- Definir SLOs y puntos de medición: latencia p95/p99, longitudes de cola, Error-Budget, adicionalmente energía/temperatura (si está disponible).
- Medir la línea base: turbostat, cpupower, carga del sistema, tasas de IRQ, cola de ejecución del scheduler, métricas de Kubernetes.
- Aplicar el cambio de forma mínimamente invasiva y solo en nodos seleccionados (Canary): p. ej. cambiar el Governor o limitar los C-States.
- Comparación contra la línea base: mismos perfiles de carga, mismos intervalos temporales, misma metodología de medición.
- Preparar rollback: restaurar parámetros de OS/Boot, perfil de BIOS documentado, playbooks de automatización ajustados.
Implementación en Linux: Governor setzen, Grenzen definieren, Persistenz herstellen
Para muchas cargas de trabajo en servidores, un punto de partida pragmático: Governor „performance“ en nodos críticos para latencia, y un modo de política de hardware eficiente (según el controlador) en nodos generales. Lo decisivo es la diferenciación de nodos, no un dogma global.
Establecer Governor temporalmente (prueba)
# Performance-Policy für alle CPUs (temporär bis Reboot/Policy-Reset)
cpupower frequency-set -g performance
# Alternativ: powersave (bei intel_pstate oft "hardware-managed")
cpupower frequency-set -g powersave
Si cpupower falla, suele deberse a permisos insuficientes (sudo), módulos/herramientas ausentes o a que el controlador no ofrece governors clásicos (p. ej. según el modo intel_pstate). Compruebe entonces qué reporta cpupower frequency-info como „available governors“.
Configuración persistente con tuned (familia RHEL-/CentOS-/Rocky-/Alma)
tuned es un daemon que aplica perfiles para energía/rendimiento. Para producción suele ser más estable que scripts individuales, porque tiene en cuenta el orden de arranque/servicio.
# Status und aktives Profil
tuned-adm active
# Beispiel: auf Performance schalten (Host-weit)
tuned-adm profile performance
Trampa: tuned puede también modificar el IRQ-Balancing, la configuración de discos o parámetros de red. Para un ajuste de CPU dirigido se recomienda un custom Profil que solo ajuste las palancas necesarias, en lugar de aplicar ciegamente un gran perfil estándar.
C-States begrenzen: sinnvoll, riskant, manchmal nötig
Limitar los C-States es una palanca burda pero eficaz cuando las latencias de salida dominan la latencia de cola. Técnicamente eso suele hacerse mediante parámetros de arranque del Kernel o límites en la BIOS. Reduce el potencial de ahorro, pero puede estabilizar la latencia.
Kernel-Boot-Parameter (beispielhaft) und Rollback-Fähigkeit
Qué parámetros son adecuados depende de la plataforma y del Kernel. Las palancas de ajuste utilizadas habitualmente son:
- intel_idle.max_cstate: limita los C-States máximos en el controlador intel_idle.
- processor.max_cstate: parámetro genérico de límite (actúa de forma diferente según el controlador).
- idle=poll: evita estados de idle profundos (muy consumidor de energía, más indicado como herramienta de diagnóstico).
Establezca tales parámetros primero en un nodo canario y documente el estado exacto antes/después. Ejemplo para GRUB (las distribuciones difieren; compruebe sus valores por defecto):
# 1) Aktuelle Kernel-Cmdline prüfen
cat /proc/cmdline
# 2) GRUB Default anpassen (Beispiel)
sudo sed -i 's/GRUB_CMDLINE_Linux="/GRUB_CMDLINE_Linux="intel_idle.max_cstate=1 processor.max_cstate=1 /' /etc/default/grub
# 3) GRUB-Konfig regenerieren (Pfad je nach Distribution)
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
# 4) Reboot planen und nach dem Boot wieder prüfen
sudo reboot
La reversión es idéntica: eliminar los parámetros, regenerar GRUB, reiniciar. Planifique una ventana de mantenimiento, pues es un cambio de arranque.
Importante para la decisión: si limita los C-States, observe también Temperatur, Lüfterkurven und Power-Limits. En entornos densos eso puede tener efectos secundarios (estrangulamiento térmico) que al final vuelven a penalizar el rendimiento, pero de otra forma.
Kubernetes-spezifisch: Node-Tuning ohne Nebenwirkungen
En Kubernetes se vuelve más complejo porque las workloads se distribuyen de forma dinámica. La optimización energética y la estabilidad de la latencia no son aquí un ejercicio de «Host-Feintuning», sino una cuestión de Node-Rollen, Scheduling y Isolation.
Grundprinzip: Unterschiedliche Node-Pools für unterschiedliche SLOs
Si mezcla workloads sensibles a la latencia (p. ej. Ingress, Service-Mesh-Data-Plane, Auth, Message-Broker Frontends) y Batch/CI/ETL en los mismos nodos, cualquier política de energía se convierte en una trampa de compromiso. Mejor:
- Node-Pool „low-latency“: mecanismos de ahorro de energía conservadores (política de rendimiento más alta, C-States limitados), aislamiento de CPU más estricto.
- Node-Pool „balanced“: políticas eficientes, pero con monitorización de la latencia de cola (tail latency).
- Node-Pool „batch“: máxima eficiencia energética, pero mayor tolerancia al jitter.
Esta separación se implementa mediante Labels/Taints/Tolerations (Label = criterio, Taint = «solo con permiso»). Esto evita que un único Deployment dicte sus políticas globales de CPU.
CPU-Manager, Cgroups und „Guaranteed“-Pods
El Kubelet CPU Manager puede asignar cores de forma exclusiva a Pods (policy «static»). Eso reduce el jitter del scheduler, porque un Pod no migra continuamente entre CPUs. Como requisito suelen emplearse Pods en la clase «Guaranteed» (Requests = Limits) para CPU. Las Cgroups (Control Groups, control de recursos en el kernel) aplican esos límites; con cgroup v2 algunos detalles son diferentes, pero el principio permanece.
Para una comprobación inicial: ¿qué versión de cgroup usan sus nodos?
stat -fc %T /sys/fs/cgroup
Y si el CPU Manager está siquiera activo (la configuración del Kubelet depende del clúster). En muchos sistemas encontrará la configuración, p. ej., en /var/lib/kubelet/config.yaml:
sudo grep -E "cpuManagerPolicy|cpuManagerReconcilePeriod" -n /var/lib/kubelet/config.yaml || true
Trampa típica: el CPU Manager «static» aporta poco si al mismo tiempo la CPU reduce agresivamente la frecuencia o permanecen activos Package C-States profundos. Los cores exclusivos reducen la migración, pero no la latencia de wakeup desde un idle profundo. Para nodos de baja latencia conviene abordar estos temas de forma conjunta.
IRQ-Affinität und „Noisy Neighbors“
Los interrupts (IRQs) son eventos de hardware que consumen tiempo de CPU fuera de los procesos normales. Si en un core «exclusivo» terminan igualmente muchos IRQs de NIC/almacenamiento, el aislamiento es prácticamente inútil. Por tanto, compruebe la carga y la distribución de IRQs:
# IRQ-Statistik (Momentaufnahme)
cat /proc/interrupts | head -n 30
# Softirqs (Netzwerk/Block-Processing im Kernel)
cat /proc/softirqs | head -n 30
En Kubernetes, un desencadenante frecuente son: Node-Local-DNS, CNI (Container Network Interface) y los plugins de almacenamiento, que generan tráfico de fondo que se procesa en CPUs «equivocadas». Según la plataforma ayudan la configuración de irqbalance, los conjuntos de CPU y una separación clara entre «System-Cores» y «Workload-Cores» (p. ej. mediante isolcpus/nohz_full como opciones avanzadas). Sin embargo, estas medidas son profundas y deben aplicarse solo con un plan de pruebas y rollback bien definido.
Checkliste: Vor dem Tuning prüfen (damit Sie nicht das Falsche optimieren)
- BIOS/UEFI: perfiles de energía, límites de C-State, Turbo, SMT, opciones de rendimiento deterministas. Documente el estado por modelo de nodo.
- Microcódigo y kernel: diferencias en las versiones modifican de forma medible el comportamiento de potencia e inactividad. Unifíquelos antes de comparar.
- Virtualización: en máquinas virtuales el CPU-steal/la política del host suele ser más determinante que el ajuste dentro del guest. Este artículo trata principalmente sobre Bare Metal o el sistema operativo anfitrión.
- Monitorización: mida p95/p99 y no solo la media; correlacione con la residencia en idle de la CPU, la frecuencia y las tasas de IRQ.
- Perfil de carga: ajustar bajo una carga sintética sostenida puede no reflejar el comportamiento real en ráfagas.
Troubleshooting: Wenn nach dem Tuning neue Probleme auftauchen
Síntoma: temperaturas más altas, pero sin mejora en la latencia
Con frecuencia la causa no es la salida de C-State, sino encolamiento en otro punto (red, almacenamiento, contención de locks) o throttling térmico. Compruebe si la CPU bajo carga opera a la frecuencia esperada y si los límites de potencia entran en efecto. En muchos servidores, BMC/Redfish o las herramientas del fabricante proporcionan los valores necesarios; a nivel del sistema operativo, turbostat sirve como indicador.
Síntoma: mayor rendimiento, pero peor latencia de cola
Esto suele indicar fases de boost/turbo «demasiado agresivas» que alcanzan límites térmicos, o más competencia por tareas en segundo plano (p. ej. porque todo se acelera pero también ocurre más en paralelo). En Kubernetes: compruebe la densidad de Pods por nodo, el estrangulamiento de CPU (cgroup) y si las clases de QoS están correctamente configuradas.
Síntoma: solo algunos Pods están afectados
En ese caso las políticas de CPU suelen ser solo un factor. Causas frecuentes son CPU-Quota/Throttling (Limits), afinidades de CPU inadecuadas, pausas de GC (en JVM/.NET) o efectos de «Noisy Neighbor» por caches compartidos/SMT. Para Pods críticos en latencia debe establecer Requests/Limits de forma consistente y, si es necesario, recurrir a nodos dedicados.
Estrategia de reversión: cómo volver de forma segura al estado inicial
Una estrategia de reversión no es una formalidad, sino la diferencia entre un experimento controlado y una escalada nocturna. Planifique al menos estos niveles:
- Reversión de políticas del SO: restablecer el governor (cpupower/tuned), recargar servicios, estado objetivo documentado en la gestión de configuración.
- Reversión de parámetros de arranque: revertir cambios en GRUB, mantener disponible la antigua Kernel-Cmdline, en caso de duda arrancar desde el menú de arranque.
- Reversión del pool de nodos en Kubernetes: retirar los canary nodes del pool (cordon/drain), devolver las cargas de trabajo a «balanced», y solo entonces seguir con cambios.
Para operaciones de Kubernetes (canary/drain) como caja de herramientas estándar:
# Node für neue Pods sperren
kubectl cordon <node-name>
# Pods kontrolliert evakuieren (Achtung: PDBs und Stateful Workloads)
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
# Nach Rollback wieder freigeben
kubectl uncordon <node-name>
Trampa: Drain puede fallar por PodDisruptionBudgets (PDB) o por datos locales (emptyDir). Esto no es un «problema de Kubernetes», sino parte de la realidad operativa — y precisamente por eso debe tratar el ajuste de potencia/latencia como un proceso controlado de pool de nodos.
Buenas prácticas: combinar eficiencia energética y latencia de forma estable
- Segmentar en lugar de ajustar globalmente: políticas diferentes por pool de nodos suelen ser casi siempre mejores que un compromiso a nivel de clúster.
- Mida la residency, no solo los vatios: las métricas de C-State y frecuencia suelen explicar picos de latencia mejor que el consumo energético puro.
- Uniformizar primero controladores/BIOS: sin una base reproducible, las comparaciones carecen de valor.
- Aislamiento de IRQ y CPU para baja latencia: núcleos exclusivos, núcleos del sistema, afinidad de IRQ — pero solo con una gestión de cambios ordenada.
- Reversión como runbook: un ajuste sin posibilidad de vuelta no está listo para producción en un centro de datos.
Conclusión: la optimización energética es un diseño operativo, no un interruptor
La optimización energética en el centro de datos funciona de forma sostenible si entiende los CPU-Freq-Governors, los P-States y los C-States como parte del diseño operativo: roles de nodo, programación en Kubernetes, metodología de medición y estrategia de retroceso forman un conjunto. Para cargas de trabajo generales, el escalado eficiente del hardware suele ser poco crítico. Para servicios sensibles a la latencia, en cambio, debe aplicar deliberadamente políticas más conservadoras, limitar el idle profundo y aplicar de forma consistente el aislamiento (CPU/IRQ) – no en todas partes, sino donde realmente protege los SLOs.
Si desea abordar el tema de forma sistemática en su entorno, planifique como siguiente paso un pool canario, defina criterios de medición (p95/p99 + residencia) y documente los parámetros de BIOS/Kernel por plataforma. Así, de „sensación de ser más rápido“ se obtiene una decisión fiable y segura para la operación.