DevOps

GenAI on K8s/EKS 인퍼런스 최적화 (2)

frontheadlock 2026. 8. 4. 22:35
반응형

지난 글에서는 EKS 위에 배포된 개별 모델들과 직접 상호작용해보았습니다.

이어서, 개별 컴포넌트들이 어떻게 하나의 플랫폼으로 통합되는지 정리해보겠습니다.

 

이번에는 LiteLLM을 통합 API 게이트웨이로,
Langfuse를 관측성 플랫폼으로 연결해,
Agentic AI 어플리케이션을 지탱하는 인프라를 완성합니다.

 

오늘은 LiteLLM을 중점적으로 다루고, Langfuse는 다음 글에서 이어가겠습니다.

 

아키텍처

 

아키텍처

 

Open WebUI의 모든 요청은 API Gateway Layer의 LiteLLM을 지나,
vLLM 또는 AWS Bedrock으로 라우팅됩니다.

 

이 과정에서 발생하는 모든 Trace가 Langfuse로 흘러가고,
Langfuse는 이를 PostgreSQL, ClickHouse, Redis에 저장합니다.

이러한 아키텍처는 Helm 차트를 사용하여 실제 배포 패턴에 중점을 둡니다.

 

  • 동적 구성: Helm 템플릿이 유연한 배포를 가능하게 하는 방법
  • 자동 통합: 컴포넌트가 서로를 발견하고 연결하는 방법
  • 확장 가능한 패턴: 리소스 관리, Ingress 및 보안 이해
  • 실습: 새 모델 추가와 관측성 기능 탐색

 

LiteLLM

 

LiteLLM이란?

LiteLLM은 다음을 제공하는 오픈소스 프록시

  • 통합 API: 모든 모델을 위한 단일 OpenAI 호환 엔드포인트
  • 스마트 라우팅: 적절한 백엔드로 요청을 자동으로 라우팅
  • 영구 스토리지: 구성을 위한 PostgreSQL, 캐싱을 위한 Redis
  • 로드 밸런싱: 여러 모델 레플리카 간에 요청 분산

    출처: AWS Workshop

 

LiteLLM 스택 구성

 

LiteLLM은 단일 Pod가 아니라, 세 개의 컴포넌트로 구성된 스택입니다.

  • LiteLLM Pod: 모든 모델 요청을 라우팅하는 API 게이트웨이 본체
  • PostgreSQL: 모델 구성, 사용 데이터, Virtual Key 등 저장
  • Redis: 응답 캐싱을 통한 응답 시간 개선

지난 글에서 kubectl get svc로 확인했던 litellm 네임스페이스의
litellm, litellm-postgresql, litellm-redis 서비스가 바로 이 구성입니다.

 

모델 구성 확인

 

먼저 실행 중인 vLLM 모델을 확인하고,
LiteLLM이 이 모델들을 어떻게 바라보는지 구성 파일에서 살펴봅니다.

 

# 실행 중인 vLLM 모델 확인
kubectl get pods -n vllm -l app

# LiteLLM의 모델 구성 확인
grep -A 16 "model_list:" /workshop/components/ai-gateway/litellm/values.rendered.yaml

 

# LiteLLM
model_list:
  # Bedrock 모델 (AWS 구성에서)
  - model_name: bedrock/claude-4.5-sonnet
    litellm_params:
      model: bedrock/global.anthropic.claude-sonnet-4-5-20250929-v1:0
      aws_region_name: us-west-2

  # vLLM 모델 (실행 중인 Pod에서 자동 발견)
  - model_name: vllm/qwen3-8b-neuron
    litellm_params:
      model: openai/qwen3-8b-neuron
      api_key: fake-key
      api_base: http://qwen3-8b-neuron.vllm:8000/v1
  - model_name: vllm/deepseek-r1-qwen3-8b-neuron
    litellm_params:
      model: openai/deepseek-r1-qwen3-8b-neuron
      api_key: fake-key
      api_base: http://deepseek-r1-qwen3-8b-neuron.vllm:8000/v1
  • api_base: vLLM Service의 클러스터 내부 DNS를 그대로 사용
  • api_key: fake-key: vLLM 엔드포인트에는 별도 인증이 없어 Mock 사용
  • model: openai/...: vLLM이 OpenAI 호환 API를 제공

 

모델 자동 발견

이러한 구성 파일은 직접 작성하지 않고,
배포 시점에 실행 중인 모델을 스캔해 자동으로 렌더링됩니다.

 

