12편까지 각 스크립트를 개별적으로 구현했습니다. 이번 편에서는 이 스크립트들이 실제로 어떤 주기로 실행되는지, 그 기준은 무엇인지, 동시 실행 시 부하를 어떻게 관리하는지 다룹니다.
수집 주기 결정 기준
모든 스크립트를 1분마다 실행하는 것이 최선처럼 보이지만, 항목마다 적절한 주기가 다릅니다.
주기 결정 기준 두 가지:
- 데이터 변화 빈도: 얼마나 자주 바뀌는가
- API 호출 비용: 한 번 실행 시 API를 몇 번 호출하는가
| 수집 대상 | 주기 | 이유 |
|---|---|---|
| 클러스터 상태 (quorum, HA) | 1분 | 이상 발생 시 즉각 감지 필요 |
| VM 리소스 (CPU, 메모리) | 1분 | 실시간에 가까운 모니터링 |
| 노드 리소스 (CPU, 메모리) | 1분 | 노드 장애 조기 감지 |
| OPNsense (게이트웨이, 터널) | 1분 | 네트워크 단절 즉시 감지 |
| TrueNAS (풀 상태, 알림) | 1분 | 스토리지 이상 조기 감지 |
| iLO / iDRAC (하드웨어 헬스) | 1분 | 하드웨어 이상 조기 감지 |
| 물리 디스크 SMART | 5분 | API 호출량 많음, 빠른 변화 없음 |
| VM / 파일시스템 Discovery | 5분 | VM 추가/삭제가 잦은 환경 |
| 백업 상태 | 15분 | 백업은 수시간 단위로 진행 |
| 노드 Discovery | 12시간 | 노드 구성 변경은 매우 드묾 |
| 디스크 Discovery | 12시간 | 디스크 교체는 매우 드묾 |
| 인증서 / OpenVPN Discovery | 6시간 | 거의 변하지 않음 |
실제 운영 crontab 전체
실제로 운영 중인 crontab입니다:
# ── VM 수집 (DEV) ──────────────────────────────────────
* * * * * python3 proxmox_vm_collector.py --collect
*/5 * * * * python3 proxmox_vm_collector.py --discovery
*/5 * * * * python3 proxmox_vm_collector.py --fs-discovery
*/15 * * * * python3 proxmox_vm_collector.py --backup-collect
0 */6 * * * python3 proxmox_vm_collector.py --disk-discovery
# ── VM 수집 (PRD) ──────────────────────────────────────
* * * * * python3 proxmox_vm_collector_prod.py --collect
*/5 * * * * python3 proxmox_vm_collector_prod.py --discovery
*/5 * * * * python3 proxmox_vm_collector_prod.py --fs-discovery
*/15 * * * * python3 proxmox_vm_collector_prod.py --backup-collect
0 */6 * * * python3 proxmox_vm_collector_prod.py --disk-discovery
# ── 노드 수집 (DEV) ────────────────────────────────────
* * * * * python3 proxmox_node_collector.py --node-collect
*/5 * * * * python3 proxmox_node_collector.py --disk-collect
0 */12 * * * python3 proxmox_node_collector.py --node-discovery
0 */12 * * * python3 proxmox_node_collector.py --disk-discovery
# ── 노드 수집 (PRD) ────────────────────────────────────
* * * * * python3 proxmox_node_collector_prod.py --node-collect
*/5 * * * * python3 proxmox_node_collector_prod.py --disk-collect
0 */12 * * * python3 proxmox_node_collector_prod.py --node-discovery
0 */12 * * * python3 proxmox_node_collector_prod.py --disk-discovery
# ── 클러스터 수집 ──────────────────────────────────────
* * * * * python3 proxmox_cluster_collector.py --collect
* * * * * python3 proxmox_cluster_collector_prod.py --collect
# ── Ceph 수집 (PRD) ────────────────────────────────────
* * * * * python3 proxmox_ceph_collector.py --collect
# ── OPNsense 수집 ──────────────────────────────────────
* * * * * python3 opnsense_collector.py --collect --site hq
* * * * * python3 opnsense_collector.py --collect --site idc
0 */6 * * * python3 opnsense_collector.py --discovery --site hq
0 */6 * * * python3 opnsense_collector.py --discovery --site idc
# ── TrueNAS 수집 ───────────────────────────────────────
* * * * * python3 truenas_collector.py --collect --site 1
* * * * * python3 truenas_collector.py --collect --site 2
0 */6 * * * python3 truenas_collector.py --discovery --site 1
0 */6 * * * python3 truenas_collector.py --discovery --site 2
# ── HP iLO 수집 ────────────────────────────────────────
* * * * * python3 ilo_collector.py --site idc02
* * * * * python3 ilo_collector.py --site idc03
* * * * * python3 ilo_collector.py --site nas01
# ── Dell iDRAC 수집 ────────────────────────────────────
* * * * * python3 idrac_collector.py --site pbs01
# ── IPMI 수집 ──────────────────────────────────────────
* * * * * python3 ipmi_collector.py --site hq02
* * * * * python3 ipmi_collector.py --site idc01
동시 실행 작업 수 계산
매 분 *로 실행되는 작업이 몇 개인지 세어 보면:
| 분류 | 작업 수 |
|---|---|
| VM 수집 (DEV + PRD) | 2 |
| 노드 수집 (DEV + PRD) | 2 |
| 클러스터 수집 (DEV + PRD) | 2 |
| Ceph 수집 | 1 |
| OPNsense (HQ + IDC) | 2 |
| TrueNAS (PRD + DEV) | 2 |
| iLO (idc02 + idc03 + nas01) | 3 |
| iDRAC | 1 |
| IPMI | 2 |
| 합계 | 17 |
매 분 최대 17개의 Python 프로세스가 동시에 기동됩니다. 각 스크립트의 실행 시간이 30초 이내라면 겹침이 생기지 않습니다. 실행 시간이 길어지면 이전 실행이 끝나기 전에 다음 실행이 시작되어 프로세스가 쌓입니다.
실행 시간 확인:
time python3 /data/zabbix/scripts/proxmox_node_collector_prod.py --node-collect
실행 시간이 30초를 넘는다면 다음을 검토합니다:
- ThreadPoolExecutor의
max_workers증가 - API 타임아웃 단축
- 수집 항목 분리
ThreadPoolExecutor로 병렬 수집
노드 수집처럼 여러 대상에 순차적으로 API를 호출하는 스크립트는 직렬 실행 시 실행 시간이 선형으로 증가합니다. 3노드면 단일 노드 시간의 3배가 걸립니다.
ThreadPoolExecutor로 노드를 병렬로 처리합니다:
from concurrent.futures import ThreadPoolExecutor, as_completed
online_nodes = [n for n in nodes_data if n.get("status") == "online"]
with ThreadPoolExecutor(max_workers=3) as ex:
futures = {ex.submit(collect_node_disks, n): n for n in online_nodes}
for future in as_completed(futures):
try:
lines.extend(future.result())
except Exception as e:
sys.stderr.write(f"[WARN] {e}\n")
3노드를 동시에 처리하면 실행 시간이 단일 노드 수준으로 유지됩니다. max_workers는 노드 수에 맞추되, 서버 CPU 코어 수의 절반을 초과하지 않는 것이 안전합니다.
Discovery 주기와 0 /N 패턴
Discovery 작업은 수집 작업과 달리 자주 실행할 필요가 없습니다:
# 잘못된 방식 — 매 6분마다 실행
*/6 * * * * ...
# 올바른 방식 — 매 6시간 정각에 실행
0 */6 * * * ...
/6은 0, 6, 12, 18, 24, 30…분마다(즉 매 6분)를 의미합니다. 0 /6은 0시, 6시, 12시, 18시 정각을 의미합니다. Discovery처럼 자주 필요 없는 작업에는 0 */N 패턴을 사용합니다.
| 패턴 | 의미 |
|---|---|
* | 매 1분 |
/5 * | 매 5분 |
/15 * | 매 15분 |
0 /6 | 매 6시간 (0, 6, 12, 18시) |
0 /12 | 매 12시간 (0, 12시) |
로그 관리
각 스크립트의 출력을 별도 로그 파일로 분리합니다:
* * * * * python3 ilo_collector.py >> /data/zabbix/scripts/collector_ilo.log 2>&1
로그가 무한히 쌓이지 않도록 logrotate를 설정합니다:
/data/zabbix/scripts/collector_*.log {
daily
rotate 7
compress
missingok
notifempty
}
/etc/logrotate.d/zabbix-collector 파일로 저장하면 시스템 logrotate가 자동으로 처리합니다.
로그에서 오류만 빠르게 확인하려면:
grep -i error /data/zabbix/scripts/collector_*.log | tail -20
crontab 관리 팁
crontab 백업:
crontab -l > /app/zabbix/crontab.bak
중요한 변경 전 반드시 백업합니다. crontab -e 편집 중 실수로 내용이 지워지면 복원이 불가능합니다.
crontab 복원:
crontab /app/zabbix/crontab.bak
현재 실행 중인 수집 프로세스 확인:
ps aux | grep collector | grep -v grep
특정 스크립트가 종료되지 않고 프로세스가 쌓이고 있다면 API 타임아웃이나 네트워크 문제를 확인합니다.
마치며
이번 편에서 다룬 핵심 포인트입니다:
- 수집 주기는 “데이터 변화 빈도”와 “API 호출 비용”으로 결정
- 매 분 17개 프로세스가 동시 실행 — 각 스크립트 실행 시간이 30초 이내여야 안전
ThreadPoolExecutor로 다중 노드 병렬 처리해 실행 시간 단축/6(매 6분)과0 /6(매 6시간)은 다름 — Discovery에는0 */N사용- 로그 파일은 스크립트별로 분리하고
logrotate로 관리 - crontab은 수정 전 반드시 백업
다음 편에서는 DEV와 PRD 환경을 하나의 Zabbix로 운영할 때 호스트 그룹, 권한, 알림을 어떻게 분리하는지 다룹니다.