Rag-llm 서빙 관련

“쿠버네티스 1.29 + 가상 GPU 파티셔닝(MIG) 환경에서 vLLM-기반 LLM 서빙(8× H100 GPU/노드)과 REST API 게이트웨이(NGINX Ingress Controller → FastAPI), 그리고 프롬메테우스-그라파나-로키 스택을 한 클러스터 안에 올려 ‘실시간 대화형 RAG 서비스’를 운영하려 합니다.

  1. HorizontalPodAutoscaler(HPA)로 qps ≥ 150일 때 LLM Replica를 동적으로 늘리면서도, GPU 메모리 단편화나 MIG 슬롯 불일치 때문에 nvidia.com/gpu 요청이 충족되지 않아 Pending → CrashLoopBackOff가 잦아지고, 2) Karpenter로 노드 자동-프로비저닝을 켜 두면 GPU 스팟 인스턴스가 예고 없이 회수되어 동접이 급락하며 503이 발생합니다. 또한 3) loki-canary 로그 무결성 지표가 간헐적으로 붉게 변하고, 4) k6 부하테스트(2 분간 3 → 200 VU 스텝)에서 P99 응답 시간이 6 초를 넘으면 Ingress NLB가 자동으로 Health Check Fail로 인스턴스를 제외해 가용성이 추가로 나빠집니다.

이 상황에서

  • (a) ResourceClaimTemplatesGPU Shared Device Plugin 조합으로 MIG 슬롯-레벨 할당을 보장하면서 HPA가 정상적으로 스케일-업/다운하도록 만드는 가장 안전한 매니페스트 구조,
  • (b) karpenter.sh/do-not-disrupt=critical 라벨과 ttlSecondsAfterEmpty 및 우선순위-가중치(spot < ondemand) 설정을 통해 스팟 회수 시 장애를 최소화하는 구체적 노드 플릿 전략,
  • (c) prometheus-operator-based Alertmanager 규칙으로 P99 latency > 4 s & loki-canary failures > 3 in 5 min 조건이 동시에 발생할 때만 슬랙·팀즈 알람을 묶어서 보내는 다단계 알림 흐름,
  • (d) Gateway API + HTTPRoute로 전환해 Ingress NLB HC를 --proxy-timeout=10s로 늘리되, 다운스트림 FastAPI에 uvicorn --timeout-keep-alive 15를 함께 맞춰 P99 지연을 흡수하는 엔드-투-엔드 튜닝 절차,

단계별 실험-검증하려면 어떤 순서로 매니페스트(Deployment, Provisioner, HPA, PromRule 등)를 수정하고 kubectl-capture-logs, promql, k6 thresholds, loki-tolerations 출력을 어떤 지표로 모니터링·해석하는 것이 좋을까요?”

[CloudBro AI Bot Response]
아주 훌륭하고 현실적인 질문입니다. 아래는 각 요구사항별 단계적 실험·검증 전략과 매니페스트/지표 관리 방안을 정리한 답변입니다.


(1) 실험 및 매니페스트 변경 순서

  1. GPU 리소스 할당(MIG 슬롯 단위) 검증
    • ResourceClaimTemplates와 GPU Shared Device Plugin을 먼저 적용합니다.
    • vLLM Deployment에 resources.requests/limits에 MIG 단위(nvidia.com/mig-...)로 명확히 지정.
    • HPA가 스케일 시 Pending/CrashLoopBackOff 발생률을 kubectl get pods -wkubectl-capture-logs로 모니터링.
    • MIG 슬롯 할당 불일치 시 이벤트 로그(kubectl describe pod)에서 “Insufficient nvidia.com/gpu” 메시지를 확인.
  2. 노드 플릿(Karpenter) 안정성 강화
    • karpenter.sh/do-not-disrupt=critical 라벨, ttlSecondsAfterEmpty, 우선순위 가중치(capacityType: spot/ondemand에 weight 적용) 추가.
    • 노드 그룹별로 Spot/OnDemand 비율을 다르게 설정하고, Spot 회수시 Graceful Drain이 되는지 kubectl get node -w로 확인.
    • Spot 노드 회수 이벤트와 HPA/Deployment Replica 변화, 503 오류 건수를 promql(e.g. sum(rate(http_requests_total{status="503"}[1m])))로 실시간 추적.
  3. 알림/모니터링(다단계 Alertmanager)
    • prometheus-operator에서 P99 latency(histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le)) > 4)와
    • Loki Canary 실패(sum(increase(loki_canary_failures_total[5m])) > 3)를 AND 조건으로 묶은 PrometheusRule 작성.
    • Alertmanager에서 Slack/Teams 알림을 Route의 group_by로 묶어, 동시에 조건 만족시만 알람이 발송되는지 검증.
  4. Ingress NLB/HTTPRoute 및 FastAPI 튜닝
    • 기존 Ingress Controller에서 Gateway API + HTTPRoute로 전환, NLB HC 옵션을 --proxy-timeout=10s로 확장.
    • FastAPI(Uvicorn)에 --timeout-keep-alive 15 적용, P99 latency 변화와 NLB Health Check Fail 이벤트(CloudWatch/K8s event) 동시 모니터링.
    • k6로 3→200 VU 부하테스트를 재실행하며, P99 응답시간(6초→4초 이내)과 NLB 인스턴스 제외율 감소 여부 확인.

(2) 실험 단계별 지표/로그 모니터링 방법

  • Pod 상태: kubectl get pods -w, kubectl describe pod, kubectl-capture-logs로 Pending/CrashLoopBackOff 원인 추적
  • GPU 할당: nvidia-smi, kubectl describe node, Device Plugin 로그로 MIG 슬롯 할당 현황 확인
  • HPA/Replica 변화: kubectl get hpa, kubectl describe hpa, Prometheus kube_deployment_status_replicas_available
  • 노드 이벤트: kubectl get node, karpenter 컨트롤러 로그, Spot 회수 이벤트(CloudWatch Events)
  • HTTP 지연/오류: Prometheus histogram_quantile, http_requests_total{status="503"}, k6 thresholds(P99 latency)
  • Loki Canary: loki-canary 로그, Prometheus increase(loki_canary_failures_total[5m])
  • NLB Health Check: AWS Console, CloudWatch Logs, K8s Ingress events, FastAPI 로그
  • Alertmanager: 알람 발생 시점과 조건, Slack/Teams 메시지 수신 여부

(3) 실험 순서 요약

  1. MIG 슬롯 할당 → HPA 동작: 리소스 매칭/스케일링 정상화
  2. Karpenter 노드 전략 적용: Spot 회수 내성, 온디맨드 자동 전환
  3. Alertmanager 다단계 알림: P99+Loki Canary 조합 알림 검증
  4. Gateway API+FastAPI 튜닝: NLB HC Fail 감소, P99 지연 흡수

(4) 참고 링크


정리:
각 실험 단계에서 매니페스트(Deployment, Provisioner, HPA, PromRule 등)을 한 번에 바꾸지 말고, 한 단계씩 적용→관찰→지표/로그 분석→문제 발생시 롤백/수정→다음 단계로 진행하는 것이 안정적입니다. 특히 GPU/MIG 할당과 노드 스케줄링, 알림 조건, 엔드-투-엔드 지연 튜닝은 반드시 실시간 모니터링과 로그 캡처를 병행해야 문제 원인을 빠르게 파악할 수 있습니다.

추가적인 YAML 예시나 PromQL 쿼리, k6 스크립트 등이 필요하면 언제든 말씀해 주세요!