Giám Sát Memory Usage Trên EC2: Tại Sao CloudWatch Mặc Định Không Hiển Thị RAM?

Bạn vừa deploy một EC2 instance, mở CloudWatch console để kiểm tra hiệu năng, và nhận ra rằng không có metric nào cho RAM hay disk usage — chỉ có CPU, network, và disk I/O ở mức hypervisor. Đây không phải lỗi cấu hình. Đây là ranh giới kiến trúc cơ bản giữa những gì AWS có thể quan sát từ bên ngoài instance và những gì chỉ OS bên trong mới biết. Bài viết này giải thích tại sao giám sát memory EC2 yêu cầu CloudWatch Agent, và cách cài đặt đúng để có đầy đủ OS-level metrics trong production.

TL;DR — Giám Sát Memory EC2

Vấn đềNguyên nhânGiải pháp
Không thấy RAM trong CloudWatchAWS không có quyền truy cập vào OS guestCài CloudWatch Agent trên instance
Không thấy disk usage (%)Cùng lý do — OS-level metricCloudWatch Agent + cấu hình disk path
Chỉ thấy CPU, Network, DiskReadOpsHypervisor-level metrics — AWS thu thập đượcĐây là hành vi đúng, không cần thay đổi
Agent không gửi metricIAM role thiếu quyền, hoặc agent chưa chạyKiểm tra IAM policy và systemd service

Tại Sao CloudWatch Không Thấy RAM Theo Mặc Định

AWS vận hành EC2 trên nền tảng ảo hóa — hypervisor quản lý CPU time, network packet, và disk I/O ở mức phần cứng ảo. Những thông tin này AWS thu thập được mà không cần can thiệp vào OS bên trong instance. Đó là nguồn gốc của các metric mặc định như CPUUtilization, NetworkIn, DiskReadOps.

RAM thì khác. Hypervisor cấp phát một khối bộ nhớ vật lý cho instance, nhưng việc OS sử dụng khối đó như thế nào — bao nhiêu là page cache, bao nhiêu là heap của ứng dụng, bao nhiêu là free — là thông tin nằm hoàn toàn bên trong OS guest. AWS không đọc memory map của OS bạn. Đây là ranh giới bảo mật và kiến trúc có chủ đích, không phải thiếu sót.

Hãy hình dung AWS như chủ tòa nhà cho thuê văn phòng: họ biết tòa nhà đang dùng bao nhiêu điện, bao nhiêu nước (hypervisor metrics), nhưng không biết bên trong phòng bạn đang xếp đồ đạc như thế nào (OS memory layout).

Disk usage cũng tương tự. CloudWatch mặc định có DiskReadBytesDiskWriteBytes — đây là I/O throughput ở mức block device, hypervisor thấy được. Nhưng 'ổ đĩa còn 15% dung lượng trống' là thông tin của filesystem, nằm trong OS. Chỉ CloudWatch Agent chạy bên trong instance mới đọc được /proc/meminfo và output của df.

