Ceilometer 커스텀 메트릭 개발
기간: 2024.06 ~ 2024.08
역할: OpenStack Telemetry 시스템 확장 개발
기술스택: Python, Ceilometer, Gnocchi, SNMP, Dynamic Pollster
프로젝트 목표
OpenStack 기본 제공 메트릭을 넘어서 사용자 정의 메트릭 수집과 특정 인스턴스 필터링을 통한 모니터링 시스템 고도화

핵심 기술 구현
1) Custom Discovery 개발
문제: Amphora 인스턴스 등 불필요한 리소스까지 메트릭 수집으로 인한 성능 저하
해결: InstanceDiscovery 상속 기반 필터링 시스템
# cloudn_custom_discovery.py
from ceilometer.compute import discovery
class CloudnCustomDiscovery(discovery.InstanceDiscovery):
def __init__(self, conf):
super(CloudnCustomDiscovery, self).__init__(conf)
def discover(self, manager, param=None):
resources = []
all_resources = super(CloudnCustomDiscovery, self).discover(manager, param)
for resource in all_resources:
# Amphora 인스턴스는 메트릭 수집 대상에서 제외
if hasattr(resource, 'name') and resource.name.startswith('amphora'):
continue
resources.append(resource)
return resources
setup.cfg 엔트리포인트 등록:
[entry_points]
ceilometer.discover.compute =
custom_discovery = ceilometer.compute.cloudn_custom_discovery:CloudnCustomDiscovery
polling.yaml 적용:
sources:
- interval: 60
meters:
- cpu
- memory.usage
- disk.device.capacity
- network.incoming.bytes
- network.outgoing.bytes
name: cloudn_vm_pollsters
discovery:
- custom_discovery # 커스텀 디스커버리 적용
sinks:
- meter_sink
2) Dynamic Pollster를 통한 SNMP 메트릭 수집
문제: Ceilometer 기본 메트릭에서 제공하지 않는 호스트 레벨 CPU 사용률 필요
해결: SNMP OID 기반 커스텀 메트릭 개발
# /etc/ceilometer/pollsters.d/custom_cpu_load.yaml
- name: "custom.metric.cpu.load"
meter_name: "custom.metric.cpu.load"
unit: "percent"
namespaces: "compute" # compute 노드에서 실행
type: "gauge"
host_command: >
echo '[{"hostname": "'$(hostname)'", "value": '$(snmpwalk -v 2c -c public localhost 1.3.6.1.2.1.25.3.3.1.2 | awk '{sum += $NF} END {print sum/NR}' | sed 's/\"//g')'}]'
value_attribute: "value"
resource_id_attribute: "hostname"
resource_type: "cloudn_host"
sample_type: "gauge"
response_handlers:
- json
3) Ceilometer 코어 수정
문제: Dynamic Pollster의 host_command
가 eval()로 파이썬 코드 파싱을 시도해 쉘 명령어 실행 제한
해결: eval() bypass를 통한 명령어 실행 확장성 확보
# ceilometer/polling/dynamic.py (수정된 부분)
def _execute_command(self, command):
"""Execute host command directly without eval() parsing"""
try:
# 기존 eval() 시도를 건너뛰고 직접 subprocess 실행
result = subprocess.run(
command,
shell=True,
capture_output=True,
text=True,
timeout=30
)
if result.returncode == 0:
return result.stdout.strip()
else:
LOG.error("Command execution failed: %s", result.stderr)
return None
except subprocess.TimeoutExpired:
LOG.error("Command execution timeout: %s", command)
return None
except Exception as e:
LOG.error("Command execution error: %s", e)
return None
4) Gnocchi 리소스 타입 및 메트릭 설정
새로운 리소스 타입과 메트릭 정의:
# 커스텀 리소스 타입 생성
openstack metric resource-type create cloudn_host -a name:string:True
# 호스트별 리소스 생성
openstack metric resource create ct01-cloud-resource \
--type cloudn_host \
-a hostname:ct01.cloud-and
# 커스텀 메트릭 생성
gnocchi metric create custom.metric.cpu.load \
--resource-id 7dba4e61-c045-5010-9858-140684c2cf99 \
--archive-policy-name cloudn202407 \
-u percent
5) Pipeline 설정
수집된 메트릭을 Gnocchi로 전송하는 파이프라인 구성:
# /etc/ceilometer/pipeline.yaml
sinks:
- name: meter_sink
publishers:
- gnocchi://?filter_project=gnocchi_swift&archive_policy=cloudn202407
전체 워크플로우
- Dynamic Pollster 정의 → SNMP OID 기반 호스트 CPU 사용률 수집 명령어 정의
- Polling Service 실행 → compute 노드에서 60초 간격으로 메트릭 수집
- Custom Discovery 적용 → Amphora 인스턴스 필터링으로 불필요한 수집 제외
- Pipeline 처리 → 수집된 샘플을 Gnocchi로 전송
- Gnocchi 저장 → 정의된 archive policy에 따라 시계열 데이터 저장
기술적 도전과 해결
도전 1: host_command의 제약사항
- 문제: Ceilometer 2023.1 이하 버전에서 eval() 파싱으로 인한 명령어 제한
- 해결: subprocess 직접 호출로 우회, 보안성과 확장성 동시 확보
도전 2: 구조화된 데이터 요구사항
- 문제: host_command 결과가 JSON/XML 형태여야 파싱 가능
- 해결: echo로 JSON 구조 생성, response_handlers에 json 명시
도전 3: 네임스페이스와 디스커버리 조합
- 문제: central과 compute 네임스페이스에서 서로 다른 디스커버리 동작
- 해결: compute 네임스페이스에서 custom_discovery 적용으로 호스트별 메트릭 수집
성과 및 한계
달성 성과:
- SNMP를 통한 호스트 레벨 CPU 사용률 메트릭 수집 성공
- Custom Discovery로 불필요한 Amphora 인스턴스 메트릭 제거
- Ceilometer journal log에서 정상적인 메트릭 수집 확인
- Gnocchi에서 커스텀 리소스 타입과 메트릭 정상 등록
기술적 한계:
- Ceilometer에서 Gnocchi로의 파이프라인 전송 이슈 (당시 미해결)
- 수동으로 추가한 테스트 데이터는 정상 조회되지만 실제 수집 데이터 전송 실패
학습 효과:
- OpenStack Telemetry 전체 아키텍처 (Ceilometer → Pipeline → Gnocchi) 이해
- Python 기반 OpenStack 컴포넌트 확장 개발 경험
- SNMP 프로토콜과 시스템 메트릭 수집 방법론 습득