Azure 账单号 微软云 Azure 账号闲置资源清理
你的 Azure 账号,正在悄悄吃掉你的预算
朋友老张上周收到 Azure 账单,差点把咖啡喷在显示器上:$1,843.67。他挠着头嘀咕:“我明明就开了两台测试虚拟机,怎么比我家半年宽带费还贵?”——结果一查,三台‘已关机但未停用’的 VM 还挂着 500GB 托管磁盘,两个没绑任何服务的公网 IP 每天收 $0.004,一个三年前部署的测试 Web App 早被遗忘在资源组角落,却还在跑 App Service Plan……这哪是云?这是‘云型貔貅’——只进不出,专吃预算。
闲置 ≠ 关机:Azure 的三大认知陷阱
陷阱一:“关机=免费”?不,它只是换了个姿势收费
Azure 上“停止(已解除分配)”和“停止(已分配)”根本不是一回事。前者释放 CPU/内存,只收磁盘费用;后者像把车熄火但挂空挡踩着油门——VM 还占着计算配额,照样按秒计费。更坑的是:很多用户点“停止”时根本没注意右下角那个小字提示:“此操作将保留分配的计算资源”。于是,一台 8 核 32GB 的 Standard_D8s_v4,关着机也照扣 $0.38/小时,一个月就是 $273——够买 90 杯喜茶。
陷阱二:“没流量=没成本”?错,静默资源才是吸血鬼
公网 IP 地址、静态 IP、未绑定的负载均衡器前端 IP、独立 DNS 区域、未启用的 Log Analytics 工作区……这些玩意儿不传一比特数据,照样按月扣钱。比如一个标准层级的 Public IP,哪怕全年零访问,$0.004/小时 × 730 小时 = $2.92/月。听起来少?但你账号里可能有 12 个——一年就是 $422。而一个未解绑的 Standard Load Balancer 前端 IP,每月固定 $18.24,比你家物业费还准时。
陷阱三:“资源组删了就干净”?别信,它可能留了半具尸体
手动删除资源组时,Azure 默认跳过“依赖项检查”。结果呢?虚拟机删了,磁盘还在;网络接口删了,公共 IP 还赖着;Web App 删了,App Service Plan 照样运转——因为 Azure 认为“Plan 是基础设施层,App 是租户层”,逻辑上分家,账单上同居。你清空了前台,后台还在给你寄账单。
Azure 账单号 实战四步法:从扫描到清零,不漏一毛钱
第一步:用 Azure Advisor 当你的省钱哨兵
别急着敲命令行——先打开 Azure Portal → Advisor → 成本。这里会自动标记“低利用率 VM”、“未使用的公共 IP”、“未附加的托管磁盘”等建议。重点看标红的“潜在节省:$XXX/月”条目。Advisor 不完美,但胜在零门槛、免配置、自带上下文说明。建议每周五下午花 5 分钟扫一眼,当周报前的小彩蛋。
第二步:PowerShell 一键揪出“幽灵资源”
复制粘贴这段脚本(需登录 Az.Accounts 模块):
# 查未附加磁盘
Get-AzDisk | Where-Object {$_.ManagedBy -eq $null -and $_.DiskState -eq 'Unattached'} | Select-Object Name, ResourceGroupName, DiskSizeGB, Location
# 查未绑定公网 IP
Get-AzPublicIpAddress | Where-Object {$_.IpConfiguration -eq $null} | Select-Object Name, IpAddress, IdleTimeoutInMinutes
# 查已关机但未解除分配的 VM
Get-AzVM | Where-Object {$_.Statuses[1].DisplayStatus -eq 'VM running'} -or {$_.Statuses[1].DisplayStatus -eq 'VM stopped'} | ForEach-Object {
$vm = $_
$status = (Get-AzVM -ResourceGroupName $vm.ResourceGroupName -Name $vm.Name -Status).Statuses[1].DisplayStatus
if ($status -eq 'VM stopped') { Write-Host "⚠️ $vm.Name 在 $vm.ResourceGroupName 中处于 STOPPED(非已解除分配)状态" }
}
运行完,你会看到一串“⚠️”警告——它们就是潜伏在黑暗中的账单刺客。
第三步:CLI 清理流水线(适合 DevOps 团队)
在 CI/CD 流水线末尾加个定时任务,每天凌晨 2 点自动执行:
# 删除 7 天前创建且无标签的测试资源组(谨慎!请先加 --dry-run)
az group list --query "[?tags.env=='test' && to_string(tags.ttl) <= '7']" -o tsv | while read rg; do
echo "即将删除测试资源组: $rg"
az group delete --name "$rg" --yes --no-wait
done
关键技巧:强制所有测试环境资源打上 env=test 和 ttl=7 标签。生产环境则必须含 env=prod 且 owner 字段非空——没标签?一律视为可回收垃圾。
第四步:设置“熔断机制”,防手滑误删
永远不要给运维账号赋予 Contributor 全局权限。改用最小权限原则:
• 清理磁盘 → 仅授予 Storage Account Contributor + Reader;
• 删除 IP → 单独给 Network Contributor;
• 关键资源组 → 开启 资源锁(Resource Lock),类型设为 CanNotDelete。
顺便,在 Azure Policy 中部署一条规则:“禁止创建未标注 owner 和 costcenter 的资源”,违规直接拒绝——让流程卡在源头,比事后补救强十倍。
那些年我们误删过的“好东西”
去年某金融客户清库,顺手删了名为 backup-disk-2021-q3 的磁盘——名字像垃圾,实则是核心数据库的快照源。恢复花了 11 小时,罚款 $28,000。教训是什么?
命名即契约:所有资源命名必须含环境(prod/test/stage)、用途(db/web/cache)、日期(20240401)和责任人(jane)。例如:prod-db-sql01-backup-20240401-jane。再懒,也别用“temp”“test123”“delete_me_soon”这种死亡代号。
终极建议:建立你的“云资源健康日”
每月第一个周五下午,雷打不动 90 分钟:
✓ 打开 Cost Management + Billing → 成本分析 → 按资源类型排序,拉出 Top 10 高耗资源;
✓ 对照资源图谱(可用 Azure Resource Graph 查询),确认每项是否仍在业务链路中;
✓ 给所有存活资源打上最新标签(尤其是 last-reviewed);
✓ 把本次清理动作写入 Confluence,标题格式:[Azure 清理] 2024-04-05 - 节省 $327.41。
坚持三个月,你会发现自己开始习惯性问:“这个资源,三个月后还有人记得它吗?”——那一刻,你就毕业了。
最后说句实在话
云不是魔法,它是另一种形态的水电煤。你不会任由水龙头滴答漏水半年才去修,也不该放任 Azure 资源在后台空转。清理闲置资源不是抠门,而是对技术负责、对团队负责、对钱包负责。下次看到账单数字跳动时,别只叹气——打开终端,敲下第一行命令。毕竟,最贵的不是 Azure,是你忘了自己才是云的主人。

