...

Ajuste del núcleo en el alojamiento Linux: los parámetros Sysctl de un vistazo

Ajuste del núcleo en alojamiento Linux aporta ganancias de rendimiento cuantificables porque ajusto específicamente los parámetros sysctl para red, memoria, CPU y seguridad. Cargo perfiles sin reiniciar y ajusto los valores de las cargas de trabajo, la concurrencia y el comportamiento de E/S para que el Servidor reacciona rápidamente bajo carga y funciona con fiabilidad.

Puntos centrales

  • sysctl Controla el comportamiento del núcleo en tiempo de ejecución
  • Red optimizar: Backlogs, sockets, TCP
  • Memoria recortar: Intercambio, Páginas Sucias
  • CPU Ajuste fino: Programador, PIDs
  • Seguridad endurecimiento sin sobrecarga

¿Qué es sysctl en el alojamiento Linux?

Con sysctl Leo y cambio los parámetros del kernel en tiempo de ejecución sin compilar el kernel. Los valores se almacenan como archivos en el directorio /proc/sys, como net/ipv4/tcp_max_syn_backlog, y controlan la red, la memoria y la seguridad. Para alojar cargas de trabajo con muchas conexiones, el ajuste directo reduce los picos de latencia y los tiempos de espera. Hago cambios temporales con sysctl -w y escribo perfiles permanentes en /etc/sysctl.d/*.conf. Después lo cargo todo con sysctl -system y compruebo los registros dmesg y journal para poder reconocer rápidamente los errores de configuración.

Cómo utilizar sysctl de forma segura

Antes de realizar cambios Perfiles y documentar los valores reales con sysctl -a para que pueda volver atrás en cualquier momento. Primero pruebo los nuevos valores en máquinas virtuales de prueba con una carga comparable. Luego aumento los parámetros paso a paso, controlo las métricas y vuelvo a ajustar. Así es como evito los OOM kills, las caídas de socket y las retransmisiones esporádicas. Para configuraciones reproducibles, creo un archivo separado como /etc/sysctl.d/99-hosting.conf y lo cargo de forma controlada.

Probar temporalmente #
sudo sysctl -w net.core.somaxconn=65535
sudo sysctl -w net.ipv4.tcp_max_syn_backlog=4096

Establezca # de forma permanente
sudo tee /etc/sysctl.d/99-hosting.conf >/dev/null <<'EOF'
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 4096
vm.swappiness = 10
vm.dirty_ratio = 20
EOF

sudo sysctl --sistema

Parámetros de red que transportan los servidores web

Para muchas conexiones simultáneas aumento somaxconn, para que la lista de conexiones pendientes de Nginx o Apache no se desborde. Uso net.ipv4.tcp_max_syn_backlog para aumentar la cola de conexiones semiabiertas, lo que ayuda durante los picos de tráfico. En configuraciones sólo web suelo dejar net.ipv4.ip_forward desactivado, con proxies inversos o pasarelas lo activo. Valido las caídas de backlog con ss -s y netstat -s y compruebo si las colas de aceptación están vacías. Si quieres profundizar en el control de la congestión, también puedes evaluar algoritmos como CUBIC o BBR; mi referencia a Control de congestión TCP.

# Valores de ejemplo para servidores web muy frecuentados
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 4096
net.ipv4.ip_forward = 0

Ajuste del almacenamiento y las máquinas virtuales para alojar cargas de trabajo

Bajo intercambio a 10 para que el núcleo utilice RAM durante más tiempo e intercambie menos. Con vm.dirty_ratio del 15 al 20 por ciento, limito las páginas sucias para que la carga de escritura no provoque largas ráfagas de descarga. Para muchos procesos, pongo vm.overcommit_memory a 1 si conozco las aplicaciones y entiendo sus reservas. También monitorizo los accesos a la caché de páginas y las esperas de IO para poder interpretar correctamente los efectos de la caché. Proporciono una mirada más profunda al comportamiento de la caché con esta guía del Caché de página.

# Perfiles de almacenamiento y VM
vm.swappiness = 10
vm.dirty_ratio = 20
vm.overcommit_memory = 1

Ajuste de la CPU y el programador

Con alta concurrencia levanto kernel.pid_max para que muchos procesos trabajadores reciban IDs. Para las cuotas CFS ajusto kernel.sched_cfs_bandwidth_slice_us para evitar slices demasiado cortos para servicios bursty. Compruebo la longitud de las colas de ejecución, los cambios de contexto y los tiempos de robo, especialmente en hosts compartidos. Si necesito aislamiento de CPU, asocio servicios a núcleos mediante taskset o cgroups. Una introducción a la optimización más profunda del kernel es proporcionada por este compacto Rendimiento del núcleo-Guía.

# Parámetros del proceso y del planificador
kernel.pid_max = 4194304
# Ejemplo para rebanadas CFS más finas
kernel.sched_cfs_bandwidth_slice_us = 5000

Parámetros de seguridad sin pérdida de rendimiento

Activo dmesg_restrict, para evitar que usuarios sin privilegios lean los registros del kernel. Utilizo kernel.kptr_restrict para ocultar direcciones que podrían ayudar a los atacantes con exploits. A nivel de red, activo rp_filter por defecto para evitar la suplantación de IP. Estos ajustes apenas cuestan rendimiento y refuerzan significativamente el endurecimiento del host. Los cargo en el mismo archivo sysctl de forma controlada para que permanezcan rastreables.

# Endurecimiento a través de sysctl
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1

Búfer de red ampliado para un alto rendimiento

Para los anfitriones de alto tráfico que me ajuste a Búfer TCP para que las conexiones rápidas no se cuelguen en el límite de la ventana. Utilizo net.ipv4.tcp_rmem y tcp_wmem para definir los tamaños mínimo, estándar y máximo. net.core.optmem_max y net.core.netdev_max_backlog ayudan a absorber limpiamente las ráfagas cortas. Superviso las retransmisiones, el desarrollo de cwnd y los niveles de llenado del búfer antes de aumentar más los valores. Estos pasos aumentan el rendimiento y reducen notablemente las fluctuaciones de latencia en los enlaces 10G modernos.

Búfer de red ampliado #
net.core.optmem_max = 81920
net.core.netdev_max_backlog = 3000
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216

Práctica: de la base al beneficio medible

Empiezo cada puesta a punto con un Línea de base y documento cifras clave como la latencia P95, el rendimiento y la tasa de error. Después cambio algunos parámetros, cargo el perfil y vuelvo a medir con ab, wrk o sysbench. Si la latencia disminuye, registro el cambio; si aumenta, la revierto. Así construyo un perfil de alojamiento que corresponde a mi aplicación. Por último, verifico de nuevo bajo carga de producción antes de dejar los valores permanentes.

# Guardar estado actual
sysctl -a > /root/sysctl-baseline.txt

# Ver parámetros de red
sysctl -a | grep -E 'net\.core|net\.ipv4'

# Recargar perfiles
sysctl --sistema

Cuadro comparativo: perfil estándar frente a perfil de alojamiento

Los siguientes Cuadro muestra valores de partida prácticos que utilizo con frecuencia. Los valores dependen de la carga de trabajo, la red y el hardware. Empiezo con esto, compruebo las métricas y las ajusto paso a paso. Si hay problemas, vuelvo a los valores por defecto y los aumento de nuevo en pequeños pasos. Así minimizo los riesgos y consigo resultados coherentes.

Parámetros Estándar Perfil de alojamiento Beneficio
net.core.somaxconn 128 65535 Más conexiones aceptadas
net.ipv4.tcp_max_syn_backlog 1024 4096 Menos gotas con picos
vm.swappiness 60 10 Menos intercambios bajo carga
kernel.pid_max 32768 4194304 Más procesos/trabajadores posibles
vm.dirty_ratio 30 20 Escritura más uniforme

Evitar errores comunes y control

No utilizo Valores extremos, porque pueden provocar timeouts, OOM kills o pérdidas de paquetes. Pruebo los cambios por etapas, cada una con una métrica clara y una breve fase de observación. Los indicadores críticos son la longitud de la cola de aceptación, las retransmisiones TCP, la latencia P95, la espera IO y el intercambio de entrada/salida. Utilizo agentes ligeros y cuadros de mando para la supervisión, de forma que pueda reconocer rápidamente las tendencias. Tras las actualizaciones del kernel, compruebo si los perfiles sysctl siguen siendo válidos y los recargo si es necesario.

Persistencia, secuencia y distribuciones

Para garantizar la reproducibilidad de los perfiles, observo la secuencia de carga en /etc/sysctl.d: Los archivos se procesan lexicográficamente. Asigno deliberadamente prefijos como 60-... o 99-... para asegurarme de que mi perfil de alojamiento anula otros predeterminados. Las diferencias entre distribuciones (Debian/Ubuntu vs. RHEL/Alma) normalmente sólo afectan a las rutas y a los valores por defecto; sysctl -system siempre carga /etc/sysctl.conf, /etc/sysctl.d/*.conf y los archivos del proveedor si procede. Después de actualizaciones importantes del sistema, compruebo con sysctl -system -o (ejecución en seco dependiendo de la versión) o comparo la configuración efectiva cargada con mi plantilla para evitar sorpresas.

# Ejemplo: asegurar una secuencia limpia
sudo ls -1 /etc/sysctl.d
10-vendor.conf
50-defaults.conf
99-hosting.conf # sobrescribe todo lo anterior

# difiere efectivamente los valores cargados
sysctl -a > /root/sysctl-after.txt
diff -u /root/sysctl-baseline.txt /root/sysctl-after.txt | less

Ciclo de vida de TCP y gestión de puertos

Cuando hay mucha carga, se crean muchas conexiones efímeras. Pongo rango_de_puertos_locales_ip para que las conexiones salientes (por ejemplo, desde proxies) no se queden atascadas en el límite de puertos efímeros. tcp_fin_timeout controla el tiempo que los enchufes permanecen en FIN-WAIT-2. Con un Keepalive-parámetros, cierro más rápido las sesiones muertas sin cortar agresivamente las conexiones. TIME_WAIT es normal y protege contra paquetes tardíos; no lo reduzco a ciegas. tcp_tw_reuse ayuda principalmente en hosts cliente, en servidores puros normalmente permanece desactivado. Dejo activadas las marcas de tiempo y SACK, ya que mejoran el rendimiento y la robustez.

# Rango de puertos y ciclo de vida TCP
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5
# Precaución con tcp_tw_reuse: sólo útil para carga de clientes salientes
# net.ipv4.tcp_tw_reuse = 1

Mantener estables las tablas IPv6 y de vecinos

Hoy en día, muchos hosts transportan tráfico de doble pila. Optimizo las tablas ARP/ND para que no haya mensajes de „desbordamiento de la tabla de vecinos“, especialmente en proxies o nodos con numerosos pares. La dirección gc_thresh-Defino umbrales para que coincidan con la matriz de conexiones. Dejo las opciones ICMPv6 y router add restrictivas para los servidores para que no se incluyan rutas no deseadas. Para IPv4, también presto atención a la recolección de basura ARP para que las entradas envejezcan a tiempo pero no desaparezcan demasiado pronto.

Tablas de vecinos #: umbrales más generosos
net.ipv4.neigh.default.gc_thresh1 = 1024
net.ipv4.neigh.default.gc_thresh2 = 4096
net.ipv4.neigh.default.gc_thresh3 = 8192

net.ipv6.neigh.default.gc_thresh1 = 1024
net.ipv6.neigh.default.gc_thresh2 = 4096
net.ipv6.neigh.default.gc_thresh3 = 8192

# ARP/ND-Aging conservador
net.ipv4.neigh.default.gc_stale_time = 60

Pensar juntos en descriptores de archivos y backlogs

Un cuello de botella frecuente son Descriptores de archivos. Si las aplicaciones tienen miles de sockets, fs.file-max (para todo el sistema) y ulimit/nofile (por servicio) encajan. somaxconn aumenta la cola de la lista, pero sólo ayuda si al propio servidor web se le permite abrir más FDs y la tasa de aceptación es lo suficientemente alta. Me aseguro de que los límites del sistema y del servicio estén sincronizados, de lo contrario se producen cuellos de botella artificiales a pesar de los „grandes“ atrasos del núcleo.

# Permitir más FDs en todo el sistema
fs.file-max = 2097152

# Lado servicio (ejemplo unidad systemd)
# [Servicio]
# LimitNOFILE=1048576

Amortiguación de cargas de trabajo UDP/QUIC

Utilizar DNS, syslog, telemetría y QUIC (HTTP/3) UDP. Aquí escalo los búferes de socket globales y los límites de memoria específicos de UDP. Para grandes cargas UDP en ráfaga (como pasarelas de telemetría), esto evita caídas en la ruta de recepción. Monitorizo los contadores de error con ss -u -a y netstat -su y gradualmente ajusto los máximos. Para QUIC, net.core.rmem_max/wmem_max también es relevante, ya que las pilas de espacio de usuario a menudo alcanzan estos límites a través de setsockopt.

# UDP buffer y límites
net.core.rmem_max = 268435456
net.core.wmem_max = 268435456
net.ipv4.udp_mem = 98304 131072 262144
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192

Especifica la escritura sucia: Bytes en lugar de porcentajes

En sistemas con mucha RAM, los valores porcentuales pueden provocar grandes descargas repentinas. Por ello, prefiero utilizar vm.dirty_background_bytes y vm.bytes sucios, para definir límites superiores absolutos. Esto estabiliza la tasa de escritura y suaviza las latencias, especialmente con discos duros o cargas de trabajo mixtas. También considero vm.min_free_kbytes moderadamente para que el núcleo disponga de suficiente memoria libre para las asignaciones en ráfaga.

# Ejemplo: límites absolutos de suciedad (aprox. 1G background, 4G hard)
vm.dirty_background_bytes = 1073741824
vm.dirty_bytes = 4294967296
vm.min_free_kbytes = 65536

Distribuir RPS/RFS y carga IRQ de red

A tasas de PPS elevadas, un solo núcleo de CPU puede colgarse de la NIC-IRQ. Utilizo Receive Packet Steering (RPS) y, si es necesario, Receive Flow Steering (RFS) para distribuir el procesamiento de paquetes entre varios núcleos. Globalmente, establezco net.core.rps_sock_flow_entries, La asignación real tiene lugar por cola a través de sysfs. Esto reduce los puntos calientes de la CPU, mejora la localización de la caché y reduce los picos de latencia. En combinación con net.core.netdev_max_backlog, el resultado es un pipeline más robusto.

# Entradas de flujo globales para RPS
net.core.rps_sock_flow_entries = 32768

# Nota: Ajuste por cola mediante /sys/class/net//queues/rx-*/rps_cpus
# y rps_flow_cnt, dependiendo de la NIC y el número de colas.

