LiteLLM Kubernetes: Despliegue Producción
Tabla de contenidos
Parte 2 de 4. En la Parte 1 vimos la arquitectura y los prerrequisitos. Aquí desplegamos LiteLLM paso a paso. Continúa a Parte 3: Configuración de Herramientas y Proveedores.
LiteLLM es un proxy de IA open-source que expone una única API compatible con OpenAI para más de 100 proveedores. Gestiona autenticación, traducción de requests y ruteo para que tus aplicaciones solo necesiten conocer un endpoint. Si eres nuevo en LiteLLM, consulta la guía desplegar-ollama-kubernetes para más contexto.
Paso 1: Preparar la Configuración de LiteLLM
LiteLLM utiliza un archivo proxy_config.yaml para definir qué modelos sirve y cómo alcanzar cada proveedor. Yo almaceno este archivo en mi NAS, montado en /k3s_storage/ en cada nodo de Kubernetes. Así la configuración persiste y sigue accesible aunque los pods se reciclen. Para un homelab los volúmenes HostPath funcionan bien. En producción necesitarás un PersistentVolume con acceso ReadWriteMany.
Crea este archivo en tu nodo de K8s en /k3s_storage/litellm/proxy_config.yaml:
model_list: - model_name: kimi-code litellm_params: model: openai/kimi-for-coding api_base: "https://api.kimi.com/coding/v1" api_key: "os.environ/KIMI_API_KEY" headers: User-Agent: "claude-code/0.1.0" X-Kimi-Client: "Kimi-Code"
- model_name: openrouter-free litellm_params: model: openai/openrouter/free api_key: "os.environ/OPENROUTER_API_KEY" api_base: "https://openrouter.ai/api/v1" headers: HTTP-Referer: "https://tu-dominio.com" X-Title: "LiteLLM-Automation"
- model_name: openrouter-free-trending litellm_params: model: openrouter/* api_key: "os.environ/OPENROUTER_API_KEY" api_base: "https://openrouter.ai/api/v1" headers: HTTP-Referer: "https://tu-dominio.com" X-Title: "LiteLLM-Automation"
- model_name: nvidia-llama litellm_params: model: nvidia_nim/meta/llama-4-maverick-17b-128e-instruct api_key: "os.environ/NVIDIA_NIM_API_KEY"Importante: Reemplaza
https://tu-dominio.comcon tu dominio real o URL de perfil de GitHub. OpenRouter lo usa para ranking y atribución.
Asegúrate de que el directorio litellm existe en tu nodo antes de empezar: mkdir -p /k3s_storage/litellm. Si falta el directorio, el pod se quedará atascado en estado Pending porque Kubernetes no puede montar un volumen HostPath inexistente.
Por Qué Estos Headers Importan
La configuración de Kimi Code exige dos headers personalizados. Sin ellos, te topas con errores de autenticación o compatibilidad incluso con una API key válida, un clásico “conocimiento tribal” que no encontrarás en la documentación.
User-Agent: "claude-code/0.1.0": La API de Kimi requiere este string exacto para aceptar la conexión. Es un shim de compatibilidad que indica al backend de Kimi que procese la request como si viniera de un cliente conocido.X-Kimi-Client: "Kimi-Code": Identifica el tipo de cliente para el ruteo interno en la infraestructura de Kimi. Omítelo y perseguirás errores de autenticación vagos por un laberinto de debugging.
Para OpenRouter, el header HTTP-Referer es obligatorio para su sistema de ranking y atribución. Sin él, las requests devuelven un 400 Bad Request al instante.
Paso 2: Crear Kubernetes Secrets para las API Keys
Nunca incrustes API keys directamente en los manifiestos. Almacena las credenciales de tus proveedores y la master key en Kubernetes Secrets. Esto mantiene los valores sensibles cifrados en reposo y desacoplados de tu YAML de despliegue:
kubectl create secret generic litellm-provider-keys \ --namespace litellm \ --from-literal=KIMI_API_KEY='sk-tu-kimi-key' \ --from-literal=OPENROUTER_API_KEY='sk-or-v1-tu-openrouter-key' \ --from-literal=NVIDIA_NIM_API_KEY='nvapi-tu-nvidia-key' \ --from-literal=LITELLM_MASTER_KEY='sk-tu-master-key'Asegúrate de que el namespace litellm exista primero. Créalo con kubectl create namespace litellm si es necesario. Luego referenciarás estos secrets en el Deployment usando secretKeyRef en lugar de valores hardcodeados.
Paso 3: Desplegar LiteLLM en Kubernetes
Aplica este manifiesto para desplegar LiteLLM en el namespace litellm:
apiVersion: apps/v1kind: Deploymentmetadata: name: litellm-deployment namespace: litellmspec: replicas: 1 selector: matchLabels: app: litellm template: metadata: labels: app: litellm spec: containers: - name: litellm-container image: ghcr.io/berriai/litellm:main-latest imagePullPolicy: Always env: - name: DATABASE_URL value: "postgresql://litellm:<PASSWORD>@<POSTGRES_HOST>:<PORT>/litellm" - name: STORE_MODEL_IN_DB value: "True" - name: LITELLM_MASTER_KEY valueFrom: secretKeyRef: name: litellm-provider-keys key: LITELLM_MASTER_KEY - name: KIMI_API_KEY valueFrom: secretKeyRef: name: litellm-provider-keys key: KIMI_API_KEY - name: OPENROUTER_API_KEY valueFrom: secretKeyRef: name: litellm-provider-keys key: OPENROUTER_API_KEY - name: NVIDIA_NIM_API_KEY valueFrom: secretKeyRef: name: litellm-provider-keys key: NVIDIA_NIM_API_KEY args: - "--config" - "/k3s_storage/litellm/proxy_config.yaml" - "--port" - "4000" ports: - containerPort: 4000 volumeMounts: - name: physical-storage mountPath: /k3s_storage/litellm livenessProbe: httpGet: path: /health/liveliness port: 4000 initialDelaySeconds: 40 periodSeconds: 15 volumes: - name: physical-storage hostPath: path: /k3s_storage/litellm type: Directory---apiVersion: v1kind: Servicemetadata: name: litellm-service namespace: litellmspec: type: NodePort selector: app: litellm ports: - protocol: TCP port: 4000 targetPort: 4000 nodePort: 30080Despliégalo:
kubectl apply -f litellm-deployment.yamlVerifica que el pod esté corriendo:
kubectl get pods -n litellm -l app=litellm# NAME READY STATUS RESTARTS AGE# litellm-deployment-7c9f4b8d5-x2k9m 1/1 Running 0 45sLa Base de Datos Postgres
LiteLLM necesita Postgres para gestión de usuarios, rate limiting y logging de requests. No es opcional. Saltearla significa que funciones como spend tracking, control de acceso por key y soporte multi-usuario dejarán de operar. Yo ejecuto Postgres en un NAS separado para desacoplarlo del ciclo de vida del cluster, lo que permite mantener la base de datos sin afectar el gateway. Apunta LiteLLM a <TU_IP_POSTGRES>:<TU_PUERTO_POSTGRES> mediante la variable DATABASE_URL. Sin una conexión válida a Postgres, LiteLLM arranca pero las funciones críticas permanecen rotas.
Si no tienes Postgres, despliégalo rápidamente para testing:
kubectl create deployment postgres \ --image=postgres:16-alpine \ --namespace litellm
kubectl set env deployment postgres \ POSTGRES_USER=litellm \ POSTGRES_PASSWORD=tu-password-segura \ POSTGRES_DB=litellm \ --namespace litellm
kubectl expose deployment postgres \ --port=5432 \ --namespace litellmTip de producción: Usa una instancia de Postgres gestionada o volúmenes persistentes con backups sólidos. El despliegue efímero de arriba pierde todos los datos en cuanto el pod se reinicia. Para la guía completa de fortalecimiento, consulta la Parte 4.
Preguntas Frecuentes
¿Necesito Postgres para LiteLLM?
Sí. Postgres es necesario para rate limiting, spend tracking y soporte multi-usuario. LiteLLM arranca sin él pero las funciones críticas no operan.
¿Puedo actualizar la config sin redeploy?
Actualiza proxy_config.yaml en el HostPath y reinicia: kubectl rollout restart deployment/litellm-deployment -n litellm.
¿Cómo añado un nuevo proveedor?
Añade una entrada a model_list en proxy_config.yaml, almacena la API key como Kubernetes Secret y referénciala con secretKeyRef.
¿Qué hago si el pod se queda en Pending?
Verifica que el directorio HostPath existe: mkdir -p /k3s_storage/litellm. Kubernetes no puede montar un path inexistente.
Tu proxy LiteLLM ya está corriendo en Kubernetes. Continúa a Parte 3: Configuración de Herramientas y Proveedores para conectar tus agentes de código.
Si te gustó esta guía, conoce al ingeniero detrás de estos builds.