¿Cómo soluciono los errores OutOfMemory en Amazon ECS?

Última actualización: 16-09-2022

Quiero solucionar problemas de uso de memoria en mi tarea de Amazon Elastic Container Service (Amazon Elastic Container Service (Amazon ECS)).

-o bien-

Los contenedores de mi tarea de Amazon Elastic Container Service (Amazon ECS) se están cerrando debido a un error OutOfMemory.

Descripción corta

De forma predeterminada, un contenedor no tiene restricciones de recursos y puede usar tantos recursos como lo permita el programador del kernel del host. Con Docker, puede controlar la cantidad de memoria que utiliza un contenedor. Asegúrese de no permitir que un contenedor en ejecución consuma la mayor parte de la memoria de la máquina host. En los hosts Linux, cuando el kernel detecta que no hay suficiente memoria para realizar funciones importantes del sistema, lanza una excepción OutOfMemory y comienza a finalizar los procesos para liberar memoria.

Con Docker, puede usar una de las siguientes opciones:

  • Límites de memoria estrictos que permiten que el contenedor no utilice más de una cierta cantidad de memoria de usuario o del sistema.
  • Límites flexibles que permiten que el contenedor use tanta memoria como sea necesario, a menos que se produzcan ciertas condiciones, como poca memoria o contención en la máquina host.

Cuando finaliza una tarea de Amazon ECS debido a problemas de OutOfMemory, es posible que reciba el siguiente mensaje de error:

OutOfMemoryError: Container killed due to memory usage

Este error se produce cuando se cierra un contenedor de la tarea porque los procesos del contenedor consumen más memoria que la cantidad que se asignó en la definición de la tarea.

Resolución

Para solucionar los errores OutOfMemory en su tarea de Amazon Elastic Container Service (Amazon ECS), haga lo siguiente:

stats max(MemoryUtilized) as mem, max(MemoryReserved ) as memreserved by bin (5m) as period, TaskId, ContainerName
| sort period desc | filter ContainerName like “example-container-name” | filter TaskId = “example-task-id”

Para mitigar el riesgo de inestabilidad de las tareas debido a problemas de OutOfMemory, haga lo siguiente:

  • Lleve a cabo pruebas para comprender los requisitos de memoria de su aplicación antes de ponerla en producción. Puede llevar a cabo una prueba de carga en el contenedor dentro de un host o de un servidor. Después, podrá comprobar el uso de memoria de los contenedores gracias a las estadísticas de Docker.
  • Asegúrese de que la aplicación se ejecute únicamente en hosts que cuenten con recursos adecuados.
  • Limite la cantidad de memoria que puede usar el contenedor. Puede hacerlo estableciendo valores apropiados para el límite estricto y el límite flexible de sus contenedores. Amazon ECS utiliza varios parámetros para asignar memoria a las tareas memoryReservation (Reserva de memoria) para el límite flexible y memory (Memoria) para el límite estricto. Cuando especifica estos valores, se restan de los recursos de memoria disponibles para la instancia del contenedor en la que se coloca el contenedor.
    Nota: El parámetro memoryReservation (Reserva de memoria) no se admite en contenedores de Windows.
  • Puede activar el intercambio para contenedores con altas demandas de memoria transitoria. Al hacerlo, se reduce la posibilidad de recibir errores OutOfMemory cuando el contenedor tiene una carga alta.
    Nota: Si utiliza tareas que aplican el tipo de lanzamiento de AWS Fargate, no se admiten los parámetros maxSwap (Intercambio máximo) y sharedMemorySize (Tamaño de memoria compartida).
    Importante: Téngalo en cuenta cuando configure el intercambio en sus hosts de Docker. Activar el intercambio puede ralentizar la aplicación y reducir el rendimiento. Sin embargo, esta característica evita que la aplicación se quede sin memoria de sistema.

