如何利用 KQL 查询定位 Azure 虚拟机上的 AMA 代理状态?—— 2026 年度运维最佳实践

在管理庞大的 Azure 基础设施时,你是否曾经遇到过这样的困惑:面对成百上千台虚拟机,如何快速确认哪些机器已经成功安装了最新的 Azure Monitor Agent (AMA)?随着 Azure 监控策略的演进,传统的监控代理(如 MMA 和 OMS)正在逐步被 AMA 取代。手动逐台检查不仅效率低下,而且在混合云环境中几乎是不可能完成的任务。

在这篇文章中,我们将深入探讨如何利用 Azure Kusto Query Language (KQL) 的强大功能,通过 Azure Resource Graph Explorer 快速、自动化地排查整个环境中的 AMA 代理部署情况。我们不仅会分享“怎么做”,还会解释“为什么这么做”,并结合 2026 年最新的运维理念,为你提供可以直接在生产环境中使用的代码示例和架构建议。

为什么我们需要关注 Azure Monitor Agent (AMA)?

在深入代码之前,让我们先统一一下认知。Azure Monitor Agent (AMA) 是 Azure 监控服务的下一代数据收集引擎。它不仅能够收集日志和性能数据,还支持更灵活的数据源配置(如 DCR – 数据收集规则)和更安全的集成方式(通过 Managed Identity,彻底淘汰了陈旧的密钥管理方式)。无论你的 Windows 或 Linux 虚拟机是运行在 Azure 上、本地数据中心还是其他云平台,AMA 都能提供一致的监控体验。

但在实际操作中,我们面临的最大挑战是“可见性”。当我们要执行合规性检查或进行安全审计时,必须精确知道每台机器的代理状态。这正是 KQL 查询大显身手的时候。在 2026 年,随着“AI 辅助运维”的普及,手动排查已经被视为技术债务,我们必须学会用数据驱动的方式管理基础设施。

2026 视角下的基础设施即代码 与 AI 协作

在我们最近的一个大型云迁移项目中,我们发现单纯依靠脚本的运维方式已经难以应对动态变化的云环境。Agentic AI(自主 AI 代理) 的兴起改变了游戏规则。我们现在不仅是在写 KQL,而是在构建“可观测性即代码”的管道。通过结合 GitHub Copilot 等 AI 辅助工具,我们可以快速生成针对特定业务场景的 KQL 查询,并将其嵌入到 CI/CD 流水线中,实现基础设施的自我修复。

前置准备:开始之前你需要什么?

为了顺利执行后续的查询操作,你需要确保具备以下基本条件:

  • Azure 访问权限:你需要拥有有效的 Azure 订阅账户,并且能够登录 Azure Portal。
  • RBAC 权限:你的账户至少需要对目标资源(订阅或管理组)拥有 Microsoft.Resources/subscriptions/resources/read 权限。通常,拥有“读取者”或“监控参与者”角色即可满足要求。
  • 思维转变:我们需要从“单点排查”转向“全域查询”。Resource Graph Explorer 允许我们跨越订阅边界进行查询,这是现代云运维的核心技能。

场景一:查询安装了 Windows AMA 代理的虚拟机

让我们从最常见的场景开始。假设我们需要找出所有订阅中安装了 AzureMonitorWindowsAgent 扩展的 Windows 虚拟机。

1. 打开 Azure Resource Graph Explorer

首先,登录 Azure Portal。在顶部的搜索栏中输入 “Resource Graph Explorer” 并选中它。这是一个功能强大的工具,允许我们针对范围内的所有 Azure 资源运行 KQL 查询,而不需要关心具体的资源组。

2. 编写并执行 KQL 查询

在查询编辑器中,我们可以输入以下 KQL 语句。这段代码的逻辑非常直观:首先筛选出所有类型为虚拟机扩展的资源,然后通过名称过滤出 Windows 监控代理,最后提取出虚拟机名称。