Contenedores, espacios de nombres y máquinas virtuales

Los contenedores contienen muchos net.*-Valores namespaced y puede aplicarse por espacio de nombres de red. Por lo tanto, yo documento si estoy personalizando la red del host o del pod/contenedor. Los orquestadores a menudo sólo permiten una lista segura de sysctls; valores como kernel.pid_max permanecen en el lado del host. En las máquinas virtuales, compruebo qué NIC virtuales y descargas están activas (virtio, ENA), porque las descargas y la MTU tienen un fuerte impacto en los requisitos de búfer y el desarrollo de cwnd. Los hosts bare-metal NUMA-heavy se benefician de la desactivación de vm.zone_reclaim_mode y una disposición deliberada de afinidad CPU/IRQ.

# Evitar el efecto secundario NUMA
vm.zone_reclaim_mode = 0

Cortafuegos Conntrack y stateful de un vistazo

Si el host se ejecuta como un NAT/firewall o aloja muchos contenedores con NAT de salida, escalo el nf_conntrack-tabla. Las tablas hash demasiado pequeñas generan caídas y latencias elevadas durante las exploraciones de las tablas. Mido la utilización con nstat y miro „esperado“ frente a „en uso“. Para servidores web puros sin NAT, conntrack no suele ser crítico o incluso se desactiva; en pasarelas, debe incluirse en el paquete de ajuste.

