Premier VPC, premier subnet, première VM

Premier VPC, premier subnet, première VM#

Ce tutoriel crée de bout en bout une VM joignable, sur un hyperviseur où l’agent est installé et répond. Il suppose l’API sur 127.0.0.1:8080 et une image disque déjà présente sur l’host.

Tout se passe sur un seul nœud : un subnet ne s’étend à d’autres hyperviseurs qu’une fois le plan de contrôle du cluster en place, cf. Architecture du cluster.

Ce que l’on construit#

        graph LR
  subgraph netns vp-admin
    BR["br-sn000001<br/>10.1.1.1"]
    MD["metadata@i-web<br/>169.254.169.254"]
  end
  VM["VM i-web<br/>10.1.1.2"] --- BR
  BR --- MD
  BR --- VXLAN["VXLAN vni 1<br/>br-000000"]
    

Le VPC est un network namespace ; le subnet y pose un bridge porteur de la gateway ; la VM s’y raccroche par un tap, reçoit son adresse en DHCP et son cloud-init depuis le serveur de metadata du netns.

1. Le VPC#

curl -X POST http://127.0.0.1:8080/vpcs \
  -H 'Content-Type: application/json' \
  -d '{"name": "vp-admin", "cidr": "192.168.0.0/16"}'

Le cidr est l’espace d’adressage global du VPC : c’est lui qui sera annoncé aux VM comme route interne, quel que soit le mode du subnet.

La réponse est un 202 : la création est acceptée, pas terminée.

curl -s http://127.0.0.1:8080/vpcs/vp-admin

Attendez "state": "running" avant l’étape suivante — un subnet dont le VPC parent n’est pas prêt est refusé en 422. Le modèle d’attente est décrit dans Modèle asynchrone et codes de retour.

2. Le subnet#

curl -X POST http://127.0.0.1:8080/subnets \
  -H 'Content-Type: application/json' \
  -d '{"name": "sn-000001",
       "vpc": "vp-admin",
       "mode": "vxlan",
       "vxlan_id": 1,
       "iface_type": "vms",
       "interface_ip": "10.1.1.1",
       "cidr": "10.1.0.0/23"}'

iface_type est une clé logique résolue dans la configuration de l’agent (section interfaces) vers un bridge physique de l’host ; une clé inconnue retombe sur default_interface. interface_ip est la gateway du subnet, portée par le bridge créé dans le netns.

Les modes disponibles et leurs conséquences sur le routage sont détaillés dans Modes réseau.

Là encore, attendez running :

curl -s http://127.0.0.1:8080/subnets/sn-000001

3. La VM#

curl -X POST http://127.0.0.1:8080/vms \
  -H 'Content-Type: application/json' \
  -d '{"name": "i-web",
       "memory": 2048,
       "cpus": 2,
       "uefi": true,
       "metadata": {"sshkey": "ssh-ed25519 AAAA…",
                    "user_data": "'"$(base64 < user-data.yml | tr -d '\n')"'"},
       "interfaces": [{"subnet": "sn-000001", "ip": "10.1.1.2", "primary": true}],
       "storage": [{"path": "/var/lib/two/volumes/i-web.qcow2", "dev": "vda"}]}'

Quatre points qui coûtent du temps quand on les découvre en production :

user_data est encodé en base64

Un base64 invalide est rejeté en 400 plutôt que servi vide. L’agent n’interprète jamais ce contenu.

password est un hash, pas un mot de passe

Le champ attend la valeur de la clé passwd de cloud-config ($6$…). Sans password ni sshkey, aucun compte n’est créé.

Exactement une interface est primary

Elle porte la route par défaut et le serveur de metadata. L’ordre du tableau détermine le slot PCI (0x03 + index), donc le nom de l’interface dans le guest. Tous les subnets d’une VM doivent appartenir au même VPC.

Un seul disque vdX

Les disques supplémentaires passent par sdX. La carte PCI en dépend — voir Invariants et pièges.

4. Vérifier#

curl -s http://127.0.0.1:8080/vms/i-web

En running, la VM est démarrée et le serveur de metadata est en place. Le provisionnement cloud-init, lui, se déroule dans le guest ; on l’observe par la console série :

socat -,raw,echo=0 UNIX-CONNECT:/run/two/vms/serial/i-web.sock

Puis, depuis l’host :

ssh syonad@10.1.1.2

Note

En mode vxlan, la VM vit dans le netns du VPC : elle n’est pas joignable depuis l’host sans route explicite. En mode bridge, elle l’est directement.

5. Supprimer#

Dans l’ordre inverse — un VPC dont il reste des subnets est refusé en 409 :

curl -X DELETE http://127.0.0.1:8080/vms/i-web
curl -X DELETE http://127.0.0.1:8080/subnets/sn-000001
curl -X DELETE http://127.0.0.1:8080/vpcs/vp-admin

La suppression d’une VM ne touche jamais aux fichiers disque.

Avertissement

instance-id vaut le nom de la VM. Recréer une VM du même nom sur le même disque fait que cloud-init la reconnaît et n’applique pas le user-data. Pour rejouer un provisionnement, changez de nom ou repartez d’un disque neuf.