El kernel Linux expone cientos de parametros ajustables a traves de /proc/sys/ y la herramienta sysctl. La diferencia entre un servidor con configuración por defecto y uno correctamente afinado puede ser dramatica: mayor throughput de red, menor latencia, mejor uso de memoria y estabilidad bajo carga. En esta guía cubrimos los parametros mas relevantes para entornos de producción, con enfasis en servidores web, bases de datos y plataformas de contenedores.

Como Funciona sysctl

sysctl es la interfaz para leer y modificar parametros del kernel en tiempo de ejecución. Los parametros se organizan en categorías bajo /proc/sys/:

  • net.* - Stack de red (TCP/IP, sockets, buffers)
  • vm.* - Gestión de memoria virtual
  • fs.* - Sistema de archivos
  • kernel.* - Parametros generales del kernel
# Ver todos los parametros actuales
sysctl -a

# Leer un parametro especifico
sysctl net.ipv4.tcp_tw_reuse

# Modificar un parametro en caliente (no persiste tras reboot)
sudo sysctl -w net.core.somaxconn=65535

# Aplicar configuracion desde archivo
sudo sysctl -p /etc/sysctl.conf

# Aplicar todos los archivos de configuracion
sudo sysctl --system

Para hacer cambios persistentes, edita /etc/sysctl.conf o crea archivos en /etc/sysctl.d/. La convención es usar archivos numerados para controlar el orden de aplicación:

# /etc/sysctl.d/10-network.conf  (se aplica antes que 20-*.conf)
# /etc/sysctl.d/20-memory.conf
# /etc/sysctl.d/99-custom.conf   (se aplica al final, tiene prioridad)

Tuning de Red (Network Stack)

La optimización de red es probablemente el area donde el tuning de kernel tiene mayor impacto inmediato, especialmente en servidores web y balanceadores de carga.

Parametros TCP Fundamentales

# /etc/sysctl.d/10-network.conf

# Reutilizar sockets en TIME_WAIT para nuevas conexiones
# Critico en servidores con muchas conexiones cortas (APIs, microservicios)
net.ipv4.tcp_tw_reuse = 1

# Tamano maximo de la cola de conexiones pendientes (backlog)
# Default: 128. Para servidores web de alto trafico, aumentar significativamente
net.core.somaxconn = 65535

# Cola de SYN pendientes (handshake TCP incompleto)
net.ipv4.tcp_max_syn_backlog = 65536

# Habilitar SYN cookies para proteccion contra SYN flood
net.ipv4.tcp_syncookies = 1

# Reducir tiempo de FIN_WAIT2 (default: 60s)
net.ipv4.tcp_fin_timeout = 15

# Intervalo de keepalive (default: 7200s = 2h, demasiado alto)
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp_keepalive_intvl = 30
net.ipv4.tcp_keepalive_probes = 5

Buffers de Red

Los buffers de red determinan cuanta memoria puede usar cada socket para enviar y recibir datos. Valores insuficientes limitan el throughput en conexiones de alta latencia o alto ancho de banda:

# Buffers de recepcion: min, default, max (en bytes)
net.core.rmem_default = 262144
net.core.rmem_max = 16777216
net.ipv4.tcp_rmem = 4096 262144 16777216

# Buffers de envio: min, default, max
net.core.wmem_default = 262144
net.core.wmem_max = 16777216
net.ipv4.tcp_wmem = 4096 262144 16777216

# Memoria total para TCP (paginas de memoria)
net.ipv4.tcp_mem = 786432 1048576 1572864

# Tamano maximo de paquetes en cola antes de ser procesados
net.core.netdev_budget = 600
net.core.netdev_budget_usecs = 8000

# Cola de paquetes entrantes por interfaz
net.core.netdev_max_backlog = 65536

Rango de Puertos Efimeros

# Ampliar el rango de puertos locales disponibles
# Importante para proxies reversos y balanceadores
net.ipv4.ip_local_port_range = 1024 65535

Gestión de Memoria

Swappiness y Overcommit

# /etc/sysctl.d/20-memory.conf

# vm.swappiness: tendencia del kernel a mover paginas a swap
# 0-10: Evitar swap al maximo (bueno para bases de datos)
# 60: Default de Ubuntu
# 100: Swap agresivo
# Para servidores de produccion con suficiente RAM:
vm.swappiness = 10

# Overcommit: como maneja el kernel las solicitudes de memoria
# 0: Heuristica del kernel (default, puede denegar solicitudes grandes)
# 1: Permitir siempre (usado por Redis, puede causar OOM)
# 2: No sobrecomprometer mas de swap + (ram * ratio)
vm.overcommit_memory = 0
vm.overcommit_ratio = 80

# Porcentaje de memoria para dirty pages antes de flush forzado
# Reducir para escrituras mas frecuentes pero menor riesgo de perdida
vm.dirty_ratio = 15
vm.dirty_background_ratio = 5

