L'équipe plateforme d'Evaneos partage son retour d'expérience sur l'intégration de LiteLLM, un proxy unifié supportant 100+ providers IA, dans leur infrastructure Kubernetes gérée en GitOps avec FluxCD.
Le contexte : quand la technologie devient trop « variée »
Evaneos a rencontré un problème classique après avoir expérimenté plusieurs modèles et providers d'IA générative. Nous avions accumulé des clés API qui commençaient à ressembler au trousseau d'un concierge : OpenAI, Anthropic, Gemini, Deepgram.
Cette fragmentation soulevait plusieurs questions critiques :
- Quelle clé appartient à quel projet ?
- Comment suivre les coûts par provider ?
- Comment éviter les points de défaillance uniques ?
- Comment avoir de la visibilité sur les requêtes ?
La solution : LiteLLM, un proxy qui unifie l'accès à 100+ providers IA avec une API unique compatible OpenAI.
La stack : simple mais solide
- Kubernetes (GKE)
- FluxCD pour la gestion GitOps
- Helm pour le packaging
- PostgreSQL pour la configuration et les métriques
- Langfuse pour le tracing et l'observabilité
La mise en place étape par étape
1. Organisation des fichiers
platform/components/helm/litellm/
├── config.yaml
├── helmrelease.yaml
├── helmrepository.yaml
├── kustomization.yaml
├── ns.yaml
└── rbac.yaml
2. Repository Helm
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: litellm
spec:
url: oci://ghcr.io/berriai
interval: 1h
type: oci
3. Configuration HelmRelease
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: litellm
spec:
releaseName: litellm
interval: 60m
driftDetection:
mode: enabled
rollback:
cleanupOnFail: true
values:
pdb:
enabled: true
maxUnavailable: 1
resources:
requests:
cpu: 200m
memory: 1500Mi
limits:
memory: 4Gi
Points clés de cette configuration :
- La détection de dérive (
driftDetection) rattrape les modifications manuelles - Le Pod Disruption Budget garantit la disponibilité lors des mises à jour
- Le rollback automatique en cas d'échec de déploiement
- Ressources : 1,5Gi nominal, jusqu'à 4Gi sous charge
4. PostgreSQL : déploiement externe
Plutôt que d'utiliser la base de données incluse dans la chart, nous avons déployé PostgreSQL séparément, pour une meilleure gestion des sauvegardes, un scaling indépendant, et une intégration de supervision simplifiée.
5. Gestion des secrets
Les clés API et credentials stockés comme Secrets Kubernetes :
- Credentials de base de données
- Clés API des providers
- Clé master du proxy
- Clé de chiffrement (salt)
6. Configuration du proxy
general_settings:
master_key: os.environ/PROXY_MASTER_KEY
salt_key: os.environ/LITELLM_SALT_KEY
litellm_settings:
callbacks: ["langfuse"]
json_logs: true
model_list:
- model_name: "provider/*"
litellm_params:
model: "provider/*"
litellm_credential_name: provider_name
credential_list:
- credential_name: provider_name
credential_values:
api_key: os.environ/PROVIDER_API_KEY
7. Orchestration avec Kustomize
Kustomize génère automatiquement les ConfigMaps depuis les fichiers de configuration, garantissant que toutes les ressources restent versionnées dans Git.
Le workflow quotidien
1. Le développeur commit des changements de config dans Git
↓
2. L'équipe revoit la pull request
↓
3. Merge sur la branche main
↓
4. FluxCD détecte les changements (toutes les heures ou via webhook)
↓
5. Déploiement automatique avec rollback en cas d'échec
Les bénéfices concrets
Clarté : La configuration centralisée remplace les clés API éparpillées dans tous les projets.
Moins de stress : GitOps garantit que l'état de production correspond toujours au dépôt Git ; revenir en arrière sur un changement ne demande qu'un git revert.
Visibilité : L'intégration Langfuse donne accès aux coûts par modèle, aux patterns d'utilisation, aux métriques de latence et à l'efficacité des prompts.
Flexibilité : Tester un modèle alternatif ne nécessite que de modifier quelques lignes YAML et ouvrir une pull request.
Sécurité : Authentification, chiffrement et contrôles d'accès via les mécanismes natifs Kubernetes.
Leçons apprises
Mémoire : 512Mi initial s'est révélé insuffisant. LiteLLM peut rapidement consommer de la mémoire, surtout si vous loggez les prompts. Recommandation : minimum 1,5Gi avec une limite à 4Gi.
Jobs de migration et PodDisruptionBudget : Définir ttlSecondsAfterFinished sur les jobs de migration de base de données évite qu'un job terminé ne soit comptabilisé comme pod actif et ne bloque la configuration HA.
Préférence pour une base externe : Une instance PostgreSQL autonome offre une meilleure stabilité, gestion des sauvegardes, et évite les mauvaises surprises par rapport aux solutions embarquées.
Gestion des credentials : Le système de nommage des credentials LiteLLM permet le pattern « définir une fois, référencer partout », en accord avec le principe DRY.
Conclusion
La mise en place ressemble à l'installation d'une bonne plomberie : une fois que c'est fait, on n'y pense plus et ça fonctionne. Tout est versionné et déployé automatiquement, ce qui permet de se concentrer sur les vrais cas d'usage plutôt que sur la maintenance de l'infrastructure.