KubeVirt: Partie 3 - Deploiement des VMs

Introduction

Il est désormais temps de déployer les VMs. L’objectif est d’arriver au résultat suivant:

Cible à déployer

Cliquez sur l'image pour l'agrandir.

Bien entendu pour ceux qui n’auraient pas pris connaissance des articles précédents et qui ne seraient pas sensibilisés à KubeVirt, je vous invite fortement à démarrer par la lecture de ces derniers avant de poursuivre ce tutoriel.

Déploiement des profils réseau

On va démarrer par la déclaration des profils réseau, ou des NetworkAttachmentDefinition (net-attach-def).

Ces nouveaux objets Kubernetes permettent de définir quelles interfaces utiliser et avec quelle configuration.

Dans notre cas nous aurons besoin de trois net-attach-def:

  • nad-lan-default: utilisé par la VM sur le réseau lan. Le profil est déclaré dans le fichier 01-nad-lan-default.yml
  •       ---
          apiVersion: k8s.cni.cncf.io/v1
          kind: NetworkAttachmentDefinition
          metadata:
            name: nad-lan-default
            annotations:
              k8s.v1.cni.cncf.io/resourceName: macvtap.network.kubevirt.io/enp8s0
            namespace: inf-kubevirt
          spec:
            config: '{
              "cniVersion": "0.3.1",
              "name": "enp8s0",
              "type": "macvtap",
              "mtu": 1500
            }'
          
  • nad-dmz-web: utilisé par la VM sur le vlan WEB. Le profil est déclaré dans le fichier 02-nad-dmz-web.yml
  •       ---
          apiVersion: k8s.cni.cncf.io/v1
          kind: NetworkAttachmentDefinition
          metadata:
            name: nad-dmz-web
            annotations:
              k8s.v1.cni.cncf.io/resourceName: macvtap.network.kubevirt.io/enp8s0.6
            namespace: inf-kubevirt
          spec:
            config: '{
              "cniVersion": "0.3.1",
              "name": "enp8s0.6",
              "type": "macvtap", 
              "mtu": 1500
            }'
          
  • nad-dmz-first: utilisé par la VM en DMZ. Le profil est déclaré dans le fichier 03-nad-dmz-first.yml
  •   
          ---
          apiVersion: k8s.cni.cncf.io/v1
          kind: NetworkAttachmentDefinition
          metadata:
            name: nad-dmz-first
            namespace: inf-kubevirt
            annotations:
                k8s.v1.cni.cncf.io/resourceName: macvtap.network.kubevirt.io/enp13s0f3   
          spec:
            config: '{
              "cniVersion": "0.3.1",
              "name": "enp13s0f3",
              "type": "macvtap",
              "mode": "bridge"
            }'
          

La configuration de chacun des profils est assez proche. Seule la carte physique à utiliser est différente et correspond à ce que nous avons décrit dans l’article précédent pour le CNI macvtap.

Pour des questions d’organisation, ils vont être hébergés dans un namespace inf-kubevirt. Il s’agit pour moi de ressources communes à la configuration de KubeVirt indépendantes des namespaces d’exécutions des VMs.

On démarre donc par la création du ns.

kubectl create ns inf-kubevirt
Création du namespace

Cliquez sur l'image pour l'agrandir.

On peut ensuite appliquer directement les trois profils que j’ai regroupés dans un dossier inf-kubevirt.

kubectl apply -f inf-kubevirt
Création des profils

Cliquez sur l'image pour l'agrandir.

Il est alors possible de lister les profils réseau disponibles dans ce namespace « d’infrastructure » créé pour l’occasion.

kubectl get network-attachment-definitions -n inf-kubevirt
Listing des profils

Cliquez sur l'image pour l'agrandir.

Création des VMs

VM dans le LAN

On enchaine par la création de la première VM vm-demo-lan. Pour respecter ma nomenclature définie dans mon cookbook Kubernetes, je crée un namespace spécifique.

