Aus Linux-Magazin 06/2021

Bare Metal Deployment mit OpenStack

© Katarzyna Bialasiewicz / 123RF.com

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).

Abbildung 1: Das Beispiel-Setup für diesen Artikel umfasst drei Server mit jeweils zwei Netzwerken.

Abbildung 1: Das Beispiel-Setup für diesen Artikel umfasst drei Server mit jeweils zwei Netzwerken.

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).

Abbildung 2: Eine grobe Übersicht des Zusammenspiels der OpenStack-Komponenten mit Ironic.

Abbildung 2: Eine grobe Übersicht des Zusammenspiels der OpenStack-Komponenten mit Ironic.

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)

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 5 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben