HOWTO : Créer une Image de Base Windows 11 avec KubeVirt et Unattend
Ce guide détaille les étapes pour créer une image Windows 11 généralisée (utilisant unattend.xml
pour Sysprep) sur un cluster Kubernetes équipé de KubeVirt. Cette image servira de modèle pour le déploiement rapide de machines virtuelles Windows 11.
Prérequis du Cluster:
Objectif: Produire un VolumeSnapshot
ou un PersistentVolumeClaim
(PVC) contenant une installation de Windows 11 généralisée, prête à être clonée pour de nouvelles VMs.
1. Prérequis
Kubernetes fonctionnel
KubeVirt installé
Stockage persistant configuré (Block, Disque, ou Partagé)
Accès réseau pour le cluster (pour télécharger les ISOs ou pour CDI)
Avant de commencer, rassemblez les éléments suivants :
- ISO Windows 11 :
Obtenez une image ISO officielle depuis le site de Microsoft.
- ISO des pilotes VirtIO :
Téléchargez la dernière image
virtio-win.iso
stable. Lien : https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/
- Fichier `unattend.xml` :
Créez ce fichier pour automatiser Sysprep et la phase OOBE (Out-Of-Box Experience). Adaptez l’exemple ci-dessous à vos besoins (langue, fuseau horaire, compte local, mot de passe).
Exemple minimal de unattend.xml<?xml version="1.0" encoding="utf-8"?> <unattend xmlns="urn:schemas-microsoft-com:unattend"> <settings pass="oobeSystem"> <component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <InputLocale>fr-FR</InputLocale> <SystemLocale>fr-FR</SystemLocale> <UILanguage>fr-FR</UILanguage> <UserLocale>fr-FR</UserLocale> </component> <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <OOBE> <HideEULAPage>true</HideEULAPage> <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen> <HideOnlineAccountScreens>true</HideOnlineAccountScreens> <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> <NetworkLocation>Work</NetworkLocation> <ProtectYourPC>1</ProtectYourPC> </OOBE> <UserAccounts> <LocalAccounts> <LocalAccount wcm:action="add"> <Password> <Value>UABzAHMAdwBvAHIAZAAxACEA</Value> <PlainText>false</PlainText> </Password> <Description>Compte Administrateur Local</Description> <DisplayName>AdminLocal</DisplayName> <Group>Administrators</Group> <Name>AdminLocal</Name> </LocalAccount> </LocalAccounts> </UserAccounts> <TimeZone>Romance Standard Time</TimeZone> </component> </settings> <settings pass="specialize"> <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <CopyProfile>true</CopyProfile> </component> </settings> <settings pass="generalize"> <component name="Microsoft-Windows-Security-SPP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SkipRearm>1</SkipRearm> </component> <component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Generalize> <Mode>VM</Mode> <ForceShutdownNow>false</ForceShutdownNow> </Generalize> </component> </settings> </unattend>
Note
Le mot de passe dans l’exemple (
UABzAHMAdwBvAHIAZAAxACEA
) correspond à “Password1!” encodé en Base64. Utilisez un mot de passe fort et générez sa version Base64 (par ex. via PowerShell :[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes("VotreMotDePasseComplexe"))
).
2. Préparation KubeVirt
- Stocker `unattend.xml` dans Kubernetes :
Utilisez un
Secret
(recommandé) ou uneConfigMap
.kubectl create secret generic win11-unattend --from-file=unattend.xml=./unattend.xml
- Rendre les ISOs accessibles à KubeVirt :
La méthode recommandée est d’utiliser CDI (Containerized Data Importer) pour importer les ISOs dans des PVCs.
Commande pour importer l’ISO Windows via CDI (adapter URL et storageClass)cat <<EOF | kubectl apply -f - apiVersion: cdi.kubevirt.io/v1beta1 kind: DataVolume metadata: name: win11-iso spec: source: http: url: "<URL_VERS_VOTRE_ISO_WINDOWS_11>" pvc: accessModes: [ "ReadWriteOnce" ] # Ou ReadOnlyMany si supporté/nécessaire resources: requests: { storage: 7Gi } storageClassName: <votre-storage-class> EOF
Commande pour importer virtio-win.iso via CDIcat <<EOF | kubectl apply -f - apiVersion: cdi.kubevirt.io/v1beta1 kind: DataVolume metadata: name: virtio-win-iso spec: source: http: url: "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso" pvc: accessModes: [ "ReadWriteOnce" ] # Ou ReadOnlyMany resources: requests: { storage: 1Gi } storageClassName: <votre-storage-class> EOF
Attendez que les DataVolumes soient
Succeeded
.
- Créer le PVC pour l’installation Windows :
Ce PVC deviendra le disque système de la VM temporaire.
Commande pour créer le PVC d’installationcat <<EOF | kubectl apply -f - apiVersion: v1 kind: PersistentVolumeClaim metadata: name: win11-install-pvc spec: accessModes: [ "ReadWriteOnce" ] # RW pour l'installation resources: requests: { storage: 80Gi } # Taille recommandée storageClassName: <votre-storage-class-block-ou-disque> # Choisir une classe performante EOF
3. Création de la VM Temporaire
Définissez la VirtualMachine
KubeVirt pour l’installation. Créez un fichier vm-template-install.yaml
:
apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
name: win11-installer
spec:
runStrategy: Manual # Démarrage manuel
template:
metadata:
labels:
kubevirt.io/domain: win11-installer
spec:
domain:
cpu: { cores: 4 }
memory: { guest: 8Gi }
resources: { requests: { memory: 8Gi } }
devices:
disks:
- name: installpvc
disk: { bus: virtio } # Pilote VirtIO disque
# bootOrder: 2
- name: winiso
cdrom: { bus: sata }
# bootOrder: 1 # Booter sur l'ISO Windows
- name: virtioiso
cdrom: { bus: sata }
- name: unattendiso # Monte le Secret/ConfigMap comme CD
cdrom: { bus: sata }
interfaces:
- name: default
masquerade: {} # Ou autre config réseau
model: virtio # Pilote VirtIO réseau
tpm: {} # Émulation TPM pour Win11
features:
acpi: {}
apic: {}
smm: { enabled: true } # Recommandé pour Windows
firmware:
uefi: { secureBoot: false } # UEFI requis pour Win11
terminationGracePeriodSeconds: 360
volumes:
- name: installpvc
persistentVolumeClaim: { claimName: win11-install-pvc }
- name: winiso
persistentVolumeClaim: { claimName: win11-iso } # PVC de l'ISO Win11
- name: virtioiso
persistentVolumeClaim: { claimName: virtio-win-iso } # PVC de l'ISO VirtIO
- name: unattendiso
secret: { secretName: win11-unattend } # Référence au Secret unattend
# Si ConfigMap:
# configMap: { name: win11-unattend-configmap }
Appliquer et démarrer :
kubectl apply -f vm-template-install.yaml virtctl start win11-installer
Se connecter à la console :
virtctl vnc win11-installer # Ou 'console'
4. Installation et Configuration Windows
Installation de Windows : * Suivez l’assistant d’installation Windows. * Lors de la sélection du disque, cliquez sur
Charger un pilote
. * Naviguez vers le lecteur CD VirtIO ->viostor
->w11
->amd64
-> chargez le pilote. Le disque PVC doit apparaître. * Terminez l’installation.Configuration post-installation : * Une fois Windows démarré, connectez-vous. * Installer les pilotes VirtIO : Exécutez
virtio-win-gt-x64.msi
depuis le CD VirtIO. * Installer QEMU Guest Agent : Exécutezqemu-ga-x86_64.msi
depuis le dossierguest-agent
du CD VirtIO. C’est essentiel pour l’intégration KubeVirt. * Configurer le réseau, activer RDP si besoin. * Installer les mises à jour Windows via Windows Update. * Installer les logiciels de base souhaités. * Nettoyer les fichiers temporaires (optionnel mais recommandé).
5. Généralisation (Sysprep)
Cette étape prépare l’image à être clonée.
Ouvrir une Invite de commandes (Admin).
Aller dans le répertoire Sysprep :
cd C:\Windows\System32\Sysprep
Identifier la lettre de lecteur du CD contenant
unattend.xml
(monté depuis le Secret/ConfigMap, ex:E:
).Exécuter Sysprep avec le fichier unattend :
sysprep.exe /generalize /oobe /shutdown /unattend:E:\unattend.xml
Remplacez ``E:unattend.xml`` par le chemin correct.
/generalize
: Supprime les informations spécifiques à la machine./oobe
: Lance l’assistant de configuration au prochain démarrage./shutdown
: Arrête la VM après Sysprep. Crucial.
La VM s’éteindra. Ne la redémarrez pas.
6. Création de l’Image de Base
Le PVC win11-install-pvc
contient l’image généralisée. Pour la préserver et l’utiliser comme modèle, deux méthodes :
- Méthode 1: Volume Snapshot (Recommandée)
Si votre stockage le supporte, créez un
VolumeSnapshot
du PVC.Création d’un VolumeSnapshot (snapshot.yaml)apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshot metadata: name: win11-base-snapshot spec: volumeSnapshotClassName: <votre-snapshot-class> # Nom de la classe de snapshot source: persistentVolumeClaimName: win11-install-pvc
Appliquez avec
kubectl apply -f snapshot.yaml
. Ce snapshot servira dedataSource
pour les PVCs des futures VMs.
- Méthode 2: Clonage de PVC
Créez un nouveau PVC en clonant le PVC d’installation.
Création d’un PVC par clonage (clone-pvc.yaml)apiVersion: v1 kind: PersistentVolumeClaim metadata: name: win11-base-image-pvc spec: accessModes: [ "ReadWriteOnce" ] # Ou ReadOnlyMany si possible storageClassName: <votre-storage-class> # Mettre la même que la source dataSource: kind: PersistentVolumeClaim name: win11-install-pvc # PVC source à cloner resources: requests: { storage: 80Gi } # Taille >= source
Appliquez avec
kubectl apply -f clone-pvc.yaml
. Attendez quewin11-base-image-pvc
soitBound
. Ce PVC cloné est votre image de base.
7. Nettoyage
Après avoir sécurisé votre image de base (via Snapshot ou Clone) :
Supprimez la VM d’installation :
kubectl delete vm win11-installer
Si vous avez utilisé la méthode de clonage, supprimez le PVC d’installation original (une fois le clone terminé) :
kubectl delete pvc win11-install-pvc
Si vous utilisez des snapshots, vérifiez si votre provisionneur nécessite de conserver le PVC source.
8. Utilisation
Vous disposez maintenant d’un VolumeSnapshot
(win11-base-snapshot
) ou d’un PersistentVolumeClaim
(win11-base-image-pvc
) qui peut être utilisé comme dataSource
lors de la création de nouveaux PVCs pour vos VM Windows 11. Chaque nouvelle VM démarrera à l’étape OOBE, prête à être configurée selon les directives de votre unattend.xml
ou manuellement.