# 통합 발견 로직 확인
grep -A 15 "integration.*llm-model" /workshop/components/ai-gateway/litellm/index.mjs

 

// LiteLLM의 모델 발견 프로세스
for (const model of value.models) {
  if (model.deploy) {
    // 모델 Pod가 실제로 실행 중인지 확인
    const result = await kubectl get pod -n ${namespace} -l app=${model.name}
    if (result.stdout.includes(model.name)) {
      // 모델을 찾아 통합에 추가
      integration["llm-model"][namespace][model.name] = true;
    }
  }
}

 

프로세스를 정리하면 다음과 같습니다.

  1. 스캔: 실행 중인 모델 Pod를 Kubernetes에서 탐색
  2. 검증: 각 모델이 정상적으로 사용 가능한지 확인
  3. 빌드: 발견된 모델로 통합 객체 생성
  4. 렌더링: 사용 가능한 모델만으로 Helm 템플릿 렌더링
  5. 배포: 해당 모델 구성으로 LiteLLM 배포

이 덕분에 LiteLLM은 실제로 실행 중인 모델만 바라보도록 구성되어,
고아 모델이 model_list에 남아 라우팅을 혼잡스러게 하지 않습니다.

 

LiteLLM 배포

 

배포에는 커스텀 values 템플릿과 공식 LiteLLM Helm Chart를 사용합니다.

# 렌더링된 values로 공식 차트 배포
helm upgrade --install litellm oci://ghcr.io/berriai/litellm-helm \
  --namespace litellm \
  --create-namespace \
  -f /workshop/components/ai-gateway/litellm/values.rendered.yaml

 

 

동작 시퀀스

 

배포된 LiteLLM의 요청 처리 흐름은 다음과 같습니다.

 

 

  1. 사용자가 모델을 선택하고 메시지를 전송
  2. Open WebUI가 LiteLLM에 POST /v1/chat/completions 호출
  3. 선택된 모델에 따라 vLLM 엔드포인트 또는 Bedrock API로 분기
  4. 어느 쪽이든 동일한 응답 형식(Unified response format) 으로 반환

백엔드가 무엇이든 응답 형식이 같기에,
클라이언트는 모델이 어디서 서빙되는지 전혀 신경 쓸 필요가 없습니다.

 

LiteLLM 웹 인터페이스 탐색

 

이제 LiteLLM 관리 인터페이스에서 모델과 지표를 확인하고, API를 테스트해보겠습니다.

 

1. LiteLLM 접속

 

 

echo "LiteLLM URL: http://$(kubectl get ingress -n litellm litellm -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')"

 

 

ALB 주소로 접속하면 먼저 Swagger 기반의 API 문서가 나타납니다.

"Proxy Server to call 100+ LLMs in the OpenAI format"라는 소개 문구처럼,
모델 관리부터 채팅까지 모든 기능이 OpenAI 형식의 REST API로 노출되어 있습니다.

상단 링크는 각각의 페이지로 이동시켜 다양한 대시보드를 제공합니다.

  • /ui: 관리 패널 (Admin Panel)
  • LiteLLM Model Cost Map: 모델별 비용 단가표
  • Model Hub: 사용 가능한 모델 확인

 

2. 모델 대시보드

 

관리 패널의 Models + Endpoints 메뉴로 이동하면, 구성된 모델을 확인할 수 있습니다.

 

 

  • Show results: values.rendered.yaml의 model_list와 동일한 3개 모델이 등록
  • LiteLLM이 OpenAI 호환 API를 통해 제공하기에 Provier가 openai
  • Costs 열은 bedrock/claude-4.5-sonnet에만 할당

 

3. 사용량 및 비용 모니터링

 

Usage 탭에서는 게이트웨이를 지나간 모든 요청의 지표를 볼 수 있습니다.

 

 

  • Total Requests 18 / Successful 17 / Failed 1: 실패한 요청까지 그대로 집계
  • Total Tokens 19,701: 워크샵 기간 사용한 토큰 총량
  • Total Spend $0.0008: 단가가 등록된 Bedrock 호출분만 계산된 금액

지난 글의 대화들이 전부 이 지표에 쌓여 있습니다.

 

4. Playground에서 모델 테스트

 

Playground에서는 대화형 인터페이스로 모델 응답을 바로 테스트할 수 있습니다.

 

 

TTFT 1.86s, Total Latency 10.73s, In 22 / Out 696 토큰
요청 단위의 성능 지표가 함께 표시되어, 모델별 응답 성능을 비교하기에 좋습니다.

 

