Zabbix 인프라 모니터링 구축 – 10. 자동화: Zabbix API로 아이템·트리거 일괄 생성 (iLO·iDRAC)

2026.10.02

·

iLO와 iDRAC 수집 스크립트를 만들었다면, 다음은 Zabbix에 호스트와 수십 개의 아이템·트리거를 등록하는 작업입니다. UI에서 하나씩 클릭하는 대신 Zabbix API를 활용하면 스크립트 한 번으로 전체 구성을 완성할 수 있습니다.


Zabbix API 구조

Zabbix API는 JSON-RPC 2.0 프로토콜을 사용합니다. 모든 요청은 단일 엔드포인트로 전송됩니다:

POST https://zabbix서버:8080/api_jsonrpc.php
Content-Type: application/json

요청 형식:

Sponsored

{
  "jsonrpc": "2.0",
  "method": "host.create",
  "params": { ... },
  "auth": "인증토큰",
  "id": 1
}

인증 토큰 발급

import requests

ZABBIX_URL = "http://localhost:8080/api_jsonrpc.php"

def zabbix_api(method, params, token=None):
    payload = {
        "jsonrpc": "2.0",
        "method": method,
        "params": params,
        "id": 1,
    }
    if token:
        payload["auth"] = token
    r = requests.post(ZABBIX_URL, json=payload, timeout=10)
    result = r.json()
    if "error" in result:
        raise RuntimeError(f"API Error: {result['error']}")
    return result["result"]

# 로그인
token = zabbix_api("user.login", {
    "username": "Admin",
    "password": "비밀번호"
})

Zabbix 7.0부터 user 대신 username 파라미터를 사용합니다. 구버전 자료를 참고할 때 주의하세요.


호스트 생성

def create_host(token, hostname, ip, group_id):
    return zabbix_api("host.create", {
        "host": hostname,
        "name": hostname,
        "interfaces": [{
            "type": 1,       # 1=Agent (Trapper는 인터페이스 타입 무관)
            "main": 1,
            "useip": 1,
            "ip": ip,
            "dns": "",
            "port": "10050"
        }],
        "groups": [{"groupid": str(group_id)}],
    }, token)

호스트 그룹 ID는 환경마다 다릅니다. 먼저 조회합니다:

groups = zabbix_api("hostgroup.get", {"output": ["groupid", "name"]}, token)
for g in groups:
    print(g["groupid"], g["name"])

아이템 생성

def create_item(token, hostid, key, name, vtype=0):
    params = {
        "hostid":       hostid,
        "name":         name,
        "key_":         key,
        "type":         2,       # 2 = Zabbix trapper
        "value_type":   vtype,   # 0=float, 1=string, 3=unsigned, 4=text
        "history":      "30d",
        "delay":        0,       # Trapper는 수집 주기 없음
    }
    # 문자열 타입은 trends 저장 불가 — 파라미터 자체를 제외해야 함
    if vtype not in (1, 4):
        params["trends"] = "365d"

    return zabbix_api("item.create", params, token)

trends 파라미터 주의: value_type이 1(string) 또는 4(text)인 아이템에 trends 파라미터를 포함하면 API가 오류를 반환합니다. 조건부로 제외해야 합니다.

value_type 값:

값타입용도
0Numeric (float)온도, 전력, 비율
1Character (string)짧은 문자열
3Numeric (unsigned)카운터, 상태값
4Text긴 문자열, JSON

iLO 아이템 일괄 생성 예시

ILO_ITEMS = [
    ("ilo.health.system",    "시스템 전체 헬스",      3),
    ("ilo.power.state",      "전원 상태",             3),
    ("ilo.health.cpu",       "CPU 헬스",              3),
    ("ilo.cpu.count",        "CPU 수",                3),
    ("ilo.health.memory",    "메모리 헬스",           3),
    ("ilo.memory.total_gb",  "메모리 전체 (GB)",      0),
    ("ilo.power.consumed",   "소비 전력 (W)",         0),
    ("ilo.power.capacity",   "전력 용량 (W)",         0),
    ("ilo.power.ps1.health", "PSU 1 헬스",            3),
    ("ilo.power.ps1.output", "PSU 1 출력 (W)",        0),
    ("ilo.power.ps2.health", "PSU 2 헬스",            3),
    ("ilo.power.ps2.output", "PSU 2 출력 (W)",        0),
]