kubectl create ns dev-demovm-lan
Création du namespace

Cliquez sur l'image pour l'agrandir.

Étant donné qu’il est possible d’établir des limites d’accès et de ressources par namespace, il devient alors très facile de réserver une partie de son cluster Kubernetes à des VMs destinées à des usages spécifiques. Par exemple toutes les VMs de DEV, ou de DMZ. C’est l’avantage de KubeVirt, il reprend la majorité des possibilités offertes par les objets de base de K8S.

La VM est décrite dans un fichier 01-vm-demo-lan.yml donc voici le contenu:

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: vm-demo-lan
  namespace: dev-demovm-lan
  labels:
    network: lan
    application: demo
    os: linux
    environnement: dev
spec:
  runStrategy: Always
  template:
    spec:
      domain:
        cpu:
          cores: 1
        resources:
          requests:
            memory: 1Gi
        devices:
          # On définit ici les disques utilisés par la VM
          disks:
            # Disque de l'image du système
            - name: containerdisk
              disk:
                bus: virtio
            # Disque cloud-init pour injecter la configuration initiale
            - name: cloudinitdisk
              disk:
                bus: virtio
          # Interfaces réseau existantes
          interfaces:
            # Interface connectée via Multus au VLAN (ici vlan LAN)
            - name: lan
              model: virtio
              binding:
               name: macvtap 
      networks:
        # Réseau 
        #L'interface LAN
        - name: lan
          multus:
            networkName: inf-kubevirt/nad-lan-default
      volumes:
        # Volume contenant l'image du système
        - name: containerdisk
          containerDisk:
            image: quay.io/containerdisks/centos:8.4
        # Volume cloud-init contenant la configuration initiale
        - name: cloudinitdisk
          cloudInitNoCloud:
            userData: |
              #cloud-config
              hostname: vm-demo-lan
              users:
                - name: bvivi57
                  sudo: ALL=(ALL) NOPASSWD:ALL
                  shell: /bin/bash
              chpasswd:
                list: |
                  bvivi57:defaultpassword
                expire: False
              ssh_pwauth: True
    

Comme vous pouvez l’observer, on retrouve la syntaxe d’un composant Kubernetes. Il s’agit de manipuler l’objet VirtualMachine de la branche API kubevirt.io/v1. Celle-ci s’est ajoutée à l’api de base lors du déploiement de KubeVirt.

Au niveau de la section spec, on va pouvoir spécifier les caractéristiques de sa VM. À commencer par la configuration CPU et mémoire.

Puis dans la sous-section devices, on ajoute les périphériques souhaités, comme les disques et les interfaces réseau.

Pour ce premier exemple, on exploite un containerdisk. C’est un disque virtuel basé sur un conteneur et récupérable depuis une registry. Il permet un déploiement rapide d’OS. Il n’a pas vocation à persister la donnée, mais à mettre à disposition très rapidement une VM basée sur un système d’exploitation, en l’occurrence ici centos:8.4 via la registry quay.io/containerdisks/ (on retrouve la référence à l’OS un peu plus bas).

Pour le réseau, on déclare une carte. Cette dernière va être rattachée via multus au profil inf-kubevirt/nad-lan-default. Il s’agit du premier profil réseau qu’on a détaillé dans l’étape précédente. Comme il est hébergé dans un autre namespace que celui de la VM, il faut indiquer le chemin complet.

Pour initier la configuration de la VM, on passe par un cloudinitdisk. C’est un disque monté en priorité qui va contenir la configuration d’amorçage. Cloud-init est un outil de configuration largement utilisé pour personnaliser des machines virtuelles lors du premier démarrage.

La configuration à utiliser est déclarée au niveau du volume rattaché au containerdisk. On n’y retrouve la syntaxe traditionnelle de Cloud-init. Je n’ai pas été très loin dans ce premier exemple en me contentant de créer un user par défaut avec un password basique, ainsi que de fixer le hostname.

