Como soluciono problemas de erros de OutOfMemory no Amazon ECS?

5 minuto de leitura
0

Desejo solucionar problemas de uso de memória na minha tarefa do Amazon Elastic Container Service (Amazon ECS). -ou- Os contêineres em minha tarefa do Amazon ECS estão sendo encerrados devido ao erro OutOfMemory.

Breve descrição

Por padrão, um contêiner não tem restrições de recursos e pode usar tantos recursos quanto o programador de kernel do host permitir. Com o Docker, você pode controlar a quantidade de memória usada por um contêiner. Certifique-se de não permitir que um contêiner em execução consuma a maior parte da memória da máquina host. Em hosts Linux, quando o kernel detecta que não há memória suficiente para executar funções importantes do sistema, ele lança uma exceção OutOfMemory e começa a encerrar os processos para liberar memória.

Com o Docker, você pode usar um dos seguintes:

  • Limites de memória rígida que permitem que o contêiner não use mais do que uma certa quantidade de memória do usuário ou do sistema.
  • Limites flexíveis que permitem que o contêiner use a quantidade de memória necessária, a menos que certas condições, como pouca memória ou contenção na máquina host, ocorram.

Quando uma tarefa do Amazon ECS é encerrada devido a problemas de OutOfMemory, você pode receber a seguinte mensagem de erro:

OutOfMemoryError: Container killed due to memory usage

Você recebe esse erro quando um contêiner em sua tarefa é encerrado porque os processos no contêiner consomem mais memória do que a quantidade alocada na definição da tarefa.

Resolução

Para solucionar erros de OutOfMemory na tarefa do Amazon ECS, faça o seguinte:

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 o risco de instabilidade de tarefas devido a problemas de OutOfMemory, faça o seguinte:

  • Realize testes para entender os requisitos de memória de sua aplicação antes de colocá-la em produção. Você pode realizar um teste de carga no contêiner em um host ou servidor. Em seguida, você pode verificar o uso de memória dos contêineres usando estatísticas do Docker.
  • Certifique-se de que sua aplicação seja executada somente em hosts com recursos adequados.
  • Limite a quantidade de memória que seu contêiner pode usar. Você pode fazer isso definindo os valores apropriados para limite rígido e limite flexível para seus contêineres. O Amazon ECS usa vários parâmetros para alocar memória para tarefas: memoryReservation para limite flexível e memory para limite fixo. Quando você especifica esses valores, eles são subtraídos dos recursos de memória disponíveis para a instância de contêiner em que o contêiner é colocado.
    Observação: o parâmetro memoryReservation não é aceito para contêineres do Windows.
  • Você pode ativar a troca para contêineres com altas demandas de memória transitória. Isso reduz a chance de erros de OutOfMemory quando o contêiner está sob alta carga.
    Observação: se você estiver usando tarefas que usam o tipo de inicialização do AWS Fargate, os parâmetros maxSwap e sharedMemorySize não serão aceitos.
    Importante: esteja atento ao configurar a troca nos hosts do Docker. Ativar a troca pode tornar sua aplicação mais lenta e reduzir a performance. No entanto, esse recurso impede que a aplicação fique sem memória do sistema.

Para detectar tarefas do Amazon ECS que foram encerradas devido a eventos OutOfMemory, use o seguinte modelo do AWS CloudFormation. Com esse modelo, você pode criar uma regra do Amazon EventBridge, um tópico do Amazon Simple Notification Service (Amazon SNS) e uma política de tópicos do Amazon SNS. Quando você executa o modelo, ele solicita uma lista de e-mail, um nome de tópico e um sinalizador para ativar ou desativar o monitoramento.

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

Depois de criar a pilha do CloudFormation, você pode verificar seu e-mail para confirmar a assinatura. Depois que uma tarefa é encerrada devido a um problema OutOfMemory, você recebe um e-mail com uma mensagem semelhante à seguinte:

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

Informações relacionadas

Como faço para solucionar problemas com contêineres saindo de minhas tarefas do Amazon ECS?

AWS OFICIAL
AWS OFICIALAtualizada há 2 anos