Pour créer une machine virtuelle avec vSphere with Tanzu via la commande kubectl, il y a des étapes à respecter pour l’administrateur et pour le développeur, elles sont très simples mais ce ne m’a pas empêché de perdre un peu de temps coté personnalisation sur la partie OS.
je vous recommande cet article pour comprendre l’intéret de déployer des VM via Kubernetes : Déployer des VMs dans et via Kubernetes. Le blog de mon collègue : Introducing Virtual Machine Provisioning, via Kubernetes with VM Service | VMware est aussi très bien détaillé.
Dans la dernière partie cet article, je vais apporter quelques précisions sur la partie Content Library et sur la partie YAML. Mais d’abord, revoyons avant les partie à faire coté administrateur et coté développeur
Concernant l’administrateur
La première étape consiste à télécharger les images VMs qui sont différentes de celles utilisées pour TKC (Tanzu Kubernetes Cluster aussi appelé Guest Cluster). Les images sont disponibles dans la marketplace VMware, au moment de la rédaction de cet article, il y en a 2 (Ubuntu et Centos), la version Ubuntu actuelle ne permet pas l’utilisation de volume persistent (PVC) car elle est basée sur une version virtual hardware 10 et il faut au minimum une version 12, ce problème va bientôt être corrigé.
Il faut aller sur la marketplace et faire une recherche avec le mot clé « vm service », ça permet de filtrer (un peu) les images compatibles => VMware Marketplace.
Ensuite cliquer sur l’image souhaitée, se connecter avec son compte MyVMware.
Vous avez deux possibilités, la télécharger puis la charger dans une content library locale
ou récupérer l’url de souscription pour créer une content library qui se synchronisera à celle hébergée par VMware.
Une fois l’image chargée ou le lien renseigné, vous devriez avoir une content library de ce type :
Toujours depuis l’interface vSphere, il faut maintenant créer, un namespace, octroyer les droits aux utilisateurs pour qu’ils puissent s’y connecter, affecter la classe de VM, la content library et la classe de stockage, ce qui devrait donner ceci :
L’exemple ci-dessus montre une fois le namespace créé, comment affecter une classe de VM, une content library, autoriser les développeurs qui pourront consommer ce namespace, quelle classe de stockage à utiliser et enfin si besoin caper les ressource, CPU, mémoire et stockage.
C’est tout ce qu’il y a à faire coté administrateur d’infrastructure.
Concernant le développeur
Il faut un descriptif YAML pour :
- La configmap qui contient la personnalisation de la VM
- La création de la VM
- Le service réseau si vous souhaitez vous y connecter à partir d’un réseau extérieur (optionnel)
- Le PVC si vous souhaitez utiliser des volumes persistants (optionnel)
Via la commande Kubernetes, le développeur se connecte avec son compte au Namespace fourni, il pourra ainsi lister les classes de services qu’il peut utiliser ainsi que les images qu’il pourra déployer.
kubectl get virtualmachineclass
NAME CPU MEMORY AGE
best-effort-2xlarge 8 64Gi 22d
best-effort-4xlarge 16 128Gi 22d
best-effort-8xlarge 32 128Gi 22d
best-effort-large 4 16Gi 22d
best-effort-medium 2 8Gi 31d
best-effort-small 2 4Gi 31d
best-effort-xlarge 4 32Gi 22d
best-effort-xsmall 2 2Gi 22d
..
guaranteed-xsmall 2 2Gi 22d
kubectl get virtualmachineimage
NAME VERSION OSTYPE FORMAT AGE
centos-stream-8-vmservice-v1alpha1-1619529007339 centos8_64Guest ovf 4h8m
ob-15957779-photon-3-k8s-v1.16.8—vmware.1-tkg.3.60d2ffd v1.16.8+vmware.1-tkg.3.60d2ffd vmwarePhoton64Guest ovf 2d19h
ob-16466772-photon-3-k8s-v1.17.7—vmware.1-tkg.1.154236c v1.17.7+vmware.1-tkg.1.154236c vmwarePhoton64Guest ovf 2d19h
ob-16545581-photon-3-k8s-v1.16.12—vmware.1-tkg.1.da7afe7 v1.16.12+vmware.1-tkg.1.da7afe7 vmwarePhoton64Guest ovf 2d19h
……
ubuntu-20-1621373774638 ubuntu64Guest ovf 4h8m
Il peut ainsi créer ses fichiers descriptifs YAML afin de définir ses besoins en ressources pour sa ou ses machines virtuelles et s’ils le souhaitent, il peut la ou les personnaliser afin d’y installer ses outils.
Le fichier descriptif configmap, comprend la personnalisation de la VM. Les 3 champs importants à renseigner pour la personnalisation sont :
- Le hostname qui contient le hostname de l’OS
- La public-keys, qui contient la clé publique d’un poste à partir duquel on se connectera à l’os en ssh.
- La partie user-data est, si vous le souhaitez, l’endroit où on met le contenu du fichier de configuration Cloud Init, il faudra le chiffrer avec la commande base64.
cat loeil-du-se-vm-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: loeil-du-se-vm-configmap # Le nom de la ConfigMap, doit être le même que celui référencé dans le YAML de la VirtualMachine
namespace: loeil-du-se
data:
# Champs OVF utilisés lors du déploiment de la VM
hostname: loeil-du-se
public-keys: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDC4Cclh3rN/l70lBNlwQyK6ZtugxqT/7HeerHZKPSO0hcl5ZWLvz2+7QG5FqvYbkPP6EomvyDhE2MPnQ0kWaIrumVxYXAbVdpBBKKdTI3xJpewWB2syxgVOXP2ZOrw4cRLFv18rnESGHfsohedyaSB1qvubPWAqBFa+PSS4xh3zKalUknwc7Bs14fci8tEwEg8cpvNsqvrPZliJ6qTYFGqKuG6Ct+y449JNW6k6itTepgSYvUdJfjBTxk5tDzBdWz28km5N7lxgUB0rIWgSDl1XLCBrmm+H6bkHtD59MxAuxwLjih4tS4PzspcVjwWiJhd0HH7u2wbsPLCrrAX7am4EP40zphu9IR+fVxk+2jp7eD2uXPS6p9sDPEWHl6wGclI7pnfuoyvcn+CIwCtMweLuUw5MPj2eIIXcBhqUffeVAXVHrx8+e7+yHvqfyhqm2J9Ay3yt3zvAcXW0VqDxfvnfmv8sc9VNUW+8fUeyoo4b4uZRLLSf2DHM8= root@fbenrejdal-z01 # Clé publique SSH du poste permettant de se connecter sans mot de passe à l’OS de la VM
user-data: | # optionel, le contenu chiffré en base64 du fichier Cloud Init. La clé peut être sur une seule ligne ou sur plusieurs, elle doit démarrer au niveau du “r” sous user-data
I2Nsb3VkLWNvbmZpZwojIFdBVENIT1VUIHRoZSBmaXJzdCBsaW5lIG11c3Qgc3RhcnQgd2l0aCAj
Y2xvdWQtY29uZmlnCmdyb3VwczoKICAtIGRldm9wcwp1c2VyczoKICAtIGRlZmF1bHQgIyBDcmVh
dGUgdGhlIGRlZmF1bHQgdXNlciBmb3IgdGhlIE9TCiAgLSBuYW1lOiBmYmUKICAgIHNzaC1hdXRo
b3JpemVkLWtleXM6ICMgdGhlIHB1YmxpYyBrZXkgb2YgbXkgbGFwdG9wLCBpdCBjb3VsZCBhbHNv
IGJlIGZpbGxlZCBpbiB0aGUgT1ZGIHByb3BlcnR5CiAgICAgIC0gc3NoLXJzYSBBQUFBQjNOemFD
MXljMkVBQUFBREFRQUJBQUFCZ1FEQzRDY2xoM3JOL2w3MGxCTmx3UXlLNlp0dWd4cVRHLzdIZWVy
SFpLUFNPMGhjbDVaV0x2ejIrN1FHNUZxdllia1BQNkVvbXZ5RGhFMk1QblEwa1dhSXJ1bVZ4WVhB
YlZkcEJCS0tkVEkzeEpwZXdXL0Iyc3l4Z1ZPWFAyWk9ydzRjUkxGdjE4cm5FU0dIZisvc29oZWR5
YVNCMXF2dWJQV0FxQkZhK1BTUzR4aDZELzN6S2FsVWtud2M3QnMxNGZjaTh0RXdFZzhjcHZOc3F2
clBabGlKNnFUWUZHcUt1RzZDdCt5NDQ5Sk5XNms2aXRUZXBnU1l2VWRKZmpCVHhrNXREekJkV3oy
OGttNU43bHhnVUIwcklXZ1NEbDFYTENCcm1tK0g2YmtIdEQ1OU14QXV4d0xqaWg0dFM0UHpzcGNW
dGFydCBtb25nb2QK
La base64 est obtenu de la manière suivante :
base64 loeil-du-se-vm-cloud-init.yaml
Son contenu en clair :
cat loeil-du-se-vm-cloud-init.yaml
#cloud-config
# ATTENTION la première ligne doit commencer par #cloud-config
groups:
– devops
users:
– default # Créé l’utisateur par défaut
– name: fbe
ssh-authorized-keys: # Clé SSH de mon laptop me permettant de me connecter via SSH sans mot de passe. Clé déjà renseignée dans la configmap
– ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDC4Cclh3rN/l70lBNlwQyK6ZtugxqTG7HeerHZKPSO0hcl5ZWLvz2+7QG5FqvYbkPP6EomvyDhE2MPnQ0kWaIrumVxYXAbVdpBBKKdTI3xJpewWB2syxgVOXP2ZOrw4cRLFv18rnESGHf+sohedyaSB1qvubPWAqBFa+PSS4xh6D3zKalUknwc7Bs14fci8tEwEg8cpvNsqvrPZliJ6qTYFGqKuG6Ct+y449JNW6k6itTepgSYvUdJfjBTxk5tDzBdWz28km5N7lxgUB0rIWgSDl1XLCBrmm+H6bkHtD59MxAuxwLjih4tS4PzspcVjwWiJhd0HH7u2wbsPLCrrAX7am4EP40zphu9IR+fVxk+2jp7eD2uXPS6p9sDPEWHl6wGclI7pnfuoyvcn+CIwCtMweLuUw5MPj2eIIXcBhqUffeVAXVHrx8+e7+yHvqfyhqm2J9Ay3yt3zvAcXW0VqDxfvnfmv8sc9VNUW+8fUeyoo4b4uZRLLSf2DHM8= root@fbenrejdal-z01
groups: sudo, devops
shell: /bin/bash
passwd: VMware1!
sudo: [‘ALL=(ALL) NOPASSWD:ALL’] # l’utilisateur fbe n’aura pas à rentrer de mot de passe avec la commande sudo
ssh_pwauth: true
chpasswd:
list: |
fbe:VMware1! # changer le mot de passe de l’utilisateur fbe
expire: false # Pour que le mot de passe n’expire pas
runcmd: # Exemple de runcmd pour installer MongoDB. Cloud Init est aussi capable d’utiliser directement APT pour faire des installations
– echo “deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse” | tee /etc/apt/sources.list.d/mongodb-org-4.4.list
– wget -qO – https://www.mongodb.org/static/pgp/server-4.4.asc | apt-key add –
– echo “deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse” | tee /etc/apt/sources.list.d/mongodb-org-4.4.list
– apt-get update
– apt-get install -y mongodb-org
– echo “mongodb-org hold” | dpkg –set-selections
– echo “mongodb-org-server hold” | dpkg –set-selections
– echo “mongodb-org-shell hold” | dpkg –set-selections
– echo “mongodb-org-mongos hold” | dpkg –set-selections
– echo “mongodb-org-tools hold” | dpkg –set-selections
– sed -i ‘s/127.0.0.1/0.0.0.0/’ /etc/mongod.conf
– ufw allow from any to any port 27017 proto tcp
– sleep 2
– systemctl start mongod
Très très important, le fichier doit absolument commencer par #cloud-config et pas autre chose. Ça reste un fichier Cloud Init classique.
Si vous ne maitrisez pas trop Cloud Init, j’y ai mis des commentaires pour que ce soit un peu plus lisible.
Le fichier descriptif de la VM
cat loeil-du-se-vm-deployment.yaml
apiVersion: vmoperator.vmware.com/v1alpha1
kind: VirtualMachine
metadata:
name: loeil-du-se-vm
namespace: loeil-du-se
labels:
vm: loeil-du-se-vm
spec:
imageName: ubuntu-20-1621373774638 #L’image doit être présente dans la content library et visible via la commande kubectl get virtualmachineimage
className: best-effort-xsmall
powerState: poweredOn
storageClass: silver-storage-policy
networkInterfaces:
– networkType: nsx-t # soit nsx-t ou vsphere-distributed en fonction de votre installation
# networkName: si -networkType est vsphere-distributed il faut mettre le nom du port group des workload
vmMetadata:
configMapName: loeil-du-se-vm-configmap # Nom de la configmap où la personnalisation de la VM est stockée
transport: OvfEnv
#
# Au moment de l’écriture de cet article l’image ubuntu (ubuntu-20-1621373774638) ne peut pas utiliser les volumes car elle est basée sur la version 10 du virtual hardware est il faut au minimum qu’elle soit en 12
# L’image centos image (centos-stream-8-vmservice-v1alpha1-1619529007339) peut utiliser des volumes
# volumes: # au moment de l’écriture de cet article, le paramètre mount n’est pas utilisable, le volume est vu mais doit être monté à la main ou via Cloud Init
# – name: loeil-du-se-volume
# persistentVolumeClaim:
# claimName: loeil-du-se-pvc
# readOnly: false
Optionnel, le fichier descriptif du service réseau
Dans mon exemple, je créé un service de type LoadBalancer pour me connecter en ssh à partir d’un réseau externe à celui des PODs.
Attention, le kind n’est pas Service comme habituellement mais VirtualMachineService
cat loeil-du-se-vm-service.yaml
apiVersion: vmoperator.vmware.com/v1alpha1
kind: VirtualMachineService
metadata:
name: loeil-du-se-vm
spec:
selector:
vm: loeil-du-se-vm
type: LoadBalancer
ports:
– name: ssh
port: 22
protocol: TCP
targetPort: 22
Une fois les fichiers YAML créés, il ne reste plus qu’à les faire prendre en compte par Kubernetes.
Kubectl create -f loeil-du-se-vm-configmap.yaml
Kubectl create -f loeil-du-se-vm-deployment.yaml
Kubectl create -f loeil-du-se-vm-service.yaml
Pour verifier la creation de la VM :
Kubectl get vm
Pour en savoir un peu plus :
Kubectl describe vm loeil-du-se-vm
Ca reste une VM classique, donc elle va bénéficier de HA et vMotion (via DRS ou mode maintenance du host). Par contre, elle est « Developer Managed », c’est-à-dire qu’elle n’est pas administrable via le vCenter, vous ne verrez pas par exemple le contenu de la console.
Une astuce tout de même, vérifiez sur quel ESXi la VM s’exécute, ensuite connectez-vous directement sur l’ESXi via un navigateur et là vous aurez accès à la console.
Pour se connecter en ssh, si vous avez comme moi un accès via un loadbalancer vous pouvez vous y connecter directement, sinon vous devrez passer par un POD de rebond (genre busybox, alpine ou autre) et faire un ssh avec l’adresse IP sur le réseau de POD. Vous pouvez la retrouver ainsi :
kubectl get vm loeil-du-se-vm -o jsonpath='{.status.vmIp}’; echo
10.244.0.130
Le ssh doit se faire via le user renseigné dans le Cloud Init, j’avais mis fbe, ca donne ça :
kubectl get svc loeil-du-se-vm
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
loeil-du-se-vm LoadBalancer 10.96.1.108 172.20.18.71 22:32148/TCP 2d22h
ssh fbe@172.20.18.71
…
To run a command as administrator (user “root”), use “sudo <command>”.
See “man sudo_root” for details.
fbe@loeil-du-se:~$
Si le ssh ne fonctionne pas, c’est que le user n’a pas était pris en compte par Cloud Init, essayez avec root pour obtenir le user par défaut, en générale ubuntu pour Ubuntu et cloud-user pour CentOS :
ssh roo@172.20.18.71
Please login as the user “ubuntu” rather than the user “root”.
Si vous avez l’erreur ci-dessous, c’est que le poste à partir duquel vous vous connectez n’a pas la clé ssh publique renseignée ou il y a une erreur dans celle-ci, il faut donc vérifier la clé figurant dans le fichier de configmap :
fbe@172.20.18.71: Permission denied (publickey,password).
Pour debugger Cloud Init, il faut se connecter à l’os de la vm via ssh ou via la console est regardez la log /var/log/cloud-init-output.log
Voilà, n’hésitez pas à me pinger si vous avez besoin d’informations complémentaires.
Laisser un commentaire