## Introduction

Kubernetes Dynamic Resource Allocation (DRA) est le mécanisme flexible de planification et d'allocation introduit comme alternative à l'API traditionnelle des plugins de périphériques. DRA permet aux charges de travail de demander du matériel spécialisé tel que des GPU, des FPGA ou des adaptateurs réseau avec des configurations plus dynamiques et spécifiques aux pods. À mesure que Kubernetes évolue, la mise à niveau de DRA et la migration entre versions présentent des défis opérationnels : les changements d'API, les évolutions des feature gates et les problèmes de compatibilité des contrôleurs peuvent perturber les charges de travail en cours d'exécution.

Ce guide s'adresse aux ingénieurs de plateforme, aux consultants DevOps et aux équipes techniques de startups gérant des clusters Kubernetes qui utilisent DRA. Il présente un chemin de mise à niveau sûr et observable, un modèle de migration pour les charges de travail existantes, la gestion des feature gates spécifiques à chaque version, des commandes de validation et des procédures de restauration. L'accent est mis sur la sécurité opérationnelle : observer avant de modifier, limiter le rayon d'impact, protéger les données sensibles, vérifier les résultats et documenter la récupération avant qu'un incident ne force une décision.

## Inventaire des versions et de l'environnement

Avant toute mise à niveau, vous devez savoir exactement ce que vous exécutez. Commencez par vérifier la version du plan de contrôle Kubernetes et l'état du feature gate pour DRA.

### Vérifier la version de Kubernetes et les feature gates

Exécutez :

```bash
kubectl version --short
kubectl get --raw /metrics | grep kubernetes_feature_enabled | grep DynamicResourceAllocation
```

Sortie attendue (exemple pour Kubernetes 1.27 avec DRA alpha) :

```text
Client Version: v1.27.3
Server Version: v1.27.3
kubernetes_feature_enabled{name="DynamicResourceAllocation",stage="Alpha"} 1
```

Si la métrique indique 0, DRA est désactivé. Vous devez l'activer via les drapeaux de feature gate du kube-apiserver, du kube-controller-manager et du kube-scheduler :

```yaml
--feature-gates=DynamicResourceAllocation=true
```

Pour Kubernetes 1.26, DRA est en alpha ; à partir de 1.27, il reste en alpha mais avec une structure d'API améliorée. Testez toujours avec la version exacte vers laquelle vous prévoyez de migrer. Consultez les notes de version de Kubernetes pour connaître les changements de stade précis.

### Inventorier les ressources DRA existantes

Listez toutes les ResourceClaims et ResourceClasses :

```bash
kubectl get resourceclaims --all-namespaces
kubectl get resourceclasses
```

Exemple de sortie :

```text
NAMESPACE   NAME           CLASS          STATE
ml-team     gpu-claim-1    gpu-class      allocated
ml-team     gpu-claim-2    gpu-class      pending

NAME        DRIVER          AGE
gpu-class   nvidia.com/gpu   3d
```

Notez le champ DRIVER : il doit correspondre à un pilote DRA enregistré dans votre cluster. Si vous utilisez le pilote d'exemple du dépôt Kubernetes, il s'agit de `dra.example.com`. Les pilotes de production diffèrent.

### Vérifier les nœuds et les pilotes

Listez les nœuds avec le label ou l'annotation `dra.example.com/driver`. Pour le pilote de référence, les nœuds sont étiquetés automatiquement :

```bash
kubectl get nodes -l dra.example.com/driver
```

Si aucun nœud n'apparaît, le pilote n'est pas déployé ou ne fonctionne pas. Vérifiez les pods du pilote :

```bash
kubectl get pods -n kube-system -l app=dra-example-driver
```

Si les pods sont en CrashLoopBackOff, inspectez les journaux :

```bash
kubectl logs -n kube-system <nom-du-pod-pilote> --previous
```

Cet inventaire établit une base de référence. Enregistrez-le avec des horodatages. Ne modifiez jamais rien avant de comprendre l'état actuel.

## Chemin de configuration sûr

