Gestión de Control de Recursos en Contenedores Docker

Introdución a cgroups en Docker

En el ecosistema de contenedores, Docker utiliza la funcionalidad de cgroups del kernel de Linux para administrar y limitar recursos del sistema como CPU, memoria y E/S de disco. cgroups permite asignar cuotas, establecer prioridades, medir el uso y controlar la ejecución de procesos dentro de los contenedores. Las capacidades principales incluyen restricciones de recursos, asignación de prioridades a través de fragmentos de tiempo de CPU o ancho de banda de E/S, estadísticas de uso, y control de tareas como pausar o reanudar procesos.

Control de CPU

El planificador CFS (Completely Fair Scheduler) de Linux gestiona el tiempo de CPU con un ciclo predeterminado de 100ms. Se pueden ajustar estos ciclos y asignar cuotas específicas a los contenedores usando parámetros como --cpu-period y --cpu-quota, donde el periodo debe estar entre 1ms y 1s (valores de 1000 a 1000000 microsegnudos), y la cuota mínima es 1000 microsegundos.

Establecer límites de uso de CPU

Para monitorear y configurar el uso de CPU, se puede inspeccionar los archivos de cgroup correspondientes. Por ejemplo, al crear un contenedor, se puede verificar los ajustes en /sys/fs/cgroup/cpu/.

# Crear un contenedor para pruebas
docker run -d --name servidor-test imagen-base:latest /bin/sh

# Acceder a los archivos de cgroup para el contenedor
cd /sys/fs/cgroup/cpu/docker/[ID_CONTENEDOR]
cat cpu.cfs_period_us  # Muestra el periodo en microsegundos, por defecto 100000
cat cpu.cfs_quota_us   # Muestra la cuota asignada, por defecto -1 (sin límite)

Para realizar una prueba de estrés de CPU, se puede ejecutar un script dentro del contenedor que consuma recursos continuamente.

# Ejecutar un bucle infinito para simular carga de CPU
cat > script-carga.sh << 'EOF'
#!/bin/bash
contador=0
while [ true ]; do
    contador=$((contador + 1))
done
EOF
chmod +x script-carga.sh
docker exec -it servidor-test ./script-carga.sh

Para limitar el uso de CPU al 50%, se puede asignar una cuota de 50000 microsegundos en un periodo de 100000. Esto se puede hacer al crear el contenedor o modificando los archivos de cgroup en tiempo de ejecución.

# Opción 1: Al crear el contenedor
docker run -d --name contenedor-limitado --cpu-quota 50000 imagen-base:latest /bin/sh

# Opción 2: Modificar cgroup para un contenedor existente
echo 50000 > /sys/fs/cgroup/cpu/docker/[ID_CONTENEDOR]/cpu.cfs_quota_us
# Luego, ejecutar el script de estrés y verificar con 'top' o 'docker stats'

Asignar ratios de recursos de CPU

Para equilibrar el uso de CPU entre múltiples contenedores, se utiliza --cpu-shares para establecer prioridades relativas. Por ejemplo, con dos contenedores, uno con 1024 shares y otro con 512, el primero tendrá acceso preferente cuando la CPU esté saturada.

# Crear contenedores con diferentes pesos de CPU
docker run -d --name contenedor-alto --cpu-shares 1024 imagen-base:latest
docker run -d --name contenedor-bajo --cpu-shares 512 imagen-base:latest

# Para probar, instalar herramientas de estrés dentro de los contenedores y ejecutar procesos concurrentes
# Monitorear con 'docker stats' para observar la distribución de recursos

Vincular contenedores a núcleos específicos de CPU

Se puede asignar núcleos de CPU específicos a un contenedor usando --cpuset-cpus. Esto es útil para aislar cargas de trabajo en núcleos dedicados.

# Asignar núcleos 1 y 3 al contenedor
docker run -d --name contenedor-vinculado --cpuset-cpus "1,3" imagen-base:latest /bin/sh

# Dentro del contenedor, ejecutar una carga de trabajo y verificar la asignación con 'top' en el host

Limitaciones de Memoria

Establecer límites de memoria física

El parámetro -m o --memory define la cantidad máxima de memoria física que puede usar un contenedor. Por ejemplo, para limitar a 512MB:

docker run -d --name contenedor-memoria -m 512m imagen-base:latest /bin/sh
# Verificar el uso de memoria con 'docker stats'

Configurar memoria física y swap

El uso de --memory-swap especifica el límite total de memoria física más swap. Si se establece --memory-swap a 1G con -m 512m, el contenedor puede usar 512MB de memoria física y hasta 512MB de swap. Opciones adicionales incluyen:

  • Si --memory-swap es igual a -m, no se usa swap.
  • Si es -1, el uso de swap es ilimitado según la disponibilidad del host.
  • Si no se define, el swap permitido es el doble de la memoria física asignada.
# Ejemplo: Limitar memoria a 512MB y swap a 1GB
docker run -d --name contenedor-memoria-swap -m 512m --memory-swap 1g imagen-base:latest /bin/sh

Control de E/S de Disco (blkio)

Configurar límites de E/S

Docker ofrece parámetros para controlar la velocidad de lectura y escritura en dispositivos específicos, como --device-read-bps y --device-write-bps para limitar bytes por segundo, o variantes para operaciones por segundo (IOPS).

# Limitar la velocidad de escritura a 1MB/s en /dev/sda
docker run -d --name contenedor-io --device-write-bps /dev/sda:1M imagen-base:latest /bin/sh

# Para limitar la velocidad de lectura a 500KB/s
docker run -d --name contenedor-lectura --device-read-bps /dev/sda:500K imagen-base:latest /bin/sh

Verificar límites de E/S

Se puede usar la herramienta dd dentro del contenedor para probar la velocidad de escritura, evitendo cachés del sistema de archivos.

# Entrar al contenedor y ejecutar una escritura de prueba
docker exec -it contenedor-io sh
dd if=/dev/zero of=prueba.out bs=1M count=50 oflag=direct
# La salida mostrará la velocidad real, que debería respetar el límite establecido

Limpieza de Espacio en Disco

Para eliminar recursos no utilizados de Docker, como contenedores detenidos, volúmenes sin referencias y redes, se puede usar el comando de poda del sistema.

docker system prune -a  # Elimina todos los recursos no utilizados

Etiquetas: Docker cgroups Linux Kernel contenedores gestión de recursos

Publicado el 6-14 20:07