이번 글에서는 Ray Serve + FastAPI로 GPU 기반 추론 API를 띄우고,
이 서비스의 /metrics를 Prometheus + Grafana로 수집/시각화하는 과정을 정리했습니다.
Ray Serve의 actor 기반 구조를 활용해 GPU 리소스를 관리하고,
FastAPI end-point로 요청 → 추론 결과 → 평균 지연 시간까지
관측 가능한 end-to-end Pipeline을 구축했습니다.
주요 구성요소
| Ray Serve | GPU inference serving framework | 
| FastAPI | REST API endpoint 제공 | 
| Prometheus | /metrics 스크레이프 및 시계열 데이터 수집 | 
| Grafana | 요청 수 / 평균 지연 시각화 대시보드 | 
| Docker Compose | 모든 스택을 컨테이너 단일 커맨드로 기동 | 
| Makefile | health, infer, obs-up 등 자동화 명령 제공 | 
1. 추론 서비스 (Ray Serve + FastAPI)
- 경로: ray_inference/serve_app.py
- GPU 자동 감지 (torch.cuda.is_available())
 - /inference/healthz, /inference/metrics, /inference/ endpoint 제공
 - Prometheus 포맷으로 metrics 노출
 
 

2. Prometheus + Grafana 설정
디렉토리 구조
observability/
└─ prometheus/prometheus.yml
grafana/
 ├─ provisioning/datasources/datasource.yml
 ├─ provisioning/dashboards/dashboards.yml
 └─ dashboards/ray-inference.json
prometheus.yml
scrape_configs:
  - job_name: 'ray-inference'
    metrics_path: /inference/metrics
    static_configs:
      - targets: ['ray-inference:8000']

- Grafana Dashboard
- “Requests total” + “Avg latency” 두 개의 panel 구
 - URL: http://localhost:3000
 - 로그인: admin / admin
 - Dashboard: “Ray Inference - Quick View”
 
 


3. docker-compose.override.yml
- Docker Compose override로 Prometheus, Grafana, MinIO, Ray Serve를 한 번에 기동.
- services: 아래에 모든 컨테이너 선언
 - Grafana, Prometheus 각각 healthcheck 추가
 - Ray Inference는 GPU 헬스 체크 포함
 
 
services:
  ray-inference:
    healthcheck:
      test: ["CMD", "curl", "-sf", "<http://127.0.0.1:8000/inference/healthz>"]
      interval: 5s
      retries: 20

4. Makefile 자동화 명령
- make up, make infer, make obs-up, make obs-check, make obs-open 등
- 명령어 하나로 헬스체크부터 Grafana까지 자동 실행.
 
 

obs-up:
        docker compose up -d prometheus grafana
        @echo "✅ Prometheus healthy"
        @echo "✅ Grafana healthy"

5. 실행 과정

추론 서비스 빌드 및 확인
make up
docker ps --format "table {{.Names}}\\t{{.Status}}\\t{{.Ports}}"
docker inspect -f '{{.State.Health.Status}}' ray-inference
추론 요청 테스트
curl -s -X POST <http://127.0.0.1:8000/inference/> \\
     -H "Content-Type: application/json" \\
     -d '{"input": [10, 20, 30, 40]}' | jq
메트릭 확인
curl -s <http://127.0.0.1:8000/inference/metrics>
지금 이미지의 Log를 보면 Prometheus의 Target이 "health": "up" 으로 전환됐고,
inference_requests_total 값도 2로 잡힌걸 확인할 수 있습니다!
→ 이건 100% 성공이에요.
요약하자면
| 단계 | 상태 | 설명 | 
| make up / make infer | 성공 | CUDA 인식 + 추론 정상 | 
| Prometheus scrape | 성공 | /inference/metrics 에서 메트릭 긁힘 | 
| Grafana 프로비저닝 | 완료 | 접속만 하면 대시보드 자동 로드됨 (Ray Inference - Quick View) | 
지금 시스템은 “로컬 GPU 추론 → Prometheus → Grafana” 흐름이고
이제 인프라가 안정적으로 작동 중이라는 뜻입니다!
Troubleshooting
| ❌ Health check failed | Makefile에서 /healthz 잘못된 경로 사용 | /inference/healthz 로 수정 | 
| ❌ Prometheus “unknown” | 첫 scrape 이전 상태 | 몇 초 기다리면 자동 “up” | 
| ❌ “additional properties not allowed” | override.yml 구조 틀림 (services: 누락) | 전체 재작성 후 docker compose config 확인 | 
| ❌ Grafana dashboard not loaded | 프로비저닝 path 불일치 | /etc/grafana/dashboards 경로 확인 | 
다음 포스팅은 — ROS2 ↔ Airflow Bridge
ROS 센서 → Airflow FileSensor → Ray Serve 호출
즉, AI Robotics MLOps Bridge 단계로 들어갈 예정입니다. 
해당 단계에서는 아래와 같이 진행됩니다.
- scripts/cam_sim.py (카메라 시뮬레이터) → images/latest.jpg 자동 생성 (sample image..)
 - Airflow DAG(sensor_camera_to_infer.py)에서 FileSensor로 새 이미지를 감지
 - 감지되면 curl을 통해 Ray Inference API 호출
 
Github Link
https://github.com/daeun-ops/hybrid-mlops-demo
GitHub - daeun-ops/hybrid-mlops-demo
Contribute to daeun-ops/hybrid-mlops-demo development by creating an account on GitHub.
github.com
'DevOps' 카테고리의 다른 글
| [MLOps] MinIO 파일 감지 자동화: Airflow S3 센서로 Ray Serve를 실행하는 완벽 가이드 (0) | 2025.10.31 | 
|---|---|
| [MLOps] hybird-mlops-demo 실행 순서 feat. 자꾸 까먹어서 내가보려고 작성한 글 (0) | 2025.10.28 | 
| [MLOps]Ray Serve GPU 자동 감지 + Dockerize + Compose (0) | 2025.10.27 | 
| [MlOps]Observability 맛보기: FastAPI·Ray Log를 Local에서 살펴보기 (0) | 2025.10.26 | 
| [MlOps] Airflow 학습 DAG부터 Ray Serve 추론, Minikube까지 (0) | 2025.10.26 |