Pour créer et démarrer la VM, il suffit d’appliquer le fichier.

kubectl apply -f 01-vm-demo-lan.yml

Très rapidement on peut lister les VMs du namespace.

kubectl get vm -n dev-demovm-lan
Controle de la VM

Cliquez sur l'image pour l'agrandir.

Notre VM est en statut running et prête à être utilisée.

Connexion à la VM

Pour pouvoir s’y connecter, il faut passer par la console de la VM. Cette dernière est accessible via la CLI virtctl (voir article précédent).

Il suffit de lancer la commande:

virtctl console vm-demo-lan -n dev-demovm-lan
Accès à la VM

Cliquez sur l'image pour l'agrandir.

On se retrouve alors dans le contexte de la VM. On peut vérifier quelques éléments, comme l’adresse IP du système.

Controle de l'IP

Cliquez sur l'image pour l'agrandir.

On est bien avec le subnet correspondant à mon LAN. La VM a eu une IP en DHCP, elle est donc bien rattachée à mon interface physique dédiée comme expliquée en introduction de KubeVirt et mise en œuvre dans les prérequis.

Il est d’ailleurs même possible d’ouvrir une session SSH avec l’utilisateur créé au niveau de cloud init.

Accès SSH à la VM

Cliquez sur l'image pour l'agrandir.

Action sur la VM

Voici donc la première VM rendue accessible. Comme on ne va pas l’utiliser par la suite, on peut décider de l’éteindre.

Pour cela il faut d’abord sortir de la VM avec la combinaison de touche crtl + 5, puis passez la commande:

virtctl stop vm-demo-lan -n dev-demovm-lan

Coupure de la VM

Cliquez sur l'image pour l'agrandir.

La VM est alors stoppée.

Etat de la VM

Cliquez sur l'image pour l'agrandir.

Si besoin, il suffira de la rédemarrer avec la commande virtctl start vm-demo-lan -n dev-demovm-lan

VM dans le VLAN WEB

On peut passer à la seconde VMs. Celle rattachée au VLAN WEB.

Étant donné qu’il s’agit pour moi d’un subnet en DMZ, je créer d’abord un nouveau namespace.

kubectl create ns dev-demovm-dmz
Création du namespace

Cliquez sur l'image pour l'agrandir.

Encore une fois, ceci est simplement un exemple d’organisation de ressources et d’usage des namespaces. Chacun est libre de retenir la logique de son choix.

Comme pour la VM en LAN, cette VM est décrite dans un fichier yaml, 01-vm-demo-web.yaml, dont voici le contenu:

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: vm-demo-web
  namespace: dev-demovm-dmz
  labels:
    network: web
    application: demo
    os: linux
    environnement: dev
spec:
  runStrategy: Always
  template:
    spec:
      domain:
        cpu:
          cores: 1
        resources:
          requests:
            memory: 1Gi
        devices:
          # On définit ici les disques utilisés par la VM
          disks:
            # Disque de l'image du système
            - name: containerdisk
              disk:
                bus: virtio
            # Disque cloud-init pour injecter la configuration initiale
            - name: cloudinitdisk
              disk:
                bus: virtio
          # Interfaces réseau existantes
          interfaces:
            # Interface connectée via Multus au VLAN (ici vlan LAN)
            - name: lan
              model: virtio
              binding:
               name: macvtap 
      networks:
        # Réseau supplémentaire via Multus (NAD existant)
        - name: lan
          multus:
            networkName: inf-kubevirt/nad-dmz-web
      volumes:
        # Volume contenant l'image du système
        - name: containerdisk
          containerDisk:
            image: quay.io/containerdisks/centos:8.4
        # Volume cloud-init contenant la configuration initiale
        - name: cloudinitdisk
          cloudInitNoCloud:
            userData: |
              #cloud-config
              hostname: vm-demo-lan
              users:
                - name: bvivi57
                  sudo: ALL=(ALL) NOPASSWD:ALL
                  shell: /bin/bash
              chpasswd: 
                list: |
                  bvivi57:defaultpassword
                expire: False
              ssh_pwauth: True

              # Configuration réseau cloud-init (statique sur eth0)
              network:
                version: 1
                config:
                  - type: physical
                    name: eth0
                    subnets:
                      - type: static
                        address: 192.168.5.188/24
                        gateway: 192.168.5.253
                        dns_nameservers:
                          - 192.168.10.30
                          - 8.8.8.8
    

