Aperçu de bhyve - Episode 2 vmrc
Dans l'article Aperçu de bhyve - Episode 1 vmrun.sh nous avons vu que bhyve est intéressant mais que le script vmrun.sh est trop limité pour pouvoir se faire plaisir. Nous allons voir si vmrc nous offre plus de possibilités ou non.
Installation de vmrc
Voyons si vmrc est disponible dans les dépôts pkgng :
# pkg search vmrc
Arf non :( ! Et visiblement il n'est pas non plus dans les ports. Il va falloir l'installer à la main. Bon, commençons par installer git :
# pkg install git
Puis récupérons les sources du projet :
# git clone https://github.com/michaeldexter/vmrc.git
Entrons dans le répertoire et installons le tout à l'aide des script install-vmrc.sh et install-templates.sh :
# cd vmrc # ./install-vmrc.sh # cd templates # ./install-templates.sh
La documentation de vmrc recommande sysutils/grub2-bhyve pour les guest Linux :
# pkg install grub2-bhyve
Utilisation de vmrc
Création d'un guest FreeBSD
Dans le répertoire de vmrc récupéré par git (/root/vmrc dans notre exemple) se trouve le script mkvm.sh qui permet de choisir le type de vm dont on a besoin et d'en automatiser la création et l'installation. Exécutons mkvm.sh :
# cd /root/vmrc # ./mkvm.sh
Nous pouvons alors choisir le type de VM que nous souhaitons créer :
Listing templates in /usr/local/vmrc/templates/ t_centos65 t_freebsd92stablezfs t_pfsense-fetch.sh t_freebsd10 t_freebsd92zfs t_ubuntu1304 t_freebsd10malloc t_freenas t_ubuntu1310 t_freebsd10zfs t_freenas-fetch.sh virtio21pf t_freebsd11current t_master_template virtio83 t_freebsd11currentzfs t_openbsd virtio83pf t_freebsd92 t_openbsd-fetch.sh virtio84 t_freebsd92stable t_pfsense virtio91 Enter a template to use:
Ici comme je veux une VM Freebsd classique j'ai sélectionné t_freebsd10 et validé. Ensuite on donne un nom à la vm, j'ai mis freebsd.
Enter a custom name without ID or leave blank to keep vm2 freebsd
Le script va créer un disque virtuel de 2G puis télécharger les différents sets (base.txz et kernel.txz) de FreeBSD pour les installer. Voyons maintenant si on peut booter. Pour cela on va utiliser le service vm qu'on doit activer dans le /etc/rc.conf.local :
vm_enable="YES"
Puis on démarre la vm :
# service vm start freebsd vm: starting freebsd vm: freebsd: no configuration file found: Skipping...
Wow ! Cela ne fonctionne pas ! Étrange. Jetons un œil au /usr/local/vmrc/vm :
# ls /usr/local/vmrc/vm/ freebsd2 openbsd01 vm0
Il semble qu'il ait décidé de nommer ma vm freebsd2. Je sens venir les confusions quand on commence à avoir beaucoup de vm, mais peut-être que j'aurais du choisir un autre nom. Bon, soit, utilisons freebsd2 :
# service vm start freebsd2 vm: starting freebsd2 starting freebsd2 Entering f_load() Entering f_eptcheck() Entering f_vmmcheck() f_vmmcheck: vmm.ko kernel module not loaded. Loading... f_netstart: bridgestp.ko kernel module not loaded. Loading... f_netstart: if_bridge.ko kernel module not loaded. Loading... f_netstart: if_tap.ko kernel module not loaded. Loading... net.link.tap.up_on_open: 0 -> 1 Creating the bridge0 network interface. Associating em0 with bridge0. Running: ifconfig bridge0 addm em0 up f_load: Attaching raw image /usr/local/vmrc/vm//freebsd2/freebsd2.img for fsck f_load: DEBUG: disk image is /usr/local/vmrc/vm//freebsd2/freebsd2.img; vm_device is md1 f_load: fsck_ufs -y md1p2 ** /dev/md1p2 ** Last Mounted on /usr/local/vmrc/vm/freebsd2/mnt ** Phase 1 - Check Blocks and Sizes ** Phase 2 - Check Pathnames ** Phase 3 - Check Connectivity ** Phase 4 - Check Reference Counts ** Phase 5 - Check Cyl groups 13303 files, 139007 used, 368296 free (208 frags, 46011 blocks, 0.0% fragmentation) ***** FILE SYSTEM MARKED CLEAN ***** Entering f_mddestroy() f_mddestroy: Destroying all memory devices associated with freebsd2 f_mddestroy: Destroying mdconfig device: md0 mdconfig: ioctl(/dev/mdctl): Device busy f_mddestroy: Destroying mdconfig device: md1 f_load: Running the bhyveload command: /usr/sbin/bhyveload -m 1024 -d /usr/local/vmrc/vm//freebsd2/freebsd2.img freebsd2 Consoles: userboot FreeBSD/amd64 User boot, Revision 1.1 (root@snap.freebsd.org, Thu Jan 16 22:18:02 UTC 2014) Loading /boot/defaults/loader.conf can't find 'kernel' - can't load 'kernel' Type '?' for a list of commands, 'help' for more detailed help. OK
Bon, ça ne marche toujours, cependant je remarque les points suivants :
- vmrc va monter les modules si nécessaires, comme vmm
- vmrc vérifier le système de fichiers du disque virtuel avant de le monter
- vmrc créé un bridge sur l'hôte, et ça c'est cool
Bon, changeons de tty (ctrl+alt+f2 ou alt+f2 pour vmware) et arrêtons la vm :
service vm stop freebsd2
Ensuite retournons en tty1 et voyons ce qui s'est passé. Analysons le contenu de /usr/local/vmrc/vm/freebsd2/mnt pour voir si le kernel est effectivement manquant (on remarque au passage que vmrc a la délicatesse de faire un point de montage, afin de voir depuis l'hôte ce qu'il y a dans le fichier freebsd2.img) :
# ls /usr/local/vmrc/vm/freebsd2/mnt/ .cshrc bin lib proc sys .profile boot libexec rescue tmp .snap dev media root usr COPYRIGHT etc
Hum, à première vue tout semble correct, mais il semble qu'un fichier kernel soit manquant dans boot/kernel.
Faisons une autre machine virtuelle pour voir, que nous nommons freetest :
# cd /root/vmrc # ./mkvm
Bon on remarque qu'il la nomme freetest3. Aucune importance, démarrons cette VM
# service vm start freetest3 ______ ____ _____ _____ | ____| | _ \\ / ____| __ \\ | |___ _ __ ___ ___ | |_) | (___ | | | | | ___| '__/ _ \\/ _ \\| _Cette fois, cela fonctionne. Donc pour une raison inconnue, la dernière fois l'installation du kernel ne s'est pas terminée correctement.
Connectons-nous à la console de freetest3 :
# service vm attach freetest3On voit alors toute la séquence de démarrage, puis on arrive au login :
Thu Jul 24 07:21:19 PDT 2014 FreeBSD/amd64 (bhyve) (console) login:Question idiote : quel est le mot de passe root défini par mkvm ? Apparemment ce n'est pas root, ce n'est pas vide, ce n'est pas le nom de la vm. Et les instructions ne disent rien à ce sujet. Passons sur le tty2 (ctrl+alt+f2 ou alt+f2) et jetons un œil au script lui-même :
# cat /usr/local/vmrc/templates/t_freebsd10 | grep password vm_password="bsd" # VM password (clear text for now) (FreeBSD only)Voilà ! Le mot de passe root est bsd !
Voyons si la connexion à internet fonctionne :
# ping 8.8.8.8Hum ! Apparemment non ! Essayons de voir pourquoi :
# cat /etc/rc.conf [...] ifconfig_vtnet0="192.168.2.210 netmask 255.255.255.0" defaultrouter="192.168.2.1" [...]Hum, ce sous-réseau ne correspond pas au réseau de l'hôte (192.168.232.0/24), donc à moins qu'il y ait du NAT cela ne peut pas marcher aussi facilement. Sur l'hôte, la commande pfctl -sr m'indique que pf ne fonctionne pas. Donc pas de NAT. Jetons un œil au /usr/local/vmrc/vm/freetest3/freetest3.conf :
[...] vm_ipv4="192.168.2.210" # VM IPv4 address (blank for DHCP) (FreeBSD only) vm_gw="192.168.2.1" # VM IPv4 gateway (FreeBSD only) [...]Donc modifions cela pour spécifier une adresse sur la même plage que l'hôte, en partant du principe que vmrc active un bridge :
[...] vm_ipv4="192.168.232.210" # VM IPv4 address (blank for DHCP) (FreeBSD only) vm_gw="192.168.232.1" # VM IPv4 gateway (FreeBSD only) [...]Puis redémarrons la VM :
# service vm restart freetest3Entrons dans la VM et modifions son /etc/rc.conf :
ifconfig_vtnet0="192.168.232.210 netmask 255.255.255.0" defaultrouter="192.168.232.1"Relançons le réseau :
# service netif restartLançons maintenant un ping vers internet :
# ping 8.8.8.8Hum, encore une fois, cela ne marche pas. Essayons un ping vers 192.168.232.1, la passerelle vmware :
# ping 192.168.232.1 PING 192.168.232.1 (192.168.232.1): 56 data bytes 64 bytes from 192.168.232.1: icmp_seq=0 ttl=128 time=2.127 msCette fois ça fonctionne !
Donc dans mon cas pas d'accès à internet, mais j’émets l'hypothèse suivante : c'est VMware qui refuse les paquets venant de mon bridge.
Le bilan est déjà beaucoup plus positif qu'avec vmrun.sh. Nous sommes parvenus à installer - très facilement - et à faire fonctionner un guest FreeBSD10. Nous n'avons pas pu utiliser le réseau, mais nous n'étions pas loin.
Guest Linux
Reprenons notre ISO de debian, debian-7.6.0-amd64-netinst.iso, et voyons si vmrc va réussir à la booter et à installer un système invité debian. Jetons un œil aux templates :
# ls /usr/local/vmrc/templates/ t_centos65 t_freebsd92stablezfs t_pfsense-fetch.sh t_freebsd10 t_freebsd92zfs t_ubuntu1304 t_freebsd10malloc t_freenas t_ubuntu1310 t_freebsd10zfs t_freenas-fetch.sh virtio21pf t_freebsd11current t_master_template virtio83 t_freebsd11currentzfs t_openbsd virtio83pf t_freebsd92 t_openbsd-fetch.sh virtio84 t_freebsd92stable t_pfsense virtio91Pas de template pour debian :( mais comme je suis fou, je vais prendre le template t_ubuntu1304 et le modifier pour Debian. Je commence par le dupliquer :
# cd /usr/local/vmrc/templates # cp t_ubuntu1304 t_debian76Puis j'édite mon template :
# My awesome debian template vm_cpus="1" # Number of VM virtual CPUs (max 16) vm_ram="256" # VM RAM Allocation in MB vm_console="nmdm" # stdio, nmdm, tmux or tmux-detached (sysutils/tmux) vm_os_type="linux" # freebsd, openbsd, or linux vm_os_ver="debian7.6" # Exact OS version if auto-fetching vm_dev_layout="gpt" # "gpt" or "mbr" volume layout (FreeBSD only) vm_dev_type="img" # "img" for image, "zvol" or blank for other device vm_device="" # An existing device (sans /dev/) i.e. "ada1" vm_dev_size="10G" # M or G for raw "img" volumes vm_hostname="" # VM hostname (FreeBSD only) vm_timezone="" # VM timezone (FreeBSD only) vm_ipv4_addr="" # Experimental for jail use vm_searchdomain="" # (FreeBSD only) Commented out below vm_dns_addr="" # (FreeBSD only) Commented out below dist_site="" # Hostname and directory for binary distribution sets iso_site="http://cdimage.debian.org/debian-cd/7.6.0/amd64/iso-cd/" # Hostname and directory for ISO image iso_img="debian-7.6.0-amd64-netinst.iso" # ISO filename for remote fetch grub_boot_cmd="/usr/local/sbin/grub-bhyve -r hd0,msdos1 -m ${host_vmroot}/${vm_name}/device.map -M $vm_ ram $vm_name" # grub-bhyve command to boot from IMG grub_iso_cmd="/usr/local/sbin/grub-bhyve -r cd0 -m ${host_vmroot}/${vm_name}/device.map -M $vm_ram $vm_ name" # grub-bhyve command to boot from ISO vm_hostbridge="" # "amd_" for the AMD hostbridge bhyve_flags="" # Additional bhyve(8) flags virtio_type="virtio-blk" # "ahci-hd" or "virtio-blk"Ensuite on lance la création de la vm que je vais nommer debian:
# cd /root/vmrc # ./mkvm.shDurant la création de la VM, j'obtiens beaucoup d'erreurs de ce type :
No such file or directoryJe remarque que le template semble se comporter comme pour un guest FreeBSD car je vois passer du loader.conf. Même problème si j'utilise les templates ubuntu fournis. Sont-ils bugués ? Bon, la documentation dit qu'après avoir provisionné la vm, il faut utiliser une commande particulière pour la démarrer vu qu'on utilise une iso. On va partir du principe que le provisionnement est fait et lancer la fameuse commande :
# /usr/local/etc/rc.d/vm iso debian0 vm: booting the ISO for VM debian0 Entering f_grubcheck() Entering f_tmuxcheck() Entering f_eptcheck() Entering f_vmmcheck() f_vmmcheck: vmm.ko is loaded. f_netstart: bridgestp.ko is loaded. f_netstart: if_bridge.ko is loaded. f_netstart: if_tap.ko is loaded. f_netstart: bridge0 exists. member: em0 flags=143f_netstart: em0 is assoc. with host0. Entering f_iso() f_iso: /usr/local/vmrc/vm//debian0/debian0.img found. f_iso: Checking for /usr/local/vmrc/distributions//debian7.6/ f_iso: Checking for /usr/local/vmrc/vm//debian0/debian0.iso f_iso: Fetching debian-7.6.0-amd64-netinst.iso /usr/local/vmrc/distributions//debian7.6//debi100% of 222 MB 2520 kBps 01m30s f_iso: Copying debian-7.6.0-amd64-netinst.iso to /usr/local/vmrc/vm//debian0/debian0.iso Copying debian-7.6.0-amd64-netinst.iso to /usr/local/vmrc/vm//debian0/debian0.iso f_iso: Creating /usr/local/vmrc/vm//debian0/device.map (hd0) /usr/local/vmrc/vm//debian0/debian0.img (cd0) /usr/local/vmrc/vm//debian0/debian0.iso f_iso: Running the ISO grub command: /usr/local/sbin/grub-bhyve -r cd0 -m /usr/local/vmrc//debian0/device.map -M 256 debian0 Could not create VM debian0 Error in initializing VM funcname: Calling f_boot Entering f_boot() f_boot: debian0 is not loaded. Skipping... Fail... encore une fois, pas moyen de démarrer Linux. Mais j'ai l'impression que cette fois le problème est localisé sur grub2-bhyve, car vmrc a bien téléchargé l'iso et commandé l'exécution de la vm.
L'article étant assez long, on va s'arrêter là.
Crashes et incidents
J'ai observé plusieurs crashes ou comportements étranges avec FreeBSD. J'ai rencontré des freezes du système, mais le bug le plus ennuyeux et le plus fréquent est celui de l'auto-démarrage des vm. En effet, puisqu'on a ajouté vm_enable="YES" au rc.conf.local , les vm sont lancées au démarrage de l'hôte. En soit ce n'est pas grave, sauf que les vm se lancent au premier plan, et bloquent systématiquement sur le bootloader. A ce stade aucune frappe clavier ne peut être prise en compte. Il faut donc redémarrer FreeBSD directement dans la console vmware et appuyer sur CTRL+c au boot pour annuler le lancement des vm. C'est un bug critique et très embêtant qui retire toute possibilité d'utiliser vmrc en production pour le moment. J'ai également fait face à un autre problème étrange : le mot de passe root de l'hôte qui saute. Parfois, après un reboot ou le lancement d'une vm, je suis dans l'incapacité de me logger en root sur l'hote, que ce soit en direct ou en SSH, car le mot de passe est refusé. Je n'ai pas d'autre solution que de me réinitialiser ou charger un snapshot VMware pour revenir en arrière.
Conclusion
vmrc apporte beaucoup par rapport au script vmrun.sh puisqu'il permet d'automatiser l'installation des vm, à la manière de lxc ou ezjail, ce qui nous facilite assez la vie. Cependant seuls les templates FreeBSD semblent fonctionnels et je n'ai toujours pas pu démarrer un guest Linux. Pas d'accès au réseau non plus mais je ne tire pas de conclusions sur ce point. Enfin on sent le côté expérimental de vmrc avec des bugs critiques au démarrage de l'hôte notamment, qui empêchent toute utilisation en production pour le moment. J'essaie de contacter l'auteur de vmrc pour obtenir de l'aide sur ce point. vmrc est un projet intéressant à suivre.
Dans le prochain