EC2 메모리 사용률 모니터링: CloudWatch Agent 없이는 RAM이 안 보이는 이유

EC2 인스턴스를 운영하다 보면 CloudWatch 콘솔에서 CPU는 보이는데 메모리가 없다는 걸 처음 마주치는 순간이 있다. 알람을 걸려고 했더니 지표 자체가 없고, 인스턴스가 OOM으로 죽었는데 CloudWatch에는 아무 흔적이 없다. EC2 메모리 사용률은 기본 CloudWatch 지표에 포함되지 않으며, 이를 수집하려면 CloudWatch Agent를 직접 설치해야 한다.

TL;DR — EC2 메모리 모니터링 핵심 요약

항목기본 CloudWatchCloudWatch Agent 설치 후
CPU 사용률✅ 자동 수집✅ 자동 수집
네트워크 I/O✅ 자동 수집✅ 자동 수집
디스크 I/O (EBS 바이트)✅ 자동 수집✅ 자동 수집
메모리 사용률 (RAM)❌ 수집 불가✅ 수집 가능
디스크 공간 사용률 (파일시스템)❌ 수집 불가✅ 수집 가능
프로세스별 메모리❌ 수집 불가✅ 수집 가능 (procstat 플러그인)

왜 EC2 메모리 사용률은 기본으로 보이지 않는가

CloudWatch가 기본으로 수집하는 지표는 AWS 하이퍼바이저 계층에서 관측 가능한 것들이다. CPU 사이클, 네트워크 패킷, EBS I/O 바이트 — 이것들은 인스턴스 외부에서 측정할 수 있다. 반면 OS 내부의 메모리 할당 상태, 파일시스템 사용량, 프로세스 목록은 게스트 OS 안에서만 볼 수 있다.

AWS는 EC2 인스턴스 내부 OS에 직접 접근하지 않는다. 이건 보안 모델의 일부이기도 하고, 공유 책임 모델(Shared Responsibility Model)의 경계이기도 하다. 게스트 OS 레이어는 고객 책임 영역이고, AWS는 그 안을 들여다보지 않는다. 결과적으로 메모리 사용률을 수집하려면 인스턴스 안에서 직접 데이터를 밀어내는 에이전트가 필요하다.

