Das Automatisieren von Abläufen aller Art ist im Cloud-Zeitalter keine nette Zugabe, sondern schiere Notwendigkeit. Das gilt auch für die Installation und Ersteinrichtung von Rechenknoten. OpenStack hilft sich hier mit seinen eigenen Mitteln.
Ist eine private Cloud mit OpenStack erst einmal einsatzbereit, lassen sich virtuelle Maschinen schnell erstellen. Doch dahin muss man zunächst einmal kommen. Das erfordert mehrere Schritte, angefangen vom Einbau der Hardware im Rechenzentrum über die Verkabelung bis hin zur Installation eines Betriebssystems. Bei der Betriebssysteminstallation setzt die OpenStack-Komponente Ironic [1] an, ein auf Bare-Metal-Installationen spezialisiertes Modul, das dieser Artikel vorstellt.
Ironic tauchte als Incubated Project im “Icehouse”-Release [2] von Open Stack (April 2017) zum ersten Mal als Ableger des Bare-Metal-Treibers Nova auf. Im Zuge des “Juno”-Releases wurde es weiter integriert und fand schließlich im “Kilo”-Release als integriertes Projekt seinen Platz.
Bifrost
Bei der Betriebssysteminstallation gibt es ein Henne-Ei-Problem: Das Betriebssystem gelangt durch einen Installer auf die Platte, der seinerseits so etwas wie ein Betriebssystem braucht, unter dem er laufen kann. Diese Kalamität soll das Unterprojekt Bifrost lösen. Darunter muss man sich ein standalone laufendes Ironic vorstellen, das OpenStack mit allen für Ironic notwendigen Komponenten zur Verfügung stellt.
Dieser Artikel geht von der folgenden Situation aus: Eine Bifrost-Instanz und OSISM, der Open Source Infrastructure & Service Manager, dienen dazu, ein Betriebssystem auf »node1« einzurichten. Mithilfe des Deployment- und Lifecycle-Management-Frameworks OSISM [3] werden alle notwendigen OpenStack-Komponenten auf »node1« installiert und konfiguriert, sodass sich »node2« anschließend via Ironic bespielen lässt. (Abbildung 1).
Bifrost schlägt dabei die Brücke zwischen “die Hardware ist fertig verkabelt im Rechenzentrum” und “nun ist eine Anmeldung am Betriebssystem möglich”. Der Name stammt aus der nordischen Mythologie, wo er die Regenbogenbrücke zwischen Midgard und Asgard bezeichnet, also die Verbindung von Erdenwelt und Himmelreich.
Bifrost benötigt im Verzeichnis »environments/kolla/files/overlays/« zwei Konfigurationsdateien, eine für sich selbst und eine für den zu installierenden Server (hier »node1«). In der Bifrost-Konfigurationsdatei »bifrost.yml« (Listing 1) kommt es vor allem auf die Parameter »enabled_-Hardware-_types«, »use_tinyipa«, »cirros_deploy_image_upstream_url« sowie »dhcp_pool*« an.
Dabei beschreibt »enabled_-Hardware-_types« die Schnittstelle zum Ansteuern der Hardware [4]. »use_tinyipa« stellt die Auswahl zwischen CoreOS (true) und CentOS (false) bereit; CoreOS ist für CI und Testumgebungen gedacht. »cirros_deploy_image_upstream_url« enthält den Link zum zu installierenden Image, »dhcp_pool*« den DHCP-Pool für die PXE-Umgebung.
Listing 1
bifrost.yml
enabled_hardware_types: ipmi
download_ipa: true
use_tinyipa: false
ipa_upstream_release: stable-{{ openstack_release }}
cirros_deploy_image_upstream_url: https://share/ironic-ubuntu-osism-20.04.qcow2
dhcp_pool_start: 192.168.21.200
dhcp_pool_end: 192.168.21.250
dnsmasq_router: 192.168.21.254
domain: osism.test
Die Konfigurationsdatei »servers.yml« für den oder die zu installierenden Server sieht so aus wie in Listing 2. Hierbei ist es wichtig, die MAC-Adresse der Deployment-NIC zu verwenden und nicht etwa die der Remote-Board-Schnittstelle. Bei Supermicro ermitteln Sie diese zum Beispiel mit dem Befehl aus Listing 3. Um zu vermeiden, dass das dabei angegebene Passwort in der Prozessliste und der History auftaucht, verwenden Sie gegebenenfalls statt »-P Passwort« den Parameter »-f /Pfad/zur/Passwortdatei« und geben so den Pfad zu einer Datei ein, die das Passwort enthält.
Listing 2
servers.yml
---
node1:
uuid: "UUID"
driver_info:
power:
ipmi_username: "LOGIN"
ipmi_address: "IP/Hostname"
ipmi_password: "lesssecret"
nics:
-
mac: "MAC of NIC"
driver: "ipmi"
ipv4_interface_mac: "MAC of NIC"
ipv4_address: "192.168.21.21"
ipv4_subnet_mask: "255.255.255.0"
ipv4_gateway: "192.168.21.254"
ipv4_nameserver:
- "8.8.8.8"
- "8.8.4.4"
properties:
cpu_arch: "x86_64"
ram: "65536"
disk_size: "1024"
cpus: "16"
name: "node1"
Listing 3
Supermicro
# ipmitool -H IP-Adresse -U User -P Passwort raw 0x30 0x21 | tail -c 18 | sed 's/ /:/g'
Haben Sie beide Dateien in ein Git-Repository eingepflegt, können Sie sich nun dem Inventory des OSISM-Manager zuwenden. Zum einen weisen Sie Rollen zu, indem Sie die Datei »inventory/20-roles« so anpassen, wie in Listing 4 gezeigt. Zum anderen legen Sie die Host-Variablen von »node1« in »inventory/host_vars/node1.osism.test.yml« fest (Listing 5).
Listing 4
20-roles
[generic] manager.osism.test node1.osism.test [manager] manager.osism.test [monitoring] manager.osism.test [control] node1.osism.test [compute] node1.osism.test [network] node1.osism.test
Listing 5
node1.osism.test.yml
--
ansible_host: 192.168.21.21
console_interface: eno1
management_interface: eno1
internal_address: 192.168.21.21
fluentd_host: 192.168.21.21
network_interfaces:
- device: eno1
auto: true
family: inet
method: static
address: 192.168.21.21
netmask: 255.255.255.0
gateway: 192.168.21.254
mtu: 1500
- device: eno2
auto: true
family: inet
method: manual
mtu: 1500
network_interface: eno1
Diese Dateien pflegen Sie ebenfalls ins Git-Repository ein und holen sie mit dem Kommando »osism-generic configuration« auf dem OSISM-Manager ab. Das aktualisiert den Repository-Inhalt unter »/opt/configuration/«. Dieser Workflow dient stets als Basis für eine OSISM-Umgebung: Git-Repository pflegen und via »osism-generic configuration« abholen (Listing 6).
Listing 6
Git-Workflow
local: git add path/to/file local: git commit -m "Commit Message" manager: osism-generic configuration
Nun lässt sich Bifrost mit dem Befehl »osism-kolla deploy bifrost« installieren, wobei der Container »bifrost_deploy« und vier Volumes entstehen (Listing 7, Zeile 1 bis 5). Es gibt zwei Betriebssystem-Images, einmal den Ironic Python Agent (IPA) und einmal das Deployment-Image (Zeile 7 bis 14). Beim IPA-Image handelt es sich um ein CentOS (Zeile 16 und 17).
Listing 7
Volumes, Images, CentOS
# docker volume ls local bifrost_httpboot local bifrost_ironic local bifrost_mariadb local bifrost_tftpboot # ll -h /var/lib/docker/volumes/bifrost_httpboot/_data/ [...] -rw-r--r-- 1 42422 42422 6.1G Mar 2 10:33 deployment_image.qcow2 -rw-r--r-- 1 root root 57 Mar 2 10:21 deployment_image.qcow2.CHECKSUMS -rw-r--r-- 1 42422 42422 318M Mar 2 10:13 ipa.initramfs -rw-r--r-- 1 42422 42422 104 Mar 2 10:13 ipa.initramfs.sha256 -rw-r--r-- 1 42422 42422 9.1M Mar 2 10:13 ipa.kernel -rw-r--r-- 1 42422 42422 101 Mar 2 10:12 ipa.kernel.sha256 # file /var/lib/docker/volumes/bifrost_httpboot/_data/ipa.kernel /var/lib/docker/volumes/bifrost_httpboot/_data/ipa.kernel: Linux kernel x86 boot executable bzImage, version 4.18.0-240.10.1.el8_3.x86_64 (mockbuild@kbuilder.bsys.centos.org) #1 SMP Mon Jan 18 17:05:51 UT, RO-rootFS, swap_dev 0x9, Normal VGA
Als Deployment-Image dient hier das oben konfigurierte »ironic-ubuntu-osism-20.04.qcow2«. Das Kommando »osism-kolla deploy-servers bifrost« stößt die Installation von »node1« an. Bifrost erzeugt eine PXE-Umgebung für die bei »node1« konfigurierte MAC-Adresse. Der via IPMI gestartete »node1« bootet in die PXE-Umgebung, das IPA-Image wird geladen und gestartet. Der Ironic Python Agent nimmt Verbindung zu Bifrost auf und schreibt das Deployment-Image auf die Festplatte. War das erfolgreich, baut Bifrost die PXE-Umgebung ab, »node1« startet neu und bootet nun von der Festplatte.
Bis Neutron mit OSISM
Das Installieren und Einrichten der OpenStack-Komponenten erfordert eine SSH-Verbindung vom Manager zu »node1«. Der private SSH-Key liegt zum einen auf dem OSISM-Manager unter »/opt/ansible/secrets/id_rsa.deploy« und zum anderen im Ansible-Vault unter »environments/kolla/secrets.yml« in der Variable »bifrost_ssh_key.private_key«. Eine Verbindungsaufnahme klappt dann mit dem Befehl aus Listing 8.
Listing 8
SSH
$ ssh -i /opt/ansible/secrets/id_rsa.deploy ubuntu@192.168.21.21
Nach einer erfolgreichen Verbindungsaufnahme lässt sich die Installation der OpenStack-Komponenten via OSISM-Framework vornehmen. Die Anweisung aus Listing 9 richtet den Operator-User ein, den Sie für alle weiteren »osism-*« Aufrufe benötigen.
Listing 9
Operator einrichten
# osism-generic operator --limit node1.osism.test --user ubuntu --ask-become-pass --private-key /ansible/secrets/id_rsa.deploy
Das Kommando »osism-generic facts« sammelt die Facts ein, die in »host_vars« hinterlegte Netzwerkkonfiguration schreibt der Befehl »osism-generic network«. Der Aufruf »osism-generic reboot« verifiziert die Netzwerkkonfiguration. Nach der Konfiguration der restlichen OpenStack-Komponenten im Git-Repository führen die Befehle aus Listing 10 zu einer Installation bis Nova.
Listing 10
Installation bis Nova
# osism-generic hosts # osism-generic bootstrap # osism-kolla deploy common # osism-kolla deploy haproxy # osism-kolla deploy elasticsearch # osism-kolla deploy kibana # osism-kolla deploy memcached # osism-kolla deploy mariadb # osism-kolla deploy rabbitmq # osism-kolla deploy openvswitch # osism-kolla deploy keystone # osism-kolla deploy horizon # osism-kolla deploy glance # osism-kolla deploy placement # osism-kolla deploy nova
OSISM setzt auf eine lokale Namensauflösung und pflegt dazu die Datei »/etc/hosts« auf »manager« und »node1«. Im Rahmen des Bootstraps setzt es Kernel-Parameter, (de-)installiert Pakete und härtet den SSH-Server. In diesem Aufbau übernimmt der Manager auch die Controller-Rolle, die man in einem produktiven Setup auf mindestens drei Nodes verteilt (Abbildung 2).
HAProxy übernimmt dabei die Verteilung der Anfragen auf die Controller-Nodes. Die Komponenten »common«, »elasticsearch« und »kibana« sorgen für ein zentrales Logging, das sich über die Weboberfläche von Kibana abrufen lässt. Memcached beschleunigt den Apache-Server hinter der OpenStack-Weboberfläche Horizon. OpenStack setzt eine Datenbank (hier: MariaDB), eine Message-Queue (RabbitMQ) sowie einen virtuellen Switch (Openvswitch) voraus.
Nun werden die Komponenten Keystone, Authentifizierung/Autorisierung, Horizon, Glance, Image-Store, Placement, Ressourcenmanagement, Nova sowie der Hypervisor installiert und eingerichtet. Listing 11 zeigt die Anpassungen für das OpenStack-Modul Neutron, damit Ironic mit der Hardware sprechen kann.
Listing 11
environments/kolla/configuration.yml
neutron_type_drivers: "flat,vxlan" neutron_tenant_network_types: "flat" enable_ironic_neutron_agent: "yes"
Der zwingend notwendige Netzwerktyp »flat« sorgt für eine Möglichkeit, auf Netzwerkebene mit der Hardware zu kommunizieren. Die Komponente »ironic_neutron_agent« zeichnet für die Kommunikation zwischen der Netzwerkkomponente Neutron und Ironic verantwortlich. Gemäß des Git-Workflows aus Listing 6 installiert und konfiguriert »osism-kolla deploy neutron« die Neutron-Komponente.
Auf dem Weg zu Ironic
Das Ironic-Deployment benötigt ein Provision- und ein Cleaning-Netzwerk. Als Cleaning-Netzwerk dient das Remote-Board-Netzwerk, das Provision-Netzwerk übernimmt das Deployment (Listing 12). Mit den UUIDs der beiden Netzwerke lässt sich die Konfiguration von Ironic befüllen (Listing 13, Listing 14).
Listing 12
Anlegen des Provision- und Cleaning-Networks
# openstack network create --provider-network-type flat --provider-physical-network physnet1 --share provisionnet # openstack subnet create --network pxenet --subnet-range 192.168.21.0/24 --ip-version 4 --gateway 192.168.21.254 --allocation-pool start=192.168.21.22,end=192.168.21.28 --dhcp provisionsubnet # openstack network create --provider-network-type flat --provider-physical-network physnet1 --share cleannet # openstack subnet create --network pxenet --subnet-range 10.21.21.0/24 --ip-version 4 --gateway 10.21.21.254 --allocation-pool start=10.21.21.22,end=10.21.21.28 --dhcp cleansubnet
Listing 13
environments/kolla/configuration.yml
enable_ironic: "yes" ironic_dnsmasq_dhcp_range: "192.168.21.150,192.168.21.199" ironic_cleaning_network: "cleannet-UUID" ironic_dnsmasq_default_gateway: "192.168.21.254" ironic_dnsmasq_boot_file: pxelinux.0
Listing 14
environments/kolla/files/overlays/ironic.conf
[DEFAULT] enabled_network_interfaces = noop,flat,neutron default_network_interface = neutron [neutron] provisioning_network = provisionnet-UUID
Ein »osism-kolla deploy ironic« installiert Ironic. Neben der Anpassung der Quota fallen noch drei weitere Schritte an: Sie müssen den Deployment-Kernel samt Ramdisk und das zu schreibende Image in Glance ablegen (Listing 15), ein Flavor mit passenden Parametern anlegen [5] (Listing 16) sowie in Ironic den Node und den Port anlegen (Listing 17).
Listing 15
Deployment-Kernel, Ramdisk und Image
# openstack image create --disk-format aki --container-format aki --file /data/ironic-agent.kernel --public deploy-kernel # openstack image create --disk-format ari --container-format ari --file /data/ironic-agent.initramfs --public deploy-ramdisk # openstack image create --disk-format qcow2 --container-format bare --file /data/osism-image.qcow2 --public deployment-image
Listing 16
Flavor
# openstack flavor create --ram 65536 --disk 500 --vcpus 16 --property resources:CUSTOM_BAREMETAL_RESOURCE_CLASS=1 baremetal-flavor
Listing 17
Ironic-Node und -Port
# openstack baremetal node create --driver ipmi --name node2 --driver-info ipmi_username=ADMIN --driver-info ipmi_password=Lesssecret --driver-info ipmi_address=192.168.33.22 --resource-class baremetal-resource-class --driver-info deploy_kernel=Deploy-Kernel-UUID --driver-info deploy_ramdisk=Deploy-Ramdisk-UUID --driver-info cleaning_network=cleannet-UUID --driver-info provisioning_network=provisionnet-UUID --property cpu_arch=x86_64 --property capabilities='boot_mode=uefi' --inspect-interface inspector --deploy-interface direct --boot-interface ipxe
Achten Sie auf korrekte IPMI-Daten sowie darauf, dass die Resource-Klasse mit der im Flavor hinterlegten übereinstimmt. Im Flavor wird »CUSTOM_BAREMETAL_RESOURCE_CLASS« verwendet und führt zu der Klasse »baremetal-resource-class«. Andere Beispiele wären »CUSTOM_BAREMETAL_LARGE« oder »CUSTOM_BAREMETAL_HANA«, die zu »baremetal-large« und »baremetal-hana« auflösen.
Als »driver-info« geben Sie neben dem Deploy-Kernel und der zugehörigen Ramdisk die Cleaning- und Provisioning-Netzwerke an. Um ein Deployment via iPXE zu ermöglichen, müssen Sie als Deploy-Interface »direct« und als »boot_mode« »UEFI« angeben. Den Ironic-Port für »node2« legen Sie manuell an (Listing 18) oder lesen ihn via In-Band-Inspection aus.
Listing 18
Ironic-Port für node2
# openstack baremetal port create MAC-Adresse --node Baremetal-Node-UUID --physical-network physnet1
Hardware auslesen
Das Kommando »openstack baremetal node manage node2« versetzt »node2« in den Status »manageable«, in dem Sie mit den Aufrufen »openstack baremetal node power on node2« und »openstack baremetal node power off node2« die IPMI-Kommunikation testen. Die Konfigurationsanpassungen aus Listing 19 und Listing 20 ermöglichen eine In-Band-Inspection [6].
Listing 19
environments/kolla/files/overlays/ironic/ironic-conductor.conf
[DEFAULT] enabled_inspect_interfaces = inspector,no-inspect
Listing 20
environments/kolla/files/overlays/ironic-inspector.conf
[processing] add_ports = pxe keep_ports = present
Neben der In-Band-Inspection gibt es noch die Out-of-Band-Inspection. Sie funktioniert zum Beispiel mit den Schnittstellen »ilo«, »idrac« und »irmc«. Das erste Kommando aus Listing 21 stößt die Inspection an, das Vorgehen dabei ähnelt dem beim Deployment: PXE-Umgebung, Initramfs und Kernel starten, wobei hier Ironic die Daten der Nodes via IPA übermittelt bekommt. Der zweite Befehl aus dem Listing startet zu guter Letzt das Deployment von »node2«.
Listing 21
Deployment von node2
# openstack baremetal node inspect node2 # openstack server create --image deployment-image --flavor baremetal-flavor node2
Vorgehen Ironic
Grundsätzlich verwenden Ironic und Nova für das Deployment ein Image, das sich auf demselben Weg erstellen lässt wie die bereits verwendeten Images. Dabei gilt es, die darunterliegende Hardware (RAID-Controller, Netzwerkkarten, etc.) zu beachten; ansonsten ist die Brücke mit Ironic und Bifrost geschlagen. Es gibt neben IPMI weitere Schnittstellen, die zusätzliche Optionen zur Verfügung stellen. Zum Beispiel können Sie mit Ironic auch das BIOS/UEFI pflegen oder ein Hardware-RAID einrichten.
Mit Ironic und Bifrost bringt OpenStack also gut funktionierende Komponenten mit, um Hardware mit einem Betriebssystem auszustatten. Die Anwendungsgebiete reichen vom Bereitstellen von High-Performance-Computing-Nodes bis hin zur Erweiterung von OpenStack um weitere Compute-Nodes. Dabei haben Sie die Möglichkeit, das zu installierende Image so weit anzupassen, dass sich Compute-Nodes ohne zusätzliche manuelle Schritte bereitstellen lassen. (jcb/jlu)
Infos
- Ironic: https://wiki.openstack.org/wiki/Ironic
- OpenStack Releases: https://releases.openstack.org
- Open Source Infrastructure & Service Manager: https://www.osism.tech
- Ironic-Treiber: https://docs.openstack.org/ironic/latest/admin/drivers
- Deploy-Ramdisk: https://docs.openstack.org/ironic/latest/install/deploy-ramdisk.html
- Inspection: https://docs.openstack.org/ironic/latest/admin/inspection.html







