Installation mit OneDeploy
Auftrag
«Der Vorstand hat sich für OpenNebula entschieden», schreibt Simone Wyss. «Die Software ist frei, kommt aus Europa und läuft auf unseren drei Servern. Kannst du sie so installieren, dass wir das bei einem neuen Server jederzeit wiederholen können? Und schreib bitte auf, was danach wo läuft, damit wir es auch in einem Jahr noch wissen.»
Lernziele
Nach diesem Kapitel kannst du:
- Erklären, wie Ansible mit Inventar, Playbooks, Tasks, Modulen, Rollen und Handlern arbeitet
- Ein eigenes kleines Playbook ausführen und an seiner Ausgabe Idempotenz erkennen
- Den Aufbau von OneDeploy beschreiben
- OpenNebula 7.4 mit einem Lauf von OneDeploy installieren
- Nennen, welche Dienste danach auf dem Front-end und auf den Knoten laufen und wie sie zusammenarbeiten
- Die Meldung eines abgebrochenen Laufs lesen und den Fehler beheben
Ansible
Abschnitt betitelt „Ansible“Eine Cloud mit drei Servern könntest du von Hand einrichten. Bei dreissig Servern oder bei einem Server, der nach einem Defekt neu aufgesetzt werden muss, wird das langsam und fehleranfällig. Werkzeuge für das Konfigurationsmanagement beschreiben deshalb den gewünschten Zustand der Server in Dateien und stellen ihn her. Ansible ist eines davon und das Werkzeug, mit dem das OpenNebula-Projekt seine Installationen automatisiert.
Ansible arbeitet ohne Agent. Auf den Zielrechnern braucht es nur SSH und Python. Ansible läuft auf einem Steuerrechner, im Lab auf dem Front-end. Von dort verbindet es sich mit den Zielrechnern, kopiert kleine Programme hinüber, führt sie aus und löscht sie wieder. Man nennt das ein Push-Modell, weil der Steuerrechner die Änderungen anstösst.
Ansible beschreibt Zielzustände. Ein Shell-Skript sagt «installiere Paket X», ein Task in Ansible sagt «Paket X ist installiert». Ist das schon so, tut Ansible nichts und meldet ok. Muss es etwas ändern, meldet es changed. Diese Eigenschaft heisst Idempotenz. Du kannst einen Lauf beliebig oft wiederholen, das Ergebnis bleibt dasselbe.
Begriffe
Abschnitt betitelt „Begriffe“| Begriff | Bedeutung | Beispiel aus dem Lab |
|---|---|---|
| Inventar | Liste der Zielrechner, in Gruppen, mit Variablen | inventory.yml mit den Gruppen frontend und node |
| Playbook | YAML-Datei mit einem oder mehreren Plays | opennebula.deploy.main |
| Play | ordnet einer Gruppe von Rechnern Rollen oder Tasks zu | «auf allen Knoten die Rolle kvm» |
| Task | ein einzelner Schritt mit einem Modul | «Paket opennebula-node-kvm ist installiert» |
| Modul | das Programm, das einen Task ausführt | apt, copy, template, service, user |
| Rolle | Bündel aus Tasks, Vorlagen, Standardwerten und Handlern für eine Aufgabe | database, opennebula/server, gui, kvm |
| Handler | Task, der nur läuft, wenn ein anderer Task etwas geändert hat | Dienst neu starten, nachdem seine Konfiguration geändert wurde |
| Variable | Wert, der Tasks und Vorlagen steuert | one_version: "7.4" |
| Facts | Angaben, die Ansible über einen Zielrechner sammelt | Version von Ubuntu, Anzahl CPUs, Netzwerkkarten |
| become | Wechsel zu einem anderen Benutzer, meist root mit sudo | ansible_become: true |
| Collection | verpacktes Bündel aus Rollen, Modulen und Playbooks | opennebula.deploy |
OneDeploy
Abschnitt betitelt „OneDeploy“OneDeploy ist eine Ansible-Collection des OpenNebula-Projekts. Sie installiert eine Cloud aus einem Front-end und mehreren Knoten, auf Wunsch auch mit hoher Verfügbarkeit, Ceph als Speicher oder einem gerouteten Netz. Der Kurs ist mit der Version release-1.4.1 getestet und nutzt davon nur den einfachsten Aufbau mit lokalem Speicher.
Das Playbook opennebula.deploy.main besteht aus zwei Teilen. Der Teil pre bereitet alle Rechner vor. Er prüft Python und die Namen der Rechner, verteilt SSH-Schlüssel und richtet die Zeitsynchronisation und die Protokollierung ein. Danach installiert der Teil site OpenNebula. Er besteht aus Plays für die Gruppen des Inventars:
- Alle Rechner mit der Rolle
common, gemeinsame Pakete und die Paketquelle von OpenNebula - Das Front-end mit den Rollen
database,opennebula/server,gate,flow,formsowiegui - Die Knoten mit den Rollen
kvm,datastore/nodesowienetwork/node - Das Front-end noch einmal mit
datastore/frontendundnetwork/frontend, die Datastores und Netze anlegen und die Knoten als Hosts eintragen
Rollen für Funktionen, die das Inventar nicht einschaltet, etwa Ceph, ein geroutetes Netz oder Prometheus, überspringt der Lauf. Sie erscheinen in der Ausgabe als skipping.
OneDeploy einrichten
Abschnitt betitelt „OneDeploy einrichten“Das Skript lab/one-deploy/install.sh installiert Ansible aus den Paketen von Ubuntu, holt OneDeploy in der Kursversion nach ~/cc-lab/one-deploy und installiert die Ansible-Collections, die OneDeploy braucht. Dieselben Schritte zeigt die Anleitung zu den Playbooks im Wiki von OneDeploy einzeln.
~/cc/lab/one-deploy/install.shmkdir -p ~/cc-labif [ ! -d ~/cc-lab/one-deploy ]; then git -c advice.detachedHead=false clone --quiet --branch "$ONE_DEPLOY_RELEASE" https://github.com/OpenNebula/one-deploy.git ~/cc-lab/one-deployficd ~/cc-lab/one-deploy# ansible.cfg of one-deploy looks for collections in ./ansible_collections onlyansible-galaxy collection install -r requirements.yml -p ./ansible_collections >/dev/nullecho "one-deploy $(git describe --tags) is ready in ~/cc-lab/one-deploy"Beim Installieren der Collections meldet Git, es sei im Zustand «detached HEAD». OneDeploy verlangt eine Collection in einer festen Version, Git holt dafür einen Tag statt eines Branches. Die Meldung ist deshalb kein Fehler. Das Skript ist erfolgreich, wenn es mit der Zeile one-deploy release-1.4.1 is ready endet.
Das Inventar
Abschnitt betitelt „Das Inventar“Das Inventar beschreibt dein Lab für OneDeploy. Das Skript make-inventory.sh schreibt es aus deinen persönlichen Parametern und erzeugt beim ersten Aufruf ein zufälliges Passwort für den Benutzer oneadmin, den Administrator von OpenNebula. Das Passwort liegt danach in ~/cc-lab/oneadmin.pass.
~/cc/lab/one-deploy/make-inventory.sh > ~/cc-lab/inventory.ymlchmod 600 ~/cc-lab/inventory.yml---all: vars: # Ansible logs in as the course user and becomes root with sudo ansible_user: $(id -un) ansible_become: true one_version: "7.4" one_pass: "$(cat "$PASS_FILE")" # one-deploy checks that every VM resolves the names of all others, prepare.sh wrote them ensure_hostname: true ensure_hosts: true # Images reach the nodes over SSH, no shared storage is needed ds: mode: ssh
frontend: hosts: # Ansible runs on the front-end, so it reaches the front-end itself without SSH $CC_FE_HOST: { ansible_host: $CC_FE_IP, ansible_connection: local }
node: hosts: $CC_NODE1_HOST: { ansible_host: $CC_NODE1_IP } $CC_NODE2_HOST: { ansible_host: $CC_NODE2_IP }EOFDie Gruppe frontend enthält das Front-end, die Gruppe node die beiden Knoten. Weil Ansible auf dem Front-end läuft, verbindet es sich dort lokal statt über SSH. Diese Verbindungsart wählt ansible_connection: local. Unter vars stehen Werte, die für alle Rechner gelten. one_version legt die Version von OpenNebula fest, ds mit mode: ssh bedeutet, dass die Knoten Images über SSH erhalten und kein gemeinsamer Speicher nötig ist. Netze für die VMs deiner Mitglieder legst du in Kapitel 2.3 selbst an, das Inventar enthält deshalb noch keine. Wie Ansible Gruppen, Variablen und Verbindungsarten in einem Inventar liest, beschreibt die Anleitung zum Inventar von ansible-core 2.20.
Vor der Installation prüfst du, ob Ansible alle drei VMs erreicht.
cd ~/cc-lab/one-deployansible -i ../inventory.yml all -m pingJede VM antwortet mit SUCCESS und ping: pong. Davor warnt Ansible für jede VM, dass es den Python-Interpreter selbst gesucht hat. Diese Warnung kannst du übergehen.
Ein erstes Playbook
Abschnitt betitelt „Ein erstes Playbook“Das Beispiel des Kurses hinterlegt auf jedem Knoten einen Gruss mit dem Namen der Genossenschaft. Es installiert ein Paket, schreibt eine Datei mit Facts der Knoten und zeigt die Datei über einen Handler an.
---# A first playbook: every node greets with the name of the cooperative when you log in.# Run it twice and compare the recap, the second run changes nothing.## ansible-playbook -i ~/cc-lab/inventory.yml ~/cc/examples/ansible/motd.yml- name: Greeting on the nodes hosts: node become: true # The ansible.cfg of OneDeploy turns automatic facts off, this play needs them gather_facts: true vars: cooperative: Wolkenwerk Bern tasks: - name: Install htop to watch the load of a node ansible.builtin.apt: name: htop state: present update_cache: true cache_valid_time: 3600
- name: Write the greeting ansible.builtin.copy: dest: /etc/motd content: | {{ cooperative }}, {{ inventory_hostname }} Ubuntu {{ ansible_facts['distribution_version'] }}, {{ ansible_facts['processor_vcpus'] }} vCPU mode: "0644" notify: Show the greeting
handlers: - name: Show the greeting ansible.builtin.command: cat /etc/motd changed_when: falseStarte es zweimal. Im ersten Lauf melden beide Tasks changed, worauf der Handler läuft. Den Gruss selbst siehst du bei der nächsten Anmeldung an einem Knoten oder mit cat /etc/motd. Der zweite Lauf meldet überall ok und changed=0. Der Handler läuft diesmal nicht, weil sich nichts geändert hat. Die Zeile gather_facts: true ist nötig, weil OneDeploy in seiner Konfiguration das automatische Sammeln von Facts abschaltet. Aufbau, Ablauf und Idempotenz eines Playbooks erklärt die Einführung in Playbooks von ansible-core 2.20.
cd ~/cc-lab/one-deployansible-playbook -i ../inventory.yml ~/cc/examples/ansible/motd.ymlOpenNebula installieren
Abschnitt betitelt „OpenNebula installieren“Der Lauf von OneDeploy dauert einige Minuten, im Lab des Kurses zwischen eineinhalb und drei, bei einem langsamen Netz deutlich länger. Ansible zeigt dabei jede Rolle und jeden Task mit dem Ergebnis pro Rechner. Den Ablauf mit Steuerrechner, Inventar und Playbooks beschreibt auch die Anleitung zu OneDeploy von OpenNebula 7.4.
cd ~/cc-lab/one-deployansible-playbook -i ../inventory.yml opennebula.deploy.main | tee ../deploy.logAm Ende steht der Abschnitt PLAY RECAP mit einer Zeile pro VM. Bei einer erfolgreichen Installation zeigt jede Zeile failed=0. Die Zahl bei ok gibt an, wie viele Tasks schon stimmten. changed zählt die Tasks, die etwas geändert haben, skipped die Tasks, die dein Lab nicht brauchte.
Die installierten Dienste
Abschnitt betitelt „Die installierten Dienste“Nach dem Lauf ist OpenNebula vollständig installiert. Die folgenden Angaben stammen aus einem Lab des Kurses mit OpenNebula 7.4.1 auf Ubuntu 26.04.
Auf dem Front-end
Abschnitt betitelt „Auf dem Front-end“| Dienst | Paket | Port | Aufgabe |
|---|---|---|---|
oned | opennebula | 2633 (XML-RPC), 2634 (gRPC) | der Kern von OpenNebula, verwaltet alle Objekte und bietet die API, über die CLI, Weboberfläche und OpenTofu arbeiten |
| Scheduler | opennebula | ein Treiber von oned, der für jede neue VM einen passenden Knoten wählt | |
onemonitord | opennebula | 4124 | sammelt den Zustand der Knoten und VMs |
| MariaDB | mariadb-server | 3306, nur lokal | Datenbank von oned mit allen Benutzern, Hosts, Images, Netzen und VMs |
| FireEdge | opennebula-fireedge | 2616 | die Weboberfläche Sunstone |
| guacd | opennebula-guacd | 4822 | zeigt die Konsole einer VM im Browser |
| OneFlow | opennebula-flow | 2474 | Dienste aus mehreren VMs mit Regeln für die Elastizität, Thema von Kapitel 3.5 |
| OneGate | opennebula-gate | 5030, nur lokal | über OneGate melden VMs Werte an OpenNebula, OneFlow braucht das |
| OneForm | opennebula-form | 13013 | stellt neue Cluster bei Anbietern bereit, im Kurs nicht genutzt |
| Hook-Manager | opennebula | 2101 und 2102, nur lokal | führt Skripte aus, wenn sich ein Objekt ändert |
| SSH-Agent | opennebula | hält den Schlüssel von oneadmin für die Verbindungen zu den Knoten |
Dazu kommen der Benutzer oneadmin mit einem SSH-Schlüsselpaar, die Zeitsynchronisation mit chrony und die Konfiguration unter /etc/one/, vor allem oned.conf. In OpenNebula selbst legt der Lauf drei Datastores an. Der Datastore system mit der Nummer 0 hält die Disks laufender VMs, default mit der Nummer 1 die Images und files mit der Nummer 2 Dateien wie Kernel oder Skripte für den Kontext. Alle drei verwenden den Transfertreiber ssh.
Auf den Knoten
Abschnitt betitelt „Auf den Knoten“| Dienst | Paket | Aufgabe |
|---|---|---|
| KVM mit QEMU | qemu-system-x86 | führt die VMs mit der Virtualisierung der CPU aus |
| libvirt | libvirt-daemon-system | verwaltet die VMs auf dem Knoten, dazu virtlogd für die Protokolle und virtlockd gegen doppelt geöffnete Disks |
| Knotenpaket | opennebula-node-kvm | richtet den Benutzer oneadmin mit den Gruppen kvm und libvirt ein und konfiguriert libvirt für OpenNebula |
Auf den Knoten läuft kein eigener Dienst von OpenNebula. Der Schlüssel von oneadmin aus dem Front-end steht dort in authorized_keys.
Zusammenspiel von Front-end und Knoten
Abschnitt betitelt „Zusammenspiel von Front-end und Knoten“Startest du eine VM, legt oned sie in der Datenbank an und der Scheduler wählt einen Knoten mit genug freier CPU und genug Speicher. Das Front-end verbindet sich als oneadmin per SSH mit diesem Knoten. Der Transfertreiber ssh kopiert das Image der VM in den Datastore system des Knotens unter /var/lib/one/datastores/0/. Dann startet ein Treiber auf dem Knoten die VM über libvirt mit KVM. Die Treiber sind kleine Programme in Ruby und Shell, die das Front-end nach /var/tmp/one/ auf jeden Knoten kopiert. Das erledigt der Handler «Sync Remotes» am Ende eines Laufs. Von da an fragt onemonitord regelmässig den Zustand von Knoten und VMs ab, den oned in onehost list und in der Weboberfläche zeigt.
Einen abgebrochenen Lauf lesen
Abschnitt betitelt „Einen abgebrochenen Lauf lesen“Bricht ein Lauf ab, steht weiter oben eine Zeile mit fatal: und dem Namen der VM, darunter die Meldung. Davor nennt Ansible den gescheiterten Task und die Datei, in der dieser Task steht. Lies zuerst die Meldung, dann den Task. Meist erklärt die Meldung den Fehler schon.
Bei der Entwicklung dieses Kurses brach der Lauf viermal ab. Das Vorbereitungsskript aus Kapitel 0.4 beugt heute jedem dieser Abbrüche vor:
| Meldung | Ursache | Lösung im Kurs |
|---|---|---|
Please make sure each cluster member can resolve all Front-end hostnames | Die VMs kannten die Namen der anderen nicht. | prepare.sh schreibt alle Namen in /etc/hosts, das Inventar setzt ensure_hosts. |
Could not find the requested service rsyslog.service | Das minimale Ubuntu 26.04 enthält rsyslog nicht. | prepare.sh installiert rsyslog auf allen VMs. |
opennebula-fireedge ... Depends nodejs (<= 21) | Ubuntu bietet ein neueres Node.js an, als die Weboberfläche verträgt. | prepare.sh legt fest, dass Node.js aus dem Repo von OpenNebula kommt. |
Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user | Ansible wechselt auf dem Front-end zum Benutzer oneadmin und braucht dafür das Paket acl. | prepare.sh installiert acl auf dem Front-end. |
Nach einer Korrektur startest du den Lauf noch einmal. Weil Ansible den Zielzustand beschreibt, ändert es nur, was noch nicht stimmt.
Die CLI als dein Benutzer
Abschnitt betitelt „Die CLI als dein Benutzer“Die Befehle von OpenNebula wie onehost oder onevm melden sich mit dem Benutzer und Passwort aus der Datei ~/.one/one_auth an der API an. Damit du nicht jedes Mal zu oneadmin wechseln musst, legst du diese Datei mit dem Passwort aus dem Inventar für deinen eigenen Benutzer an. Nur du darfst sie lesen. Welche Variablen und Dateien die CLI sonst noch liest, steht in der Konfiguration der CLI von OpenNebula 7.4.
mkdir -p ~/.one(umask 077; echo "oneadmin:$(cat ~/cc-lab/oneadmin.pass)" > ~/.one/one_auth)Für ein Lab ist das bequem. In einer echten Cloud arbeitet das Plattform-Team mit eigenen Benutzern statt mit oneadmin. Wie Benutzer und Gruppen in OpenNebula funktionieren, zeigt Kapitel 3.1.
Ob OpenNebula läuft und beide Knoten bereit sind, zeigt onehost list. In der Spalte STAT muss bei beiden Knoten on stehen. OneDeploy trägt die Knoten mit ihren IP-Adressen als Namen ein.
onehost listWelche Dienste auf dem Front-end laufen und auf welchen Ports sie warten, zeigen systemctl und ss.
systemctl list-units 'opennebula*' mariadb.servicesudo ss -ltnpDie Weboberfläche öffnest du im Browser des Clients, auf smartlearn die Kali-VM, mit eigenem Hypervisor dein PC. Sie ist auf Port 2616 des Front-ends erreichbar, zum Beispiel unter http://192.168.210.137:2616/. Du meldest dich als oneadmin mit dem Passwort aus ~/cc-lab/oneadmin.pass an.
Nach der Anmeldung zeigt Sunstone das Dashboard.

