Proxmox VE는 REST API를 통해 클러스터 상태, 노드 리소스, VM 정보, 물리 디스크 SMART 데이터까지 수집할 수 있습니다. API에 접근하려면 토큰과 적절한 권한이 필요합니다.
이번 편에서는 모니터링 전용 API 토큰을 만들고 권한을 설계하는 방법을 다룹니다.
왜 토큰을 쓰는가
Proxmox API는 사용자 계정의 비밀번호로도 인증할 수 있지만, 모니터링 스크립트에 비밀번호를 직접 넣는 것은 좋지 않습니다. API 토큰을 사용하면:
- 토큰별로 권한을 독립적으로 제어할 수 있습니다
- 토큰만 폐기해도 계정은 유지됩니다
- 토큰에 유효기간을 설정할 수 있습니다
모니터링 목적이라면 읽기 전용 권한만 부여된 전용 토큰을 만드는 것이 원칙입니다.
전용 사용자 생성
토큰을 발급하기 전에 모니터링 전용 사용자를 먼저 만듭니다.

| 항목 | 값 |
|---|---|
| User name | zabbix-monitor |
| Realm | pve (Proxmox VE 인증) |
| Password | 임의값 (토큰 사용 시 불필요) |
| Enabled | 체크 |
@pve 영역(Realm)을 선택하면 Proxmox 내부 인증을 사용합니다. LDAP 연동 환경이라면 @pam 또는 별도 영역을 선택합니다.
API 토큰 발급


항목 | 값 |
|---|---|
| User | zabbix-monitor@pve |
| Token ID | zabbix |
| Privilege Separation | 체크 해제 권장 (사용자 권한 그대로 상속) |
| Expire | 0 (만료 없음) |
발급 후 화면에 표시되는 토큰 시크릿은 이 순간만 볼 수 있습니다. 반드시 복사해 둡니다.
발급된 토큰은 다음 형식으로 사용합니다:
PVEAPIToken=zabbix-monitor@pve!zabbix=발급된-시크릿-UUID
Python 스크립트에서 Authorization 헤더에 그대로 넣으면 됩니다:
API_TOKEN = "PVEAPIToken=zabbix-monitor@pve!zabbix=발급된-UUID"
req = urllib.request.Request(
url,
headers={"Authorization": API_TOKEN}
)
권한(Role) 설계
Proxmox의 권한은 Path + User/Token + Role 조합으로 구성됩니다.
모니터링에 필요한 최소 권한은 두 가지입니다:
| Role | 포함된 권한 | 용도 |
|---|---|---|
| PVEAuditor | VM.Audit, Datastore.Audit 등 | 클러스터·VM·스토리지 조회 |
| 커스텀 Role | Sys.Audit | 노드 시스템 정보·디스크 조회 |
PVEAuditor만으로는 /nodes/{node}/disks/list나 /nodes/{node}/disks/smart API가 403 Forbidden을 반환합니다. Sys.Audit 권한이 추가로 필요합니다.
권한 부여 방법
방법 1: 커스텀 Role 생성 후 부여

MonitorRole이라는 이름으로 아래 권한을 포함한 Role을 만듭니다:
Sys.AuditVM.AuditDatastore.AuditPool.Audit
그런 다음 Path / (루트)에 토큰과 이 Role을 연결합니다.