Bedrock 모델 추가

 

이제 게이트웨이의 편리함은 이제 시작입니다.
어플리케이션 코드 변경 없이, 구성 변경만으로 새 모델을 추가해보겠습니다.

 

# 액세스 권한이 있는 Bedrock 모델 확인
aws bedrock list-foundation-models \
  --query "modelSummaries[?contains(modelId, 'gpt-oss')].{ModelId:modelId,ModelName:modelName}" \
  --output table

 

# 구성 파일에 모델 추가 (components/ai-gateway/litellm/values.rendered.yaml)
model_list:
  - model_name: bedrock/gpt-oss-20b
    litellm_params:
      model: bedrock/openai.gpt-oss-20b-1:0
      aws_region_name: us-west-2

 

# 업데이트된 구성 적용
helm upgrade litellm oci://ghcr.io/berriai/litellm-helm \
  --namespace litellm \
  -f /workshop/components/ai-gateway/litellm/values.rendered.yaml

# 배포 완료 대기
kubectl rollout status deployment/litellm -n litellm

 

돌아가면, bedrock/gpt-oss-20b가 드롭다운에 새로 등록되어 있습니다.

 

 

바로 "오늘 저녁 메뉴 추천 해줘"라고 물어보니,
4초 동안 생각한 뒤 한식 메뉴와 디저트를 표로 정리해줍니다.
(밥 줘)

 

여기서 중요한 점은, Open WebUI를 한 번도 건드리지 않았다는 것입니다.
values 수정과 helm upgrade로, 서비스 중단 없이 스택 전체에 전파되었습니다.

 

Virtual Key 생성

 

이후 모듈에서 만들 에이전트가 모델들에 접근하려면 전용 API 키가 필요합니다.
LiteLLM은 이를 Virtual Key로 해결합니다.

 

Virtual Key란?

LiteLLM 프록시가 발급하고 관리하는 가상 API 키.
AWS 자격 증명 같은 실제 제공자 키를 노출하지 않으면서,
키 단위로 접근 가능한 모델, 예산, 속도 제한, 사용량 추적을 관리할 수 있습니다.

출처: LiteLLM Docs

 

관리 패널의 Virtual Keys 메뉴에 처음 들어가면 키가 하나도 없습니다.

 

 

+ Create New Key를 누르면 키 생성 폼이 나타납니다.

 

 

  • Owned By: You (기본값)
  • Team: 선택하지 않음 (선택 사항)
  • Key Name: agent-key
  • Models: 사용 가능한 모든 모델 선택
    • bedrock/claude-4.5-sonnet
    • bedrock/gpt-oss-20b
    • vllm/qwen3-8b-neuron
    • vllm/deepseek-r1-qwen3-8b-neuron
  • Key Type: Default

Create Key를 클릭하면 sk-로 시작하는 키가 발급됩니다.

키 전문은 이 화면에서 단 한 번만 표시되므로, 복사해서 안전한 곳에 보관합니다.

 

Key 동작 검증

 

발급받은 키가 실제로 동작하는지 Playground에서 검증합니다.

 

 

Virtual Key Source를 Current UI에서 Virtual Key로 변경하고,
발급받은 키를 붙여넣은 뒤 테스트 메시지를 보냅니다.

이후, 모델(claude-4.5-sonnet)이 정상적으로 응답하는 것을 확인할 수 있습니다.

이 키는 이후 모듈에서 LangGraph 에이전트가 모델에 접근할 때 그대로 사용됩니다.

 

마무리

 

이번 실습을 통해 통합 AI 게이트웨이가 주는 이점을 직접 확인할 수 있었습니다.

  • 원활한 모델 전환: 애플리케이션 변경 없이 모든 모델 간 전환
  • 자동 발견: 실행 중인 모델만 스캔해 구성에 반영
  • 무중단 모델 추가: values 수정과 helm upgrade만으로 새 모델 전파
  • 내장 관측성: 요청, 토큰, 비용이 게이트웨이 한 곳에 집계
  • 접근 제어: Virtual Key로 모델 접근과 사용량을 키 단위로 관리

모델 종류에 상관없이, 클라이언트 입장에서는 전부 같은 OpenAI 호환 API입니다.
덕분에 모델 추가, 비용 집계, 키 관리가 전부 LiteLLM 한 곳에서 해결됩니다.

 

다음 글에서는 이 게이트웨이를 지나간 모든 상호작용을 추적하는
관측성 플랫폼, Langfuse를 살펴보겠습니다.

반응형