Comment puis-je résoudre les erreurs OutOfMemory dans Amazon ECS ?

Lecture de 6 minute(s)
0

Je souhaite résoudre les problèmes d'utilisation de la mémoire dans ma tâche Amazon Elastic Container Service (Amazon ECS). Autre cas de figure : les conteneurs de ma tâche Amazon ECS se ferment en raison d'une erreur « OutOfMemory ».

Brève description

Par défaut, un conteneur n'a pas de contraintes de ressources, et peut en utiliser autant de ressources que le planificateur du noyau de l'hôte le permet. Docker vous permet de contrôler la quantité de mémoire qu'utilise un conteneur. Veillez à ce qu'un conteneur en cours d'exécution ne consomme pas l'essentiel de la mémoire de la machine hôte. Sur les hôtes Linux, le noyau lance une exception OutOfMemory lorsqu'il détecte que la mémoire est insuffisante pour exécuter des fonctions système importantes. Ensuite, il met fin aux processus pour libérer de la mémoire.

Docker vous permet d'utiliser l'une ou l'autre des limites de mémoire suivantes :

  • Limites de mémoire strictes qui permettent au conteneur de ne pas utiliser plus d'une certaine quantité de mémoire utilisateur ou système
  • Limites modérées qui permettent au conteneur d'utiliser la mémoire nécessaire à moins que certaines conditions, notamment une mémoire insuffisante ou un conflit sur la machine hôte, ne soient réunies

Lorsqu'une tâche Amazon ECS se termine en raison de problèmes de type OutOfMemory, vous pouvez recevoir le message d'erreur suivant dans la console Amazon ECS. Pour afficher le message, choisissez l'identifiant de la tâche, puis reportez-vous à la section Détails pour afficher les détails du conteneur :

OutOfMemoryError: Container killed due to memory usage

Dans ce cas, un conteneur de votre tâche se ferme, car ses processus consomment plus de mémoire que la quantité allouée à la tâche.

Résolution

Pour résoudre les erreurs OutOfMemory dans votre tâche Amazon ECS, procédez comme suit :

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"

Pour atténuer le risque d'instabilité des tâches en raison de problèmes OutOfMemory, procédez comme suit :

  • Faites des tests pour comprendre les besoins en mémoire de votre application avant de la mettre en production. Vous pouvez faire un test de charge sur le conteneur au sein d'un hôte ou d'un serveur. Vérifiez ensuite l'utilisation de la mémoire par les conteneurs à l'aide des statistiques Docker (à partir du site Web de Docker Docs).
  • Assurez-vous que votre application s'exécute uniquement sur des hôtes disposant de ressources adéquates.
  • Limitez la quantité de mémoire que votre conteneur peut utiliser. Définissez des valeurs appropriées pour les limites strictes et les limites modérées de vos conteneurs. Amazon ECS utilise plusieurs paramètres pour allouer de la mémoire aux tâches : memoryReservation pour les limites modérées et mémoires pour les limites strictes. Lorsque vous spécifiez ces valeurs, elles sont soustraites des ressources mémoire disponibles pour l'instance de conteneur dans laquelle se trouve le conteneur. Remarque : le paramètre memoryReservation n'est pas pris en charge pour les conteneurs Windows.
  • Vous pouvez activer le paramètre échange pour les conteneurs dont les demandes en mémoire transitoire sont fortes. Ce faisant, vous réduisez le risque d'erreurs OutOfMemory lorsque le conteneur est fortement sollicité. Remarque : Si vous utilisez des tâches ayant le type de lancement AWS Fargate, les paramètres maxSwap et sharedMemorySize ne sont pas pris en charge. Important : Soyez attentif au moment où vous configurez la fonctionnalité échange sur vos hôtes Docker. L'activation de l'échange peut ralentir votre application et réduire les performances. Toutefois, cette fonctionnalité empêche votre application de manquer de mémoire système.

Pour détecter les tâches Amazon ECS qui se sont arrêtées en raison d'événements OutOfMemory, utilisez le modèle AWS CloudFormation suivant. Grâce à ce modèle, vous pouvez créer une règle Amazon EventBridge, une rubrique Amazon Simple Notification Service (Amazon SNS) et une politique relative aux rubriques Amazon SNS. Lorsque vous exécutez le modèle, celui-ci demande une liste d'e-mails, un nom de rubrique et un indicateur pour activer ou désactiver la surveillance :

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."

Une fois la pile CloudFormation créée, allez dans votre boîte e-mail pour confirmer l'abonnement. Lorsqu'une tâche se termine en raison d'un problème OutOfMemory, vous recevez un e-mail contenant un message similaire à l'exemple suivant :

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

Informations connexes

Comment puis-je résoudre les problèmes d'arrêt ou d'échec des tâches Amazon ECS à la fermeture de mon conteneur ?

AWS OFFICIEL
AWS OFFICIELA mis à jour il y a 10 mois