host_result = create_host(token, "proxmox-idc-02-ilo", "10.0.92.112", group_id=27)
hostid = host_result["hostids"][0]

for key, name, vtype in ILO_ITEMS:
    create_item(token, hostid, key, name, vtype)
    print(f"  [OK] {key}")

온도·팬 센서처럼 서버마다 이름이 다른 동적 아이템은 수집 스크립트가 처음 데이터를 전송할 때 Zabbix에서 자동으로 인식되지 않습니다. 이 경우 먼저 스크립트를 한 번 실행해 어떤 키로 데이터가 전송되는지 확인한 뒤, 해당 키로 아이템을 등록합니다.


트리거 생성

Zabbix 7.0에서 트리거 생성 시 두 가지 함정이 있습니다.

함정 1: hostid 파라미터 불가

구버전 자료를 보면 trigger.create에 hostid를 넣는 예시가 있습니다. Zabbix 7.0에서는 이 파라미터가 없습니다. 호스트 정보는 expression 안에 포함됩니다:

# 잘못된 코드
zabbix_api("trigger.create", {
    "hostid": hostid,   # 오류: unexpected parameter
    "expression": "...",
    ...
})

# 올바른 코드
zabbix_api("trigger.create", {
    "expression": "last(/proxmox-idc-02-ilo/ilo.health.system) >= 2",
    ...
}, token)

함정 2: 트리거 표현식 포맷

3편에서 다뤘던 것처럼 Zabbix 7.0은 새 포맷만 허용합니다:

def create_trigger(token, hostname, key, name, expr, severity=2):
    # severity: 0=미분류, 1=정보, 2=경고, 3=보통, 4=심각, 5=재해
    return zabbix_api("trigger.create", {
        "description": name,
        "expression":  expr.format(host=hostname),
        "priority":    severity,
        "status":      0,  # 0=활성화
    }, token)

# 사용 예시
create_trigger(
    token,
    hostname="proxmox-idc-02-ilo",
    key="ilo.health.system",
    name="iLO: 시스템 헬스 이상",
    expr="last(/{host}/ilo.health.system) >= 2",
    severity=4,  # High
)

iLO/iDRAC 공통 트리거 목록

COMMON_TRIGGERS = [
    # (이름, 표현식, 심각도)
    ("시스템 헬스 Critical",
     "last(/{host}/ilo.health.system) >= 2",    4),  # High

    ("전원 OFF",
     "last(/{host}/ilo.power.state) = 0",       4),  # High

    ("CPU 헬스 이상",
     "last(/{host}/ilo.health.cpu) >= 1",       3),  # Average

    ("메모리 헬스 이상",
     "last(/{host}/ilo.health.memory) >= 1",    3),  # Average

    ("PSU 1 이상",
     "last(/{host}/ilo.power.ps1.health) >= 1", 4),  # High

    ("PSU 2 이상",
     "last(/{host}/ilo.power.ps2.health) >= 1", 4),  # High

    ("소비 전력 과다 (500W 초과)",
     "last(/{host}/ilo.power.consumed) > 500",  2),  # Warning
]

iLO와 iDRAC의 키 이름 앞부분(ilo. / idrac.)만 다르고 구조는 동일합니다. 공통 트리거 목록을 만들고 prefix만 교체하면 재사용할 수 있습니다.


전체 자동화 흐름

def setup_ilo_host(token, site_key, cfg, group_id):
    hostname = cfg["zabbix_host"]
    ip       = cfg["ilo_host"]

    # 1. 호스트 생성
    result = create_host(token, hostname, ip, group_id)
    hostid = result["hostids"][0]
    print(f"[OK] 호스트 생성: {hostname} (ID: {hostid})")

    # 2. 아이템 생성
    for key, name, vtype in ILO_ITEMS:
        create_item(token, hostid, key, name, vtype)
    print(f"[OK] 아이템 {len(ILO_ITEMS)}개 생성")

    # 3. 트리거 생성
    for tname, expr, severity in COMMON_TRIGGERS:
        create_trigger(token, hostname, "", tname,
                       expr.replace("{host}", hostname), severity)
    print(f"[OK] 트리거 {len(COMMON_TRIGGERS)}개 생성")