# Tamaño de conntrack (¡sólo si se utiliza activamente!)
net.netfilter.nf_conntrack_max = 1048576

Robustez frente a ataques y anomalías

Ayuda con el tráfico de bots y los escaneos tcp_syncookies y opciones ICMP/redirect conservadoras. Los Syncookies salvan el apretón de manos en caso de colas SYN desbordadas sin estrangular excesivamente el tráfico legítimo. Deshabilito los redireccionamientos y las rutas de origen en los servidores que no deben ser enrutados. Estas medidas de refuerzo son ligeras y complementan los mecanismos de protección mencionados anteriormente.

# Defensa contra inundaciones SYN y comportamiento de enrutamiento conservador
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

Profundizar en la práctica de la medición: Lo que compruebo regularmente

Para obtener resultados reproducibles, realizo mediciones sistemáticas antes y después de los cambios. En cuanto a la red, utilizo ss -s, ss -ti, nstat y netstat -s para ver la longitud de las colas, las retransmisiones y las estadísticas de sack. En cuanto a la memoria de E/S, vmstat, iostat y pidstat ayudan a clasificar las descargas sucias, los cambios de contexto y los tiempos de espera de la CPU. También miro las pruebas de carga:

  • Cola de aceptación (LISTEN) y cola SYN: Dropped vs. overflows
  • Pacing/rendimiento por conexión y desarrollo de cwnd
  • latencias P95/99 en comparación A/B, en lugar de sólo la media
  • Tasa de entrada/salida de intercambio y tasa de aciertos de la caché de páginas
  • Distribución de la carga IRQ y longitud de las colas de ejecución por CPU