Il est très proche de l’exemple précédent, sauf qu’ici on utilise le profil réseau inf-kubevirt/nad-dmz-web.

On va aussi un petit peu plus loin dans cloud init en fournissant cette fois-ci une IP à l’interface de la VM, car je n’ai pas de DHCP sur ce subnet.

Il suffit de déployer le yaml pour créer la VM:

kubectl apply -f 01-vm-demo-web.yml
Déploiement de la VM

Cliquez sur l'image pour l'agrandir.

Si on liste les VMs du namespace, on retrouve notre machine virtuelle.

kubectl get vm -n dev-demovm-dmz
Controle de la VM

Cliquez sur l'image pour l'agrandir.

Connexion à la VM

Ici aussi on peut accéder à la console de la VM via la commande: virtctl console vm-demo-web -n dev-demovm-dmz

On peut par exemple lancer des opréations d’upgrade.

Exemple de commande dans la VM

Cliquez sur l'image pour l'agrandir.

Mais comme pour la VM du LAN, on utilise ici un disque éphémère de type container disque.

VM dans la DMZ FIRST

Il est temps de passer à la dernière VMs, celle sur le second subnet en DMZ (DMZ First).

Pour cet exemple, on va aller un peu plus loin et se mettre dans une installation classique d’un OS, soit Rocky Linux 9.5.

On va définir un véritable disque, qu’on va pouvoir formater comme on le souhaite et monter dans la VM l’ISO de l’OS pour l’installer à notre convenance.

Gestion du stockage: usage d'un ISO

Pas besoin de créer un nouveau namespace, puisque je reste sur une zone en DMZ et que je n’ai pas dans ma ma nomenclature de distinction de fait entre mes DMZ.

Par contre, il va falloir d’abord préparer l’ISO. Dans l’article précédent , je décris comment installer et configurer Containerized-Data-Importer (CDI).

C’est le moment d’utiliser cet addon. Le but est d’uploader l’ISO dans un objet de type DataVolume (dv).

Celui-ci va automatiquement provisionner un pvc (et donc un pv) en utilisant la storage class NFS dédiée.

L’upload va passer par l’ingress rattaché au service provisionné par l’installation de CDI. N’hésitez pas à parcourir la section dédiée sur le sujet dans l’article précédent.

On utilise la CLI virtctl.

virtctl image-upload dv dv-iso-rocky-linux-9-5 --namespace dev-demovm-dmz --size=3Gi --storage-class=sc-local-storage-nfs-iso --access-mode=ReadWriteOnce --image-path=/mnt/nfs/nfstools/src-iso/pvc-iso-rocky-linux-9-5/Rocky-9.5-x86_64-minimal.iso --uploadproxy-url=https://cdi.coolcorp.priv –insecure
Upload de l'ISO

Cliquez sur l'image pour l'agrandir.

La commande prend en arguments principaux:

  • le chemin de l’iso: /mnt/nfs/nfstools/src-iso/pvc-iso-rocky-linux-9-5/Rocky-9.5-x86_64-minimal.iso
  • le nom du dv: dv-iso-rocky-linux-9-5 et le namespace ou le déclarer: dev-demovm-dmz
  • La taille rattachée (choisir un peu plus que la taille de l’ISO): 3Gi
  • L’URL du proxy CDI: https://cdi.coolcorp.priv

Encore une fois, n’hésitez pas à faire un tour dans l’article précédent dédié à l’installation et la configuration du CDI.

