Aller au contenu principal

KubeVirt

Dans ma quête pour trouver la solution idéale de provisionnement d'environnements pour mon homelab, j'ai découvert KubeVirt via Joël SEGUILLON. Cette extension (un opérateur et des CRD) de Kubernetes permet d'ajouter la gestion des machines virtuelles (VM) et à celle des conteneurs. KubeVirt se présente comme une solution d'hyperconvergence, permettant une intégration transparente des VMs dans les écosystèmes basés sur Kubernetes. Ainsi, il ouvre la voie à une gestion plus intuitive et centralisée des ressources, tout en conservant les avantages des technologies de virtualisation traditionnelles et modernes.

Architecture de KubeVirt

Comprendre l'architecture de KubeVirt est essentiel pour optimiser son utilisation dans mon homelab. KubeVirt est conçu pour s'intégrer de manière transparente avec Kubernetes.

KubeVirt étend Kubernetes en utilisant ses API existantes, permettant ainsi de gérer les VMs comme toute autre ressource Kubernetes. Cette intégration offre une expérience unifiée pour gérer à la fois les conteneurs et les VMs, facilitant la gestion des ressources, la mise à l'échelle et la surveillance dans un environnement homogène.

Composants Clés :

  • Opérateur KubeVirt : Gère le cycle de vie de tous les composants de KubeVirt.
  • Custom Resource Definitions (CRDs) : Définit les VMs et d'autres ressources spécifiques à KubeVirt dans Kubernetes.
  • virt-controller : S'occupe de la logique métier, gérant les états et les événements des VMs.
  • virt-handler : Un DaemonSet exécuté sur chaque nœud Kubernetes, responsable du cycle de vie des VMs sur ce nœud.
  • virt-api : Fournit une API pour interagir avec les composants de KubeVirt.
  • virt-launcher : Un pod créé pour chaque VM, encapsulant la logique de gestion de la VM.

Prérequis Techniques pour KubeVirt

Avant de plonger dans l'installation de KubeVirt pour mon homelab, il est crucial de s'assurer que l'environnement est prêt. Les prérequis techniques incluent principalement deux composants : QEMU et KVM. QEMU est un émulateur de machine open-source qui permet la virtualisation, tandis que KVM (Kernel-based Virtual Machine) est une solution de virtualisation intégrée au noyau Linux.

KVM/QEMU

Pour garantir une installation réussie de KubeVirt, il faut vérifier que le système est compatible avec la virtualisation. Ceci peut être confirmé en exécutant des commandes telles que kvm-ok sur des systèmes Linux. De plus, il est important de s'assurer que QEMU et KVM sont non seulement installés, mais aussi correctement configurés. Cette étape est essentielle car KubeVirt s'appuie sur ces technologies pour créer et gérer des machines virtuelles au sein de l'environnement Kubernetes. Si ce n'est pas le cas, consultez mon guide.

INFO: /dev/kvm exists
KVM acceleration can be used

Cluster Kubernetes

Le composant fondamental est un cluster Kubernetes opérationnel. KubeVirt étant une extension à Kubernetes, la présence d'un cluster configuré et fonctionnel est une nécessité absolue. Ce cluster peut être local, comme avec Minikube ou kind, ou un environnement de cluster plus robuste, selon les besoins et ressources disponibles. Personnellement j'ai fait le choix de K3s.

Une fois ces vérifications effectuées et les prérequis en place, on peut procéder en toute confiance à l'installation de KubeVirt, en vue de créer un homelab dynamique et efficace.

Installation de KubeVirt

Après m'être assuré que les prérequis techniques sont en place sur mon mini-pc, je passe à l'installation de KubeVirt. Cette étape est essentielle pour transformer mon cluster Kubernetes en une plateforme capable de gérer à la fois des conteneurs et des machines virtuelles.

Je commence par définir la variable RELEASE sur la dernière version stable de KubeVirt en exécutant :

