Docker Compose: límites de memoria

Docker Compose Memory Limits



Docker compose es una poderosa utilidad. Ahorra tiempo y reduce los errores al implementar su aplicación Dockerizada. Por lo general, no es una buena idea ejecutar toda la pila, incluida la interfaz, el servidor de la base de datos, etc., desde dentro de un solo contenedor.

Desarrollamos diferentes contenedores para manejar diferentes cargas de trabajo de una aplicación y usamos Docker Compose para hacerlo fácilmente. Cada carga de trabajo lógicamente diferente se enumera como una Servicio . Por ejemplo, su servidor http de frontend aparecerá como un servicio de frontend que ejecuta una imagen de Apache o Nginx como contenedor.







Todos los servicios, sus necesidades de red, requisitos de almacenamiento, etc. se pueden especificar en un archivo docker-compose.yml. Nos centraremos en especificar la utilización de la memoria aquí.



Necesitaría las siguientes herramientas en su arsenal para seguir adelante:



  1. Comprensión básica de Docker
  2. Docker para Windows o Mac o si está ejecutando Linux, DockerCE para Linux
  3. Docker Compose binar y (los usuarios de Windows y Mac ya lo tendrán instalado)

Nos ceñiremos a la versión 2.4 para nuestros archivos docker-compose.yml, ya que admite la versión 17.12 y superior de Docker Engine y superior. Podríamos haber optado por la versión 3, que es más reciente, pero no es compatible con la sintaxis de limitación de memoria anterior. Si intenta usar la sintaxis más nueva, insiste en usar Docker en el modo Swarm. Así que, para simplificar las cosas para los usuarios habituales de Docker, me quedaré con la versión 2.4.





La mayor parte del código funcionaría igual para la versión 3, y donde habrá una diferencia, mencionaré la sintaxis más nueva para los usuarios de Docker Swarm.

Aplicación de muestra

Intentemos ejecutar un servicio Nginx simple en el puerto 80 usando primero la CLI y luego un simple docker-compose.yml. En la siguiente sección, exploraremos sus limitaciones de memoria y su utilización y modificaremos nuestro docker-compose.yml para ver cómo se imponen las limitaciones personalizadas.



Comencemos un servidor nginx simple usando Docker-CLI:

$ docker ejecutar -d --name my-nginx -p80:80nginx: último

Puede ver el funcionamiento del servidor nginx visitando http: // localhost o reemplace lcoalhost

Con la dirección IP de su host Docker. Este contenedor puede utilizar potencialmente toda la memoria disponible en su host Docker (en nuestro caso, es de aproximadamente 2 GB). Para verificar la utilización de la memoria, entre otras cosas, podemos usar el comando:

$ docker stats my-nginx

NOMBRE DE ID DE CONTENEDOR CPU% MEM USO / LÍMITE MEM% NET E / S BLOQUE E / S PIDS
6eb0091c0cf2 my-nginx0.00% 2.133MiB / 1.934GiB0.11% 3,14 kB / 2,13 kB 0B / 0B2

El USO / LÍMITE DE MEM es de 2.133MiB del total de 1.934GiB. Eliminemos este contenedor y comencemos a escribir secuencias de comandos de composición de Docker.

$ docker detener mi-nginx
$ docker rm my-nginx

Archivo ym equivalente

El contenedor exacto como el anterior se puede crear si seguimos estos pasos:

$ mkdir my-compose
$ cd my-compose
$ vim docker-compose.yml

Creamos un nuevo directorio vacío y creamos un archivo docker-compose.yml en él. Cuando ejecutemos docker-compose desde este directorio, buscará este archivo específico (ignorando todo lo demás) y creará nuestra implementación en consecuencia. Agregue el siguiente contenido dentro de este archivo .yml.

versión:'3'
servicios:
mi-nginx:
imagen: nginx: último
puertos:
-'80:80'

$ docker-compose up -d

Se agrega la marca -d para que los contenedores recién creados se ejecuten en segundo plano. De lo contrario, la terminal se adherirá a los contenedores y comenzará a imprimir informes desde ella. Ahora podemos ver las estadísticas de los contenedores recién creados:

$ docker stats -todos

NOMBRE DE ID DE CONTENEDOR CPU% MEM USO / LÍMITE MEM% NET E / S BLOQUE E / S PIDS
5f8a1e2c08ac my-compose_my-nginx_10.00% 2,25 MiB / 1,934 GiB0.11% 1,65 kB / 0B 7,35 MB / 0B2