Le chemin de mise à niveau pour DRA dépend de si vous mettez à niveau Kubernetes lui-même ou seulement le pilote DRA. DRA est une API dans Kubernetes, mais les pilotes sont des composants externes qui peuvent avoir leur propre versionnage.

### Étape 1 : Mettre à niveau le pilote DRA séparément de Kubernetes

Si vous avez seulement besoin d'une nouvelle version du pilote, appliquez les nouveaux manifestes du pilote tout en maintenant Kubernetes stable. Par exemple, le pilote DRA de référence (appelé « sample-driver » ou « pilote d'exemple ») est déployé via un DaemonSet. Mettez-le à niveau avec une mise à jour progressive :

```bash
kubectl set image daemonset/dra-example-driver -n kube-system dra-example-driver=registry.k8s.io/dra-example-driver:v0.2.0
kubectl rollout status daemonset/dra-example-driver -n kube-system
```

Sortie attendue :

```text
daemonset "dra-example-driver" successfully rolled out
```

Si le déploiement se bloque, vérifiez l'état des pods :

```bash
kubectl get pods -n kube-system -l app=dra-example-driver -o wide
```

Recherchez les erreurs ImagePullBackOff, CrashLoopBackOff ou des problèmes de planification sur les nœuds.

### Étape 2 : Mettre à niveau la version de Kubernetes (changements d'API DRA)

Lors de la mise à niveau de Kubernetes lui-même, vous devez être conscient des changements de version de l'API DRA. Par exemple :

- Kubernetes 1.26 : `resource.k8s.io/v1alpha1`
- Kubernetes 1.27 : `resource.k8s.io/v1alpha1` (changements mineurs)
- Kubernetes 1.28 : toujours `v1alpha1` mais avec de nombreuses mises à jour ; les anciens manifestes peuvent ne pas fonctionner.

Consultez toujours le guide de dépréciation des API pour votre version. Testez vos manifestes ResourceClaim et ResourceClass existants contre le nouveau serveur d'API en utilisant `kubectl apply --dry-run=server`.

Exemple :

```bash
kubectl apply --dry-run=server -f resourceclaim.yaml
```

Si vous voyez une erreur comme :

```text
error: resource mapping not found for name: "gpu-claim-1" namespace: "ml-team" from "resourceclaim.yaml": no matches for kind "ResourceClaim" in version "resource.k8s.io/v1alpha1"
```

alors la version de l'API n'est pas servie. Vous devrez peut-être mettre à jour le manifeste vers la nouvelle version ou activer le feature gate.

### Étape 3 : Migrer les charges de travail du plugin de périphériques vers DRA

Si vous migrez des pods qui utilisaient auparavant des ressources de plugin de périphériques (par exemple, `nvidia.com/gpu: 1`) vers DRA, vous devez modifier la spécification du pod. Au lieu de demander `nvidia.com/gpu: 1`, vous référencez une ResourceClaim. Créez une ResourceClaim :

```yaml
apiVersion: resource.k8s.io/v1alpha1
kind: ResourceClaim
metadata:
  name: my-gpu
  namespace: ml-team
spec:
  resourceClassName: gpu-class
  parameters:
    apiVersion: gpu.example.com/v1alpha1
    kind: GpuParameters
    spec:
      count: 1
      memory: 16Gi
```

Ensuite, mettez à jour le pod :

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: training-job
  namespace: ml-team
spec:
  containers:
  - name: trainer
    image: pytorch/pytorch:latest
    resources:
      claims:
      - name: gpu
  resourceClaims:
  - name: gpu
    source:
      resourceClaimName: my-gpu
