Amazon ECS의 OutOfMemory 오류를 해결하려면 어떻게 해야 하나요?

4분 분량
0

Amazon Elastic Container Service(Amazon ECS) 태스크의 메모리 사용 문제를 해결하고 싶습니다. -또는- OutOfMemory 오류로 인해 Amazon ECS 태스크의 컨테이너가 종료됩니다.

간략한 설명

기본적으로 컨테이너는 리소스 제약이 없으며 호스트의 커널 스케줄러가 허용하는 만큼의 리소스를 사용할 수 있습니다. Docker를 사용하면 컨테이너에서 사용하는 메모리 양을 제어할 수 있습니다. 실행 중인 컨테이너가 호스트 머신의 메모리 대부분을 사용하지 않도록 해야 합니다. Linux 호스트에서 커널이 중요한 시스템 기능을 수행하기에 충분한 메모리가 없음을 감지하면 OutOfMemory 예외를 보내고 프로세스를 종료하여 메모리를 비우기 시작합니다.

Docker를 사용하면 다음 중 하나를 사용하도록 선택할 수 있습니다.

  • 컨테이너가 일정량 이하의 사용자 또는 시스템 메모리를 사용할 수 있도록 하는 하드 메모리 제한
  • 메모리 부족이나 호스트 머신의 경합과 같은 특정 조건이 발생하지 않는 한 컨테이너가 필요한 만큼의 메모리를 사용할 수 있도록 하는 소프트 제한

OutOfMemory 문제로 인해 Amazon ECS 태스크가 종료되면 다음과 같은 오류 메시지가 표시될 수 있습니다.

OutOfMemoryError: Container killed due to memory usage

컨테이너의 프로세스가 태스크 정의에 할당된 양보다 많은 메모리를 사용하기 때문에 태스크의 컨테이너가 종료되면 이 오류가 발생합니다.

해결 방법

Amazon ECS 태스크의 OutOfMemory 오류를 해결하려면 다음을 수행합니다.

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”

OutOfMemory 문제로 인한 태스크 불안정 위험을 완화하려면 다음을 수행합니다.

  • 애플리케이션을 프로덕션 환경에 배치하기 전에 테스트를 수행하여 애플리케이션의 메모리 요구 사항을 파악합니다. 호스트 또는 서버 내의 컨테이너에서 부하 테스트를 수행할 수 있습니다. 그런 다음 도커 통계를 사용하여 컨테이너의 메모리 사용량을 확인할 수 있습니다.
  • 애플리케이션이 적절한 리소스가 있는 호스트에서만 실행되어야 합니다.
  • 컨테이너가 사용할 수 있는 메모리 양을 제한합니다. 컨테이너의 하드 제한 및 소프트 제한에 적절한 값을 설정하여 이 작업을 수행할 수 있습니다. Amazon ECS는 태스크에 메모리를 할당할 때 소프트 제한의 경우 memoryReservation과 하드 제한의 경우 memory라는 여러 파라미터를 사용합니다. 이 값을 지정하면 컨테이너가 배치된 컨테이너 인스턴스의 사용 가능한 메모리 리소스에서 해당 값이 차감됩니다.
    참고: memoryReservation 파라미터는 Windows 컨테이너에서 지원되지 않습니다.
  • 일시적으로 메모리가 많이 필요한 컨테이너의 경우 스왑을 켤 수 있습니다. 이렇게 하면 컨테이너에 많은 부하가 걸릴 때 OutOfMemory 오류가 발생할 가능성이 줄어듭니다.
    참고: AWS Fargate 시작 유형을 사용하는 작업을 사용하는 경우 파라미터 maxSwapsharedMemorySize는 지원되지 않습니다.
    중요: Docker 호스트에서 스왑을 구성할 때는 주의해야 합니다. 스왑을 켜면 애플리케이션 속도가 느려지고 성능이 저하될 수 있습니다. 하지만 이 기능을 사용하면 애플리케이션의 시스템 메모리가 부족해지는 것을 방지할 수 있습니다.

메모리 부족 이벤트로 인해 종료된 Amazon ECS 작업을 감지하려면 다음 AWS CloudFormation 템플릿을 사용하세요. 이 템플릿을 사용하여 Amazon EventBridge 규칙, Amazon Simple Notification Service(SNS) 주제 및 Amazon SNS 주제 정책을 생성할 수 있습니다. 템플릿을 실행하면 템플릿에서 이메일 목록, 주제 이름 및 모니터링을 켜거나 끌 플래그를 입력하라는 메시지가 표시됩니다.

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

CloudFormation 스택을 생성한 후 이메일을 확인하여 구독을 확인할 수 있습니다. OutOfMemory 문제로 작업이 종료되면 다음과 비슷한 메시지가 포함된 이메일을 받게 됩니다.

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

관련 정보

Amazon ECS 태스크에서 컨테이너가 종료되는 문제를 해결하려면 어떻게 해야 합니까?

AWS 공식
AWS 공식업데이트됨 2년 전