
Telegraf Proxmox 输入插件实战通过 Proxmox API 采集 QEMU 虚拟机与 LXC 容器指标【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf本篇技术指南围绕 Telegraf 的 Proxmox 输入插件plugins/inputs/proxmox展开讲解如何通过 Proxmox API Token 采集节点上所有 QEMU 虚拟机和 LXC 容器的运行指标覆盖权限准备PVEAuditor 角色、完整配置参数、指标标签与字段清单并结合插件源码剖析其 API 调用链、FQDN 构造逻辑与模板虚拟机过滤机制。读完之后你可以直接完成插件的部署配置并理解每一条指标背后的数据来源。插件概述与适用前提Proxmox 插件从 Proxmox Virtual EnvironmentPVE节点收集其运行的容器LXC和虚拟机QEMU的指标数据数据采集完全基于 Proxmox 的 HTTP API而非在虚拟机/容器内部安装 Agent。插件自 Telegraf v1.16.0 起提供服务端类型server支持所有平台。使用本插件有一个硬性前提Proxmox 版本必须高于 6.2。原因在于 API Tokenapi_token这一认证方式是 Proxmox v6.2 才引入的插件正是通过 Token 进行身份认证的见 proxmox.go 中的请求认证实现request.Header.Add(Authorization, PVEAPITokenpx.APIToken)即每次请求都在 HTTP 头中携带Authorization: PVEAPITokenUSERREALM!TOKENIDUUID完成鉴权。插件通过标准注册机制接入 Telegrafinit 函数 将插件注册为proxmoxfunc init() { inputs.Add(proxmox, func() telegraf.Input { return Proxmox{} }) }在自定义构建custom build中该插件对应 plugins/inputs/all/proxmox.go 中的构建标签inputs.proxmox//go:build !custom || inputs || inputs.proxmox配置参数详解插件的官方示例配置见 sample.conf完整配置如下与 README.md 中sample.conf内嵌的内容一致因为源码中通过//go:embed sample.conf将示例配置嵌入插件# Provides metrics from Proxmox nodes (Proxmox Virtual Environment 6.2). [[inputs.proxmox]] ## API connection configuration. The API token was introduced in Proxmox v6.2. ## Required permissions for user and token: PVEAuditor role on /. base_url https://localhost:8006/api2/json api_token USERREALM!TOKENIDUUID ## Node name, defaults to OS hostname ## Unless Telegraf is on the same host as Proxmox, setting this is required. # node_name ## Additional tags of the VM stats data to add as a tag ## Supported values are vmid and status # additional_vmstats_tags [] ## Optional TLS Config # tls_ca /etc/telegraf/ca.pem # tls_cert /etc/telegraf/cert.pem # tls_key /etc/telegraf/key.pem ## Use TLS but skip chain host verification # insecure_skip_verify false ## HTTP response timeout (default: 5s) # response_timeout 5s各参数说明与源码对应关系结构体定义见 proxmox.go#L25-L38参数说明默认值 / 备注base_urlProxmox API 的 JSON 接口地址示例为https://localhost:8006/api2/json8006 是 PVE Web UI/API 的默认端口api_token形如USERREALM!TOKENIDUUID的 API Token用户与 Token 至少需要/上的 PVEAuditor 角色node_name目标 PVE 节点名默认取 OS 主机名若 Telegraf 不在 Proxmox 同一主机上运行则必须显式设置additional_vmstats_tags额外以标签形式输出的 VM 统计项支持vmid和status两个值配置非法值时插件启动校验会直接报错tls_ca/tls_cert/tls_key可选的 TLS 证书配置来自 Telegraf 通用 TLS 配置插件内嵌tls.ClientConfigresponse_timeoutHTTP 响应超时默认5s在Init()中设置为http.Client的Timeout几个值得注意的实现细节节点名的默认值Init 方法 在node_name为空时调用os.Hostname()回填注释标明这是出于向后兼容的考虑。因此远端部署时必须显式指定节点名否则所有 API 请求都会打到错误的主机。标签值校验Init()会遍历additional_vmstats_tags只接受vmid和status其他值会返回invalid additional vmstats tag错误即在 Telegraf 启动阶段就能发现配置笔误。超时生效位置response_timeout通过http.Client{Timeout: ...}作用于每一次 API 请求。权限准备创建专用用户与受限 API Token在 Proxmox 中API Token 是其所对应用户的一个子集——Token 无法执行用户本身没有权限的操作。因此 Telegraf 插件的用户和 Token两者都需要被授予/根路径上的至少PVEAuditor角色。文档给出的完整操作序列如下## Create a influx user with PVEAuditor role pveum user add influxpve pveum acl modify / -role PVEAuditor -user influxpve ## Create a token with the PVEAuditor role pveum user token add influxpve monitoring -privsep 1 pveum acl modify / -role PVEAuditor -token influxpve!monitoring要点解读pveum user add influxpve创建 realm 为pve的专用用户pveum acl modify / -role PVEAuditor -user ...给用户授予只读审计角色pveum user token add influxpve monitoring -privsep 1创建名为monitoring的 Token-privsep 1表示 Token 的权限分离不继承用户超出显式授权的部分最后一步容易被遗漏Token 自身也需要独立地acl modify授权否则受限 Token 仍然没有 API 访问权。配置完成后api_token应填写influxpve!monitoringtoken形式UUID部分即创建 Token 时返回的随机串。工作流程与源码级调用链每个采集周期内插件的 Gather 方法 按以下顺序执行从源码结构看共涉及 5 类 API 端点Gather() ├── getNodeSearchDomain() GET /nodes/node/dns ├── gatherVMData(lxc) ← LXC 容器 │ ├── getVMStats(lxc) GET /nodes/node/lxc │ └── 对每个 VM │ ├── getVMConfig(id, lxc) GET /nodes/node/lxc/vmid/config │ └── getCurrentVMStatus() GET /nodes/node/lxc/vmid/status/current └── gatherVMData(qemu) ← QEMU 虚拟机同样的三步1. 获取节点搜索域。getNodeSearchDomain 请求/nodes/node/dns端点解析出 JSON 中的data.search字段存入nodeSearchDomain用于后续拼接 FQDN。对应的数据结构在 structs.go 中定义type nodeDNS struct { Data struct { Searchdomain string json:search } json:data }2. 遍历两种资源类型。Gather()先后调用gatherVMData(acc, lxc)和gatherVMData(acc, qemu)lxc/qemu是 structs.go 中定义 的resourceType常量直接对应 API 路径中的资源段。3. 逐 VM 拉取状态与配置。gatherVMData 对每个 VM 依次调用getVMStats拿到节点上该类型的所有 VM 列表vmid、name、status等调用getVMConfig读取单个 VM 的配置若data.template 1则跳过该 VM——模板虚拟机不产生指标仅记录一条 Debug 日志源码 L140-L143调用getCurrentVMStatus获取status/current端点的实时资源数据这是绝大多数字段的最终来源。4. FQDN 构造。插件会尽量把 VM 名补全为完整域名优先使用 VM 配置中的hostname缺失时退回 VM 的name再拼接配置里的searchdomain缺失时退回节点级nodeSearchDomain得到vm_fqdnnode_fqdn则由node_name加搜索域构成源码 L151-L173。5. 派生指标计算。内存、Swap、磁盘三类指标都由 getByteMetrics 统一计算从 API 返回的total与used两个原始值推导出free与used_percentage总量为 0 时百分比记 0避免除零func getByteMetrics(total, used json.Number) metrics { int64Total : jsonNumberToInt64(total) int64Used : jsonNumberToInt64(used) int64Free : int64Total - int64Used usedPercentage : 0.0 if int64Total ! 0 { usedPercentage float64(int64Used) * 100 / float64(int64Total) } ... }所有数值字段都通过json.Number承接 API 的 JSON 数值再由jsonNumberToInt64/jsonNumberToFloat64安全转换转换失败记 0这在 Proxmox 不同版本对同一字段返回数字或字符串类型不一致时提供了容错。6. 错误处理策略。任一 VM 的 config 或 status 请求失败时插件记录Errorf日志并放弃本批次该类型的数据不会让单个 VM 的异常中断整个采集流程源码 L134-L138、L145-L149。输出指标清单指标名为proxmox标签与字段完整清单如下来自 README.md 的 Metrics 一节Tags标签标签说明node_fqdnTelegraf 所连接的 PVE 节点的 FQDNvm_name虚拟机/容器名称vm_fqdn虚拟机/容器的 FQDNvm_type资源类型lxc或qemuvm_id虚拟机/容器 ID需配置additional_vmstats_tags [vmid]输出见下Fields字段字段类型说明statusstringVM 运行状态如runninguptimeint运行时长秒cpuloadfloatCPU 负载mem_used/mem_total/mem_freeint内存用量字节mem_used_percentagefloat内存使用百分比swap_used/swap_total/swap_freeintSwap 用量字节swap_used_percentagefloatSwap 使用百分比disk_used/disk_total/disk_freeint磁盘用量字节disk_used_percentagefloat磁盘使用百分比disk_read_bytes/disk_write_bytesint累计磁盘读写字节数net_in_bytes/net_out_bytesint累计网络入出字节数关于additional_vmstats_tags从 gatherVMData 源码 可见基础标签固定为node_fqdn、vm_name、vm_fqdn、vm_type四个vm_id和status标签分别只有在配置了vmid和status时才会额外附加if slices.Contains(px.AdditionalVmstatsTags, vmid) { tags[vm_id] vmStat.ID.String() } if slices.Contains(px.AdditionalVmstatsTags, status) { tags[status] currentVMStatus.Status }需要注意status无论如何都会以字段形式输出开启标签后它是同时以字段和标签双形式出现的——把变化不频繁的维度放标签、数值放字段是控制时序数据基数cardinality的常规做法。输出示例InfluxDB line protocol 格式的实际输出来自 README 的 Example Outputvm_id标签出现是因为示例中开启了additional_vmstats_tags [vmid]proxmox,hostpxnode,node_fqdnpxnode.example.com,vm_fqdnvm1.example.com,vm_id112,vm_namevm1,vm_typelxc cpuload0.147998116735236,disk_free4461129728i,disk_total5217320960i,disk_used756191232i,disk_used_percentage14,disk_read_bytes8604417024i,disk_write_bytes2481549824i,net_in_bytes1469711887i,net_out_bytes58448585i,mem_free1046827008i,mem_total1073741824i,mem_used26914816i,mem_used_percentage2,statusrunning,swap_free536698880i,swap_total536870912i,swap_used172032i,swap_used_percentage0,uptime1643793i 1595457277000000000可以看到整数型字段带i后缀int64cpuload和百分比为浮点数status为字符串字段。测试用例对行为的印证插件的单元测试 proxmox_test.go 通过替换requestFunction源码中设计为可注入的请求函数正是为了可测试性来模拟 API 响应验证了上述全部逻辑TestGatherLxcData/TestGatherQemuData给定testnode 搜索域test.example.com的模拟数据断言生成的标签如node_fqdntestnode.test.example.com和全部 19 个字段值包括百分比的精确计算LXC 容器内存使用率18.34716796875TestGatherLxcDataWithID/TestGatherQemuDataWithID验证配置additional_vmstats_tags [vmid]后标签中新增vm_idTestGetNodeSearchDomain单独验证节点搜索域的解析TestGather完整走一遍Gather确认两个资源类型合计产生 38 个字段值。测试用的模拟 JSON 响应如 qemuTestData与 Proxmox API 的真实返回结构一致可以直接作为理解 API 字段映射如maxmem→mem_total、cpu→cpuload的参考字段映射关系定义在 structs.go 的 vmStat 结构体 中。部署要点小结同机部署base_url用默认的https://localhost:8006/api2/jsonnode_name可留空自动取主机名跨机部署必须设置base_url指向目标 PVE 节点并显式配置node_name同时按需配置tls_ca/tls_cert/tls_key完成双向认证或信任自签证书最小权限只读监控场景下 PVEAuditor 角色已足够配合-privsep 1的受限 Token 可进一步收敛权限面版本下限Proxmox ≤ 6.2 的环境因没有 API Token 机制不适用当前插件实现。插件的全部源码位于 plugins/inputs/proxmox/ 目录约 300 行 Go 代码配合 Telegraf 全局的 插件配置说明别名、字段过滤、标签修改等即可把 Proxmox 监控接入任意 Telegraf 输出后端。【免费下载链接】telegrafAgent for collecting, processing, aggregating, and writing metrics, logs, and other arbitrary data.项目地址: https://gitcode.com/GitHub_Trending/te/telegraf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考