```

Appliquez les deux dans l'ordre :

```bash
kubectl apply -f resourceclaim.yaml
kubectl apply -f pod.yaml
```

Surveillez la planification :

```bash
kubectl describe pod training-job -n ml-team
```

Vérifiez les événements pour des erreurs comme « resource claim not allocated » ou « driver not found ».

### Étape 4 : Migration progressive avec des pods canaris

Ne migrez pas tous les pods en une seule fois. Utilisez des labels et des sélecteurs pour migrer un sous-ensemble :

```bash
kubectl label pods -l app=training canary=true
```

Créez ensuite un déploiement dupliqué avec des ResourceClaims DRA et un label canari. Comparez les performances et le comportement avant de basculer. Pour une approche plus contrôlée, utilisez un outil comme Argo Rollouts avec des étapes canari.

## Vérification et diagnostics

Après tout changement, vérifiez que les ressources DRA sont allouées correctement et que les pods fonctionnent.

### Vérifier l'allocation des ResourceClaims

```bash
kubectl get resourceclaims -n ml-team
```

Attendu :

```text
NAME     CLASS       STATE
my-gpu   gpu-class   allocated
```

Si l'état est `pending`, vérifiez les événements :

```bash
kubectl describe resourceclaim my-gpu -n ml-team
```

Recherchez des messages comme « waiting for driver to allocate » — cela indique que le pilote ne répond pas.

### Vérifier la planification des pods

```bash
kubectl get pods -n ml-team -o wide
```

Assurez-vous que le pod est `Running` et assigné à un nœud avec le matériel. S'il est `Pending`, décrivez-le :

```bash
kubectl describe pod training-job -n ml-team
```

Problèmes courants :

- `0/3 nodes are available: 3 Insufficient dra.example.com/gpu.` — aucun nœud n'a la ressource, ou le pilote ne signale pas la capacité.
- `resource claim not found` — le nom de la ResourceClaim ne correspond pas.
- `driver not found` — la ResourceClass référence un pilote qui n'est pas déployé.

### Vérifier les journaux du pilote

Pour le pilote de référence, les pods du pilote enregistrent les demandes d'allocation. Vérifiez :

```bash
kubectl logs -n kube-system -l app=dra-example-driver --tail=50
```

Recherchez des lignes indiquant que `Allocate` a réussi ou des erreurs.

### Tester avec une charge de travail simple

Avant de faire confiance au système, exécutez un pod minimal qui demande une ressource DRA puis le supprime. Par exemple, un pod qui exécute une commande triviale et se termine :

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: dra-test
spec:
  restartPolicy: Never
  containers:
  - name: test
    image: busybox
    command: ["sh", "-c", "echo DRA test"]
    resources:
      claims:
      - name: gpu
  resourceClaims:
  - name: gpu
    source:
      resourceClaimName: my-gpu
```

Appliquez et vérifiez l'état :

```bash
kubectl apply -f dra-test-pod.yaml
kubectl get pod dra-test
```

Une fois que le pod s'est terminé, la réclamation devrait devenir réutilisable ou être libérée, selon votre configuration.

## Modes de défaillance et récupération

DRA ajoute de nouveaux points de défaillance. Voici les modes de défaillance courants et les étapes de récupération.

### Défaillance : Pod du pilote en CrashLoopBackOff

Symptôme : les ResourceClaims restent `pending`, les pods du pilote redémarrent.

Diagnostic :

```bash
kubectl get pods -n kube-system -l app=dra-example-driver
kubectl logs -n kube-system <pod-pilote> --previous
```

Causes courantes :

- Permissions RBAC manquantes pour le compte de service du pilote.
- Version d'API Kubernetes incompatible (pilote construit pour une ancienne API DRA).
- Matériel du nœud absent.

Récupération : si vous avez mis à niveau le pilote, revenez à la version précédente :

```bash
kubectl rollout undo daemonset/dra-example-driver -n kube-system
```

Si cela échoue, réappliquez les anciens manifestes.

### Défaillance : ResourceClaim bloquée en Pending

Symptôme : la réclamation n'est jamais allouée.

Vérifiez l'état du pilote :

```bash
kubectl get csidrivers
kubectl get resourceclasses
```

Assurez-vous que le champ `driver` de la ResourceClass correspond à un nom de pilote connu. Par exemple :

```yaml
apiVersion: resource.k8s.io/v1alpha1
kind: ResourceClass
metadata:
  name: gpu-class
driver: nvidia.com/gpu
```

Si le pilote est mal orthographié, corrigez-le. Mais le pilote de la ResourceClass est immuable — vous devrez peut-être le supprimer et le recréer.

### Défaillance : le pod ne peut pas monter la ressource