# 실행
token = zabbix_api("user.login", {"username": "Admin", "password": "pw"})
for site_key, cfg in HOSTS.items():
    setup_ilo_host(token, site_key, cfg, group_id=27)

API 사용 시 자주 보는 오류

오류 메시지원인해결
No permissions to referred object해당 호스트/그룹 접근 권한 없음Admin 계정 사용 확인
unexpected parameter "hostid"trigger.create에 hostid 포함파라미터 제거
Invalid parameter "trends"string 타입 아이템에 trends 설정vtype 1·4이면 trends 제외
Invalid parameter "username"구버전 user 파라미터 사용username으로 변경
Trigger expression ... is incorrect구버전 트리거 표현식 포맷신규 포맷으로 변경

마치며

이번 편에서 다룬 핵심 포인트입니다:

  • Zabbix API는 JSON-RPC 2.0 — 단일 엔드포인트로 모든 요청
  • string/text 타입 아이템은 trends 파라미터 제외 필수
  • trigger.create에 hostid 파라미터 없음 — 표현식에 호스트명 직접 포함
  • Zabbix 7.0 트리거 표현식: last(/hostname/key) >= 값
  • iLO와 iDRAC은 키 prefix만 다르고 트리거 구조 동일 — 재사용 가능

다음 편에서는 OPNsense 방화벽 모니터링을 다룹니다.


MORE POSTS

다른 글 보기

guniq 인사이트 썸네일 — 중소기업 OpenLDAP 통합 인증 구축 – 00. 왜 OpenLDAP인가: 비용과 자유, 그리고 표준의 중요성
테크 랩

중소기업 OpenLDAP 통합 인증 구축 – 00. 왜 OpenLDAP인가: 비용과 자유, 그리고 표준의 중요성

MS Active Directory 대신 OpenLDAP을 선택한 이유, 오픈소스 디렉토리 서버의 장단점, 그리고 연동 유연성을 결정짓는 LDAP 표준 준수의 중요성을 실제 운영 경험 기반으로 정리합니다.
2026.10.12
guniq 인사이트 썸네일 — Zabbix 인프라 모니터링 구축 – 15. 실전 이슈: 운영 중 마주친 오탐·누락·설정 오류 총정리 (트러블슈팅)
테크 랩

Zabbix 인프라 모니터링 구축 – 15. 실전 이슈: 운영 중 마주친 오탐·누락·설정 오류 총정리 (트러블슈팅)

Zabbix 모니터링 구축과 운영 중 실제로 마주친 문제들을 총정리합니다. Media Type 기본 비활성화, 트리거 표현식 포맷 변경, stale value 오탐, crontab 초기화, netstat 타입 오류 등 삽질의 기록과 해결책을 공유합니다.
2026.10.09
guniq 인사이트 썸네일 — Zabbix 인프라 모니터링 구축 – 14. 환경 분리: DEV·PRD를 하나의 Zabbix로 운영하기 (호스트그룹·권한)
테크 랩

Zabbix 인프라 모니터링 구축 – 14. 환경 분리: DEV·PRD를 하나의 Zabbix로 운영하기 (호스트그룹·권한)

개발과 운영 환경을 하나의 Zabbix 서버로 운영하면서 호스트 그룹, 사용자 권한, Slack 알림 채널을 분리하는 방법을 다룹니다. API 토큰, 스크립트, 로그까지 환경별 분리 전략 전체를 설명합니다.
2026.10.08

프로젝트 문의 환영합니다

기획부터 개발, 운영까지 함께 만들어 드립니다.

무료 3분 자가진단

우리 회사, 자체 클라우드가 답일까?

AWS vs 자체 인프라 · 11개 항목 3분 체크