Der Check dieses Kapitels prüft den Dienst, die Version, beide Hosts und die Weboberfläche.
python3 ~/cc/checks/check.py installAufgabe Einstieg
Richte OneDeploy ein, erzeuge das Inventar und starte das Playbook motd.yml zweimal. Vergleiche die beiden PLAY RECAP und erkläre, warum der Handler beim zweiten Lauf nicht läuft.
Lösung
Der erste Lauf meldet bei beiden Knoten changed=2, weil htop neu installiert und /etc/motd neu geschrieben wurde. Der zweite Lauf meldet changed=0. Weil der Task «Write the greeting» nichts geändert hat, benachrichtigt er den Handler nicht, der deshalb auch nicht läuft.
Aufgabe Lab
Installiere OpenNebula 7.4 mit OneDeploy, richte die CLI für deinen Benutzer ein, prüfe die Hosts mit onehost list, melde dich an der Weboberfläche an und lade den Bericht des Checks install in dein Abgabe-Repo.
Lösung
Der Check endet mit «8 von 8 Prüfungen der Basis erfüllt». onehost list zeigt beide Knoten mit on in der Spalte STAT. Steht dort err, nennt onehost show mit dem Namen des Hosts den Grund im Abschnitt MONITORING INFORMATION, oft eine fehlende SSH-Verbindung vom Front-end zum Knoten.
Aufgabe Vertiefung
Ordne jeden Port, den sudo ss -ltnp auf deinem Front-end zeigt, einem Dienst aus der Tabelle zu. Welche Ports sind nur lokal erreichbar und warum ist das bei der Datenbank sinnvoll?
Lösung
Nur lokal, also auf 127.0.0.1, warten MariaDB auf 3306, OneGate auf 5030 und der Hook-Manager auf 2101 und 2102. Die Datenbank braucht nur oned auf demselben Rechner. Wäre sie im Netz erreichbar, könnte jemand mit ihrem Passwort alle Daten der Cloud lesen oder ändern, an der API von OpenNebula vorbei. SSH auf Port 22 und der lokale DNS-Cache systemd-resolved auf Port 53 der Adressen 127.0.0.53 und 127.0.0.54 gehören zu Ubuntu und fehlen deshalb in der Tabelle.
Texte und Abbildungen stehen unter CC BY-SA 4.0 und der Code unter der MIT-Lizenz. Die Quellen liegen auf GitHub.