Symptôme : le pod démarre mais le conteneur ne démarre pas avec une erreur de permission.

Vérifiez les événements :

```bash
kubectl describe pod <nom-du-pod>
```

Si vous voyez `failed to open device` ou similaire, le pilote n'a peut-être pas monté le périphérique correctement. Dans le pilote de référence, le périphérique est représenté comme un fichier. Vérifiez à l'intérieur du conteneur :

```bash
kubectl exec <nom-du-pod> -- ls /dev/dra
```

S'il est manquant, vérifiez les journaux du pilote. Vous devrez peut-être mettre à jour la configuration de montage du pilote.

### Stratégie de restauration

Ayez toujours un plan de restauration :

1. Conservez une copie des manifestes du pilote précédent fonctionnel.
2. Utilisez `kubectl rollout undo` pour les Deployments/DaemonSets.
3. Pour la mise à niveau de la version Kubernetes, la rétrogradation n'est pas prise en charge ; prévoyez un remplacement complet du pool de nœuds si nécessaire. Utilisez l'API de cluster ou les instantanés de service géré.
4. Avant les changements, étiquetez les pods critiques et utilisez `kubectl drain` de manière sélective pour éviter la perturbation des charges de travail.

## Liste de contrôle des opérations

Utilisez cette liste de contrôle pour chaque opération de mise à niveau ou de migration DRA.

- [ ] Enregistrer la version actuelle de Kubernetes et l'état du feature gate DRA : `kubectl version`, `kubectl get --raw /metrics | grep DynamicResourceAllocation`
- [ ] Inventorier toutes les ResourceClaims, ResourceClasses et les pods du pilote : `kubectl get resourceclaims --all-namespaces`, `kubectl get resourceclasses`, `kubectl get pods -n kube-system -l app=dra-example-driver`
- [ ] Examiner les notes de version de Kubernetes pour les changements d'API DRA entre les versions actuelle et cible.
- [ ] Tester tous les manifestes existants avec `kubectl apply --dry-run=server` sur un cluster de préproduction exécutant la version cible.
- [ ] Mettre à niveau le pilote DRA séparément à l'aide d'une mise à jour progressive : `kubectl set image` et `kubectl rollout status`.
- [ ] Migrer un pod à faible risque (par exemple, un pod de développement) du plugin de périphériques vers DRA. Vérifier la planification et l'exécution.
- [ ] Exécuter un déploiement canari avec DRA et le comparer à la référence.
- [ ] Vérifier les transitions d'état des ResourceClaims : `kubectl get resourceclaims` affiche `allocated`.
- [ ] Vérifier les journaux des pods et du pilote pour les erreurs.
- [ ] Effectuer un test négatif : supprimer une ResourceClaim et s'assurer que la replanification ou l'échec du pod est géré avec élégance.
- [ ] Documenter les étapes de restauration : commandes exactes pour annuler la mise à niveau du pilote, supprimer les réclamations cassées ou revenir sur les spécifications des pods.
- [ ] Planifier la mise à niveau pendant une fenêtre de maintenance avec disponibilité de l'équipe.
- [ ] Après la mise à niveau, surveiller le cluster pendant 24 à 48 heures pour la stabilité : `kubectl get events --all-namespaces --sort-by='.lastTimestamp' | grep dra`

## Conclusion

La mise à niveau et la migration de Kubernetes Dynamic Resource Allocation exigent une planification et une vérification minutieuses. Les clés sont l'inventaire, les changements par étapes et la préparation de la restauration. En suivant les commandes et les modèles de ce guide, vous pouvez éviter les pièges courants tels que les incompatibilités d'API, l'incompatibilité des pilotes et les ResourceClaims bloquées.

Commencez petit : choisissez une charge de travail à faible risque, enregistrez son état actuel, exécutez les étapes de migration documentées et validez que les ResourceClaims s'allouent et que les pods fonctionnent. Ensuite, étendez la migration progressivement. DRA évolue encore, consultez donc toujours les notes de version de Kubernetes pour votre version. Avec une approche disciplinée, vous pouvez tirer parti de la flexibilité de DRA tout en maintenant la stabilité du cluster.