// 针对 Windows 虚拟机的 Azure Monitor Agent 查询
resources 
| where type == "microsoft.compute/virtualmachines/extensions"  // 1. 筛选虚拟机扩展资源
| extend VMName = split(id, "/")                               // 2. 解析资源 ID 以提取虚拟机名称
| where name has "AzureMonitorWindowsAgent"                     // 3. 过滤出 Windows 监控代理
// 4. 可选:将订阅 ID 映射为易读的名称(请根据实际情况修改)
| extend SubscriptionName=case(                                 
    subscriptionId =~ ‘xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx‘, ‘Production Subscription‘,
    subscriptionId =~ ‘yyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy‘, ‘Development Subscription‘,
    subscriptionId                                              // 默认显示 ID
    )
| project VMName=VMName[-3], AgentName=name, SubscriptionName, ResourceGroup, Location // 5. 选择需要显示的列

代码解析:

  • INLINECODE5f699d97:这是关键的一步。VM 扩展的资源 ID 包含其父级 VM 的名称,但它在 ID 的路径中间。通过分割字符串,我们将 ID 拆分为数组,然后通过 INLINECODE1286008b 轻松提取出倒数第三段,这正是虚拟机的名称。
  • project:我们只展示最相关的信息(VM名称、代理名、订阅),保持结果集的整洁。

场景二:查询安装了 Linux AMA 代理的虚拟机

对于 Linux 环境,过程完全一致,只是代理的名称不同。Linux 使用的是 AzureMonitorLinuxAgent。我们可以使用几乎相同的查询结构,只需微调过滤条件。

// 针对 Linux 虚拟机的 Azure Monitor Agent 查询
resources 
| where type == "microsoft.compute/virtualmachines/extensions"
| extend VMName = split(id, "/")
| where name has "AzureMonitorLinuxAgent" // 注意这里筛选的是 Linux Agent
| extend SubscriptionName=case(
    subscriptionId =~ ‘xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx‘, ‘Production Subscription‘,
    subscriptionId =~ ‘yyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy‘, ‘Development Subscription‘,
    subscriptionId
    )
| project VMName=VMName[-3], AgentName=name, SubscriptionName, ResourceGroup, Location

场景三:综合查询(同时获取 Windows 和 Linux 状态)

在实际的生产环境中,我们的环境通常是混合的(既有 Windows 也有 Linux)。为了不重复运行两次查询,我们可以使用逻辑运算符 or 来合并这两个条件。在 2026 年的混合云架构中,这种统一的视图对于自动化运维平台至关重要。

// 综合:查找所有安装了 AMA (Windows 或 Linux) 的虚拟机
resources 
| where type == "microsoft.compute/virtualmachines/extensions"
| extend VMName = split(id, "/")
// 使用 ‘or‘ 逻辑同时匹配两种代理名称
| where name has "AzureMonitorWindowsAgent" or name has "AzureMonitorLinuxAgent"
| extend SubscriptionName=case(
    subscriptionId =~ ‘xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx‘, ‘Production Subscription‘,
    subscriptionId =~ ‘yyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy‘, ‘Development Subscription‘,
    subscriptionId
    )
// 添加操作系统类型判断以便于区分
| extend OSType = case(
    name has "WindowsAgent", "Windows",
    name has "LinuxAgent", "Linux",
    "Unknown"
    )
| project VMName=VMName[-3], AgentName=name, SubscriptionName, OSType, ResourceGroup, Location
| order by OSType asc, VMName asc // 按操作系统和名称排序

进阶技巧:查询尚未安装 AMA 的机器

知道哪些机器已经安装了代理固然好,但运维人员更关心的是哪些机器漏掉了。让我们换个角度,先找出所有的虚拟机,再通过 leftouter 连接来排除那些已经有代理的机器。这种“反向清单”思维是我们在进行大规模合规性审计时的核心策略。

