Mira la lección en vídeo
Accede al vídeo completo de esta lección y a más contenido exclusivo con el Plan Plus.
Desbloquear Plan PlusLímites CPU y memoria
Los contenedores Docker por defecto tienen acceso a todos los recursos del sistema host, lo que puede provocar que un contenedor consuma toda la CPU o memoria disponible, afectando el rendimiento de otros contenedores y el sistema en general. Docker proporciona varios parámetros para establecer límites de recursos y garantizar un comportamiento predecible en entornos de producción.
Límites de memoria
El parámetro --memory
permite establecer la cantidad máxima de memoria que puede utilizar un contenedor. Docker utiliza cgroups para hacer cumplir estos límites de forma estricta.
# Limitar memoria a 512MB
docker run -d --memory=512m --name nginx-limited nginx:alpine
# Limitar memoria a 1GB
docker run -d --memory=1g --name mysql-db mysql:8.0
La unidad de medida puede especificarse usando sufijos como k
, m
o g
(kilobytes, megabytes o gigabytes). Si un contenedor intenta usar más memoria de la permitida, el kernel matará el proceso principal del contenedor.
Control de memoria swap
El parámetro --memory-swap
controla la cantidad total de memoria más swap que puede usar el contenedor. Por defecto, Docker establece el límite de swap igual al límite de memoria, duplicando efectivamente la memoria disponible.
# Memoria 512MB + swap 512MB = total 1GB
docker run -d --memory=512m --memory-swap=1g nginx:alpine
# Desactivar completamente el swap
docker run -d --memory=512m --memory-swap=512m nginx:alpine
# Swap ilimitado (no recomendado)
docker run -d --memory=512m --memory-swap=-1 nginx:alpine
Es importante entender que --memory-swap
representa el límite total (memoria + swap), no la cantidad adicional de swap. Para desactivar el swap completamente, establece --memory-swap
igual a --memory
.
Límites de CPU
Docker ofrece varias opciones para controlar el uso de CPU en contenedores, desde límites absolutos hasta pesos relativos para el tiempo de CPU compartido.
1 - Límite absoluto de CPU con --cpus
:
# Limitar a 1.5 CPUs
docker run -d --cpus=1.5 --name cpu-limited nginx:alpine
# Limitar a medio CPU
docker run -d --cpus=0.5 --name half-cpu mysql:8.0
2 - Peso relativo con --cpu-shares
:
# Contenedor con peso normal (1024)
docker run -d --cpu-shares=1024 --name normal-weight nginx:alpine
# Contenedor con el doble de prioridad
docker run -d --cpu-shares=2048 --name high-priority mysql:8.0
# Contenedor con menor prioridad
docker run -d --cpu-shares=512 --name low-priority postgres:15
El parámetro --cpu-shares
establece un peso relativo para el tiempo de CPU. Solo tiene efecto cuando hay contención de CPU; si hay CPUs libres, los contenedores pueden usar toda la capacidad disponible.
Afinidad de CPU
El parámetro --cpuset-cpus
permite vincular un contenedor a CPUs específicas, útil en sistemas con múltiples cores para optimizar rendimiento o aislar cargas de trabajo.
# Ejecutar solo en las CPUs 0 y 1
docker run -d --cpuset-cpus="0,1" --name cpu-pinned nginx:alpine
# Ejecutar en un rango de CPUs (0 a 3)
docker run -d --cpuset-cpus="0-3" --name cpu-range mysql:8.0
# Combinar con límites de CPU
docker run -d --cpuset-cpus="0,2" --cpus=1.0 --name optimized-app postgres:15
Comportamiento en diferentes entornos
Los límites de recursos se comportan de manera diferente según el entorno donde se ejecute Docker:
-
Docker Desktop (Windows/macOS): Los límites se aplican dentro de la máquina virtual de Docker, que a su vez tiene sus propios límites de recursos asignados desde el sistema operativo host.
-
Linux nativo: Los límites se aplican directamente usando cgroups v2 (en distribuciones modernas), proporcionando un control más preciso y eficiente de los recursos.
# Verificar la versión de cgroups en Linux
docker info | grep -i cgroup
# Ejemplo completo con múltiples límites
docker run -d \
--name webapp \
--memory=1g \
--memory-swap=1g \
--cpus=2.0 \
--cpuset-cpus="0-3" \
nginx:alpine
Monitoreo y validación
Para verificar que los límites se están aplicando correctamente, puedes combinar estos parámetros con el comando docker stats
que aprendiste en la lección anterior:
# Crear un contenedor con límites específicos
docker run -d --name limited-mysql \
--memory=512m \
--cpus=1.0 \
mysql:8.0
# Monitorear el uso real de recursos
docker stats limited-mysql --no-stream
Los límites de memoria son estrictos y se hacen cumplir inmediatamente, mientras que los límites de CPU son más flexibles y permiten ráfagas cuando hay recursos disponibles, a menos que uses --cpus
para establecer un límite absoluto.
PIDs y afinidad CPU
Guarda tu progreso
Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.
Más de 25.000 desarrolladores ya confían en CertiDevs
Además de los límites básicos de CPU y memoria, Docker permite un control granular sobre otros aspectos críticos del sistema como el número de procesos y la asignación específica de cores de CPU para optimizar el rendimiento en entornos empresariales.
Límite de procesos (PIDs)
El parámetro --pids-limit
controla el número máximo de procesos que puede crear un contenedor, incluyendo threads y procesos hijos. Este límite es fundamental para prevenir ataques de fork bombs y garantizar la estabilidad del sistema.
# Limitar a 100 procesos máximo
docker run -d --pids-limit=100 --name nginx-pids nginx:alpine
# Limitar a 50 procesos para una aplicación específica
docker run -d --pids-limit=50 --name mysql-controlled mysql:8.0
Sin este límite, un contenedor malicioso o una aplicación con errores podría crear procesos de forma infinita hasta agotar los recursos del sistema host. El límite de PIDs se aplica de manera estricta: cuando se alcanza el límite, cualquier intento de crear nuevos procesos fallará.
Verificar el límite de PIDs en ejecución:
# Crear contenedor con límite específico
docker run -d --name app-limited --pids-limit=25 nginx:alpine
# Verificar procesos activos dentro del contenedor
docker exec app-limited ps aux | wc -l
Afinidad avanzada de CPU
Aunque ya conoces --cpuset-cpus
, existen configuraciones avanzadas que permiten un control más específico sobre la afinidad de CPU, especialmente útil en sistemas con arquitecturas NUMA o para aplicaciones que requieren latencia mínima.
Asignación de CPUs en sistemas NUMA:
# Asignar CPUs del mismo nodo NUMA
docker run -d --cpuset-cpus="0-7" --name numa-aware postgres:15
# Verificar la topología NUMA del sistema
docker run --rm --cpuset-cpus="0-3" alpine:latest \
sh -c "cat /proc/cpuinfo | grep 'processor\|physical id'"
Combinación de límites para optimización:
# Aplicación crítica con recursos dedicados
docker run -d \
--name critical-app \
--cpuset-cpus="0,1" \
--cpus=2.0 \
--memory=2g \
--pids-limit=200 \
nginx:alpine
Esta configuración reserva las CPUs 0 y 1 exclusivamente para el contenedor, limita el uso total a 2 CPUs completas, asigna 2GB de memoria y permite hasta 200 procesos.
Comportamiento en cgroups v2
Los sistemas Linux modernos utilizan cgroups v2, que proporciona un control más eficiente y unificado de los recursos. Los límites de PIDs y la afinidad de CPU se benefician de estas mejoras:
# Verificar la versión de cgroups
docker info | grep -i cgroup
# En cgroups v2, los límites son más precisos
docker run -d --pids-limit=10 --name cgroups-test alpine:latest sleep 3600
En cgroups v2, el control de PIDs es más granular y permite establecer límites más bajos de forma fiable, mientras que en cgroups v1 algunos límites muy bajos podrían no funcionar correctamente.
Monitoreo de PIDs y CPU
Para supervisar el cumplimiento de estos límites, puedes usar herramientas específicas que muestren el uso real de procesos y la asignación de CPU:
# Ver procesos activos en un contenedor
docker exec container-name ps aux | wc -l
# Verificar qué CPUs está usando realmente
docker exec container-name taskset -p 1
# Monitorear límites en tiempo real
docker stats container-name --format "table {{.Container}}\t{{.CPUPerc}}\t{{.PIDs}}"
Casos de uso específicos
Aplicaciones web con alta concurrencia:
# Servidor web con límites balanceados
docker run -d \
--name web-server \
--cpuset-cpus="0-2" \
--pids-limit=500 \
--memory=1g \
nginx:alpine
Base de datos con recursos dedicados:
# Base de datos con CPUs específicas y límite de conexiones
docker run -d \
--name database \
--cpuset-cpus="4-7" \
--pids-limit=1000 \
--memory=4g \
-e MYSQL_ROOT_PASSWORD=secret \
mysql:8.0
Contenedor de desarrollo con restricciones:
# Entorno de desarrollo limitado
docker run -it \
--cpuset-cpus="1" \
--pids-limit=50 \
--memory=512m \
alpine:latest sh
La combinación inteligente de estos límites permite crear entornos containerizados que utilizan los recursos de manera eficiente, previenen interferencias entre contenedores y garantizan un rendimiento predecible en producción.
Aprendizajes de esta lección de Docker
- Comprender cómo limitar el uso de memoria y swap en contenedores Docker.
- Aprender a controlar el uso de CPU mediante límites absolutos, pesos relativos y afinidad de CPU.
- Conocer cómo establecer límites en el número de procesos (PIDs) para evitar sobrecarga del sistema.
- Entender el comportamiento de estos límites en diferentes entornos y con cgroups v2.
- Saber cómo monitorear y validar la aplicación de estos límites en contenedores en ejecución.
Completa este curso de Docker y certifícate
Únete a nuestra plataforma de cursos de programación y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.
Asistente IA
Resuelve dudas al instante
Ejercicios
Practica con proyectos reales
Certificados
Valida tus conocimientos
Más de 25.000 desarrolladores ya se han certificado con CertiDevs