跳转到内容

REST API 与 pvesh ​

Web UI 本身就是这个 API 的一个客户端,界面上能点的每一个按钮背后都是一次 API 调用。搞懂这个 API 的结构和认证方式,你就能把"界面上能做的事"变成"脚本能做的事"。

为什么需要它 ​

  • 命令行工具全景 里的 qm/pct 这些命令只能在 PVE 节点本地跑。想从另一台机器(CI、NAS、你自己的电脑)操作 PVE,必须直接走 REST API。
  • Terraform、Ansible 这些自动化工具,底层都是在调这个 API。理解它,排查这些工具的报错会容易很多。
  • 自己写监控脚本、巡检脚本,直接调 API 比解析命令行输出更稳定(返回的是结构化 JSON)。

开始之前 ​

  • 一个有足够权限的 PVE 账号,或者一个 API Token(推荐用于脚本,见下文)。权限模型见用户与权限、Token 的创建见 API Token 与最小权限。
  • 本地装好 curl,想让输出好看可以再装 jq。
  • 知道 PVE 管理端口是 8006,走 HTTPS。

API 长什么样 ​

基础地址是:

text
https://<你的PVE地址>:8006/api2/json/

后面接资源路径,和 Web UI 的层级基本对应,例如:

路径对应的东西
/nodes集群里的所有节点
/nodes/{node}/qemu某节点上的虚拟机列表
/nodes/{node}/qemu/{vmid}/status/current某台虚拟机的当前状态
/nodes/{node}/storage某节点的存储状态
/access/users用户列表

HTTP 方法对应操作类型:GET 读取、POST 创建/触发动作、PUT 修改、DELETE 删除。整个 API 由一份 JSON Schema 定义,官方的 API 文档查看器 能按树状结构浏览每个端点、支持的方法、参数和所需权限——写脚本前先去那里确认端点和参数名,比凭记忆猜可靠。

端点后面加 /{node} 通常需要真实节点名

{node}、{vmid} 这类花括号是占位符,替换成实际值,例如你的主机名或客户机编号。命令行里常用 $(hostname) 自动代入当前节点名。

两种认证方式怎么选 ​

每个请求都必须带认证信息,二选一:

方式怎么拿到有效期适合场景
登录票据 (ticket)POST 用户名密码到 /access/ticket,拿到 ticket 和 CSRFPreventionToken约 2 小时,到期前可用旧票据续交互式网页会话(浏览器登录背后就是这个)
API Token数据中心 → 权限 → API Tokens → 添加可设过期时间,也可以不过期自动化脚本、CI、长期运行的程序

脚本一律用 Token,不要用票据或密码

Token 可以单独撤销、可以限定比账号本身更小的权限范围(保持默认勾选的 Privilege Separation,再单独给这个 Token 授权),泄露了直接删掉重建,不影响账号本身。详细创建步骤见 API Token 与最小权限。Token Secret 创建后只显示一次,立刻存进密码管理器。

用 curl 直接调(Token 方式) ​

请求头格式是 Authorization: PVEAPIToken=<用户>@<认证域>!<TokenID>=<Secret>:

sh
# 本地电脑执行,把 <PVE_HOST> 换成实际地址或主机名
# <token-secret> 是占位符,换成你自己 Token 的 Secret,不要把真实值提交进任何仓库
curl -k \
  -H 'Authorization: PVEAPIToken=automation@pve!ci=<token-secret>' \
  https://<PVE_HOST>:8006/api2/json/nodes

用 Token 发起的写请求(POST/PUT/DELETE)不需要额外的 CSRF 头,这是 Token 相比票据的另一个好处——票据方式的写请求还要带上登录时拿到的 CSRFPreventionToken。

-k 只在自签证书环境下用

-k 会跳过 TLS 证书校验,方便测试,但也意味着中间人攻击时你不会被提醒。给 PVE 配好受信任证书后应该去掉它;如果只是自签证书又不想每次都 -k,可以把 CA 证书导入本地信任库。

用 pvesh 直接调(本地方式) ​

如果脚本本身就跑在 PVE 节点上,用 pvesh 更省事——不用处理认证,因为它是以 root 身份直接调用 API 函数,压根没走 HTTPS:

sh
# 宿主机 shell,以 root 执行
pvesh get /nodes
pvesh get /nodes/$(hostname)/qemu/<vmid>/status/current
pvesh get /nodes --output-format json

--output-format 支持 json、json-pretty、yaml、text(默认,带 ASCII 边框,适合人看)。写脚本时用 json 配合 jq 解析最方便。

pvesh 和 curl 怎么选

脚本跑在 PVE 节点本地:用 pvesh,少一层认证的麻烦。脚本跑在别的机器上:只能用 REST API + Token,pvesh 没有走网络,用不了。

检查结果 ​

任选一种方式,确认能拿到数据:

sh
# pvesh 方式(宿主机 shell)
pvesh get /version

# curl + Token 方式(本地电脑或任意能连到 8006 端口的机器)
curl -k -H 'Authorization: PVEAPIToken=<用户>@<域>!<TokenID>=<Secret>' \
  https://<PVE_HOST>:8006/api2/json/version

两者应该返回同样内容的 JSON(版本号等信息)。再去 API 文档查看器里找一个你打算用的端点,确认它列出的所需权限和你的账号/Token 权限对得上。

常见问题 ​

报 401 或提示认证失败。 Token 格式是不是漏了 !(用户和 Realm 之间是 @,TokenID 前是 !);票据是不是已经过期(2 小时);Authorization 头拼写和大小写是否正确。

报 403 Permission check failed。 认证本身没问题,但这个账号/Token 在目标路径上没有对应权限。回到 API 文档查看器 确认该端点需要的权限,再去 数据中心 → 权限 里核对路径和角色。

没有 pvesh 命令(比如在 Windows 或 macOS 上写脚本)。 pvesh 只存在于 PVE 节点上。别的系统一律用 REST API + curl(或对应语言的 HTTP 库)。

自签证书导致 curl 报证书错误。 测试用 -k 跳过校验;长期使用建议给 PVE 换成受信任证书,或者把它的 CA 证书导入调用方的信任库。

参考资料 ​

Proxmox VE 非官方中文使用指南,与 Proxmox Server Solutions GmbH 无隶属关系。