Para detectar las tareas de Amazon ECS que se han finalizado debido a eventos OutOfMemory, utilice la siguiente plantilla de AWS CloudFormation. Gracias a esta plantilla, puede crear una regla de Amazon EventBridge, un tema de Amazon Simple Notification Service (Amazon SNS) y una política de temas en Amazon SNS. Cuando ejecute la plantilla, esta solicitará una lista de correo electrónico, un nombre de tema y un indicador para activar o desactivar el monitoreo.

AWSTemplateFormatVersion: 2010-09-09
Description: >
        - Monitor OOM Stopped Tasks with EventBridge rules with AWS CloudFormation.

Parameters:
  EmailList:
    Type: String
    Description: "Email to notify!"
    AllowedPattern: '[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z]+'
    Default: "mail@example.com"

  SNSTopicName:
    Type: String
    Description: "Name for the notification topic."
    AllowedPattern: '[a-zA-Z0-9_-]+'
    Default: "oom-monitoring-topic"

  MonitorStatus:
    Type: String
    Description: "Enable / Disable monitor."
    AllowedValues:
      - ENABLED
      - DISABLED
    Default: ENABLED

Resources:
  SNSMonitoringTopic:
    Type: AWS::SNS::Topic
    Properties:
      Subscription:
        - Endpoint: !Ref EmailList
          Protocol: email
      TopicName: !Sub ${AWS::StackName}-${SNSTopicName}
      
  SNSMonitoringTopicTopicPolicy:
    Type: AWS::SNS::TopicPolicy
    Properties:
      Topics:
        - !Ref SNSMonitoringTopic
      PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Sid: SnsOOMTopicPolicy
            Effect: Allow
            Principal:
              Service: events.amazonaws.com
            Action: [  'sns:Publish' ]
            Resource: !Ref SNSMonitoringTopic
          - Sid: AllowAccessToTopicOwner
            Effect: Allow
            Principal:
              AWS: '*'
            Action: [  'sns:GetTopicAttributes',
                       'sns:SetTopicAttributes',
                       'sns:AddPermission',
                       'sns:RemovePermission',
                       'sns:DeleteTopic',
                       'sns:Subscribe',
                       'sns:ListSubscriptionsByTopic',
                       'sns:Publish',
                       'sns:Receive' ]
            Resource: !Ref SNSMonitoringTopic
            Condition:
              StringEquals:
                'AWS:SourceOwner': !Ref 'AWS::AccountId'
          
  EventRule:
    Type: AWS::Events::Rule
    Properties:
      Name: ECSStoppedTasksEvent
      Description: Triggered when an Amazon ECS Task is stopped
      EventPattern:
        source:
          - aws.ecs
        detail-type:
          - ECS Task State Change
        detail:
          desiredStatus:
            - STOPPED
          lastStatus:
            - STOPPED
          containers:
            reason:
              - prefix: "OutOfMemory"
      State: !Ref MonitorStatus
      Targets:
        - Arn: !Ref SNSMonitoringTopic
          Id: ECSOOMStoppedTasks
          InputTransformer:
            InputPathsMap:
              taskArn: $.detail.taskArn
            InputTemplate: >
                "Task '<taskArn>' was stopped due to OutOfMemory."

Una vez que haya creado la pila de CloudFormation, puede verificar el correo electrónico para confirmar la suscripción. Cuando se haya finalizado una tarea debido a un problema OutOfMemory, recibirá un correo electrónico con un mensaje parecido al siguiente:

"Task 'arn:aws:ecs:eu-west-1:555555555555:task/ECSFargate/0123456789abcdef0123456789abcdef' was stopped due to OutOfMemory."

How do I troubleshoot issues with containers exiting in my Amazon Elastic Container Service (Amazon ECS) tasks? (¿Cómo puedo solucionar problemas con los contenedores salientes de mis tareas de Amazon Elastic Container Service (Amazon ECS)?)

¿Le resultó útil este artículo?


¿Necesita asistencia técnica o con la facturación?