Une fois l’upload terminé, on peut lister le dv:

kubectl get dv -n dev-demovm-dmz
Listing du dv

Cliquez sur l'image pour l'agrandir.

Ainsi que le pvc qui s’y rattache:

kubectl get pvc -n dev-demovm-dmz
Listing du pvc

Cliquez sur l'image pour l'agrandir.

L’iso est maintenant contenu dans le pvc qu’il nous sera possible de rattacher à notre VM par la suite.

Gestion du stockage: création du disque système

On enchaine avec le disque de la VM à proprement parlé. On ne veut plus utiliser un containerdisk, mais stocker les datas de notre VMs sur le nœud Kubernetes.

Pour rappel, j’ai déployé KubeVirt sur une configuration K8S mononode que j’avais déjà utilisée pour démontrer l’usage d’un GPU avec Kubernetes. Dans l’article associé, j’explique que j’utilise trois classes de storage (sc) correspondant à trois disques SSD présents au sein du serveur.

Je n’ai pas besoin de passer par ces sc, mais je vais m’appuyer sur un des disques SSD haute performance que j’ai dédiés au stockage de mes conteneurs.

Celui-ci est monté dans /mnt/datastores/prddtsnme001.

Point de montage du disque SSD

Cliquez sur l'image pour l'agrandir.

Je vais donc créer un dossier dédié à la VM dans cette arborescence:

mkdir -p /mnt/datastores/prddtsnme001/localpv/dev-demovm-dmz/vm-demo-dmz

On va faire référence à cet emplacement via le pv décrit dans le yaml 01-pv-vm-demo-dmz.yml.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-vm-demo-dmz
  labels:
    environment: dev
    network: dmz
    application: kubevirt
spec:
  capacity:
    storage: 30Gi 
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: sc-local-storage-prddtsnme001
  local:
    path: /mnt/datastores/prddtsnme001/localpv/dev-demovm-dmz/vm-demo-dmz
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
                - prdk8sctp001
              

Puis on associe ce pv a un pvc à travers le fichier 02-pvc-vm-demo-dmz.yml.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-vm-demo-dmz
  namespace: dev-demovm-dmz
  labels:
    environment: dev
    network: dmz
    application: kubevirt
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: sc-local-storage-prddtsnme001
  resources:
    requests:
      storage: 30Gi
    

