You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

获取近30天CPU<2%、网络IO<5Mb的AWS EC2闲置低利用率实例列表

获取低利用率AWS EC2实例列表及成本管控方案

一、前提准备

  • 已配置AWS CLI并拥有权限:ec2:DescribeInstances、cloudwatch:GetMetricStatistics、ec2:TerminateInstances(终止实例时需后者)
  • 确认CloudWatch已开启EC2指标自动收集(默认开启)

二、Shell脚本自动筛选(推荐)

以下脚本会遍历所有EC2实例,查询近30天的平均CPU利用率和网络I/O,输出符合条件的实例,可选自动终止:

#!/bin/bash

# 定义时间范围与阈值
START_TIME=$(date -u -d "30 days ago" +"%Y-%m-%dT%H:%M:%SZ")
END_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
CPU_THRESHOLD=2.0       # CPU利用率阈值(百分比)
NETWORK_THRESHOLD=5.0   # 网络I/O阈值(MB)

# 获取所有EC2实例ID
INSTANCE_IDS=$(aws ec2 describe-instances --query 'Reservations[*].Instances[*].InstanceId' --output text)

echo "正在筛选符合条件的实例..."
echo "----------------------------------------"

for INSTANCE_ID in $INSTANCE_IDS; do
    # 查询平均CPU利用率
    CPU_USAGE=$(aws cloudwatch get-metric-statistics \
        --namespace AWS/EC2 \
        --metric-name CPUUtilization \
        --dimensions Name=InstanceId,Value=$INSTANCE_ID \
        --start-time $START_TIME \
        --end-time $END_TIME \
        --period 86400 \
        --statistics Average \
        --query 'Datapoints[*].Average' --output text | awk '{sum+=$1} END {print sum/NR}')
    
    # 跳过运行不足30天、无指标数据的实例
    if [ -z "$CPU_USAGE" ]; then
        continue
    fi

    # 查询平均网络入站/出站流量,转换为MB
    NETWORK_IN=$(aws cloudwatch get-metric-statistics \
        --namespace AWS/EC2 \
        --metric-name NetworkIn \
        --dimensions Name=InstanceId,Value=$INSTANCE_ID \
        --start-time $START_TIME \
        --end-time $END_TIME \
        --period 86400 \
        --statistics Average \
        --query 'Datapoints[*].Average' --output text | awk '{sum+=$1} END {print sum/NR}')
    
    NETWORK_OUT=$(aws cloudwatch get-metric-statistics \
        --namespace AWS/EC2 \
        --metric-name NetworkOut \
        --dimensions Name=InstanceId,Value=$INSTANCE_ID \
        --start-time $START_TIME \
        --end-time $END_TIME \
        --period 86400 \
        --statistics Average \
        --query 'Datapoints[*].Average' --output text | awk '{sum+=$1} END {print sum/NR}')
    
    TOTAL_NETWORK_MB=$(echo "($NETWORK_IN + $NETWORK_OUT)/1048576" | bc -l)

    # 匹配阈值则输出实例信息
    if (( $(echo "$CPU_USAGE < $CPU_THRESHOLD" | bc -l) )) && (( $(echo "$TOTAL_NETWORK_MB < $NETWORK_THRESHOLD" | bc -l) )); then
        echo "符合条件实例:$INSTANCE_ID"
        echo "平均CPU利用率:${CPU_USAGE}%,平均网络I/O:${TOTAL_NETWORK_MB}MB"
        echo "----------------------------------------"
        # 如需自动终止,取消注释以下一行
        # aws ec2 terminate-instances --instance-ids $INSTANCE_ID
    fi
done

脚本使用步骤

  1. 保存为find-idle-ec2.sh,赋予执行权限:chmod +x find-idle-ec2.sh
  2. 运行脚本:./find-idle-ec2.sh
  3. 确认输出的实例无业务负载后,可取消脚本中终止命令的注释,再次运行完成批量终止

三、AWS CLI快速筛选(需jq工具)

适用于快速获取符合条件的实例ID列表:

# 获取CPU利用率低于2%的实例ID
CPU_IDLE_INSTANCES=$(aws cloudwatch get-metric-data --metric-data-queries '[{ "Id": "cpu", "MetricStat": { "Metric": { "Namespace": "AWS/EC2", "MetricName": "CPUUtilization", "Dimensions": [{ "Name": "InstanceId" }] }, "Period": 86400, "Stat": "Average" }, "ReturnData": true }]' --start-time $(date -u -d "30 days ago" +"%Y-%m-%dT%H:%M:%SZ") --end-time $(date -u +"%Y-%m-%dT%H:%M:%SZ") --query 'MetricDataResults[*].Values' --output json | jq -r '.[] | select(.[0] < 2) | .[]')

# 获取网络I/O低于5MB的实例ID
NETWORK_IDLE_INSTANCES=$(aws cloudwatch get-metric-data --metric-data-queries '[{ "Id": "netin", "MetricStat": { "Metric": { "Namespace": "AWS/EC2", "MetricName": "NetworkIn", "Dimensions": [{ "Name": "InstanceId" }] }, "Period": 86400, "Stat": "Average" }, "ReturnData": true }, { "Id": "netout", "MetricStat": { "Metric": { "Namespace": "AWS/EC2", "MetricName": "NetworkOut", "Dimensions": [{ "Name": "InstanceId" }] }, "Period": 86400, "Stat": "Average" }, "ReturnData": true }]' --start-time $(date -u -d "30 days ago" +"%Y-%m-%dT%H:%M:%SZ") --end-time $(date -u +"%Y-%m-%dT%H:%M:%SZ") --query 'MetricDataResults[*].Values' --output json | jq -r '.[] | add / 1048576 | select(. < 5) | .[]')

# 取两个列表的交集(同时符合双条件的实例)
comm -12 <(echo "$CPU_IDLE_INSTANCES" | sort) <(echo "$NETWORK_IDLE_INSTANCES" | sort)

四、控制台手动操作指引

  1. 打开CloudWatch控制台,进入「指标」→「EC2」→「按实例ID」
  2. 添加CPUUtilization、NetworkIn、NetworkOut三个指标,设置时间范围为「过去30天」
  3. 切换图表为「平均值」视图,筛选出CPU平均低于2%、网络总流量(In+Out)平均低于5MB的实例
  4. 记录实例ID,打开EC2控制台,选中目标实例后点击「终止实例」

五、注意事项

  • 终止实例前务必确认实例无业务负载,建议先创建磁盘快照备份数据
  • 脚本会自动跳过运行不足30天的实例,可根据需求调整START_TIME参数
  • 跨账号批量操作需提前配置AWS Organizations跨账号权限

内容的提问来源于stack exchange,提问作者SriNivas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 00:41:13