EBS 디스크 I/O 바이트는 하이퍼바이저에서 보이지만, 파일시스템이 그 공간을 얼마나 채웠는지는 OS 안에서만 알 수 있다. 같은 디스크인데 측정 지점이 다르다.
graph TD HV["하이퍼바이저 계층
(AWS 관리 영역)"] CW["Amazon CloudWatch"] OS["게스트 OS 계층
(고객 관리 영역)"] AGT["CloudWatch Agent
(인스턴스 내부 실행)"] IAM["IAM 역할
CloudWatchAgentServerPolicy"] HV -->|"CPU, 네트워크, EBS I/O
자동 수집"| CW OS -->|"메모리, 디스크, 프로세스
직접 접근 불가"| HV AGT -->|"mem_used_percent
disk used_percent 전송"| CW OS --> AGT IAM -->|"PutMetricData 권한 부여"| AGT style HV fill:#f0f4ff,stroke:#4a6fa5 style OS fill:#fff4e6,stroke:#e07b00 style AGT fill:#e6ffe6,stroke:#2d8a2d style CW fill:#e6f7ff,stroke:#0077b6 style IAM fill:#fff0f0,stroke:#c0392b
  1. 하이퍼바이저 계층: AWS가 직접 관측. CPU, 네트워크, EBS I/O 등 인프라 수준 지표가 여기서 수집된다.
  2. 게스트 OS 계층: 고객 책임 영역. 메모리 사용률, 파일시스템 사용량, 프로세스 정보는 여기에만 존재한다.
  3. CloudWatch Agent: 게스트 OS 안에서 실행되며 OS 지표를 수집해 CloudWatch로 전송한다.
  4. IAM 역할: 에이전트가 CloudWatch API를 호출하려면 인스턴스에 적절한 IAM 역할이 연결되어 있어야 한다.

CloudWatch Agent 설치 및 EC2 메모리 사용률 수집 설정

설치 전에 인스턴스에 연결된 IAM 역할을 확인해야 한다. 에이전트가 지표를 전송하려면 CloudWatchAgentServerPolicy 관리형 정책이 필요하다. 역할 없이 설치부터 하면 에이전트가 조용히 실패하고 지표가 안 올라온다 — 이게 가장 흔한 함정이다.

1단계: IAM 역할 확인 및 연결

인스턴스에 연결된 IAM 역할에 CloudWatch 쓰기 권한이 있는지 먼저 확인한다. 역할이 없거나 권한이 부족하면 에이전트 설치 후에도 지표가 수집되지 않는다.

# 인스턴스에 연결된 IAM 역할 확인
aws ec2 describe-instances \
  --instance-ids i-1234567890abcdef0 \
  --query 'Reservations[0].Instances[0].IamInstanceProfile' \
  --region us-east-1

# 역할에 연결된 정책 확인
aws iam list-attached-role-policies \
  --role-name YourEC2RoleNameHere

역할에 CloudWatchAgentServerPolicy가 없다면 연결한다.

aws iam attach-role-policy \
  --role-name YourEC2RoleNameHere \
  --policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy

2단계: CloudWatch Agent 설치

Amazon Linux 2 / Amazon Linux 2023 기준이다. 다른 배포판은 AWS 공식 문서의 패키지 설치 방법을 참조한다.

# Amazon Linux 2 / Amazon Linux 2023
sudo yum install -y amazon-cloudwatch-agent

# Ubuntu
sudo apt-get install -y amazon-cloudwatch-agent

3단계: 에이전트 설정 파일 작성

설정 마법사를 쓰거나 직접 JSON을 작성할 수 있다. 마법사는 대화형으로 진행되며 처음 설정할 때 편리하다.

# 설정 마법사 실행
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

마법사 없이 직접 설정 파일을 작성하는 경우 아래 예시를 참고한다. 메모리와 디스크 사용률을 60초 간격으로 수집하는 최소 구성이다.

🔽 CloudWatch Agent 설정 파일 예시 (클릭하여 펼치기)
{
  "agent": {
    "metrics_collection_interval": 60,
    "run_as_user": "cwagent"
  },
  "metrics": {
    "append_dimensions": {
      "InstanceId": "${aws:InstanceId}",
      "InstanceType": "${aws:InstanceType}"
    },
    "metrics_collected": {
      "mem": {
        "measurement": [
          "mem_used_percent"
        ],
        "metrics_collection_interval": 60
      },
      "disk": {
        "measurement": [
          "used_percent"
        ],
        "metrics_collection_interval": 60,
        "resources": [
          "/"
        ]
      }
    }
  }
}

설정 파일을 /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json에 저장한다.

4단계: 에이전트 시작

# 설정 파일을 지정하여 에이전트 시작
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -a fetch-config \
  -m ec2 \
  -c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json \
  -s

# 에이전트 상태 확인
sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -m ec2 \
  -a status

상태 출력에서 "status": "running"이 보이면 정상이다. 1-2분 후 CloudWatch 콘솔의 CWAgent 네임스페이스에서 mem_used_percent 지표를 확인할 수 있다.

수집된 EC2 메모리 사용률 지표 확인 및 알람 설정

에이전트가 정상 실행되면 지표는 CWAgent 네임스페이스 아래에 쌓인다. CLI로 직접 조회해서 데이터가 들어오는지 확인하는 게 콘솔보다 빠르다.

aws cloudwatch get-metric-statistics \
  --namespace CWAgent \
  --metric-name mem_used_percent \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
  --start-time 2024-01-01T00:00:00Z \
  --end-time 2024-01-01T01:00:00Z \
  --period 300 \
  --statistics Average \
  --region us-east-1

데이터가 반환되면 알람을 건다. 메모리 사용률 90% 초과 시 SNS 알림을 보내는 예시다.

aws cloudwatch put-metric-alarm \
  --alarm-name EC2-Memory-High \
  --alarm-description 'EC2 memory usage exceeded 90 percent' \
  --metric-name mem_used_percent \
  --namespace CWAgent \
  --statistic Average \
  --dimensions Name=InstanceId,Value=i-1234567890abcdef0 \
  --period 300 \
  --evaluation-periods 2 \
  --threshold 90 \
  --comparison-operator GreaterThanThreshold \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:YourSNSTopic \
  --region us-east-1

실제 장애 패턴: 지표가 올라오지 않는 경우

에이전트를 설치했는데 CloudWatch에 지표가 없다. 콘솔을 새로고침해도 CWAgent 네임스페이스 자체가 안 보인다. 처음엔 설정 파일 문법 오류를 의심하고 JSON을 몇 번 고쳤지만 달라지지 않았다.

실제 원인은 IAM 역할 문제였다. 인스턴스에 역할이 연결되어 있었지만 CloudWatchAgentServerPolicy가 아닌 커스텀 정책이었고, 거기에 cloudwatch:PutMetricData 권한이 빠져 있었다. 에이전트는 실행 중이었고 로그에도 별다른 에러가 없었다 — 권한 거부가 에이전트 로그에 명확히 찍히지 않는 경우가 있다.

graph TD START["지표 미수집 확인"] --> A["에이전트 상태 확인
amazon-cloudwatch-agent-ctl -a status"] A --> A1{"running?"} A1 -->|"No"| A2["에이전트 재시작
설정 파일 문법 검토"] A1 -->|"Yes"| B["IAM 권한 확인
PutMetricData 허용 여부"] B --> B1{"권한 있음?"} B1 -->|"No"| B2["CloudWatchAgentServerPolicy 연결"] B1 -->|"Yes"| C["네트워크 경로 확인
프라이빗 서브넷 여부"] C --> C1{"인터넷 경로?"} C1 -->|"없음"| C2["VPC 엔드포인트 생성
또는 NAT 게이트웨이 확인"] C1 -->|"있음"| D["에이전트 로그 상세 분석
/logs/amazon-cloudwatch-agent.log"] A2 --> END["지표 수집 정상화"] B2 --> END C2 --> END D --> END style START fill:#f8f9fa,stroke:#6c757d style END fill:#d4edda,stroke:#28a745 style A2 fill:#fff3cd,stroke:#ffc107 style B2 fill:#fff3cd,stroke:#ffc107 style C2 fill:#fff3cd,stroke:#ffc107
  1. 에이전트 상태 확인: status 명령으로 running 여부를 먼저 본다.
  2. 에이전트 로그 확인: /opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log에서 오류 패턴을 찾는다.
  3. IAM 권한 확인: 가장 흔한 원인. cloudwatch:PutMetricData 권한이 있는지 확인한다.
  4. 네트워크 연결 확인: 프라이빗 서브넷이라면 CloudWatch VPC 엔드포인트 또는 NAT 게이트웨이가 필요하다.
  5. 설정 파일 검증: JSON 문법 오류는 에이전트가 시작은 되지만 지표를 수집하지 않는 증상을 만들 수 있다.
# 에이전트 로그 실시간 확인
sudo tail -f /opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log

# IAM 권한 시뮬레이션 (역할 이름 확인 후 실행)
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789012:role/YourEC2RoleNameHere \
  --action-names cloudwatch:PutMetricData \
  --region us-east-1

프라이빗 서브넷 인스턴스에서 지표가 안 올라오는 경우, 인터넷 경로가 없으면 CloudWatch 엔드포인트에 도달하지 못한다. VPC 엔드포인트를 생성하거나 NAT 게이트웨이를 통해 아웃바운드 경로를 확보해야 한다.

# CloudWatch용 VPC 인터페이스 엔드포인트 생성
aws ec2 create-vpc-endpoint \
  --vpc-id vpc-0123456789abcdef0 \
  --vpc-endpoint-type Interface \
  --service-name com.amazonaws.us-east-1.monitoring \
  --subnet-ids subnet-0123456789abcdef0 \
  --security-group-ids sg-0123456789abcdef0 \
  --region us-east-1

Systems Manager로 대규모 배포 시 고려사항

인스턴스가 수십 대라면 각 인스턴스에 SSH로 들어가서 에이전트를 설치하는 건 현실적이지 않다. AWS Systems Manager의 Run Command 또는 State Manager를 사용하면 플릿 전체에 에이전트를 배포하고 설정을 관리할 수 있다.

# SSM Run Command로 여러 인스턴스에 CloudWatch Agent 설치
aws ssm send-command \
  --document-name 'AWS-ConfigureAWSPackage' \
  --parameters 'action=Install,name=AmazonCloudWatchAgent' \
  --targets 'Key=tag:Environment,Values=production' \
  --region us-east-1

설정 파일은 SSM Parameter Store에 저장하고 에이전트가 참조하도록 구성할 수 있다. 이렇게 하면 설정 변경 시 파라미터만 업데이트하고 에이전트를 재시작하면 된다 — 각 인스턴스에 직접 접속할 필요가 없다.

마무리 및 다음 단계

EC2 메모리 사용률 모니터링은 CloudWatch Agent 설치로 해결되지만, 설치 자체보다 IAM 권한과 네트워크 경로를 먼저 확인하는 게 실제 운영에서 시간을 아끼는 방법이다. 에이전트가 조용히 실패하는 경우가 많기 때문이다.

  • 다음 단계: CloudWatch Agent 공식 설치 가이드에서 운영체제별 상세 설치 방법을 확인한다.
  • 프로세스별 메모리 추적이 필요하다면 에이전트 설정의 procstat 플러그인을 추가로 구성한다.
  • Container Insights를 사용하는 ECS/EKS 환경은 별도의 에이전트 구성 방식을 따른다.

핵심 용어 정리

용어설명
CloudWatch AgentEC2 인스턴스 내부에서 실행되어 OS 수준 지표를 CloudWatch로 전송하는 소프트웨어
CWAgent 네임스페이스CloudWatch Agent가 수집한 지표가 저장되는 CloudWatch 지표 네임스페이스
공유 책임 모델AWS와 고객 간 보안 및 운영 책임을 구분하는 모델. 게스트 OS 내부는 고객 책임 영역
VPC 인터페이스 엔드포인트인터넷 없이 AWS 서비스에 프라이빗 연결을 제공하는 VPC 엔드포인트 유형
procstat 플러그인CloudWatch Agent의 플러그인으로 개별 프로세스의 CPU, 메모리 사용률을 수집

댓글

이 블로그의 인기 게시물

EC2 SSH 연결 시간 초과: 확인해야 할 보안 그룹(Security Group) 규칙

EC2 SSH 연결 타임아웃 완전 해결 가이드: Security Group 인바운드 규칙부터 라우팅까지

IAM User vs IAM Role 차이점 완전 정리 — EC2에서 S3 접근 시 무엇을 써야 하는가