Contents
Puppet deployment
Puppet deployment is under development, see the puppet 4.x/5.x control repository.
on a testé sur sur les nodes/cluster GanetiCluster en KVM
Suivre la procédure PratiquesCréationServeur et configurer avec Puppet.
- Assigner au moins in IP publique
- Assurer que la machine est connecté dans le bon VLAN
Comment determines-t-on le bon VLAN? -- need documentation about this in PratiquesCréationServeur
Dans le manifest puppet, eg.
node 'vices.koumbit.net' { include role::ganeti }
- In the hierdata, enter something similar to
--- # Add cluster SSH public key # Note this will need to be changed if the cluster key changes. # Also, the purging of the root ssh authorized keys could be done to avoid managing this profile::admins::root_ssh_keys: stratus: type: ssh-rsa pubkey: 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDgALI5xWDMpl2hpgiGxRMIfXScrCkCmSzJ2+6JsQPx8j/Z0l5Hvl0bY6L/HbAdEPcAesidzq9ziBYKvryoAIu+ab6KM/4ZIXTM8vZIj2H6thE5tI4qg5/Okp8a9T5ZwFS7vDnh41XJckaZQSBOWugn7n0Pd0geQ2Hux56VeVf1cwm4n1n2uujzUVay1uUdIQA9F/jqy/hrnjz+b4dOjMN/wkMM/34Q9XD0Q2Gjna0L0M9wlRLFmr22w/1HxY0EB302nmstWOoYwHgalct02lLal/AwfubFCBr8xLvcxEcky4Qbu4TSCCrt7oWXqcZF51OKM82JhytYMe7/oAA1e8a/' # We still use Xen in the client cluster # Defaults to kvm if not set here profile::ganeti::hypervisor: 'xen' # We don't use DRBD in our client cluster presently profile::ganeti::drbd: false # Set up network bridge for ganeti # Note: make sure the serial console works and you have connection before starting to manage the network configuration # the puppet run _may_ cut the networking in some cases. profile::network::interfaces: eth0: ipaddress: '' method: manual br0: ipaddress: '199.58.81.108' netmask: '255.255.255.192' gateway: '199.58.81.65' bridge_ports: - eth0 bridge_stp: 'off' bridge_fd: '0'
- (For a new cluster) Manually initialize the cluster
- Use @gnt-cluster initialize@
- Choose and set MAC address prefix
Disable capacity checks except for DRBD nodes:
gnt-cluster modify --default-iallocator-params='-no-capacity-checks'
Integrate the node into an existing cluster manually (gnt-node add, see GanetiMaintenance)
Config DRBD
On a des instructions pour la configuration manuelle de DRBD. Mais comme c'est géré par puppet, le mieux c'est de laisser puppet installer et configurer les choses.
Attention, ça demande un reboot de la machine.
Créer un nouveau cluster
Un détail important à noter: le Volume Group (VG) LVM qui contient les VMs doit avoir le même nom sur toutes les nodes dans le cluster. Donc lors de la création d'un cluster, il faut prévoir un nom de VG et l'utiliser de façon consistente sur toutes les nodes.
S'il s'agit d'un nouveau cluster complètement indépendant des clusters existants, il faut créer un nouveau nom de domaine et réserver une adresse IP dans le bon réseau. Il faut s'assurer que le reverse pointe sur le même nom de domaine.
Ensuite, rouler gnt-cluster init (ici on créé un cluster qui utilise kvm uniquement):
gnt-cluster init --enabled-hypervisors=kvm \
-s 10.0.0.81 \
--master-netdev=br0 --vg-name=data \
-N link=br0 -B vcpus=2,memory=512M \
--uid-pool=4000-4019 \
-H kvm:vhost_net=True,kernel_path="",initrd_path="",serial_console=True,serial_speed=115200,security_model=pool,migration_bandwidth=70 \
<nom du cluster>.koumbit.net
Notez comment on utilise --secondary-ip (-s) pour prévoir qu'on a un réseau interne pour les communications internes de Ganeti, DRBD et les live migrations. (Etrangement par contre, Ganeti n'utilise pas ça pour la communication avec les daemons qui roulent sur les nodes, mais passe plustôt par les IPs primaires des nodes)
Dans le cas où on ne prévoie pas utiliser DRBD et qu'on ne l'a pas configuré, gnt-cluster va se plaindre qu'il n'a pas le bon "drbd helper". A ce moment là, on peut disabler DRBD comme template de disque en ajoutant --enabled-disk-templates plain.
Le paramètre de KVM migration_bandwidth est utilisé pour la vitesse de transfert donnée au transfert des blocs de mémoire RAM (e.g. les disques utilisent déjà DRBD) dans une "live migration".
Attention: le param utilise MiB/s comme unité. Donc on doit s'assurer de convertir ce qu'on veut en Mbps vers MiB/s pour que ça ait du sens. La valeur par défaut qu'on configure plus haut, 70MiB/s, correspond plus ou mois à 600Mbps.
- C'est désirable d'avoir une bandwidth élevée pour les migrations parce que une des deux machines (ou les deux) a une charge d'utilisation élevée ça peut devenir long de migrer des VMs. Par contre, on ne veut probablement pas utiliser toute la bandwidth disponible sur l'IP secondaire, parce que le transfert va se battre avec les réplications DRBD, et donc tout ralentir.
Le range de UIDs dans --uid-pool est utilisé en combinaison avec le param de KVM security_model=pool. Ça sert à rouler les processes qemu (donc la VM elle-même) sous des users qui n'ont pas de privilège sur la machine. Les deux limites d'un range sont incluses dans les UIDs utilisés. Comme puppet créé automatiquement 20 users avec toujours les mêmes UIDs, on utilise 4000-4019 pour correspondre.
Si jamais on est mal pris et que: on aimerait avoir un setup multi-homed mais seulement une machine est disponible lors de la création du cluster, et aussi que sa deuxième interface réseau n'est pas encore branchée physiquement on peut:
- assigner l'IP privée qu'on aimerait utiliser pour le serveur comme "secondary IP" à la deuxième interface, même si l'interface n'est pas branchée
- spécifier l'adresse IP comme "secondary IP" dans la commande init avec "-s $ip_privée"
Le cluster sera initialisé comme on le veut même si le réseau secondaire ne se rend nulle part.
Il ne faudra pas oublier à ce moment là d'ajouter les prochaines nodes avec une IP privée aussi, donc avec "gnt-node add -s $ip_privée ..."
Si le process de ganeti ping out dans le syslog ou que gnt-cluster info n'est pas capable de rejoint le domaine défini pour le cluster, vérifier que l'interface localhost est bien up. Rouler ip link set lo up au besoin.
Il faut ensuite assigner un réseau au cluster, en prenant bien soin de réserver les IPs déjà en utilisation. Ici, le but est de réserver toutes les IP qui NE SERONT PAS utilisées par les VMs:
gnt-network add --network 199.58.80.0/25 --gateway 199.58.80.1 def0-arin00.koumbit.net gnt-network modify --add-reserved-ips=$(for f in $(seq 1 35) ; do printf "199.58.80.$f,"; done)199.58.80.42 def0-arin00.koumbit.net gnt-network modify --add-reserved-ips=$(for f in $(seq 48 127) ; do printf "199.58.80.$f,"; done)199.58.80.42 def0-arin00.koumbit.net gnt-network connect --nic-parameters mode=bridged,link=br0 def0-arin00.koumbit.net default
Xen: Pour éviter des problèmes de stabilité
Faire seulement sur le premier node!
Il semble que sur les cluster en KVM, le service ganeti-mond va chercher des informations à propos de l'état de xen, ça fini par aller au bout des files descriptors! Voici le bug upstream https://github.com/ganeti/ganeti/issues/1241
et le workaround : https://github.com/ganeti/ganeti/issues/1241#issuecomment-331115336
# gnt-cluster modify --enabled-data-collectors=inst-status-xen=false # gnt-cluster modify --enabled-data-collectors=xen-cpu-avg-load=false # gnt-cluster command service ganeti restart # il faut redémarrer les services pour que ça prenne effet
Référence de notre débug: 26995
Tester la création d'un VPS
Il semble que dans certains cas, il faut ajouter -n <cluster domain>.koumbit.net. Il faut aussi mettre network au lieu de link.
root@chypre:~# gnt-instance add -d -o debootstrap+default -t plain -s 5G -B memory=1G,vcpus=1 --net 0:ip=199.58.80.42,link=br0 ganetiinst1.koumbit.net 2015-08-12 15:36:30,177: gnt-instance add pid=6076 cli:2594 INFO Command line: gnt-instance add -d -o debootstrap+default -t plain -s 5G -B memory=1G,vcpus=1 --net 0:ip=199.58.80.42,link=br0 ganetiinst1.koumbit.net Wed Aug 12 15:36:42 2015 - INFO: Selected nodes for instance ganetiinst1.koumbit.net via iallocator hail: chypre.koumbit.net Wed Aug 12 15:36:44 2015 * disk 0, size 5.0G Wed Aug 12 15:36:44 2015 * creating instance disks... Wed Aug 12 15:36:47 2015 adding instance ganetiinst1.koumbit.net to cluster config Wed Aug 12 15:36:48 2015 - INFO: Waiting for instance ganetiinst1.koumbit.net to sync disks Wed Aug 12 15:36:49 2015 - INFO: Instance ganetiinst1.koumbit.net's disks are in sync Wed Aug 12 15:36:49 2015 * running the instance OS create scripts...
Installation de ganeti
Faire sur tous les nodes!
- installer ganeti
# apt install ganeti ganeti-instance-debootstrap
pour tester rapidement un cluster ganeti
Créer un nouveau cluster zfs + drbd pour remplacer un ancien setup
# ça prend un ip de spare pour le cluster gnt-cluster init --enabled-hypervisors=kvm --master-netdev=br0 --vg-name=data -N link=br0 \ -B vcpus=2,memory=512M -H kernel_path="",initrd_path="" phoque-test.office.koumbit.net # ca va prendre un réseau... gnt-network add --network 192.168.20.0/24 --gateway 192.168.20.1 resau-bidon.office.koumbit.net # pour le zfs... gnt-cluster modify --enabled-disk-templates=ext,plain,drbd gnt-group add test gnt-group assign-nodes test badbrains.koumbit.net gnt-network connect resau-bidon.office.koumbit.net test
Avec ces éléments là en place, il manque seulement la configuration du type zfs pour extstorage. Voir la section de configuration pour zfs
Après ça, pour créer des instances avec des disques lvm ou drbd, on peut utiliser les mêmes commandes que d'habitude. Pour créer une instance avec des disques sur des volumes zfs, voir GanetiMaintenance#Cr.2BAOk-er_une_instance_avec_un_volume_ZFS
?? En zfs, il y a création d'une instance kpartx qui gère les partitions en zfs, en faisant kpartx -a /dev/ZPOOL/ZFS les instances de partitions sont créées dans /dev/mapper à la place, et donc, il faut faire attention en copiant. (gab: je suis pas certain ce que ça veut dire ce paragraphe..)
Initialiser le cluster
Voir #Cr.2BAOk-er_un_nouveau_cluster
Intégrer un node au cluster
Un détail important à noter: le Volume Group (VG) LVM qui contient les VMs doit avoir le même nom sur toutes les nodes dans le cluster.
- Si un dom0 est monté à neuf pour l'intégrer au cluster, il faut absolument utiliser le même nom de VG.
- Si un dom0 "legacy" qui contient plusieurs volume groups avec des VMs, ou qui a un différent nom de VG doit être intégré comme node à ganeti, il faut prévoir des manipulations manuelles aux VGs pour qu'il n'y en ait qu'un seul qui ne contienne des VMs et que le groupe ait exactement le bon nom.
Faire seulement sur les autres nodes d'un cluster! i.e. on ne doit pas faire ça sur la node qui est master.
On assume que l'on peut se connecter par SSH en root sur l'autre serveur.
# gnt-node add veles.koumbit.net
Note: ceci change les clés SSH du *serveur*, on va dire que c'est correct...
Ça ajoute aussi le hostname du master dans /etc/hosts.
ajouter une node stretch dans un cluster jessie
Rajouter les sources de jessie et faites:
apt-get install ganeti=2.12.4-1+deb8u3 apt-get install openssh-server=1:6.7p1-5+deb8u4 openssh-client=1:6.7p1-5+deb8u4 openssh-sftp-server=1:6.7p1-5+deb8u4
Woot ! you won !
Création d'une première VM
On est maintenant prêt à créer une première instance ("guest VM"):
gnt-instance add -d -o debootstrap+default -t drbd \ --disk 0:size=14G --disk 1:size=1G -B memory=1G,vcpus=1 \ --net 0:ip=199.58.81.89,link=br0 \ clou0.koumbit.net
- on utilise la distro par defaut (i.e. stretch pour le moment)
- drbd est actif
- 2 volumes sont créés (un pour le système + l'autre swap)
- coté réseau on fixe le ip et le bridge
- enfin le nom de l'instance qui a déjà eu un ip d'assigner (autant le forward que le reverse)
Il est intéressant de noter qu'avant de créer une instance, son hostname doit résoudre au niveau DNS. On peut utiliser --no-ip-check and --no-name-check pour contourner le check.
configurations
éviter que ganeti écoute sur le réseau public
# lsof -P -i -n | grep ganeti ganeti-no 30986 root 9u IPv4 137696274 0t0 TCP *:1811 (LISTEN) ganeti-co 30999 gnt-confd 6u IPv4 137695285 0t0 UDP *:1814 ganeti-ra 31027 gnt-rapi 9u IPv4 137694351 0t0 TCP 127.0.0.1:5080 (LISTEN) ganeti-mo 31072 root 6u IPv4 137690434 0t0 TCP *:1815 (LISTEN)
On veut soit juste écouter en local (lo) ou sur l'interface réseau interne (eth1) mais pas eth0.
on va faire la gestion de ça dans puppet pour modifier le fichier /etc/default/ganeti
configurer debootstrap
configurer l'install via debootstrap pour que ça utilise la bonne release et que ça installe des prérequis pour nos besoins, dans /etc/default/ganeti-instance-debootstrap:
MIRROR="http://debian.mirror.netelligent.ca/debian" SUITE="wheezy" EXTRA_PKGS="linux-image-amd64,lsb-release,augeas-tools,puppet,openssh-server" GENERATE_CACHE="yes" CLEAN_CACHE="14"
- effacer la cache créée pour squeeze, si elle existe:
rm -f /var/cache/ganeti-instance-debootstrap/cache-squeeze-amd64.tar
Configurer d'autres distributions
D'autres distributions peuvent être configurées en utilisant le système de "variantes", défini dans /etc/ganeti/instance-debootstrap/variants. Par exemple, la suite jessieest configurée avec:
root@venus:/etc/ganeti/instance-debootstrap# git diff --cached diff --git a/ganeti/instance-debootstrap/variants.list b/ganeti/instance-debootstrap/variants.list index 4ad96d5..df01551 100644 --- a/ganeti/instance-debootstrap/variants.list +++ b/ganeti/instance-debootstrap/variants.list @@ -1 +1,2 @@ default +jessie diff --git a/ganeti/instance-debootstrap/variants/jessie.conf b/ganeti/instance-debootstrap/variants/jessie.conf new file mode 100644 index 0000000..c771a95 --- /dev/null +++ b/ganeti/instance-debootstrap/variants/jessie.conf @@ -0,0 +1 @@ +SUITE="jessie"
Autrement dit, on peut définir des nouvelles "variantes" en remplaçant les réglages du fichier /etc/default/ganeti-instance-debootstrap. Pour utiliser une autre variante, on la passe à l'option -o, après le +, voir GanetiMaintenance pour plus d'informations.
Setup grub
Faire sur tous les nodes!
préparer un hook pour un menu.lst de base dans les domU. le hook d'exemple de Ganeti (/usr/share/doc/ganeti-instance-debootstrap/examples/hooks/grub) est brisé), donc on a fait une alternative bidon, tirée de notre XenMaintenance#pygrub, dans /etc/ganeti/instance-debootstrap/grub:
if [ -z "$TARGET" -o ! -d "$TARGET" ]; then echo "Missing target directory" exit 1 fi # fake grub's existence mkdir "$TARGET"/boot/grub cat > "$TARGET"/boot/grub/menu.lst <<EOF default 0 timeout 5 title Debian kernel /vmlinuz root=/dev/xvda1 ro initrd /initrd.img EOF
On peut aussi utiliser les kernels du dom0:
cd /boot ln -s vmlinuz-3.2.0-4-amd64 vmlinuz-3-xenU ln -s initrd.img-3.2.0-4-amd64 initrd-3-xenU
Idéalement on utiliserait le package pv-grub-menu, mais c'est seulement dans wheezy-backports et on ne veut peut-être pas ça dans tous les domU. Ça serait à corriger au passage à jessie.
Aussi, on préfèrerait éviter pygrub, qui est "deprecated", et utiliser PvGrub (voire carrément le grub2 normal qui supporte maintenant Xen), mais c'est seulement dans 4.4 (donc >=jessie également).
Noter que la configuration de Pygrub a été documentée également dans 16332. Voir 16480 pour le passage à un "vrai" grub.
Extstorage: volumes zfs
Si jamais on veut utiliser un pool zfs local à une node comme source de volumes pour les instances, on doit installer une série de scripts qui configure un nouveau type de "extstorage".
Le profile puppet pour ganeti peut installer les scripts pour nous.
En supposant que vous utilisez le rôle ganeti pour la node (donc ça implique le profile ganeti est déjà inclus), redéfinissez un paramètre dans le fichier hiera de la node:
---
[...]
profile::ganeti::zfs: true
Ensuite, assurez-vous d'installer ZFS. Pour ça, il faut vous assurer d'inclure le profile zfs qqpar dans votre rôle ou un profile utilisé:
class role::ganetizfs {
# [...]
include profile::zfs
}
Voir: https://github.com/candlerb/ganeti-zfs.git
Pour un exemple de création d'instance avec des volumes zfs, voir GanetiMaintenance#Cr.2BAOk-er_une_instance_avec_un_volume_ZFS
Bugs connus avec cette méthode là:
- peut seulement gérer un pool zfs à la fois
les volumes zfs ne s'affichent pas dans la commande gnt-node volumes. On peut voir l'info seulement si on demande gnt-instance info $instance.
le total d'espace disque du pool zfs n'est pas comptabilisé dans le calcul pour une node. e.g. ça s'affiche pas dans gnt-node list mais aussi c'est probablement pas pris en compte quand on rebalance le cluster automatiquement.
Il peut y arriver des situations de "race condition" entre l'apparition du device @/dev/zvol/$POOL/$VOLUME@ et l'exécution de l'install d'OS par ganeti. Si ça arrive, ganeti va chialer que le device n'existe pas alors que vous pourrez le voir. Vous pouvez supprimer manuellement le volume qui traîne (attention de ne pas supprimer le mauvais!) avec zfs destroy "$POOL/$VOLUME" et recommencer la création d'instance avec ganeti.
- p-e qu'on pourrait ajouter un sleep après la création de volume pour éviter ça, mais quelle valeur serait raisonnable?
Changer les 'Instance policy' pour permettre plus de ressources sur les instances
C'est un peu de la marde parce qu'il faut repasser toutes les valeurs actuelles + les changements qu'on veut apporter. Pire encore, faut repasser toutes les valeurs minimales et les valeurs maximales, ffs.
On va donc chercher toutes les valeurs avec gnt-cluster. J'ai pas trouvé (ou trop cherché) comment avoir un output en json ou autre.
root@rouch:~# gnt-cluster info | grep -iA15 "bounds specs:" bounds specs: - min/0: cpu-count: 1 disk-count: 1 disk-size: 1024 memory-size: 128 nic-count: 1 spindle-use: 1 max/0: cpu-count: 8 disk-count: 16 disk-size: 1048576 memory-size: 32768 nic-count: 8 spindle-use: 12
Puis on veut rebalancer tout ça à gnt-cluster en faisant les ajustements qu'on veut (ici, on change le max disk-size pour 75To)
gnt-cluster modify --ipolicy-bounds-specs=max:disk-size=78643200,memory-size=32768,spindle-use=12, \ disk-count=16,cpu-count=8,nic-count=8/min:disk-size=1024,memory-size=128,spindle-use=1,disk-count=1, \ cpu-count=1,nic-count=1
Pis on check que tout est comme on voulait
gnt-cluster info | grep -iA15 "bounds specs:" bounds specs: - min/0: cpu-count: 1 disk-count: 1 disk-size: 1024 memory-size: 128 nic-count: 1 spindle-use: 1 max/0: cpu-count: 8 disk-count: 16 disk-size: 78643200 memory-size: 32768 nic-count: 8 spindle-use: 12 std:
Mise à jour
En général (sauf quand mentionné, les opérations se font seulement sur le master):
vérifier l'état du cluster avant de démarrer: gnt-cluster verify
installer les packages de la nouvelle version sur toutes les nodes depuis les backports (donc pour un upgrade sur buster vers la version 3.0 avant une upgrade à bullseye, on tire la version de buster-backports)
Si la source apt xxxx-backports n'est pas disponible, vous devrez l'ajouter pour pouvoir installer le package.
apt install -t xxxx-backports ganeti
service ganeti restart
sur toutes les nodes
gnt-cluster upgrade --to x.xx
si ganeti dit que la version x.xx est pas installé sur toutes les nodes même si ça l'est, vérifier si la clef ssh du user root a changée. un fix pour ça c'est de recopier /root/.ssh/id_rsa.pub dans le fichier /root/.ssh/authorized_keys de toutes les nodes (y compris la node master!)
ganeti peut faire ça plus qu'une fois. c'est commun au moins après l'install du package ganeti x.xx et encore une fois après la commande d'upgrade plus haut (pendant laquelle les clefs RSA déjà existantes -- si on avait hacké d'utiliser rsa avant que ça soit disponible dans ganeti -- sont déplacées avec un nom du genre .backup-$random)
- vérifier que
le cluster est bien rendu à la bonne version: gnt-cluster --version
des opérations sur le cluster fonctionnent bien: gnt-node list, gnt-instance list
- si ça ne veut pas upgrader et reste à l'ancienne version, vérifier qu'il y aurait pas de mauvais symlinks dans /etc/ganeti/ vers /usr/lib/ganeti/2.x (ancienne)
si ça ne fonctionne toujours pas, on peut essayer de suivre la procédure manuelle 2.1
retirer l'ancienne version sur les nodes: apt purge ganeti-x.xx ganeti-haskell-x.xx ganeti-htools-x.xx
- si on ne fait pas ça, on va tomber dans une loop où ganeti-3.0 veut retirer une diversion de fichier mais échouer
- si jamais vous restez pris dans cette loop là parce que vous avez pas écouté le conseil ici, vous pouvez:
modifier le fichier /var/lib/dpkg/info/ganeti-3.0.postrm et mettre en commentaire le bloc if en haut qui veut retirer le dpkg-divert
- terminer l'upgrade d'OS
apt purge ganeti-x.xx ganeti-haskell-x.xx ganeti-htools-x.xx
dpkg-divert --remove /usr/share/ganeti/x.xx/ganeti/utils/version.py
(seulement en upgradant de jessie à stretch)
gnt-cluster renew-crypto --new-node-certificates
gnt-cluster renew-crypto --new-ssh-keys --ssh-key-type=rsa --ssh-key-bits=4096
gnt-cluster renew-crypto --new-cluster-certificate --new-rapi-certificate --new-spice-certificate
gnt-cluster verify
(en upgradant de stretch à buster, e.g. vers 2.16.0)
gnt-cluster renew-crypto --new-cluster-certificate --new-rapi-certificate --new-spice-certificate
gnt-cluster verify
Voir:
/usr/share/doc/ganeti-2.16/NEWS.Debian.gz
Upgrade à Bullseye: https://fiat-tux.fr/2021/09/07/precaution-a-prendre-pour-la-mise-a-jour-vers-debian-bullseye-dun-cluster-ganeti/
Upgrade a wheezy-backports
Faire sur tous les nodes!
Ceci devrait probablement être déplacé dans GanetiMaintenance, pour vu qu'on installe bien dans wheezy-backports ci-haut.
On a upgradé à Wheezy-backports pour s'assurer d'avoir un ganeti plus récent, entre autre pour le network management.
apt-get install -t wheezy-backports ganeti2 apt-get install -t wheezy-backports ganeti-instance-debootstrap apt-get install molly-guard /usr/lib/ganeti/tools/cfgupgrade gnt-cluster upgrade --to=2.11 gnt-cluster renew-crypto --new-node-certificates gnt-cluster verify /etc/init.d/ganeti restart
à la fin on a:
Thu Nov 13 17:05:49 2014 - ERROR: node venus.koumbit.net: wrong drbd usermode helper: /sbin/drbdadm
... mais on utilise pas drbd encore... voir https://code.google.com/p/ganeti/issues/detail?id=65 peut-être?
Network management
Ici on configure le bloc d'IP assigné au cluster ainsi que certains IPs réservées:
Faire seulement sur le premier node!
root@venus:~# gnt-network add --network 199.58.81.128/25 --gateway 199.58.81.193 colo2-arin01.koumbit.net Thu Nov 13 17:23:27 2014 - INFO: Reserved IP address of node 'venus.koumbit.net' (199.58.81.189) Thu Nov 13 17:23:27 2014 - WARNING: Cannot reserve IP address '199.58.81.189' of node 'venus.koumbit.net': IP 199.58.81.189 is already externally reserved Thu Nov 13 17:23:27 2014 - INFO: Reserved cluster master IP address (199.58.81.188) root@venus:~# gnt-network list Network Subnet Gateway MacPrefix GroupList Tags colo2-arin01.koumbit.net 199.58.81.128/25 199.58.81.193 - root@venus:~# gnt-network modify --add-reserved-ips=$(for f in $(seq 190 255) ; do printf "199.58.81.$f,"; done)199.58.81.129 colo2-arin01.koumbit.net Thu Nov 13 17:23:54 2014 - WARNING: Cannot reserve IP address 199.58.81.193: IP 199.58.81.193 is already externally reserved Thu Nov 13 17:23:54 2014 - WARNING: Cannot reserve IP address 199.58.81.255: IP 199.58.81.255 is already externally reserved root@venus:~# gnt-network connect -N link=br0 colo2-arin01.koumbit.net default
J'ai écrit ce hook pour s'assurer que la configuration IP est propagée au domU:
Faire sur tous les nodes!
root@venus:/etc/ganeti/instance-debootstrap/hooks# cat gnt-debian-interfaces #!/usr/bin/python # simple script to write a interfaces file from ganeti metadata # test with NIC_COUNT=1 NIC_0_IP=10.0.0.1 NIC_0_NETWORK_SUBNET=255.0.0.0 NIC_0_NETWORK_GATEWAY=10.0.0.1 TARGET=./foo python gnt-os-interfaces import ipaddr import logging import os import sys # should depend on DEBUG_LEVEL logging.basicConfig(format='%(message)s', level=logging.INFO) # the environment variable prefix #prefix = 'GANETI_INSTANCE_' # for a gnt-wide level hook prefix = '' # for a ganeti-instance-debootstrap hook # XXX: not sure this will work in a gnt-wide level hook if ('TARGET' not in os.environ or os.environ['TARGET'] == '/'): logging.error("Invalid target directory '{}', aborting".format(os.environ['TARGET'] if 'TARGET' in os.environ else '')) sys.exit(1) filename = os.environ['TARGET'] + '/etc/network/interfaces' count = int(os.environ['{}NIC_COUNT'.format(prefix)]) if '{}NIC_{}_IP'.format(prefix,count-1) not in os.environ: logging.warn('missing last interface {}, bad NIC_COUNT provided {}, exiting'.format('{}NIC_{}_IP'.format(prefix,count-1), count)) # this should be a failure, but we still get NIC_COUNT=1 and NIC_0_IP if no --ip is provided sys.exit(0) logging.info('Configuring {} interfaces'.format(count)) try: with open(filename, 'a') as interfaces: for i in range(count): logging.info('Configuring interface #{}'.format(i)) interfaces.write(''' # automatically configured interface auto eth{i} iface eth{i} inet static address {address} netmask {netmask} gateway {gateway} '''.format(i=i, address=os.environ['{}NIC_{}_IP'.format(prefix,i)], netmask=str(ipaddr.IPNetwork(os.environ['{}NIC_{}_NETWORK_SUBNET'.format(prefix,i)]).netmask), gateway=os.environ['{}NIC_{}_NETWORK_GATEWAY'.format(prefix,i)], )) except IOError: logging.error("Cannot write to '{}', aborting".format(filename)) except KeyError as e: # known keys if 'NIC_' in str(e): logging.error('missing expected environment, aborting: {}'.format(str(e))) sys.exit(2) # this is something else, don't hide bugs else: raise
On teste que ça marche:
gnt-instance add -d -n venus.koumbit.net -o debootstrap+default -t plain -s 50G -B memory=2G,vcpus=2 --net 0:ip=pool,network=colo2-arin01.koumbit.net ganetiinst1.koumbit.net
swap
Faire sur tous les nodes!
Pour configurer la swap, on utilise le hook de ~abate, modifié.
root@venus:/etc/ganeti/instance-debootstrap/hooks# cat swap #!/bin/sh if [ $DISK_COUNT -lt 2 -o -z "$DISK_1_PATH" ]; then echo "Skipping swap creation" >&2 exit 0 fi swapdev=$DISK_1_PATH # Make sure we're not working on the root directory if [ -z "$TARGET" -o "$TARGET" = "/" ]; then echo "Invalid target directory '$TARGET', aborting." 1>&2 exit 1 fi if [ "$(mountpoint -d /)" = "$(mountpoint -d "$TARGET")" ]; then echo "The target directory seems to be the root dir, aborting." 1>&2 exit 1 fi if [ -f /sbin/blkid -a -x /sbin/blkid ]; then VOL_ID="/sbin/blkid -o value -s UUID" VOL_TYPE="/sbin/blkid -o value -s TYPE" else for dir in /lib/udev /sbin; do if [ -f $dir/vol_id -a -x $dir/vol_id ]; then VOL_ID="$dir/vol_id -u" VOL_TYPE="$dir/vol_id -t" fi done fi if [ -z "$VOL_ID" ]; then log_error "vol_id or blkid not found, please install udev or util-linux" exit 1 fi if [ -n "$swapdev" ]; then mkswap $swapdev swap_uuid=$($VOL_ID $swapdev || true ) fi [ -n "$swapdev" -a -n "$swap_uuid" ] && cat >> $TARGET/etc/fstab <<EOF UUID=$swap_uuid swap swap defaults 0 0 EOF
Après il faut mettre deux disques dans la création de la VM pour que le second disque soit configuré comme du swap, donc ca donne:
gnt-instance add -d -n venus.koumbit.net -o debootstrap+default -t plain --disk 0:size=50G --disk 1:size=2G -B memory=2G,vcpus=2 --no-ip-check --no-name-check golden-wheezy-amd64
password root
Faire sur tous les nodes!
J'ai aussi mis un hook pour mettre un password root par défaut:
root@venus:/etc/ganeti/instance-debootstrap/hooks# rm clear-root-password root@venus:/etc/ganeti/instance-debootstrap/hooks# cat random-root-passwd #!/bin/sh set -e printf "setting root account password to: " ( printf "root:" ; pwqgen random=80 | tee -a /dev/stderr ) | chpasswd -c SHA512 -R $TARGET
Noter que le tee -a permet d'afficher le mot de passe dans les logs. Le -a est important sinon ça tronque les logs.
Activer le template de disque pour DRBD
Si on veut utiliser DRBD pour les disques, il faut activer le template de disque. Pour ça on doit modifier le cluster pour activer le template, mais aussi spécifier un helper à ganeti:
gnt-cluster modify --enabled-disk-templates plain,drbd --drbd-usermode-helper /sbin/drbdadm --ipolicy-disk-templates plain,drbd
L'option "ipolicy*" s'assure que la politique de création d'instance elle aussi contient le template drbd, sans quoi c'est impossible d'utiliser le template sur des instances.
Normalement après ça c'est possible d'utiliser le template de disque drbd pour une nouvelle instance ou bien de modifier une instance pour utiliser drbd.
Préparation de l'installation manuelle
On ne veut pas faire de configuration manuelle. Utilisez puppet svp. Si qqch n'est pas géré par puppet, on doit l'ajouter dans la gestion.
... donc ça veut dire que cette section devrait être retirée. mais on a probablement de l'information à conserver quand même de tout ça.
On vise l'installation de cluster avec la version de stretch de ganeti 2.15 en mode drbd avec Kvm à la place de Xen.
On veut donc prendre connaissance de la doc upstream http://docs.ganeti.org/ganeti/2.15/html/install.html pour l'installation.
À noter que ceci s'applique également à la création d'un dom0 secondaire, un "node" qui est ajouté dans le cluster. Une note comme celle-ci indique les variations:
Faire seulement sur le premier node!
Faire sur tous les nodes!
On assume ici que la configuration du bridge sur les interfaces est déjà fait et opérationnelle.
DNS
Faire seulement pour le premier node!
- Pour la création d'un cluster, il faut créer un hostname pour le cluster (e.g. l'IP du master). j'ai créé:
vps IN A 199.58.81.188
Si la node est dans puppet la modification du fichier /etc/hosts n'est pas nécessaire c'est déjà fait.
Pour le reste: faire sur tous les nodes!
- changer /etc/hosts pour que le hostname de la machine pointe sur son IP publique au lieu de 127.0.0.1:
199.58.81.189 venus.koumbit.net venus
- s'assurer que le hostname est bien réglé:
hostname venus hostname > /etc/hostname
KVM
voir la page KvmConfiguration
DRBD
On veut installer drbd dans tous les types de configuration de cluster ganeti. Ça peut devenir utile dans le future pour transférer des instances d'un serveur à l'autres.
Faire sur tous les nodes!
Voir DrbdConfiguration#Avec_Ganeti
Voir DrbdMaintenance pour les opérations qu'on peut exécuter sous DRBD
clé ssh
- générer une clef ssh sans mot de passe pour root
ssh-keygen
Vous pouvez distribuer la clé ssh publique de l'utilisateur root du master vers le fichier /root/.ssh/authorized_keys sur les nodes secondaires. L'objectif est de faciliter l'intégration des nodes secondaires au cluster.
Déploiement par image
On a essayé (15592) d'installer des VMs à partir d'images, mais ce n'est pas très bien supporté, et ça assume qu'on a déjà une image d'installée qu'on clone. De plus, le software n'est pas dans Debian (RFP #769611). De plus, la config du réseau n'a pas été portée au nouveau "gnt-network", donc il faudrait spécifier les IPs à la main, une grosse perte. Sinon il y a des fonctionalités intéressantes de configuration IP et grub... et ça devrait être plus performant, en théorie, pour créer des VMs.
En attendant, pour optimiser la création d'images, il y a une cache des packages de 14 jours pour chaque node. Peut-être qu'on voudrait avoir notre propre cache au centre de données, voire même notre mirror debian (14531 - hahaha).
Interfaces additionnelles à Ganeti
Ganeti c'est nice et avec son API on peut faire vraiment bcoup de choses. Par contre ça demande des connaissances en command line qui sont assez poussées. Donc pour certains clients (p-e pour nos VPS aussi?) on pourrait avoir une interface de gestion par dessus Ganeti. Voilà quelques idées d'interfaces qu'on n'a pas encore (2021-01) testé:
- Application Django qui offre une interface web pour la création, migration, destruction d'instances
- Intègre la gestion des instances via console avec VNC dans la page web.
- A une API pour elle-même, qui offre certaines abstractions plus haut niveau sur la gestion.
References
- Documentation officielle:
hooks - installed dans /etc/ganeti/hooks dans Debian
- Autre documentation
- Documentation de Debian DSA
script d'install, avec un debootstrap manuel
- Outils pour ganeti