# Tiempo maximo antes de que dirty pages se escriban a disco (centisegundos)
vm.dirty_expire_centisecs = 1500
vm.dirty_writeback_centisecs = 500

Memoria para Bases de Datos

Las bases de datos como PostgreSQL usan shared memory del kernel. Ajustar estos parametros es esencial:

# Tamano maximo de un segmento de shared memory (bytes)
# Para PostgreSQL con shared_buffers grande:
kernel.shmmax = 68719476736    # 64GB
kernel.shmall = 4294967296     # Paginas totales de shared memory

# Semaforos: PostgreSQL usa muchos
kernel.sem = 250 32000 100 128

Sistema de Archivos

# /etc/sysctl.d/30-filesystem.conf

# Limite global de file descriptors abiertos
# Default: ~100k. Para servidores con muchas conexiones, aumentar
fs.file-max = 2097152

# Limite de file descriptors por proceso
fs.nr_open = 1048576

# Watchers de inotify (necesario para herramientas como webpack, IDEs)
fs.inotify.max_user_watches = 524288
fs.inotify.max_user_instances = 512

# Tamano de cola de eventos de AIO (async I/O)
fs.aio-max-nr = 1048576

No olvides ajustar también los límites de ulimit en /etc/security/limits.conf:

# /etc/security/limits.conf
*    soft    nofile    1048576
*    hard    nofile    1048576
*    soft    nproc     65535
*    hard    nproc     65535

Schedulers de I/O

El scheduler de I/O determina como el kernel ordena las solicitudes de lectura/escritura al disco. La elección correcta depende del tipo de almacenamiento:

# Ver el scheduler actual
cat /sys/block/sda/queue/scheduler

# Schedulers disponibles:
# - none/noop: Sin reordenamiento. Ideal para NVMe y SSDs rapidos
# - mq-deadline: Garantiza latencia maxima. Bueno para SSDs y bases de datos
# - bfq: Budget Fair Queueing. Bueno para escritorios y cargas mixtas
# - kyber: Diseñado para SSDs rapidos con colas multiples

# Cambiar scheduler en caliente
echo "mq-deadline" | sudo tee /sys/block/sda/queue/scheduler

# Hacer persistente via udev rules
# /etc/udev/rules.d/60-scheduler.rules
# ACTION=="add|change", KERNEL=="sd*", ATTR{queue/scheduler}="mq-deadline"
# ACTION=="add|change", KERNEL=="nvme*", ATTR{queue/scheduler}="none"

Parametros del Scheduler

# Profundidad de cola para NVMe (puede aumentarse para mas paralelismo)
echo 1024 > /sys/block/nvme0n1/queue/nr_requests

# Read-ahead: cuanto leer por adelantado (KB)
# Aumentar para workloads secuenciales (backups, ETL)
echo 4096 > /sys/block/sda/queue/read_ahead_kb

Tuning Especifico para Contenedores y Kubernetes

Los nodos de Kubernetes y hosts de Docker necesitan parametros adicionales para manejar gran cantidad de contenedores, redes overlay y conexiones:

# /etc/sysctl.d/90-kubernetes.conf

# Habilitar IP forwarding (obligatorio para networking de pods)
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1

# Mas conexiones tracked en conntrack (cada pod genera entradas)
net.netfilter.nf_conntrack_max = 1048576
net.nf_conntrack_max = 1048576

# Aumentar hash size para conntrack
# Se configura via modprobe, no sysctl:
# echo "options nf_conntrack hashsize=262144" > /etc/modprobe.d/conntrack.conf

# Rango de puertos para NodePort (default K8s: 30000-32767)
# Asegurar que no colisione con ip_local_port_range
net.ipv4.ip_local_reserved_ports = 30000-32767

# Permitir mas mapeos ARP (nodos con muchos pods)
net.ipv4.neigh.default.gc_thresh1 = 4096
net.ipv4.neigh.default.gc_thresh2 = 8192
net.ipv4.neigh.default.gc_thresh3 = 16384

# PID limits para nodos con muchos contenedores
kernel.pid_max = 4194304

Herramientas de Profiling del Kernel

Antes de ajustar parametros a ciegas, es fundamental medir. Linux ofrece herramientas potentes para analizar el rendimiento a nivel de kernel.

perf

# Instalar perf
sudo apt install linux-tools-common linux-tools-$(uname -r)

# Analizar CPU durante 10 segundos (global)
sudo perf stat -a sleep 10

# Grabar eventos de CPU para analisis detallado
sudo perf record -a -g -- sleep 30
sudo perf report

# Top en tiempo real de funciones del kernel con mas CPU
sudo perf top

ftrace

# ftrace vive en /sys/kernel/debug/tracing/
# Listar tracers disponibles
cat /sys/kernel/debug/tracing/available_tracers