Notará que se creó un contenedor similar al anterior con límites de memoria e incluso utilización similares. Desde el mismo directorio que contiene el archivo yml. Ejecute el siguiente comando para eliminar el contenedor recién creado, junto con la red de puente del cliente que se creó.

$docker-componer abajo

Esto devolverá la ventana acoplable a un estado limpio con la excepción de los volúmenes que se crearon (no creamos ninguno, así que eso no es una preocupación).

Límites de memoria y reservas de memoria

Los límites de memoria y las reservas de memoria son dos aspectos diferentes para garantizar un buen funcionamiento de sus aplicaciones y del host de Docker en el que está ejecutando.

En términos generales, Memory Limit impone un límite superior a la cantidad de memoria que potencialmente puede usar un contenedor Docker. De forma predeterminada, un contenedor de Docker, como cualquier otro proceso del sistema, puede utilizar toda la memoria disponible del host de Docker. Esto puede causar una excepción de memoria insuficiente y es muy posible que su sistema se bloquee. Incluso si nunca se llega a eso, aún puede privar a otros procesos (incluidos otros contenedores) de recursos valiosos, lo que nuevamente perjudica el rendimiento. Los límites de memoria garantizan que los contenedores hambrientos de recursos no superen un límite determinado. Esto limita el radio de explosión de una aplicación mal escrita a unos pocos contenedores, no a todo el host.

Las reservas de memoria, por otro lado, son menos rígidas. Cuando el sistema se está quedando sin memoria e intenta recuperar parte de ella. Intenta que el consumo de memoria del contenedor sea igual o inferior al límite de reserva. Sin embargo, si hay mucha memoria, la aplicación puede expandirse hasta el límite de memoria establecido.

Para resumir:

  1. Límite de memoria: límite superior estricto para la cantidad de memoria disponible para un contenedor.
  2. Reserva de memoria: debe establecerse como la cantidad mínima de memoria que una aplicación necesita para ejecutarse correctamente. Por lo tanto, no se bloquea ni se comporta mal cuando el sistema intenta recuperar parte de la memoria.

Si la reserva de memoria es mayor que el límite de memoria, el límite de memoria tiene prioridad.

Especificación de límites de memoria y reserva

Versión 2

Regresemos al docker-compose.yml que escribimos anteriormente y agreguemos un límite de memoria. Cambie la versión a 2.4 por las razones discutidas en la sección de requisitos previos.

versión:'2.4'
servicios:
mi-nginx:
imagen: nginx: último
puertos:
-'80:80'
mem_limit: 300 m

La última línea establece el límite para el servicio my-nginx en 300MiB. Puede usar k para KiB, g para GiB yb para solo bytes. Sin embargo, el número anterior debe ser un número entero. No puede usar valores como 2.4 m, tendría que usar 2400k en su lugar. Ahora si corres:

$ docker stat --todos

NOMBRE DE ID DE CONTENEDOR CPU% MEM USO / LÍMITE MEM% NET E / S BLOQUE E / S PIDS
44114d785d0a my-compose_my-nginx_10.00% 2,141 MiB / 300 MiB0.71% 1,16 kB / 0B 0B / 0B2

Notará que el límite de memoria está establecido en 300 MiB. Configurar la reserva de memoria es igualmente fácil, simplemente agregue una línea mem_reservation: xxx al final.

versión:'2.4'
servicios:
mi-nginx:
imagen: nginx: último
puertos:
-'80:80'
mem_limit: 300 m
mem_reservation: 100m

Versión 3 (opcional)

Para usar la versión tres, debe ejecutar Docker en modo enjambre. Para Windows y Mac, puede habilitarlo usando el menú de configuración de Docker. Los usuarios de Linux deberían ejecutar docker swarm init. Se puede encontrar más información al respecto. aquí . Sin embargo, no es un paso necesario y, si no lo ha habilitado, también está bien. Esta sección es para personas ya se ejecuta en modo enjambre y puede hacer uso de la versión más reciente.

versión:'3'
servicios:
mi-nginx:
imagen: nginx: último
puertos:
-'80:80'
desplegar:
recursos:
límites:
memoria: 300m
reservas:
memoria: 100 m

Definimos todo esto en la opción de recursos. Los límites y la reserva se convierten en claves primarias por sí mismas y la memoria es solo uno de los muchos recursos que se administran aquí. La CPU es otro parámetro importante.

Más información

Puede obtener más información sobre docker-compose en la documentación oficial vinculado aquí . Una vez que obtenga la esencia de cómo escribir un archivo de redacción, la documentación puede ayudarlo con los diversos parámetros específicos.

No es necesario que lo sepa todo, solo busque lo que requiere su aplicación y la referencia lo guiará para implementarlo.