Cómo establecer un límite de memoria para contenedores Docker
Los contenedores Docker se ejecutan de forma predeterminada sin restricciones de recursos. Los procesos que se ejecutan en contenedores tienen la libertad de utilizar cantidades ilimitadas de memoria, lo que podría afectar a los contenedores vecinos y otras cargas de trabajo en su host.
Esto es peligroso en entornos de producción. Cada contenedor debe configurarse con un límite de memoria adecuado para evitar el consumo descontrolado de recursos. Esto ayuda a reducir la contención, lo que maximizará la estabilidad general del sistema.
Cómo funcionan los límites de memoria de Docker
Docker le permite establecer límites de memoria rígidos y flexibles en contenedores individuales. Estos tienen diferentes efectos sobre la cantidad de memoria disponible y el comportamiento cuando se alcanza el límite.
- Límites de memoria dura establezca un límite absoluto en la memoria proporcionada al contenedor. Superar este límite normalmente hará que el kernel out-of-memory killer termine el proceso del contenedor.
- Límites de memoria blanda indicar la cantidad de memoria que se espera que use un contenedor. El contenedor puede usar más memoria cuando hay capacidad disponible. Podría cancelarse si excede un límite suave durante una condición de poca memoria.
Docker también proporciona controles para establecer restricciones de memoria de intercambio y cambiar lo que sucede cuando se alcanza un límite de memoria. Verá cómo usarlos en las siguientes secciones.
Configuración de límites de memoria duros y blandos
Un límite de memoria dura es establecido por el docker run
de comando -m
o --memory
bandera. Toma un valor como 512m
(para megabytes) o 2g
(para gigas):
$ docker run --memory=512m my-app:latest
Los contenedores tienen un requisito mínimo de memoria de 6 MB. tratando de usar --memory
valores menores que 6m
provocará un error.
Los límites de la memoria flexible se establecen con el --memory-reservation
bandera. Este valor debe ser menor que --memory
. El límite solo se aplicará cuando se produzca una contención de recursos del contenedor o cuando el host tenga poca memoria física.
$ docker run --memory=512m --memory-reservation=256m my-app:latest
Este ejemplo inicia un contenedor que tiene 256 MB de memoria reservada. El proceso podría finalizar si está usando 300 MB y la capacidad se está agotando. Siempre se detendrá si el uso supera los 512 MB.
Gestión de la memoria de intercambio
A los contenedores se les puede asignar memoria de intercambio para acomodar un alto uso sin afectar el consumo de memoria física. Swap permite que el contenido de la memoria se escriba en el disco una vez que se haya agotado la RAM disponible.
los --memory-swap
bandera controla la cantidad de espacio de intercambio disponible. Solo funciona en conjunto con --memory
. cuando configuras --memory
y --memory-swap
a diferentes valores, el valor de intercambio controla la cantidad total de memoria disponible para el contenedor, incluido el espacio de intercambio. El valor de --memory
determina la porción de la cantidad que es memoria física.
$ docker run --memory=512m --memory-swap=762m my-app:latest
Este contenedor tiene acceso a 762 MB de memoria de los cuales 512 MB son RAM física. Los 250 MB restantes son espacio de intercambio almacenado en el disco.
Ajuste --memory
sin que --memory-swap
le da al contenedor acceso a la misma cantidad de espacio de intercambio que la memoria física:
$ docker run --memory=512m my-app:latest
Este contenedor tiene un total de 1024 MB de memoria, que comprende 512 MB de RAM y 512 MB de intercambio.
El intercambio se puede deshabilitar para un contenedor configurando el --memory-swap
marca al mismo valor que --memory
. Como --memory-swap
establece la cantidad total de memoria, y --memory
asigna la proporción de memoria física, le está indicando a Docker que el 100 % de la memoria disponible debe ser RAM.
En todos los casos, el intercambio solo funciona cuando está habilitado en su host. Los informes de intercambio dentro de los contenedores no son confiables y no deben usarse. Comandos como free
que se ejecutan dentro de un contenedor mostrarán la cantidad total de espacio de intercambio en su host Docker, no el espacio de intercambio accesible para el contenedor.
Desactivación de muertes de procesos por falta de memoria
Los errores de falta de memoria en un contenedor normalmente hacen que el núcleo elimine el proceso. Esto da como resultado que el contenedor se detenga con el código de salida 137.
Incluyendo la bandera opcional --oom-kill-disable
con tu docker run
El comando deshabilita este comportamiento. En lugar de detener el proceso, el núcleo simplemente bloqueará las nuevas asignaciones de memoria. El proceso parecerá bloquearse hasta que reduzca su uso de memoria, cancele nuevas asignaciones de memoria o reinicie manualmente el contenedor.
Este indicador no debe usarse a menos que haya implementado mecanismos para resolver usted mismo las condiciones de falta de memoria. Por lo general, es mejor dejar que el kernel elimine el proceso, lo que provoca un reinicio del contenedor que restaura el consumo normal de memoria.
Resumen
Los contenedores Docker vienen sin restricciones de recursos aplicadas previamente. Esto deja a los procesos de contenedores libres para consumir memoria ilimitada, lo que amenaza la estabilidad de su host.
En este artículo, aprendió cómo establecer límites de memoria de contenedores rígidos y flexibles para reducir la posibilidad de que se encuentre con una situación de falta de memoria. Establecer estos límites en todos sus contenedores reducirá la contención de recursos y lo ayudará a mantenerse dentro de la capacidad de memoria física de su host. Debe considerar el uso de límites de CPU junto con sus límites de memoria; esto evitará que los contenedores individuales con una alta demanda de CPU afecten negativamente a sus vecinos.