// 进阶:查找所有虚拟机及其 AMA 安装状态(包含未安装的)
Resources 
| where type == "microsoft.compute/virtualmachines" // 1. 获取所有虚拟机(不仅仅是扩展)
| project VMId=id, VMName=name, SubscriptionId, ResourceGroup, Location
| join kind=leftouter (
    Resources 
    | where type == "microsoft.compute/virtualmachines/extensions"
    | where name has "AzureMonitorWindowsAgent" or name has "AzureMonitorLinuxAgent"
    | extend ParentVMId = substring(id, 0, indexof(id, "/extensions")) // 获取父 VM ID
    | distinct ParentVMId // 去重,防止同一个 VM 有多个扩展导致重复
) on $left.VMId == $right.ParentVMId // 2. 关联 VM 和扩展
| where isnull(ParentVMId) // 3. 筛选出 ParentVMId 为空的记录,即未安装代理的 VM
| project VMName, SubscriptionId, ResourceGroup, Location
| order by VMName asc

这个查询非常实用。如果你正在执行全公司的监控推广计划,你可以直接把这个查询结果导出为 CSV,或者通过 Logic App 触发自动化的安装脚本。

生产级深度实践:2026年的最佳方案

处理边界情况与状态验证

让我们深入探讨一个真实的挑战:处理边界情况。在简单的查询中,我们可能会忽略掉处于“已停止”状态的虚拟机,或者是那些正在处理扩展变更的虚拟机。盲目地对这些机器执行安装操作可能会导致不一致的状态。

以下是一个经过优化的、生产级别的查询,它不仅检查是否存在代理,还检查了 VM 的 Power State 和扩展的 Provisioning State。请注意,获取 Power State 通常需要联合 vmextensions 和实例视图,这里我们展示一种高效的近似方法,重点在于验证扩展的健康状况。

// 生产级查询:检查 VM 状态、代理状态以及是否处于可操作状态
resources
| where type == "microsoft.compute/virtualmachines"
| project VMId=id, VMName=name, RG=resourceGroup, Sub=subscriptionId, Loc=location
| join kind=leftouter (
    resources
    | where type == "microsoft.compute/virtualmachines/extensions"
    | where name has "AzureMonitorWindowsAgent" or name has "AzureMonitorLinuxAgent"
    | project ExtensionName=name, ParentId=substring(id, 0, indexof(id, "/extensions")), ProvState=properties.provisioningState
) on $left.VMId == $right.ParentId
// 筛选出没有代理的,或者代理状态不是 ‘Succeeded‘ 的机器
| where isnull(ExtensionName) or ProvState != "Succeeded"
| project VMName, RG, Sub, Loc, Status=case(
    isnull(ExtensionName), "Missing Agent", 
    ProvState =~ "Failed", "Installation Failed",
    ProvState =~ "Creating", "Provisioning",
    "Other: " + ProvState
    )
| order by Status desc, VMName asc

深度解析:

  • INLINECODEcf64d050:这是关键。很多新手只看扩展是否存在,但忽略了扩展可能安装失败(Failed)或正在创建中(Creating)。在生产修复脚本中,你必须跳过 INLINECODEf62c4781 状态的机器,以免造成资源锁冲突。
  • 容灾与恢复:如果 INLINECODE5ae2c0c7 为 INLINECODEf82ab7d7,我们的策略通常是先移除扩展,再重新安装。这个查询可以作为自动化修复流程的触发器。

性能优化策略:应对超大规模环境