export RELEASE=$(curl https://storage.googleapis.com/kubevirt-prow/release/kubevirt/kubevirt/stable.txt)

Ensuite, j'utilise la commande suivante pour déployer l'opérateur KubeVirt :

kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/kubevirt-operator.yaml

Cette commande lance l'installation réelle de KubeVirt :

kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${RELEASE}/kubevirt-cr.yaml

Enfin, je m'assure que tous les composants de KubeVirt sont opérationnels en exécutant :

kubectl -n kubevirt wait kv kubevirt --for condition=Available

On peut contrôler que tout fonctionne correctement en vérifiant l'état des pods du namespace kubevirt :

kubectl -n kubevirt get pod                                                                                                                03:40:53
NAME                               READY   STATUS    RESTARTS   AGE
virt-operator-656b9658fc-mchtx     1/1     Running   0          38m
virt-operator-656b9658fc-sb78h     1/1     Running   0          38m
virt-api-668b69dd4-d8h9w           1/1     Running   0          37m
virt-controller-7b6686f4ff-qp9b2   1/1     Running   0          37m
virt-controller-7b6686f4ff-7tgrs   1/1     Running   0          37m
virt-handler-p8tt7                 1/1     Running   0          37m

Installation de l'Utilitaire Virtctl

Après l'installation de KubeVirt, je procède à l'installation de virtctl, un outil en ligne de commande essentiel pour gérer les machines virtuelles dans KubeVirt.

virtctl fournit des commandes spécifiques pour la gestion des VMs dans KubeVirt, notamment pour accéder aux consoles (série et graphique), démarrer et arrêter les VMs et gérer les migrations en direct. Ces fonctionnalités sont cruciales pour un contrôle précis et efficace des machines virtuelles dans mon homelab, allant au-delà des capacités de kubectl.

Je définis d'abord la variable VERSION sur la version souhaitée de virtctl, puis je télécharge le binaire correspondant. Par exemple :

export VERSION=v0.41.0
sudo wget https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/virtctl-${VERSION}-linux-amd64 -O /usr/local/bin/virtctl
sudo chmod +x /usr/local/bin/virtctl
virtctl --version
Client Version: version.Info{GitVersion:"v1.1.1", GitCommit:"689c0e66cc6893f311dd648ff32e247203b6c96a", GitTreeState:"clean", BuildDate:"2023-12-25T10:58:20Z", GoVersion:"go1.19.9", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{GitVersion:"v1.1.1", GitCommit:"689c0e66cc6893f311dd648ff32e247203b6c96a", GitTreeState:"clean", BuildDate:"2023-12-25T11:56:11Z", GoVersion:"go1.19.9", Compiler:"gc", Platform:"linux/amd64"}

Les principales sous-commandes de virtctl

La commande virtctl de KubeVirt offre une multitude d'options pour gérer les machines virtuelles :

  • addvolume / removevolume : Ajouter ou supprimer un volume sur une VM en cours d'exécution.
  • completion : Générer le script d'autocomplétion pour le shell spécifié.
  • console : Se connecter à la console d'une instance de machine virtuelle.
  • create : Créer un manifeste pour le type de ressource spécifié.
  • credentials : Manipuler les identifiants sur une machine virtuelle.
  • expand : Obtenir l'objet VirtualMachine avec l'instancetype et les préférences étendus.
  • expose : Exposer une instance de VM, une VM ou un ensemble de réplicas en tant que nouveau service.
  • fslist / userlist : Lister les systèmes de fichiers ou utilisateurs sur la machine invité.
  • guestfs : Démarrer un shell dans le pod libguestfs.
  • guestosinfo : Obtenir des informations de l'agent invité sur le système d'exploitation.
  • image-upload : Téléverser une image de VM vers un DataVolume ou PersistentVolumeClaim.
  • memory-dump : Dumper la mémoire d'une VM en cours d'exécution vers un PVC.
  • migrate / migrate-cancel : Migrer ou annuler la migration d'une machine virtuelle.
  • pause / unpause : Mettre en pause ou reprendre une machine virtuelle.
  • permitted-devices : Lister les périphériques autorisés pour les VMIs.
  • port-forward : Rediriger des ports locaux vers une machine virtuelle ou une instance de machine virtuelle.
  • restart : Redémarrer une machine virtuelle.
  • scp : Transférer des fichiers vers/depuis une instance de machine virtuelle.
  • soft-reboot : Redémarrer en douceur une instance de machine virtuelle.
  • ssh : Ouvrir une connexion SSH vers une instance de machine virtuelle.
  • start / stop : Démarrer ou arrêter une machine virtuelle.
  • usbredir : Rediriger un périphérique USB vers une instance de machine virtuelle.
  • vmexport : Exporter un volume de VM.
  • vnc : Ouvrir une connexion VNC vers une machine virtuelle.
  • version : Afficher les informations de version du client et du serveur.

Chaque option est conçue pour faciliter des actions spécifiques liées à la gestion des machines virtuelles dans un environnement KubeVirt.

Création et Gestion de Machines Virtuelles avec KubeVirt

L'utilisation de KubeVirt pour la création et la gestion de machines virtuelles (VMs) est une étape clé pour fusionner les avantages de la virtualisation traditionnelle et de la conteneurisation.

Création de VMs

Avec KubeVirt, la création de VMs se fait par des fichiers YAML, semblables à n'importe quelle autre ressource Kubernetes. Ces fichiers définissent les spécifications de la VM, telles que la quantité de CPU, de mémoire, les disques et les réseaux.

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: testvm
spec:
  running: false
  template:
    metadata:
      labels:
        kubevirt.io/size: small
        kubevirt.io/domain: testvm
    spec:
      domain:
        devices:
          disks:
            - name: containerdisk
              disk:
                bus: virtio
            - name: cloudinitdisk
              disk:
                bus: virtio
          interfaces:
          - name: default
            masquerade: {}
        resources:
          requests:
            memory: 64M
      networks:
      - name: default
        pod: {}
      volumes:
        - name: containerdisk
          containerDisk:
            image: quay.io/kubevirt/cirros-container-disk-demo
        - name: cloudinitdisk
          cloudInitNoCloud:
            userDataBase64: SGkuXG4=
  • apiVersion et kind : Spécifie la version de l'API KubeVirt et indique que la ressource est une VirtualMachine.
  • metadata : Nomme la VM testvm.
  • spec :
    • running : Indique que la VM n'est pas en cours d'exécution (false).
    • template : Définit la configuration de la VM.
      • metadata.labels : Étiquettes pour la VM.
      • spec.domain : Configuration du matériel virtuel, incluant les périphériques et les ressources.
        • devices.disks : Deux disques avec un bus virtio (un pour le système d'exploitation et un autre pour CloudInit).
        • interfaces : Configure une interface réseau avec masquerading.
        • resources.requests : Demande 64M de mémoire pour la VM.
      • networks : Définit le réseau de la VM.
      • volumes : Définit les volumes, y compris le disque conteneur pour l'image du système d'exploitation et un disque CloudInit avec des données utilisateur encodées en base64.

Gestion des VM

Une fois créées, les VMs sont gérées via les commandes habituelles de Kubernetes (kubectl) et les commandes spécifiques de virtctl. Cela inclut le démarrage, l'arrêt, la surveillance et la mise à jour des configurations. L'intégration étroite avec Kubernetes offre une gestion cohérente et simplifiée, permettant de traiter les VMs comme des ressources natives du cluster.

Cette approche centralisée et unifiée de la gestion des VMs dans mon homelab améliore significativement l'efficacité opérationnelle et la flexibilité pour tester divers scénarios et configurations.

Lister les VM

Pour lister toutes les machines virtuelles (VMs) dans un cluster Kubernetes qui utilise KubeVirt, vous pouvez utiliser la commande kubectl avec les ressources appropriées. Voici la commande à exécuter :

NAMESPACE   NAME     AGE   STATUS    READY
demo        testvm   3s    Stopped   False

Cette commande affiche la liste de toutes les VMs déployées dans le cluster, en fournissant des détails tels que leur état, leur nom et d'autres informations pertinentes.

Obtenir des informations sur une VM

Pour obtenir plus de détails sur une VM spécifique, vous pouvez utiliser :

kubectl describe vm testvm

Name:         testvm
Namespace:    demo
Labels:       <none>
Annotations:  kubevirt.io/latest-observed-api-version: v1
              kubevirt.io/storage-observed-api-version: v1
API Version:  kubevirt.io/v1
Kind:         VirtualMachine
Metadata:
  Creation Timestamp:  2023-12-27T15:28:22Z
  Finalizers:
    kubevirt.io/virtualMachineControllerFinalize
  Generation:        1
  Resource Version:  15961
  UID:               dc034399-365b-4bd2-a260-ba25604a49d3
Spec:
  Running:  false
  Template:
    Metadata:
      Creation Timestamp:  <nil>
      Labels:
        kubevirt.io/domain:  testvm
        kubevirt.io/size:    small
    Spec:
      Architecture:  amd64
      Domain:
        Devices:
          Disks:
            Disk:
              Bus:  virtio
            Name:   containerdisk
            Disk:
              Bus:  virtio
            Name:   cloudinitdisk
          Interfaces:
            Masquerade:
            Name:  default
        Machine:
          Type:  q35
        Resources:
          Requests:
            Memory:  64M
      Networks:
        Name:  default
        Pod:
      Volumes:
        Container Disk:
          Image:  quay.io/kubevirt/cirros-container-disk-demo
        Name:     containerdisk
        Cloud Init No Cloud:
          userDataBase64:  SGkuXG4=
        Name:              cloudinitdisk
Status:
  Conditions:
    Last Probe Time:       2023-12-27T15:28:22Z
    Last Transition Time:  2023-12-27T15:28:22Z
    Message:               VMI does not exist
    Reason:                VMINotExists
    Status:                False
    Type:                  Ready
  Printable Status:        Stopped
  Volume Snapshot Statuses:
    Enabled:  false
    Name:     containerdisk
    Reason:   Snapshot is not supported for this volumeSource type [containerdisk]
    Enabled:  false
    Name:     cloudinitdisk
    Reason:   Snapshot is not supported for this volumeSource type [cloudinitdisk]
Events:       <none>

Démarrer une VM

Pour démarrer un vm, nous allons utiliser la commande virtctl :

kubectl virt start testvm
VM testvm was scheduled to start

On vérifie son status :

NAMESPACE   NAME     AGE     STATUS    READY
demo        testvm   5m32s   Running   True

Se connecter via la console

On utilise toujours la commande virtcl :

bob@internal ~/Projects/perso/kubevirt 48s ❯ virtctl console testvm                                                                                                                                    04:39:10

Successfully connected to testvm console. The escape sequence is ^]

login as 'cirros' user. default password: 'gocubsgo'. use 'sudo' for root.
testvm login: cirros
Password:
$ cat /etc/os-release
NAME=Buildroot
VERSION=2015.05-g31af4e3-dirty
ID=buildroot
VERSION_ID=2015.05
PRETTY_NAME="Buildroot 2015.05"

Pour quitter, il faut utiliser CTRL + 5

Stopper un VM

virtctl stop testvm

Avantages et Inconvénients de KubeVirt

Avantages

  • Intégration avec Kubernetes : KubeVirt s'intègre harmonieusement à Kubernetes, offrant une gestion unifiée des VMs et des conteneurs.
  • Flexibilité : Permet de combiner des applications traditionnelles basées sur VM avec des architectures modernes basées sur conteneurs.
  • Efficacité des Ressources : Optimise l'utilisation des ressources en permettant de gérer VMs et conteneurs dans une même infrastructure.

Inconvénients

  • Complexité : Ajoute une couche de complexité à la gestion du cluster Kubernetes.
  • Ressources : Peut nécessiter plus de ressources système, en particulier pour la gestion des VMs en plus des conteneurs.
  • Courbe d'Apprentissage : Nécessite une compréhension approfondie de Kubernetes et de la virtualisation pour une utilisation efficace.

En conclusion, KubeVirt est une solution puissante pour des environnements de test, mais elle exige une expertise technique pour gérer efficacement la complexité supplémentaire qu'elle introduit.

Conclusion

L'exploration de KubeVirt dans le cadre de mon homelab a révélé un outil puissant et polyvalent pour gérer à la fois des machines virtuelles et des conteneurs. Bien qu'il introduise une complexité supplémentaire et exige une compréhension approfondie des technologies sous-jacentes, les avantages en termes d'intégration, de flexibilité et d'optimisation des ressources sont significatifs. KubeVirt se positionne comme une solution idéale pour moderniser les infrastructures informatiques, offrant une plateforme robuste pour les applications traditionnelles et modernes. Son adoption dans mon homelab est un pas en avant vers un environnement plus dynamique et efficace, mais nous éloigne des pratiques actuelles.