(Si vous n'êtes pas à l'aise avec les notions de pv, pvc et sc, n'hésitez pas à faire un tour ici et ici)

L’application du pv et du pvc permettent de préparer le terrain pour la vm.

kubectl apply -f 01-pv-vm-demo-dmz.yml
Création du PV

Cliquez sur l'image pour l'agrandir.

kubectl apply -f 02-pvc-vm-demo-dmz.yml
Création du PVC

Cliquez sur l'image pour l'agrandir.

On vérifie que tout le stockage est disponible:

kubectl get pvc -n dev-demovm-dmz

On n’a le pvc rattaché à l’ISO et le pvc rattaché au volume qu’on va utiliser comme disque de la VM.

Statut des PVC

Cliquez sur l'image pour l'agrandir.

Déploiement de la VM

Il ne reste plus qu’à décrire la machine virtuelle dans le fichier 03-vm-demo-dmz.yml:

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: vm-demo-dmz
  namespace: dev-demovm-dmz
  labels:
    network: dmz
    application: demo
    os: linux
    environnement: dev
spec:
  runStrategy: Always
  template:
    spec:
      domain:
        firmware:
          bootloader:
            efi:
              secureBoot: false
        cpu:
          cores: 1
        resources:
          requests:
            memory: 1Gi
        devices:
          # On définit ici les disques utilisés par la VM
          disks:
            # CDROM
            - name: pv-iso-rocky-linux-9-5
              cdrom:
                bus: sata
                readonly: true
              bootOrder: 2  
            # Disque du systeme
            - name: pv-vm-demo-dmz
              disk:
                bus: virtio
              bootOrder: 1       
          # Interfaces réseau existantes
          interfaces:
            # Interface connectée via Multus au VLAN (ici vlan LAN)
            - name: eth0
              model: virtio
              binding:
               name: macvtap 
      networks:
        # Réseau supplémentaire via Multus (NAD existant)
        - name: eth0
          multus:
            networkName: inf-kubevirt/nad-dmz-first
      volumes:
        # Volume local 
        - name: pv-iso-rocky-linux-9-5
          persistentVolumeClaim:
            claimName: dv-iso-rocky-linux-9-5
        - name: pv-vm-demo-dmz
          persistentVolumeClaim:
            claimName: pvc-vm-demo-dmz            
    

La syntaxe est très proche des exemples précédents.

On va néanmoins retrouver la notion de cdrom, à travers le disque pv-iso-rocky-linux-9-5. On défini bien qu’il s’agit d’un device spécifique connectée sur un bus sata.

Le second disque pv-vm-demo-dmz est celui qui correspond à notre pv qu’on n’a créé précédemment.

À noter qu’on n’inclut un ordre de boot avec l’option bootOrder.

Le profil réseau utilisé est le dernier déclaré: inf-kubevirt/nad-dmz-first.

Cette fois-ci plus de configuration cloud init par contre on n’agit en début de section spec sur le type de bios à émuler, en l’occurrence non pas un bios, mais un efi avec le mode secureBoot défini à false.

Il suffit d’appliquer le yaml pour exécuter la vm:

kubectl apply -f 03-vm-demo-dmz.yml
Création de la VM

Cliquez sur l'image pour l'agrandir.

Celle-ci apparait désormais bien dans la liste des VMs démarrées au niveau du namespace dev-demovm-dmz.

Listing des VMs

Cliquez sur l'image pour l'agrandir.

Connexion à la VM (vnc)

La problématique va maintenant de pouvoir accéder à l’assistant d’installation de l’OS, car si le paramétrage de la VM est correct, le disque système rattaché au pv pv-vm-demo-dmz étant vierge, la machine virtuelle devrait booter sur l’ISO.

L’installateur de Rocky Linux s’exécute à travers une GUI, on ne peut donc pas utiliser l’accès console comme pour les précédentes VMs.

Il faut disposer d’un environnement graphique.

Pour cela on peut passer directement par son poste de travail et utiliser à nouveau virtctl, mais cette fois-ci avec l’option vnc.

C’est en effet via ce protocole que kubevirt permet l’accès à la vue « graphique » des vms.

Il faut donc en plus de virtctl (et du fichier kubeconfig qui va bien) avoir un client vnc à disposition.

Sous Windows, il en existe plusieurs, personnellement j’utilise TigerVNC, il est léger simple et régulièrement mis à jour.

Site de tigervnc

Cliquez sur l'image pour l'agrandir.

Pour accéder à la GUI de la VM, il faut donc lancer la commande suivante sur un poste bénéficiant d’une interface graphique (dans mon cas mon W11).

virtctl vnc vm-demo-dmz -n dev-demovm-dmz --proxy-only
Lancement du proxy vnc

Cliquez sur l'image pour l'agrandir.

Avec cette instruction, virtctl agit comme un proxy en écoute sur l’IP local de votre poste (127.0.0.1) sur un port choisi dynamiquement et visible dans le retour de la commande.

Il suffit d’utiliser l’IP local et ce port dans votre client VNC pour obtenir la vue graphique de la VM.

Paramétrage du client VNC

Cliquez sur l'image pour l'agrandir.

De là on peut entamer la procédure d’installation de l’OS comme si on avait raccordé un écran à la VM.

GUI de l'installation

Cliquez sur l'image pour l'agrandir.

On retrouve bien le disque vierge mappé à la machine virtuelle à travers les pv/pvc.

Controle du disque

Cliquez sur l'image pour l'agrandir.

On retrouve l’interface réseau mappée sur le bon subnet. On peut d’ailleurs définir le hostname.

Controle de la carte réseau

Cliquez sur l'image pour l'agrandir.

Il suffit de suivre les instructions d’installation pour enfin redémarrer.

Lancement de l'installation

Cliquez sur l'image pour l'agrandir.

Déroulé de l'installation

Cliquez sur l'image pour l'agrandir.

La VM dispose désormais d’un OS déployé et va booter directement sur ce dernier.

De là on peut revenir à une connexion via console si on a pas déployé de GUI ou utiliser, comme précédemment, le protocole VNC.

Controle de l'installation

Cliquez sur l'image pour l'agrandir.

Conclusion

Si on liste l’ensemble des VMs sur tout le node Kubernetes:

kubectl get vm --all-namespaces
Présence des trois VMs

Cliquez sur l'image pour l'agrandir.

On liste les trois VMs souhaitées (dont la première est arrêtée).

On a donc bien trois machines virtuelles, chacune sur une zone réseau différente et exploitant les interfaces physiques du node.

À côté de ça on a toujours nos pods et conteneurs, notamment ceux utilisés pour démontrer les capacités d’usage de GPU avec K8S et le déploiement de Ollama.

Par rapport aux objectifs décrits dans le premier article dédié à KubeVirt on a bien réussi à remplir les attentes: à savoir mixer au sein d’une plateforme Kubernetes, des VMs et des conteneurs, le tout via la logique K8S: l’usage d’API et la manipulation d’objets.

J’ai essayé d’aller un peu plus loin que les démonstrations traditionnelles qu’on trouve sur le web autour de KubeVirt. Je souhaitais exploiter différentes interfaces réseaux pour arriver à quelque chose de plus proche de ce qu’on peut retrouver sur des configurations plus classiques autour des machines virtuelles.

J’ai toujours à l’esprit l’idée d’essayer de réduire mon empreinte à VMware suite aux problématiques de son rachat et de centraliser le plus possible de mes ressources autour de Kubernetes.

Mais ce n’est pas gagné. Certe KubeVirt est fonctionnel et l’hyperviseur KVM sur lequel il s’appuie pour exécuter les VMs n’a plus rien à prouver.

L’écosystème reste encore en plein développement et les nombreux addons nécessaires au bon fonctionnement de l’ensemble ne présentent pas tous la même stabilité, surtout autour du réseau.

Je suis aussi bien loin d’avoir implémenté tout le nécessaire pour vraiment tirer parti au mieux des fonctions de KubeVirt. Il reste un gros travail à faire coté stockage et surtout basculer en multinode avec la capacité de déplacer des VMs d’un serveur à un autre, idéalement sans perte d’accès comme on pourrait le faire avec vMotion coté VMware. Ça me laisse encore beaucoup à découvrir.

En l’état, l’implémentation de tous les composants brique par brique reste fastidieuse…mais motivante. L’alternative serait de passer par OpenShift qui semble offrir une bien plus grande simplicité de déploiement avec une intégration packagée et stabilisée.

Mais c’est aussi dépendre d’une offre commerciale (onéreuse) et d’une entreprise tierce. Il existe l’équivalent gratuit et communautaire de OpenShift appelé OKD. Mais je n’ai pas eu l’occasion de l’essayer, et pour l’instant je n’ai pas l’impression de le voir adopter massivement.

Aucune solution n’est parfaite, mais je n’ai aucune inquiétude quant à l’amélioration de l’écosystème de KubeVirt. Le projet reste intéressant à suivre et à implémenter. Je n’ai plus qu’a trouver du temps (et ce n’est pas simple) pour poursuivre tout ça et finir un jour par ne plus avoir que du Kub dans le Lab 😊 (et un peu de XCP-ng…)

(Si besoin, l'intégralité des fichiers utilisés pour ce tutoriel sont accessibles librement dans mon repo github