在拥有超过 10,000 台虚拟机的大型租户中,直接运行上述查询可能会导致超时。我们建议以下优化策略:

  • 分批处理与并行化:不要一次性查询所有订阅。利用 KQL 中的 INLINECODEb5c242da 或 INLINECODE0c16a3ad 提前过滤字段,减少数据传输量。在编写调用 ARG 的代码(如 C# 或 Python SDK)时,使用多线程并行查询不同的订阅 ID。
  • 使用 summarize 进行预聚合:先按资源组聚合,只返回那些包含“问题 VM”的资源组。
// 性能优化示例:仅统计有问题的资源组
Resources 
| where type == "microsoft.compute/virtualmachines"
| join kind=leftouter (
    Resources 
    | where type == "microsoft.compute/virtualmachines/extensions"
    | where name has "AzureMonitorAgent"
    | summarize count() by ParentId=substring(id, 0, indexof(id, "/extensions"))
) on $left.id == $right.ParentId
| where isnull(count_) // 找不到代理记录的 VM
| summarize ProblematicVMs=count() by resourceGroup, subscriptionId
| where ProblematicVMs > 0 // 只关注有问题的组

这个查询返回的不是具体的机器列表,而是受影响的资源组列表。对于拥有数万资源的环境,这种“分诊”式的查询可以在几秒钟内完成,帮助你快速定位问题范围。

2026 年技术视角:结合 Agentic AI 实现自动化修复

仅仅发现问题是不够的,现代 DevOps 的理念是“自我修复”。在 2026 年,我们不再满足于手动执行查询。我们可以利用 Agentic AI(自主 AI 代理) 来消费这些 KQL 数据。

我们可以想象这样一个工作流:

  • 监控代理 定期运行上述“进阶查询”。
  • 当发现未安装 AMA 的虚拟机时,它自动触发一个 Azure Function 或运行一个 PowerShell 脚本
  • 如果安装失败(例如权限问题),AI 代理会分析错误日志,自动调整 RBAC 策略,然后重试。

这就是 Vibe Coding(氛围编程) 的精髓——我们通过自然语言描述意图,结合 KQL 和底层 API,让 AI 帮助我们完成繁琐的修复工作。在我们的近期项目中,我们使用 GitHub Copilot 生成了类似的自动化脚本,将原本需要数天的合规性检查缩短到了 15 分钟。

避坑指南:我们踩过的那些坑

在我们最近的一个大型迁移项目中,我们总结了一些容易忽视的陷阱:

  • 大小写敏感性:KQL 的标量函数(如 INLINECODE8681756d)通常是不区分大小写的,但使用 INLINECODEc8003c8a 进行字符串比较时是敏感的。为了避免环境差异导致的查询失败,建议统一使用 INLINECODE48fcbbab(不等于对应 INLINECODEe6148b15)。
  • 数据延迟:Azure Resource Graph (ARG) 本质上是一个缓存层。它不是实时的。如果你刚刚通过 ARM 模板部署了一个代理,可能需要等待 5 到 15 分钟才能在 ARG 中查询到。不要在代码中立即执行“安装后验证”,否则你会得到误报。
  • 多网卡环境:在极少数情况下,如果 VM 配置了复杂的网络扩展,可能会影响资源的发现顺序。虽然这通常不影响扩展查询,但要注意 Resource ID 的解析逻辑。

常见问题与替代方案

Q: 如果我有成千上万台 VM,ARG 查询超时怎么办?

A: 这是一个经典的扩展性问题。在 2026 年,我们可以引入 Azure Monitor Agent 的自动扩缩容管理方案。与其全量查询,不如依赖 Azure Policy。定义一个 Policy(如:“所有 VM 必须安装 AMA 扩展”),利用 Azure Policy 的合规性引擎来进行扫描,它比 ARG 更适合大规模的合规性检查,并支持 Remediation Task(修正任务)自动安装。

Q: 除了 KQL,还有别的方法吗?

A: 当然。你可以使用 Azure CLI (INLINECODEdd939699) 或 PowerShell (INLINECODEac7f1a98)。但 ARG 和 KQL 的优势在于它直接在云端的后端运行,不需要你的本地机器下载所有 VM 的元数据,网络开销几乎为零。

总结

通过这篇文章,我们不仅学习了如何利用 Azure Resource Graph 和 KQL 来解决基础设施管理中的实际问题,还深入探讨了如何结合 2026 年的 Agentic AI 和自动化理念来提升效率。我们掌握了查找已安装 Azure Monitor Agent 的基本查询,反向查找未安装的机器,以及处理混合操作系统环境的策略。

掌握这些查询技巧,将使你在日常的运维巡检、合规性审查和大规模迁移项目中事半功倍。下次当你需要统计代理覆盖率时,不妨试着打开 Resource Graph Explorer,运行几行 KQL 代码,或者更进一步,让 AI 代劳。让数据为你工作,这才是云原生运维的终极奥义。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/27562.html
点赞
0.00 平均评分 (0% 分数) - 0