graph TD HV["AWS Hypervisor
CPU / Network / Block I/O"] CW_DEFAULT["CloudWatch Namespace: AWS/EC2"] OS["Guest OS /proc/meminfo, df, ps"] AGENT["CloudWatch Agent chạy trong OS"] CW_CUSTOM["CloudWatch Namespace: CWAgent"] HV -->|"Thu thập tự động (không cần agent)"| CW_DEFAULT OS -->|"Agent đọc OS-level data"| AGENT AGENT -->|"PutMetricData API (cần IAM role)"| CW_CUSTOM style HV fill:#2d6a9f,color:#fff style OS fill:#5a7a3a,color:#fff style AGENT fill:#8b4513,color:#fff style CW_DEFAULT fill:#1a5276,color:#fff style CW_CUSTOM fill:#1a5276,color:#fff
  1. Hypervisor Layer: AWS thu thập CPU, Network, Block I/O trực tiếp từ lớp ảo hóa — không cần agent.
  2. Guest OS Layer: RAM usage, filesystem usage, process-level metrics nằm trong OS. AWS không có quyền truy cập trực tiếp.
  3. CloudWatch Agent: Chạy bên trong OS, đọc /proc/meminfo, /proc/diskstats, và các nguồn OS khác, sau đó đẩy lên CloudWatch qua API.
  4. Custom Namespace: Metric từ agent xuất hiện trong namespace CWAgent, tách biệt với namespace AWS/EC2 của hypervisor metrics.

Cài Đặt CloudWatch Agent Để Giám Sát Memory EC2

Trước khi cài agent, instance cần có IAM role với policy cho phép gửi metric và (tùy chọn) đọc cấu hình từ SSM Parameter Store. Thiếu bước này là lý do phổ biến nhất khiến agent chạy nhưng không có metric nào xuất hiện trong console.

Bước 1: Gắn IAM Role với Quyền Cần Thiết

IAM role gắn vào EC2 instance cần có policy CloudWatchAgentServerPolicy (AWS managed policy). Policy này cho phép agent gọi cloudwatch:PutMetricData, đọc từ SSM, và ghi logs. Nếu bạn muốn dùng SSM Parameter Store để lưu cấu hình agent tập trung, cần thêm AmazonSSMManagedInstanceCore.

Kiểm tra role hiện tại của instance:

aws ec2 describe-instances \
  --instance-ids i-0123456789abcdef0 \
  --query 'Reservations[0].Instances[0].IamInstanceProfile.Arn' \
  --output text \
  --region us-east-1

Kiểm tra policies đã gắn vào role:

aws iam list-attached-role-policies \
  --role-name YourEC2RoleName

Nếu chưa có CloudWatchAgentServerPolicy, gắn vào:

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

Bước 2: Cài CloudWatch Agent Trên Instance

SSH vào instance và cài agent. Ví dụ dưới đây dành cho Amazon Linux 2 / Amazon Linux 2023:

sudo yum install -y amazon-cloudwatch-agent

Trên Ubuntu/Debian:

wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb
sudo dpkg -i amazon-cloudwatch-agent.deb

Bước 3: Tạo File Cấu Hình Agent

Cách nhanh nhất là dùng wizard tương tác. Wizard hỏi bạn muốn thu thập metric nào và tạo file JSON cấu hình:

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

Hoặc tạo thủ công file /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json. Cấu hình tối thiểu để thu thập memory và disk:

🔽 Xem cấu hình CloudWatch Agent (JSON)
{
  "metrics": {
    "namespace": "CWAgent",
    "metrics_collected": {
      "mem": {
        "measurement": [
          "mem_used_percent"
        ],
        "metrics_collection_interval": 60
      },
      "disk": {
        "measurement": [
          "used_percent"
        ],
        "metrics_collection_interval": 60,
        "resources": [
          "/"
        ]
      }
    }
  }
}

Trường resources trong phần disk chỉ định mount point cần giám sát. Thêm các path khác nếu instance có nhiều volume được mount.

Bước 4: Khởi Động Agent

Nạp cấu hình và khởi động agent:

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

Kiểm tra trạng thái:

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -m ec2 \
  -a status

Output mong đợi có "status": "running". Nếu thấy stopped hoặc dead, kiểm tra log tại /opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log.

Xác Nhận Metric Đã Xuất Hiện Trong CloudWatch

Sau khoảng 1-2 phút, metric sẽ xuất hiện trong namespace CWAgent. Kiểm tra bằng CLI:

aws cloudwatch list-metrics \
  --namespace CWAgent \
  --region us-east-1

Lấy giá trị metric mem_used_percent trong 10 phút vừa qua:

aws cloudwatch get-metric-statistics \
  --namespace CWAgent \
  --metric-name mem_used_percent \
  --dimensions Name=InstanceId,Value=i-0123456789abcdef0 \
  --start-time $(date -u -d '10 minutes ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 60 \
  --statistics Average \
  --region us-east-1

Nếu không có data point nào trả về sau 5 phút, đây là dấu hiệu agent đang chạy nhưng không gửi được metric — thường do IAM hoặc network (instance không reach được CloudWatch endpoint).

Giám Sát Memory EC2: Chẩn Đoán Khi Agent Không Gửi Metric

Đây là pattern thường gặp nhất: agent báo running, nhưng CloudWatch console trống. Lúc đầu bạn nghĩ do delay, chờ 10 phút, vẫn không có gì. Kiểm tra log agent thì thấy lỗi RequestError hoặc AccessDeniedException.

graph TD START["Agent báo 'running' nhưng không có metric"] CHECK_LOG["Kiểm tra agent log /logs/amazon-cloudwatch-agent.log"] IAM_ERR{"AccessDeniedException?"} NET_ERR{"RequestError / Connection refused?"} CONFIG_ERR{"No metrics collected?"} DIM_ERR{"Metric có nhưng không thấy trong console?"} FIX_IAM["Gắn CloudWatchAgentServerPolicy vào EC2 IAM role"] FIX_NET["Thêm NAT Gateway hoặc VPC Endpoint cho monitoring"] FIX_CONFIG["Validate JSON config chạy lại wizard"] FIX_DIM["Dùng list-metrics CLI kiểm tra dimension thực tế"] START --> CHECK_LOG CHECK_LOG --> IAM_ERR IAM_ERR -->|"Có"| FIX_IAM IAM_ERR -->|"Không"| NET_ERR NET_ERR -->|"Có"| FIX_NET NET_ERR -->|"Không"| CONFIG_ERR CONFIG_ERR -->|"Có"| FIX_CONFIG CONFIG_ERR -->|"Không"| DIM_ERR DIM_ERR --> FIX_DIM style START fill:#7b241c,color:#fff style FIX_IAM fill:#1e8449,color:#fff style FIX_NET fill:#1e8449,color:#fff style FIX_CONFIG fill:#1e8449,color:#fff style FIX_DIM fill:#1e8449,color:#fff
  1. IAM Permission: Lỗi AccessDeniedException trong agent log — role thiếu cloudwatch:PutMetricData.
  2. Network Connectivity: Instance trong private subnet không có NAT Gateway hoặc VPC Endpoint cho CloudWatch — agent không reach được endpoint.
  3. Agent Config Error: File JSON cấu hình sai cú pháp — agent start nhưng không collect metric nào.
  4. Wrong Dimension: Metric có nhưng dimension InstanceId không khớp — kiểm tra lại list-metrics để xem dimension thực tế.

Kiểm tra log agent để xác định nguyên nhân:

sudo tail -f /opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log

Kiểm tra connectivity đến CloudWatch endpoint từ instance:

curl -I https://monitoring.us-east-1.amazonaws.com

Nếu instance trong private subnet và không có NAT, tạo VPC Endpoint cho CloudWatch:

aws ec2 create-vpc-endpoint \
  --vpc-id vpc-0123456789abcdef0 \
  --service-name com.amazonaws.us-east-1.monitoring \
  --vpc-endpoint-type Interface \
  --subnet-ids subnet-0123456789abcdef0 \
  --security-group-ids sg-0123456789abcdef0 \
  --region us-east-1

Tạo CloudWatch Alarm Cho Memory Usage

Sau khi có metric, tạo alarm để cảnh báo khi RAM vượt ngưỡng. Ví dụ alarm khi mem_used_percent vượt 85% trong 5 phút liên tiếp:

aws cloudwatch put-metric-alarm \
  --alarm-name EC2-HighMemoryUsage \
  --alarm-description 'Memory usage vuot 85 phan tram' \
  --metric-name mem_used_percent \
  --namespace CWAgent \
  --statistic Average \
  --period 300 \
  --evaluation-periods 1 \
  --threshold 85 \
  --comparison-operator GreaterThanThreshold \
  --dimensions Name=InstanceId,Value=i-0123456789abcdef0 \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:YourSNSTopic \
  --region us-east-1

Quản Lý Cấu Hình Agent Tập Trung Với SSM Parameter Store

Khi có nhiều instance, việc SSH từng máy để cập nhật cấu hình agent rất tốn công. SSM Parameter Store cho phép lưu file cấu hình agent tập trung và đẩy xuống tất cả instance cùng lúc.

Lưu cấu hình vào SSM:

aws ssm put-parameter \
  --name "/cloudwatch-agent/config" \
  --type String \
  --value file://amazon-cloudwatch-agent.json \
  --region us-east-1

Trên instance, nạp cấu hình từ SSM thay vì file local:

sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl \
  -a fetch-config \
  -m ec2 \
  -c ssm:/cloudwatch-agent/config \
  -s

Điều này đặc biệt hữu ích khi kết hợp với Auto Scaling Group — instance mới tự động lấy cấu hình agent từ SSM qua user data script khi khởi động.

Wrap-Up: Giám Sát Memory EC2 Đúng Cách

CloudWatch không hiển thị RAM mặc định vì đây là OS-level metric nằm ngoài tầm quan sát của hypervisor — đây là ranh giới kiến trúc có chủ đích. CloudWatch Agent giải quyết vấn đề này bằng cách chạy bên trong OS, đọc /proc/meminfo và filesystem stats, rồi đẩy lên CloudWatch dưới namespace CWAgent. Ba điều kiện cần thiết để agent hoạt động: IAM role đúng quyền, network reach được CloudWatch endpoint, và file cấu hình JSON hợp lệ.

Bước tiếp theo: Xem xét tài liệu chính thức CloudWatch Agent để biết thêm về các metric có thể thu thập, bao gồm process-level metrics và custom metrics từ ứng dụng.

Glossary — Thuật Ngữ Chính

Thuật ngữGiải thích
Hypervisor MetricMetric thu thập ở lớp ảo hóa (CPU, Network, Block I/O) — AWS có thể đọc mà không cần agent trong OS
Guest OS MetricMetric nằm trong OS bên trong instance (RAM, filesystem usage) — chỉ agent chạy trong OS mới đọc được
CloudWatch AgentPhần mềm cài trong EC2 instance, thu thập OS-level metrics và logs, đẩy lên CloudWatch qua API
CWAgent NamespaceNamespace trong CloudWatch chứa metric từ CloudWatch Agent, tách biệt với namespace AWS/EC2
VPC Endpoint (Interface)Cho phép instance trong private subnet gọi AWS API (như CloudWatch) mà không cần NAT Gateway

Nhận xét

Bài đăng phổ biến từ blog này

EC2 Không Có Internet Trong Custom VPC: Cách Gắn Internet Gateway và Cập Nhật Route Table

RDS Multi-AZ: Lợi Ích Thực Sự Là Gì và Khi Nào Nên Bật?

Lỗi CORS trên API Gateway: Cách bật CORS và Lambda phải trả về header gì