# Habilitar function tracer
echo function > /sys/kernel/debug/tracing/current_tracer
echo 1 > /sys/kernel/debug/tracing/tracing_on

# Ver las funciones mas llamadas
cat /sys/kernel/debug/tracing/trace | head -50

# Deshabilitar
echo 0 > /sys/kernel/debug/tracing/tracing_on
echo nop > /sys/kernel/debug/tracing/current_tracer

Otras Herramientas Utiles

# vmstat: Resumen de memoria, procesos, I/O, CPU
vmstat 1 10

# iostat: Estadisticas de I/O por disco
iostat -x 1 5

# ss: Estado de sockets (reemplazo moderno de netstat)
ss -s          # Resumen de sockets
ss -tlnp       # Listening TCP con PID

# slabtop: Uso de cache del kernel (slab allocator)
sudo slabtop -o

Metodologia para Aplicar Cambios

Modificar parametros del kernel en producción requiere un proceso disciplinado:

  1. Medir antes: Establece una linea base con las herramientas de profiling. Documenta métricas actuales.
  2. Cambiar un parametro a la vez: Nunca modifiques multiples parametros simultaneamente. No podras aislar el impacto.
  3. Probar en staging primero: Aplica el cambio en un entorno no productivo y ejecuta tests de carga.
  4. Monitorear despues: Observa métricas durante al menos 24-48 horas en producción antes de considerar el cambio exitoso.
  5. Documentar todo: Registra que cambiaste, por que, y el resultado medido.
  6. Versionamiento: Gestiona tus archivos de sysctl en un repositorio Git.
# Script para aplicar y verificar cambios de sysctl
#!/bin/bash
SYSCTL_DIR="/etc/sysctl.d"
echo "Aplicando configuracion de sysctl..."
sudo sysctl --system
echo ""
echo "Verificando parametros criticos:"
sysctl net.core.somaxconn \
       net.ipv4.tcp_tw_reuse \
       vm.swappiness \
       fs.file-max \
       net.ipv4.ip_forward

Conclusion

El tuning del kernel Linux no es un ejercicio de copiar y pegar valores de internet. Cada servidor tiene su carga de trabajo, hardware y patrones de uso unicos. Los parametros presentados en esta guía son puntos de partida probados para escenarios comunes (servidores web, bases de datos, nodos de Kubernetes), pero la clave esta en medir, ajustar y verificar. Un buen proceso de tuning, respaldado por herramientas de profiling como perf y ftrace, puede transformar el rendimiento de tu infraestructura sin cambiar una sola linea de código de aplicación.

Para complementar la optimización del kernel, consulta nuestra guía de hardening y seguridad de servidores Linux y aprende a gestionar recursos con cgroups y systemd. Si quieres una vision completa, revisa nuestra guía de administración avanzada de Linux.

Preguntas Frecuentes sobre Tuning del Kernel Linux

¿Qué es el tuning del kernel de Linux?

El tuning del kernel de Linux es el ajuste de los parámetros del sistema operativo para optimizar el rendimiento, la red, la memoria o la seguridad según la carga de trabajo. Se realiza principalmente modificando parámetros de sysctl, que controlan el comportamiento del kernel en tiempo de ejecución sin recompilarlo.

¿Qué es sysctl y para qué sirve?

sysctl es la interfaz de Linux para leer y modificar parámetros del kernel en tiempo de ejecución. Sirve para ajustar el comportamiento de red (buffers TCP, conexiones), memoria (swappiness, overcommit), límites del sistema y opciones de seguridad, sin necesidad de recompilar el kernel ni reiniciar el servidor.

¿Cómo aplicar los cambios de sysctl de forma permanente?

Para que los cambios de sysctl sean permanentes, agregá los parámetros en /etc/sysctl.conf o en un archivo dentro de /etc/sysctl.d/, y aplicalos con sudo sysctl —system. Los cambios hechos en caliente con sysctl -w se pierden al reiniciar; solo los archivos de configuración persisten tras un reinicio.

¿Qué parámetros del kernel conviene ajustar en un servidor de alto tráfico?

En servidores de alto tráfico conviene ajustar: net.core.somaxconn y net.ipv4.tcp_max_syn_backlog (conexiones entrantes), net.ipv4.tcp_tw_reuse (reutilización de sockets en TIME_WAIT), los buffers de recepción y envío (rmem/wmem), vm.swappiness para el uso de memoria, y las protecciones contra ataques SYN flood.

¿El tuning del kernel puede afectar la estabilidad del sistema?

Sí. Ajustar parámetros sin entenderlos puede degradar el rendimiento o causar inestabilidad. Lo recomendable es cambiar un parámetro a la vez, medir el impacto con benchmarks, probar primero en entornos de prueba y documentar cada cambio para poder revertirlo si algo sale mal.

Recursos