Comprobación rápida del estado del #
ss -s
netstat -s | egrep 'listen|SYN|retran|dropped'
vmstat 1 10
pidstat -w -u -r 1 5

Ejemplo: perfil de alojamiento consolidado

Para empezar, combino los valores básicos y ampliados en un solo archivo. Luego los aumento en pequeños pasos, cada uno con puntos de medición claros. Los siguientes valores son un punto de partida conservador pero de alto rendimiento para servidores web y proxies con mucho tráfico.

sudo tee /etc/sysctl.d/99-hosting.conf >/dev/null <<'EOF'
# Conceptos básicos de red
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 4096
net.core.netdev_max_backlog = 3000
net.core.optmem_max = 81920

Búferes y puertos # TCP
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.ip_local_port_range = 10240 65535
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5

# UDP/QUIC
net.core.rmem_max = 268435456
net.core.wmem_max = 268435456
net.ipv4.udp_mem = 98304 131072 262144
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192

# Tablas de vecinos
net.ipv4.neigh.default.gc_thresh1 = 1024
net.ipv4.neigh.default.gc_thresh2 = 4096
net.ipv4.neigh.default.gc_thresh3 = 8192
net.ipv6.neigh.default.gc_thresh1 = 1024
net.ipv6.neigh.default.gc_thresh2 = 4096
net.ipv6.neigh.default.gc_thresh3 = 8192
net.ipv4.neigh.default.gc_stale_time = 60