| 항목 | 값 |
|---|---|
| Path | / |
| API Token | zabbix-monitor@pve!zabbix |
| Role | MonitorRole |
| Propagate | 체크 (하위 경로 전체 적용) |
방법 2: PVEAuditor + Sys.Audit 분리 부여
/ 경로에 PVEAuditor를, /nodes 경로에 Sys.Audit만 포함한 별도 Role을 추가로 부여하는 방법도 있습니다.
/ → PVEAuditor (VM, 클러스터, 스토리지 조회)
/nodes → SysAuditor (Sys.Audit만 포함한 커스텀 Role)
권한을 최소화하면서 노드 물리 정보까지 수집하고 싶다면 이 방식이 더 정교합니다.
SSL 처리
Proxmox는 기본으로 자체 서명(self-signed) 인증서를 사용합니다. Python의 urllib로 API를 호출할 때 인증서 검증을 비활성화해야 합니다.
import ssl
ssl_ctx = ssl.create_default_context()
ssl_ctx.check_hostname = False
ssl_ctx.verify_mode = ssl.CERT_NONE
with urllib.request.urlopen(req, context=ssl_ctx, timeout=15) as r:
data = json.load(r).get("data")
운영 환경에서는 Let’s Encrypt나 내부 CA 인증서를 Proxmox에 적용하고 검증을 활성화하는 것이 바람직합니다. 하지만 내부망 모니터링 전용 스크립트라면 검증 비활성화로 충분합니다.
클러스터 API 접근 구조
Proxmox 클러스터에서 API를 호출할 때는 어느 노드에 요청해도 무방합니다. 클러스터 API(/cluster/*)는 어느 노드나 동일한 응답을 반환합니다.
단, 물리 디스크 SMART처럼 노드 로컬 정보는 반드시 해당 노드에 직접 요청해야 합니다:
/nodes/pve11/disks/smart → pve11에 직접 요청해야 정확한 결과
이를 위해 스크립트에서 노드명과 IP를 미리 매핑해 둡니다:
NODE_IPS = {
"pve11": "10.0.92.11",
"pve12": "10.0.92.12",
"pve13": "10.0.92.13",
}
클러스터 API는 세 노드 중 하나가 응답하지 않아도 다른 노드로 폴백할 수 있도록 순서대로 시도하는 구조로 구현합니다:
PROXMOX_HOSTS = ["10.0.92.11", "10.0.92.12", "10.0.92.13"]
def api(path, node_ip=None):
hosts = [node_ip] if node_ip else PROXMOX_HOSTS
for host in hosts:
url = f"https://{host}:8006{path}"
req = urllib.request.Request(url, headers={"Authorization": API_TOKEN})
try:
with urllib.request.urlopen(req, context=ssl_ctx, timeout=15) as r:
return json.load(r).get("data")
except Exception as e:
sys.stderr.write(f"[WARN] {host} {path}: {e}\n")
return None
첫 번째 노드가 실패하면 두 번째, 세 번째 순서로 시도합니다. 노드 한 개가 다운되어도 수집이 중단되지 않습니다.
권한 설정 후 동작 확인
API 토큰과 권한 설정이 완료되면 간단하게 동작을 확인합니다:
curl -k -H "Authorization: PVEAPIToken=zabbix-monitor@pve!zabbix=UUID" https://10.0.92.11:8006/api2/json/cluster/status
정상이면 JSON 응답이 반환됩니다. 권한이 부족하면:
{"data": null, "errors": {"...": "403 Forbidden"}}
403이 반환된다면 해당 경로에 필요한 Role이 부여되어 있는지 확인합니다. Proxmox의 권한은 경로별로 작동하기 때문에 /cluster/에는 접근되지만 /nodes/에 403이 뜨는 경우가 있습니다. 이때 /nodes 경로에 Sys.Audit을 추가 부여하면 해결됩니다.
마치며
이번 편에서 다룬 핵심 포인트입니다:
- 모니터링용 전용 사용자와 API 토큰을 분리해서 생성
PVEAuditor만으로는 디스크 SMART API 접근 불가 →Sys.Audit추가 필요- 클러스터 API는 어느 노드나 폴백 가능, 노드 로컬 API는 해당 노드에 직접 요청
- SSL 자체 서명 인증서는
ssl.CERT_NONE으로 우회
다음 편에서는 준비된 API 토큰을 활용해 클러스터 수준의 상태를 수집하는 Cluster Collector를 구현합니다. quorum, HA 상태, VM 요약, 스토리지 현황까지 한 번에 수집하는 구조를 설명합니다.