Vermutlich haben sich bei fast allen durch Covid-19 die Prioritäten verschoben, bei mir kam sehr schnell zu dem Thema „Ausbildung trotz 100% Home-Office aufrecht erhalten“ noch ein weiteres dazu. Und zwar das Thema Online-Schulungen bzw. genauer die technische Plattform dafür, denn um andere Aspekte wie die Kommunikations- und Präsentationssoftware, Organisation, Marketing und ähnliches haben sich dankenswerterweise andere Kollegen gekümmert.
Die zu nutzende Infrastruktur sollte logischerweise die Openstack-Plattform von NWS sein, da hier entsprechende Kapazitäten vorhanden sind, somit hatte ich mein Ziel. Die Ausgangsbasis war auch leicht definiert, da fast alle Schulungen zum Erstellen der virtuellen Maschinen für die praktischen Übungen auf Vagrant setzen. Die somit erstellten Systeme werden dann zwar noch exportiert um die Provisionierung der Schulungsnotebooks zu beschleunigen, aber sollten trotzdem einen guten Start darstellen.
Als erstes musste natürlich dann der Provider installiert werden, da ich Fedora als Betriebssystem nutze, ging das mit dnf install vagrant-openstack-provider
. Für die anderen Linux-Systeme habe ich keine Pakete gefunden, daher wird der Rest wohl auf den Plugin-Mechanismus mit vagrant plugin install vagrant-openstack-provider
zurückgreifen müssen. Wichtig ist dann noch zu wissen, ob es der einzige oder Standard-Provider ist, denn sonst darf man später beim Starten der Systeme mit vagrant up
nicht den entsprechender Parameter --provider=openstack
vergessen.
Natürlich stand als erstes aber eine Schulung auf dem Plan, die normalerweise ohne virtuelle Maschine auskommt, was aber nicht so schlimm war, denn es gab mir mehr Freiheit zum Experimentieren und Kennenlernen der Unterschiede zwischen Openstack-Provider und den von mir gewohnten. Der vielleicht größte Unterschied ist, dass hier nicht mit bestehenden Boxen von einem zentralen System wie app.vagrantup.com gearbeitet wird, sondern mit bereits in Openstack vorhandenen Images. Außerdem muss eine Anmeldung an einem Openstack-Projekt erfolgen, in dem dann nicht nur die Images vorbereitet sein müssen, sondern auch die Netzwerkkonfiguration inklusive der Sicherheitsgruppen mit entsprechender Portfreigabe und ein zu verwendender SSH-Key.
Mein Ausgangsdatei sah also ungefähr so aus:
require 'vagrant-openstack-provider' Vagrant.configure('2') do |config| config.ssh.username = 'centos' config.ssh.private_key_path = '/home/dirk/.ssh/openstack' config.vm.define "online-training" do |node| node.vm.provider :openstack do |os| os.openstack_auth_url = 'https://cloud.netways.de:5000/v3/' os.identity_api_version = '3' os.username = 'dgoetz' os.password = 'PASSWORT' os.domain_name = 'Default' os.project_name = 'OPENSTACK-PROJEKT' os.flavor = 's1.small' os.image = 'Centos 7' os.floating_ip_pool = 'public-network' os.security_groups = [ 'default', 'ssh-access-internet' ] os.keypair_name = 'dgoetz' os.networks = [ 'internal' ] end end end
Der Parameter config.ssh.username
wird mir dabei von den Images vorgegeben und der Benutzer hat sudo-Regeln hinterlegt, die ihm alle Befehle ohne Passwort erlauben. Der config.ssh.private_key_path
steht für den lokalen Ablageort des privaten Schüssels, zu dem in Openstack hinterlegten öffentlichen Schüssel des Schlüsselpaars hinter os.keypair_name
. Die öffentliche IPv4-Adresse aus dem Pool hinterlegt mit os.floating_ip_pool
zusammen mit der Sicherheitsgruppe ssh-access-internet
im Array os.security_groups
erlauben dann den Zugriff.
Ein Standard-Image ist leider nicht ausreichend, daher wurde natürlich noch der entsprechende Provisioner eingebaut. Da in den Schulungen unterschiedliche Ansätze verwendet werden, durfte ich „alle“ ausprobieren und kann sagen File, Shell, Puppet und Ansible funktionieren alle gleichermaßen gut. Wobei ich hier noch einen Vorteil von Ansible als Provider herausstellen möchte, denn mit diesem lassen sich lokal auf meinem System bzw. über delegate
auch auf anderen Maschinen Befehle ausführen, was ich zum DNS-Management nutzen muss, da dies kein Standardfeature in dieser Openstack-Umgebung ist.
Der nächste Schritt war nun das ganze für die Provisionierung für bis zu 10 Schulungsteilnehmer zu erweitern. Hierfür also den ganzen Block in eine „for each“-Schleife gepackt und den Namen dynamisch gestaltet:
require 'vagrant-openstack-provider' Vagrant.configure('2') do |config| config.ssh.username = 'centos' config.ssh.private_key_path = '/home/dirk/.ssh/openstack' (0..9).each do |i| config.vm.define "online-training0#{i}" do |node| node.vm.provider :openstack do |os| ... end end end
Für ein paar Schulungen wird aktuell ein privates Netzwerk verwendet. Damit die Schulungsunterlagen in diesem Bereich nicht anzupassen sind, habe ich jeweils ein eigenes Netzwerk in Openstack für jedes Schulungssetup erstellt, das entsprechend immer das gleiche Subnet konfiguriert bekommen hat. In diesen Netzen ist kein Gateway konfiguriert und DHCP deaktiviert, da ja nur eine direkte Verbindung notwendig ist. Konfiguriert wird dies über einen Hash im Netzwerk-Parameter:
os.networks = [ 'internal', { name: "online-training0#{i}", address: '192.168.56.101' } ]
Dies bringt mich allerdings zu ein paar technischen Einschränkungen, über die ich gestolpert bin. Zum einen wird mit diesen Einstellungen das private Netzwerk nicht automatisch aktiviert und konfiguriert, was sich mit einem Provisioner aber relativ einfach lösen lässt. Zum anderen muss man, wenn man den Hostnamen setzen möchte, dies auch auch über einen Provisioner tun, da dies nicht über den Vagrant-Provider geschieht.
Als zusätzliche Herausforderung kam dann noch hinzu Windows-Systeme für die „Icinga 2 Fundamentals“-Schulung bereitzustellen. Die eigentliche Provisionierung ist hierbei fast genau wie bei Linux, es wird nur ein bestehender Administrator-Benutzer mit Passwort und Remote-Zugriff auf WinRM benötigt, welchen man entsprechend auf Node-Ebene in das Vagrantfile eintragen muss.
node.vm.communicator = "winrm" node.winrm.username = "Administrator" node.winrm.password = "PASSWORT" node.vm.synced_folder ".", "/vagrant", disabled:true
Zusätzlich habe ich den standardmäßigen, synchronisierten Ordner deaktivieren müssen wie man sieht, da die Provisionierung über rsync als Standard oder auch eine der anderen getesteten Methoden wie Samba und SSHFS nicht funktioniert haben. Daher muss zum Anstoßen der Provisionierung auf Script mit Powershell gesetzt werden und da auf dem System wenig bereitzustellen ist, wurde hier die bestehende Provisionierung von Puppet auf Powershell umgebaut. Hätte ich dies nicht tun wollen oder können, hätte ich den Puppet-Installer, Ablage des Puppet-Codes sowie die Ausführung über Powershell anstoßen können.
Mein Fazit ist, dass ich sehr überrascht war wie gut und einfach die Kombination aus Vagrant und Openstack funktioniert hat. Mit beidem hatte ich bis dahin nicht besonders viel mehr als es einfach nur zu nutzen gemacht, so dass ich auch sagen kann man kommt auch mit Grundwissen, der gut verständlichen Dokumentation und etwas Ausprobieren zum Ziel. Wie oft merkt man leider, dass Windows hierbei etwas schwieriger zu nutzen ist. Was auf der einen Seite dem geschuldet ist, dass Windows einfach eigene Standards verwendet, aber auf der anderen Seite diese oftmals gar nicht versucht werden einzubauen. Nicht desto trotz denke ich, wir sind mit der Lösung technisch gut aufgestellt, um den Teilnehmern an einer Online-Schulung das gleiche Setup wie in einer Präsenz-Schulung zu bieten. Und das hoffentlich nicht nur für die Zeit der Corona-Pandemie sondern auch danach als zusätzliche Option in unserem umfangreichen Schulungsportfolio.
Ganz herzlichen Dank für Dein Posting. Sehr nützlich und hilfreich!