# Seguridad
kernel.dmesg_restrict = 1
kernel.kptr_restrict = 2
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

# Memoria/VM
vm.swappiness = 10
vm.dirty_ratio = 20
bytes de fondo sucios de máquina virtual = 1073741824
vm.dirty_bytes = 4294967296
vm.min_free_kbytes = 65536
vm.overcommit_memory = 1
vm.zone_reclaim_mode = 0

# CPU/Procesos
kernel.pid_max = 4194304
kernel.sched_cfs_bandwidth_slice_us = 5000

# RPS
net.core.rps_sock_flow_entries = 32768

# FDs
fs.file-max = 2097152
EOF

sudo sysctl --sistema

Resumen: La puesta a punto como proceso recurrente

Dirigido a Ajuste del núcleo con sysctl ofrece efectos claros en el alojamiento: tiempos de respuesta más cortos, valores de rendimiento más altos y servicios constantes. Empiezo con los básicos de red como somaxconn y tcp_max_syn_backlog, luego cuido la memoria con swappiness y dirty_ratio. A continuación, optimizo los PID y los planificadores y endurezco el host con dmesg_restrict, kptr_restrict y rp_filter. Mido cada cambio, lo documento y vigilo las métricas. Paso a paso, creo un perfil que sirve a mis cargas de trabajo de manera eficiente y tiene reservas para los picos de tráfico.

Artículos de actualidad