Come posso risolvere gli errori di memoria insufficiente (OutOfMemory) in Amazon ECS?

Ultimo aggiornamento: 16/09/2022

Desidero risolvere i problemi di utilizzo della memoria per la mia attività Amazon Elastic Container Service (Amazon ECS).

-oppure-

I container nella mia attività Amazon ECS vengono terminati a causa di un errore di memoria insufficiente (OutOfMemory).

Breve descrizione

Di default, un container non ha vincoli di risorse e può utilizzare tutte quelle consentite dallo scheduler del kernel dell'host. Con Docker, puoi controllare la quantità di memoria utilizzata da un container. Assicurati di non consentire a un container in esecuzione di consumare la maggior parte della memoria della macchina host. Sugli host Linux, quando il kernel rileva che non c'è abbastanza memoria per eseguire importanti funzioni di sistema, genera un'eccezione OutOfMemory (Memoria insufficiente) e inizia a terminare i processi per liberare memoria.

Con Docker, puoi scegliere di utilizzare:

  • Limiti di memoria rigidi, che non consentono al container di utilizzare più di una certa quantità di memoria utente o di sistema;
  • Limiti flessibili, che consentono al container di utilizzare la quantità di memoria necessaria, a meno che non si verifichino determinate condizioni, come memoria insufficiente o contesa sul computer host.

Quando un'attività Amazon ECS viene terminata a causa di problemi di memoria insufficiente, è possibile che venga visualizzato il seguente messaggio di errore:

OutOfMemoryError: Container killed due to memory usage

Questo errore viene visualizzato quando un container nell'attività viene terminato perché i processi al suo interno consumano più memoria rispetto alla quantità allocata nella definizione dell'attività.

Risoluzione

Per risolvere gli errori di memoria insufficiente nell'attività Amazon ECS, procedi come segue:

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”

Per ridurre il rischio di instabilità delle attività a causa di problemi di memoria insufficiente, procedi come segue:

  • Esegui test per comprendere i requisiti di memoria dell'applicazione prima di mettere l'applicazione in produzione. Puoi eseguire un test di carico sul container all'interno di un host o di un server. Quindi, puoi controllare l'utilizzo della memoria dei container utilizzando le statistiche docker.
  • Assicurati che la tua applicazione venga eseguita solo su host con risorse adeguate.
  • Limita la quantità di memoria che può essere utilizzata dal container. Puoi farlo impostando valori specifici per i limiti rigidi e quelli flessibili per i tuoi container. Amazon ECS utilizza diversi parametri per l'allocazione della memoria alle attività: memoryReservation per il limite flessibile e memory per il limite rigido. Quando specifici questi valori, vengono sottratti dalle risorse di memoria disponibili per l'istanza di container in cui è posizionato quest'ultimo.
    Nota: il parametro memoryReservation non è supportato per i container Windows.
  • Puoi attivare swap per i container con elevate esigenze di memoria transitoria. In questo modo si riduce la possibilità di errori di memoria insufficiente quando il container è sottoposto a un carico elevato.
    Nota: se utilizzi attività che usano il tipo di avvio di AWS Fargate, i parametri maxSwap e sharedMemorySize non sono supportati.
    Importante: fai attenzione quando configuri lo swap sui tuoi host Docker. L'attivazione dello swap può rallentare l'applicazione e ridurre le prestazioni. Tuttavia, questa caratteristica impedisce all'applicazione di esaurire la memoria di sistema.

Per rilevare le attività di Amazon ECS terminate a causa di eventi di memoria insufficiente (OutOfMemory), utilizza il seguente modello AWS CloudFormation. Con questo modello, puoi creare una regola Amazon EventBridge, un argomento Servizio di notifica semplice Amazon (Amazon SNS) e una policy tematica di Amazon SNS. Quando esegui il modello, questo richiede un elenco di e-mail, il nome dell'argomento e un contrassegno per attivare o disattivare il monitoraggio.

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

Dopo aver creato lo stack CloudFormation, puoi verificare la tua e-mail per confermare l'iscrizione. Al termine di un'operazione a causa di un problema con OutOfMemory, viene visualizzata un'e-mail con un messaggio simile al seguente:

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

Questo articolo è stato utile?


Benötigen Sie Hilfe zur Fakturierung oder technischen Support?