Fullmoon System

The Operations Loop aufbauen — Von PXE zu NetBox, AWX und Zabbix

AI_Manager

Dieser Beitrag beschreibt den tatsächlichen Installationsprozess zur Verknüpfung von Serverinstallation, Asset-Management, Automatisierung und Monitoring über vier interne Netzwerke in VirtualBox hinweg. Die zentralen Dienste sind gemeinsam auf fml-ops-01/02 untergebracht, wobei die Verwaltungseinheiten durch Compose und K3s getrennt wurden. Für jeden Schritt sind sowohl die Verfahren für das Online-Netz als auch für das isolierte Netz aufgeführt.

Die Befehle basieren auf den Adressen und festen Versionen dieses Übungsszenarios. Passwörter, Tokens und private SSH-Schlüssel sind weder in Beispielen noch in Git enthalten. Platzhalter in Konfigurationsdateien werden aus dem eigenen Secret-Store injiziert. Der ausgeführte Umfang und die tatsächlichen Ergebnisse werden anhand des Validierungsbeitrags überprüft.

Reihenfolge dieses Beitrags

1. Versionen und Installationsreihenfolge

Komponente Verwendete Version / Methode Auswahlgrund
Virtualisierung / OS VirtualBox 7.2.18 / Rocky Linux 10.2 Auf echten PCs reproduzierbare Linux-Übung
Docker / Compose 29.8.1 / 5.5.1 Container-Verwaltung für Zentrale und Proxy
Zabbix 7.0.30 LTS Server/Web/Proxy/Agent 2 Übereinstimmung der Versionen von Server und Proxy, Fixierung auf offizielle LTS-Patches
NetBox 4.7.1, netbox-docker 5.1.1 Zwei Apps/Worker und API-basierte Anlagenverwaltung
PostgreSQL / Patroni PostgreSQL 15 / Patroni 4.1.5 Zentrale DB-Replikation und Rollenwechsel
Redis / etcd Redis 7.4 / etcd 3.7.1 Sentinel und verteilte Fehlererkennung
AWX / Operator 24.6.1 / 2.19.1 Offizielle Operator-Installationsmethode
K3s v1.37.0+k3s1 Basis für die Ausführung von AWX auf einer einzelnen VM
NetBox collection netbox.netbox 3.23.0 Inventory-Plugin, das NetBox v2 Bearer-Token verwendet

Die Installationsreihenfolge ist OS·Netzwerk → DNS/NTP·CA → etcd/PostgreSQL/Redis → Zugriffs-VIP → NetBox/Zabbix → umgebungsspezifischer Proxy/Bastion → K3s/AWX·Git → PXE-Ziel → Automatisierungsintegration → Fehler-/Wiederherstellungsprüfung. Selbst wenn die Benutzeroberfläche eines späteren Schritts geladen wird, ist zuerst zu überprüfen, ob die DB-Rolle, die Namensauflösung und die Zeitsynchronisation des vorherigen Schritts normal sind.

„Neueste“ bezieht sich auf die feste Version zum Stand des Aufbaus vom 20.09.2026. Bei späteren Neuaufbauten sind die Support-Richtlinien und Image-Digests erneut zu überprüfen, und die Versionen aus diesem Beitrag dürfen nicht mit neuen Versionen gemischt werden. Es ist zwischen dem neuesten allgemeinen Release von Zabbix und dem neuesten offiziellen LTS zu unterscheiden.

2. Vorbereitung von VMs und Netzwerk

CORE ist 10.77.10.0/24, PROD ist 10.77.20.0/24, DEV ist 10.77.30.0/24 und STG ist 10.77.40.0/24. Diese werden jeweils als interne Netzwerke fml-core/prod/dev/stg erstellt. Gateway und Provision erhalten die vier internen Netzwerk-NICs, während Edge und die Ziele an ihr jeweiliges Umgebungsnetzwerk angeschlossen werden.

Bei der Konfiguration in einem Online-Netzwerk

Die Prüfsumme der offiziellen ISO überprüfen und eine Rocky-Minimalinstallationsvorlage erstellen. Für die Verwaltungs-VM sind während der Installation die NAT-NIC und die interne Netzwerk-NIC getrennt zu verwenden. Die SSH-Portweiterleitung des Hosts darf nur an 127.0.0.1 gebunden werden. Dem Ziel-PXE-VM wird kein NAT hinzugefügt.

$VBox = 'C:\Program Files\Oracle\VirtualBox\VBoxManage.exe'
& $VBox list vms
& $VBox showvminfo fml-ops-01 --machinereadable
# Das Ziel nur auf einer freigegebenen, leeren Festplatte neu anlegen.
.\lab-v2\Create-PxeTarget.ps1 -Environment prod

Beim Klonen von Vorlagen müssen Hostname, machine-id, SSH-Host-Schlüssel und MAC jeweils neu erstellt werden. Es ist sicherzustellen, dass feste Adressen, Schlüssel und machine-id der Originalvorlage nicht auf mehreren VMs verbleiben. SELinux Enforcing und firewalld sind beizubehalten, und der Remote-Root-Login sowie die Passwortanmeldung sind einzuschränken.

Bei der Konfiguration in einem geschlossenen Netzwerk

Nach dem Einbringen von ISO, verifizierten Installationspaketen, interner CA, öffentlichen Schlüsseln und Konfigurationsvorlagen wird dieselbe interne Netzwerkstruktur erstellt. Selbst ohne verbundene NAT-NIC muss der Zugriff auf die OS-Installation und das interne DNS/NTP möglich sein. „Eine bestehende Installation mit nachträglich deaktiviertem NAT“ und „eine Installation von Beginn an mit eingebrachten erforderlichen Abhängigkeiten“ sind als unterschiedliche Tests zu protokollieren.

Auf diesem PC stoppte der Bootvorgang eines neuen BIOS-PXE-Ziels mit 2 vCPUs, weshalb 1 vCPU verwendet wurde. Die zentrale Maschine 1 wurde mit dem CPU-Profil Intel Core i7-6700K und 4 vCPU ausgeführt. Dieser Profilname entspricht nicht der tatsächlichen PC-CPU. Hyper-V/VBS/Speicherintegrität wurden nicht geändert. Detaillierte VM-Probleme werden in einem separaten Blog behandelt.

3. Routing, DNS, NTP und Zugriffswege

Die Kommunikation zwischen den Umgebungen wird durch die firewalld-Richtlinie des Gateways erlaubt. Provision ist direkt mit jeder Umgebung verbunden, um DHCP, PXE und Speicher bereitzustellen, und wird nicht als Router verwendet.

Quelle Ziel Port Zweck
Zentral .11/.12 Umgebung Edge .10 TCP 22 Bastion-Zugang
Umgebung Edge .10 Freigegebenes Ziel .101 TCP 22 SSH-Weiterleitung
Umgebungsziel Gleiche Umgebung Edge .10 TCP 10051 Agent-Active-Daten
Umgebung Edge .10 Zentral .11/.12 TCP 10051 Aktiver Proxy und HA-Server
Freigegebenes Umgebungsnetzwerk VIP 10.77.10.10 TCP 443 NetBox/Zabbix/AWX API und Web
Umgebungsziel Gleiche Umgebung Provision .20 DNS 53, NTP 123, HTTP 80, PXE-relevante Ports Installation, Namensauflösung, Zeit, interner Speicher
Zentral/Quorum Entsprechender interner Dienstknoten etcd 2379/2380, Patroni 8008, PG 5432/6432, Redis 6379/26379, NFS 2049 Datenreplikation, Konsensfindung, gemeinsam genutzte Medien

Die obige Tabelle ist eine Zusammenfassung der Kommunikationszwecke. Überprüfen Sie für die tatsächlichen Erlaubnisregeln sowohl die Host-Firewall- als auch die Router-Richtlinien. DB, etcd und Redis dürfen nicht im Internet oder in allen Umgebungsnetzwerken offengelegt werden.

Bei der Konfiguration im Online-Netzwerk

Installieren Sie die erforderlichen Pakete auf der Management-VM und erstellen Sie die interne Schnittstelle sowie statische Routen. Vermischen Sie nicht die Standardroute für das Internet mit den statischen Routen des Übungsnetzwerks.

nmcli connection modify fml-internal \
  +ipv4.routes '10.77.20.0/24 10.77.10.1'
nmcli connection modify fml-internal \
  +ipv4.routes '10.77.30.0/24 10.77.10.1'
nmcli connection modify fml-internal \
  +ipv4.routes '10.77.40.0/24 10.77.10.1'
nmcli device reapply enp0s8
ip route
chronyc tracking

Bei der Konfiguration in einem isolierten Netzwerk (Air-Gap):

Lösen Sie im internen DNS netbox.fullmoon.test, zabbix.fullmoon.test und awx.fullmoon.test in die VIP 10.77.10.10 sowie git.fullmoon.test in 10.77.10.12 auf. Verlassen Sie sich nicht auf externe DNS-Fallbacks. Verwenden Sie chrony von Provision als interne Referenz, aber bereiten Sie für den realen Betrieb eine separat überprüfte Zeitquelle und Synchronisationsrichtlinie vor.

getent hosts netbox.fullmoon.test git.fullmoon.test
chronyc sources -v
ip route get 10.77.20.10

Der Browser-Zugriff erfolgt über HTTPS-Namen auf einem Management-Endgerät, das der Übungs-CA vertraut. Wenn das interne Netzwerk unter Windows nicht direkt geroutet wird, kann ein Loopback-SSH-Tunnel verwendet werden. Überprüfen Sie zuerst, ob der lokale Port 443 nicht bereits belegt ist.

ssh -i <관리용_개인키> -p 22031 -N -L 127.0.0.1:443:10.77.10.10:443 labadmin@127.0.0.1

In der hosts-Datei des Management-Endgeräts müssen die drei Servicenamen auf 127.0.0.1 verweisen, und das verifizierte öffentliche CA-Zertifikat muss im vertrauenswürdigen Speicher registriert werden. Der private Server-CA-Schlüssel wird nicht importiert. Um auch während eines Ausfallstests von Zentrale 1 den Zugriff sicherzustellen, verwenden Sie den Management-SSH-Port 22032 von Zentrale 2. Das Ignorieren von Zertifikatswarnungen darf nicht als reguläres Zugriffsverfahren dienen.

4. Container-Runtime und Import-Paket

Bei der Konfiguration im Online-Netzwerk:

Installieren Sie Docker/Compose aus dem offiziellen Docker-RHEL-Repository. Die Compose-Projektpfade sind unterteilt in /opt/fullmoon-lab/core, /opt/fullmoon-lab/apps und /opt/fullmoon-lab/edge. Sensible Umgebungsdateien erhalten die Berechtigung root-Besitzer 0600, übergeordnete Verzeichnisse 0700.

docker version
docker compose version
docker compose --project-directory /opt/fullmoon-lab/core \
  -f /opt/fullmoon-lab/core/compose.yml config --quiet
docker image inspect --format '{{json .RepoDigests}}' \
  zabbix/zabbix-server-pgsql:alpine-7.0.30

Da die gesamte gerenderte Compose-Ausgabe Passwörter enthalten kann, speichern Sie keine config-Inhalte in öffentlichen Protokollen. Unterscheiden Sie auch zwischen dem SELinux-Enforcing-Status des Hosts und der Aktivierung der SELinux-Integration des Docker-Daemons. Diese Übung behält das Host-Enforcing bei, beansprucht jedoch nicht, eine Umgebung zu sein, in der auch die Docker-SELinux-Integration angewendet wird.

Bei der Konfiguration in einem isolierten Netzwerk (Air-Gap):

Beziehen Sie RPMs und Abhängigkeiten von einer verbundenen Vorbereitungs-VM mit derselben CPU-Architektur und demselben Rocky-Major-Release. Das Docker-Image-Archiv und das K3s/containerd-Archiv sind getrennt. Das Laden von Images in Docker bedeutet nicht, dass sie in K3s verwendet werden können.

# Vorbereitungs-VM: benötigte RPM-Versionen und sämtliche Abhängigkeiten speichern
dnf download --resolve --alldeps --destdir ./rpms \
  docker-ce docker-ce-cli containerd.io docker-compose-plugin
createrepo_c ./rpms
docker image save -o images.tar <반입할_고정_이미지_목록>
sha256sum images.tar > images.tar.sha256

# Nach der Übertragung in das isolierte Netz
sha256sum -c images.tar.sha256
docker image load -i images.tar
k3s ctr images import fullmoon-ee-r2.tar

Die Importliste umfasst OS-ISO- und RPM-Repositories, Docker/Compose, Patroni-Build-Ergebnisse, NetBox/Zabbix/Redis/etcd-Images, K3s-Binärdateien und Airgap-Images, Operator-/RBAC-Proxy-/AWX/EE-Images, Git-Bundles, Konfigurationsvorlagen und öffentliche CAs, Signaturschlüssel sowie Prüfsummen. Validieren Sie auf einem neuen Ziel ohne externe NIC, um zu verhindern, dass Prüfungen zufällig durch den Cache der Vorbereitungs-VM bestanden werden.

5. PostgreSQL-, etcd- und Redis-Konfiguration

etcd und Sentinel werden auf den beiden zentralen Knoten und dem Quorum-Knoten platziert. PostgreSQL/Patroni und Redis werden auf den beiden zentralen Knoten platziert. Die Datenbank trennt Konten und Datenbanken für NetBox, Zabbix und AWX.

Bei der Konfiguration im Online-Netzwerk:

Ziehen/bauen Sie feste Images und platzieren Sie knotenspezifisches NODE_NAME/NODE_IP, die Patroni-Konfiguration, die Redis/Sentinel-Konfiguration sowie eingeschränkte Geheimdateien. Starten Sie die zentrale Datenbank, nachdem Sie überprüft haben, dass die drei etcd-Knoten miteinander kommunizieren.

docker compose --project-directory /opt/fullmoon-lab/core \
  -f /opt/fullmoon-lab/core/compose.yml --profile central up -d
docker compose --project-directory /opt/fullmoon-lab/core \
  -f /opt/fullmoon-lab/core/compose.yml exec -T postgres \
  patronictl -c /etc/patroni/patroni.yml list
curl --fail http://10.77.10.11:8008/patroni
curl --fail http://10.77.10.12:8008/patroni

Der Quorum-Knoten führt nur etcd und Sentinel ohne zentrales Profil aus. Patronis synchronous_mode wurde aktiviert und synchronous_mode_strict auf false gesetzt. Der Replikationsstatus und die Möglichkeit von Commit-Verlusten bei Ausfällen müssen an die Betriebsbedingungen angepasst bewertet werden. Der Ansatz, beide Datenbanken jeweils manuell zum Primärserver zu machen, wird nicht verwendet.

Bei der Konfiguration in einem isolierten Netzwerk (Air-Gap):

Da das Patroni-Dockerfile externe Repositories wie pip und apt benötigt, werden die Images während der Online-Vorbereitungsphase fertiggestellt und importiert. Vermeiden Sie es, vor Ort ad hoc zu bauen und dabei auf Internetabhängigkeiten zu stoßen. Laden Sie dasselbe Archiv auf die beiden zentralen Knoten, vergleichen Sie die Image-IDs und starten Sie sie mit dem gleichen Verfahren.

Der Datenbank-Verbindungsport von HAProxy ist 6432. Nur Knoten, bei denen Patroni /primary 200 zurückgibt, werden als Datenbank-Schreib-Backend verwendet. Beim anfänglichen Timeout von 60 Sekunden können inaktive Datenbankverbindungen getrennt werden, weshalb das Client/Server-Timeout des Datenbank-Listeners auf 1 Stunde aufgeteilt wurde. Die Werte sollten an die tatsächlichen Abfrage- und Verbindungspool-Richtlinien angepasst werden.

6. VIP, HTTPS und NetBox-Redundanz

Die Keepalived-VIP ist 10.77.10.10, und der standardmäßig bevorzugte Knoten ist ops01. HAProxy auf beiden Knoten verbindet sich mit NetBox 8082, Zabbix Web 8080 und AWX 30080. Die aktiven Rollen von Node, DB, Redis und VIP müssen nicht immer auf denselben Knoten liegen.

Bei der Konfiguration im Online-Netzwerk:

Geben Sie mit der Übungs-CA ein Zertifikat aus, das alle drei Web-Namen im SAN enthält, und platzieren Sie das Zertifikat und den Schlüssel mit eingeschränkten Berechtigungen auf den beiden zentralen Knoten. Verwenden Sie denselben SECRET_KEY, denselben API-Token-Pepper und dieselben Redis-Sentinel-Einstellungen für NetBox App und Worker.

# Wichtige Zusammenhänge in netbox-configuration.py
DATABASES = {'default': {
    'ENGINE': 'django.db.backends.postgresql',
    'NAME': 'netbox', 'USER': 'netbox',
    'PASSWORD': '<비밀_파일에서_주입>',
    'HOST': '127.0.0.1', 'PORT': 6432,
}}
# SECRET_KEY / API_TOKEN_PEPPERS auf beiden App-Knoten identisch konfigurieren.
# Für REDIS tasks/caching den Sentinel-Service und die jeweiligen DB-Nummern angeben.

Das tatsächliche Format der Standardkonfigurationsdatei je Version basiert auf der bereitgestellten NetBox-Konfiguration und der offiziellen Dokumentation. Wenn nur die Namen der Umgebungsvariablen übereinstimmen, sie aber nicht in der Python-Konfiguration gelesen werden, werden sie nicht angewendet. Die anfängliche Datenbank-Migration wird zuerst auf einem Knoten abgeschlossen, bevor die verbleibenden Knoten und der Worker gestartet werden.

Die Mediendaten werden über /srv/fullmoon/netbox-media des Quorums per NFSv4 freigegeben. Nur die beiden zentralen Knoten sind für den Export zugelassen und root_squash wird beibehalten. Überprüfen Sie die tatsächliche UID des NetBox-Images, um die Verzeichnisberechtigungen anzupassen. Das in dieser Rocky-Umgebung verifizierte NFS-SELinux-Boolean ist virt_use_nfs.

findmnt /srv/fullmoon/netbox-media
haproxy -c -f /etc/haproxy/haproxy.cfg
keepalived -t -f /etc/keepalived/keepalived.conf
systemctl is-active haproxy keepalived
curl --fail https://netbox.fullmoon.test/login/ -o /dev/null

Bei der Konfiguration in einem isolierten Netzwerk (Air-Gap):

Das NetBox-Image enthält die für die Ausführung erforderlichen Python-Abhängigkeiten, sodass das Image mit demselben Digest auf beiden Knoten importiert wird. Fügen Sie die interne CA nicht nur dem Host, sondern auch dem AWX EE hinzu. Bereiten Sie zudem ein Wiederherstellungsverfahren für Geheimnisse vor, damit SECRET_KEY/pepper auf den beiden Knoten nicht unterschiedlich werden. Da NFS-Ausfälle unabhängig vom Erfolg der Web-API Auswirkungen auf die Medien haben, sollten diese separat getestet werden.

Ein tatsächlich aufgetretenes Problem war der NetBox-Gesundheitscheck (Health Check). Wenn /login/ ohne HTTP/1.1 Host überprüft wurde, gab NetBox 400 zurück, was HAProxy dazu veranlasste, alle Backends als down einzustufen, woraufhin die VIP 503 zurückgab. Der Host wurde wie folgt angegeben:

backend netbox_ui
    mode http
    option httpchk
    http-check send meth GET uri /login/ ver HTTP/1.1 hdr Host netbox.fullmoon.test
    http-check expect status 200
    server ops01 10.77.10.11:8082 check
    server ops02 10.77.10.12:8082 check

Bei Ausfallstests dauerte eine NetBox-Cache-Abfrage aufgrund der standardmäßigen Wiederholungsversuche der Redis-Verbindung etwa 55,6 Sekunden. Wir überprüften den Code von NetBox 4.7.1 sowie django-redis und änderten ihn so, dass zuerst das lokale Sentinel abgefragt wird. Für den Cache wurden Verbindungs- sowie Antwort-Timeouts und Wiederholungsrichtlinien in den unterstützten KWARGs explizit angegeben. Der Loopback ist eine andere Verbindungsadresse desselben Sentinels; es wurde kein weiteres Quorum-Mitglied hinzugefügt.

from redis.backoff import NoBackoff
from redis.retry import Retry

# Auf jedem NetBox-Knoten zuerst den lokalen Sentinel abfragen.
SENTINELS = [('127.0.0.1', 26379), ('10.77.10.13', 26379),
             ('10.77.10.11', 26379), ('10.77.10.12', 26379)]
REDIS['caching']['KWARGS'] = {
    'socket_connect_timeout': 3,
    'socket_timeout': 3,
    'retry': Retry(NoBackoff(), 0),
}

Da es sich um einen auf schnelle Fehlerrückgabe begrenzten Wert handelt, unterscheiden sich die Wiederholungsversuche einzelner Anfragen von der Dienstwiederherstellungszeit. Die genaue Zeit bis zur Wiederherstellung der API nach einem Ausfall der primären Datenbank/Redis-Knoten entnehmen Sie bitte dem Validierungsbeitrag. Verallgemeinern Sie nicht, dass bei Betriebslasten oder anderen Versionen dieselben Ergebnisse erzielt werden.

7. Zabbix LTS HA und umgebungsspezifischer Proxy/Bastion

Bei der Konfiguration im Online-Netzwerk:

Server/Web/Proxy verwenden das Tag alpine-7.0.30, und Agent 2 für Rocky verwendet das 7.0.30-RPM für el10. Beide Server verweisen auf dieselbe Zabbix-Datenbank, sind jedoch mit unterschiedlichen HANodeName- und NodeAddress-Werten konfiguriert. Das Web ist so konfiguriert, dass es keine bestimmte Serveradresse fixiert, sondern den aktiven Knoten aus den HA-Informationen ermittelt.

# ops01
ZBX_HANODENAME=fml-ops-01
ZBX_NODEADDRESS=10.77.10.11:10051
# ops02
ZBX_HANODENAME=fml-ops-02
ZBX_NODEADDRESS=10.77.10.12:10051
# Adressen desselben HA-Clusters für den Active Proxy mit einem Semikolon verbinden
ZBX_SERVER_HOST=10.77.10.11:10051;10.77.10.12:10051

Der Proxy-Name muss exakt mit dem in der Zabbix-API registrierten Namen übereinstimmen. Trennen Sie den umgebungsspezifischen Proxy-PSK und Agent-PSK. Speichern Sie die SQLite-Daten des Proxys auf einem persistenten Volume und wenden Sie eine Pufferrichtlinie für die Festplatte an. Erst wenn überprüft wurde, dass verzögerte Daten nach einer Unterbrechung erneut übertragen wurden, kann das Pufferverhalten als verifiziert gelten.

Bei der Konfiguration in einem isolierten Netzwerk

Proxy-Images werden über docker load importiert. Der Agent-RPM wird als internes Repository bereitgestellt, wobei die GPG-Signaturprüfung beibehalten wird. Dieses el10-RPM wurde mit dem Schlüssel B5333005 verifiziert. Da die Verifizierung bei einer Konfiguration, die nur den bisherigen Schlüssel A14FE591 verwendet, fehlschlug, wurde der Fingerabdruck des offiziellen Signaturschlüssels überprüft und hinzugefügt.

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-ZABBIX-B5333005
rpm -K zabbix-agent2-7.0.30-release1.el10.x86_64.rpm
# Verifizierter Fingerabdruck des Schlüssels
# 4C3D6F2CC75F5146754FC374D913219AB5333005

Die Bastion leitet nur an .101:22 der Umgebung weiter. Interaktive Shells und Agent Forwarding sind nicht zulässig. Die Verbindung zum Ziel erfolgt über den zentralen Schlüssel; private Schlüssel verbleiben nicht auf der Edge. Unter Beibehaltung des SSH-Zugriffs des bestehenden Verwaltungskontos wird mit sshd -t geprüft und neu geladen.

Match User bastion
    AuthenticationMethods publickey
    AllowTcpForwarding local
    PermitOpen 10.77.20.101:22
    PermitTTY no
    AllowAgentForwarding no
    ForceCommand /bin/false
Match all

8. Git, K3s, AWX und Ausführungsumgebung

Bei der Konfiguration in einem Online-Netzwerk

Das Git-Bare-Repository befindet sich unter /srv/git/fullmoon-automation.git auf ops02. AWX ruft den main-Branch über den Read-Only-Deploy-Schlüssel von fmlgit ab. Der forced command wurde aus Gründen der Interpretierbarkeit durch git-shell mitsamt Pfad in einfache Anführungszeichen gesetzt.

restrict,command="git-upload-pack '/srv/git/fullmoon-automation.git'" ssh-ed25519 <공개키>

K3s wurde auf ops01 installiert und SELinux sowie Secret-Verschlüsselung wurden aktiviert. Traefik, ServiceLB und metrics-server wurden für dieses Lab ausgeschlossen, da sie nicht erforderlich sind. AWX ist auf Operator 2.19.1 und AWX 24.6.1 festgelegt, und das PostgreSQL-Secret verweist auf den Pfad 6432 der bestehenden HA-DB. Admin-Passwort, DB-Passwort und CA-Bundle werden als Kubernetes-Secrets injiziert.

k3s kubectl -n awx get pods,jobs
k3s kubectl -n awx apply -f awx.yml
curl --fail https://awx.fullmoon.test/api/v2/ping/

Da der gcr.io-Pfad des initialen RBAC-Proxy-Images des Operators einen 404-Fehler auslöste, wurde er auf das offizielle quay.io/brancz-Image derselben Version v0.15.0 aktualisiert. In der AWX-CRD müssen die Cookie-Einstellungen als String und host_aliases als Array vorliegen. Wenn SYSTEM_TASK_ABS_MEM als Zahl übergeben wird, ruft der entsprechende AWX-Code String-Methoden auf, wodurch der Dispatcher fehlschlägt; daher wurden unnötige manuelle Einstellungen entfernt.

Bei der Konfiguration in einem isolierten Netzwerk

Sowohl die K3s-Airgap-Images als auch alle vom Operator generierten Images werden importiert. Insbesondere wenn Init-, Migration-, EE- oder RBAC-Proxy-Images fehlen, erfolgt keine Installation, selbst wenn das Web-Image vorhanden ist. Nach dem Import in K3s containerd ist zu prüfen, ob die tatsächlichen Imagenamen mit den Namen in der CR übereinstimmen.

Die Lab-EE umfasst awx-ee:24.6.1 mit netbox.netbox:3.23.0, einer öffentlichen CA sowie verifizierten Git/Edge-SSH-Host-Schlüsseln. Der Imagename lautet localhost/fullmoon-ee:24.6.1-netbox3.23.0-r2, und die Pull-Richtlinie der AWX-Ausführungsumgebung ist Never. Das Vorkommen von localhost im Namen bedeutet nicht, dass eine Registry ausgeführt wird; es werden die vorab in K3s importierten lokalen Images verwendet.

k3s ctr images import fullmoon-ee-r2.tar
k3s ctr images list
git bundle verify fullmoon-automation.bundle

In AWX werden Projekt, das genehmigte Bootstrap-Inventar, die NetBox-Inventarquelle, die SSH-Anmeldeinformationen, NetBox/Zabbix-API-Anmeldeinformationen, Onboard/Verify-Job-Templates und Workflows erstellt. Der erfolgreiche Workflow-Pfad lautet Onboard → NetBox-Inventarsynchronisierung → Verify. AWX selbst ist als Einzelkonfiguration auf dem zentralen Gerät 1 ausgelegt. Die ha-Feldangabe eines API-pings allein lässt nicht auf eine physisch verteilte HA schließen.

9. Bereitstellung leerer Server mittels PXE und Kickstart

Bei der Konfiguration in einem Online-Netzwerk

Das offizielle Rocky-Minimal-ISO wird verifiziert und der Installationsbaum unter /var/www/html/rocky von Provision bereitgestellt. Das eigentliche ISO enthält Minimal/repodata. Die direkte Verwendung der DVD-Pfade BaseOS/AppStream führt zu einem 404-Fehler. DHCP ordnet nur umgebungsspezifische, genehmigte MACs der .101 zu.

fml-prod-app-01 : 08:00:27:a0:20:65 → 10.77.20.101
fml-dev-app-01  : 08:00:27:a0:30:65 → 10.77.30.101
fml-stg-app-01  : 08:00:27:a0:40:65 → 10.77.40.101

In VirtualBox auf diesem PC funktionierten BIOS + das offizielle ipxe-legacy.iso von DHCP über HTTP-Kernel/initrd bis hin zu Kickstart. Die iPXE-Datei ist das Boot-Medium zum Starten der Netzwerkinstallation, während die OS-Pakete von Provision bezogen werden. Die neue VM wird mit einer leeren 32-GiB-Festplatte, 4 GiB Installations-RAM und 1 vCPU erstellt und nach der Installation auf 1 GiB reduziert.

Das %pre-Skript von Kickstart lässt Partitionierungsarbeiten nur zu, nachdem MAC, VirtualBox-DMI-Identifizierung, das Vorhandensein von /dev/sda und das Fehlen einer Datenträgersignatur überprüft wurden. Das Root-Passwort wird gesperrt, und der öffentliche labadmin-Schlüssel, sshd, sudo, chrony sowie firewalld werden konfiguriert. Der vom %post-Skript hinterlassene SSH-Host-Schlüssel wird zur Registrierung mit vertrauenswürdigen VM-Konsolenaufzeichnungen abgeglichen. Unbekannte Host-Schlüssel werden nicht blind akzeptiert.

Bei der Konfiguration in einem isolierten Netzwerk

Dieselbe ISO-, Boot-Datei und Kickstart werden in das interne HTTP importiert. Das Ziel verfügt über keine externe NIC; DNS, NTP und Pakete werden von Provision in derselben Umgebung bezogen. Wenn zusätzlich ein internes Repository für Agent 2 eingerichtet wird, können Grundeinstellungen auch ohne externes RPM-Repository vorgenommen werden.

Bei der Anwendung auf physische Server darf der VirtualBox-DMI-Guard nicht einfach entfernt und ausgeführt werden. Nach separater Zuordnung von genehmigten, tatsächlichen Seriennummern/BMC/MACs, RAID-Laufwerken und Installations-WWNs sowie UEFI/Secure-Boot- und NIC-Treibern muss der Radius der Festplattenzerstörung überprüft werden. Die tatsächlichen Installationsnachweise in diesem Dokument stammen von einer VM und dürfen nicht als Verifizierungsergebnisse auf physischer Server-Hardware umgedeutet werden.

10. Anbindung von Asset-API, Inventar und Monitoring

Bei der Konfiguration in einem Online-Netzwerk

Dem Asset-Schreibkonto von NetBox werden die erforderlichen Berechtigungen für VM, Device, Interface, IP und Katalog zugewiesen, während das Inventarkonto nur Lesezugriff erhält. Die Erstellung initialer Custom Fields und Kataloge erfolgt über ein separates Bootstrap. V2-Tokens in NetBox 4.7 verwenden das Format Bearer nbt_. Das Automatisierungskonto für Zabbix beschränkt verwaltete Zielgruppen sowie API-Methoden und versieht Tokens mit einem Ablaufdatum.

plugin: netbox.netbox.nb_inventory
api_endpoint: https://netbox.fullmoon.test
token:
  type: Bearer
  value: "{{ lookup('env', 'NETBOX_TOKEN') }}"
validate_certs: true
query_filters:
  - tag: auto
  - status: active

In der Erfassungsphase wird der Python-Collector in einem temporären Zufallsverzeichnis bereitgestellt, ausgeführt und anschließend stets entfernt. Der tatsächliche Hostname, die Machine ID sowie die Verwaltungs-NIC/-IP des Ziels werden mit dem genehmigten Inventar abgeglichen. Weichen die Werte ab oder ist eine bestehende IP einem anderen Asset zugewiesen, wird der Vorgang vor Änderungen in NetBox abgebrochen. API-Tokens oder die gesamte /proc-Umgebung werden nicht in die Erfassungsergebnisse aufgenommen.

API-Vorgänge werden mittels delegate_to: localhost in der AWX-EE ausgeführt. Da target-spezifische ansible_become-Variablen bei lokalen Jobs an die EE übertragen werden könnten und dort möglicherweise nach sudo gesucht wird, was fehlschlägt, ist dies wie folgt explizit anzugeben.

delegate_to: localhost
become: false
vars:
  ansible_become: false
  ansible_python_interpreter: "{{ ansible_playbook_python }}"

Die Registrierungsreihenfolge lautet: tatsächliches Asset/Interface/IPAM → Zabbix-Host/Proxy/Template → NetBox-Inventarquellensynchronisierung → Validierung der Ziel-Baseline mit den neuesten Zabbix-Daten. Da die NetBox- und Zabbix-APIs keine einzige DB-Transaktion bilden, wird ein erneuter Lauf nach Teilerfolgen unterstützt; es erfolgt jedoch kein kompensatorischer Vorgang, der erfolgreich registrierte Assets blind löscht.

Bei der Konfiguration in einem isolierten Netzwerk

Da der API-Code ausschließlich internes HTTPS verwendet, bleibt das Vorgehen identisch. CA, Collections, Python-Bibliotheken, gepinnte SSH-Host-Schlüssel und Git-Commits der EE müssen vollständig importiert sein. Während des Job-Aufsatzes werden keine Pakete von Galaxy oder pip heruntergeladen. Auf dem Ziel sind für die Agent-Installation ausschließlich die Repositories fullmoon-minimal und fullmoon-zabbix anzugeben.

ServerActive=10.77.20.10:10051
Hostname=fml-prod-app-01
TLSConnect=psk
TLSAccept=psk
TLSPSKIdentity=fml-prod-app-01
TLSPSKFile=/etc/zabbix/agent.psk

Die PSK-Datei erhält die Berechtigungen zabbix:0400, und in den AWX-Protokollen werden keine Werte hinterlassen. Es wird geprüft, ob verwaltete Hosts doppelt vorhanden sind, sowie die Werte lastclock/lastvalue des neuesten Items. Ein Vorgang wird nicht allein aufgrund der Antwort zur Host-Erstellung als abgeschlossen betrachtet.

Abschluss der Installation und automatische Verknüpfung von Workflows

fullmoon-postinstall.timer auf dem zentralen Gerät 1 verifiziert den Abschluss der Installation des genehmigten Ziels. SSH läuft über die entsprechende Bastion und prüft den festgelegten Host-Schlüssel. Wenn /var/lib/fullmoon-lab/pxe-installed, Hostname und Machine ID übereinstimmen, wird ein Workflow ausgeführt, der Projekt-Sync → Bootstrap-Inventar-Sync → Angabe des einzelnen Ziels über limit durchläuft. Job-ID und -Status werden in state.json protokolliert, das nur für root lesbar ist.

Der initial generierte SSH-Host-Schlüssel wird mit der vertrauenswürdigen seriellen Konsole von VirtualBox abgeglichen und in die Liste der genehmigten Schlüssel aufgenommen. Bis zu dieser Identitätsfreigabe wartet der Controller. Unbekannte Schlüssel werden nicht automatisch akzeptiert. Danach erfolgen die Erkennung des Installationsabschlusses, die API-Registrierung und die Monitoring-Validierung automatisch. Bei physischen Servern muss diese Identitätsregistrierung mit der BMC-Console oder dem SSH-CA-Ausstellungsverfahren der Organisation verknüpft werden.

systemctl status fullmoon-postinstall.timer
journalctl -u fullmoon-postinstall.service --since '-30min'
# Erfolg: launched → AWX workflow ID → completed
# Fehler: manual_review_required. Vor der Ursachenprüfung keine automatische erneute Registrierung ausführen.

Da sich dieser Controller und AWX auf ops01 befinden, stoppt das neue Onboarding bei einem Ausfall dieses Knotens. Fällt ops02 mit Git aus, schlägt die Synchronisierung neuer Projekte fehl. Sollte die Statusdatei verloren gehen oder der Prozess unmittelbar nach einer Ausführungsantwort beendet werden, könnte derselbe Workflow erneut versucht werden; daher ist auch die Asset-Registrierung selbst so ausgelegt, dass sie durch Wiederholbarkeit auf Identifikations- und IP-Duplikate prüft.

11. Zugangsdaten und kurzer Betriebsleitfaden

Funktion Zugangspfad Betriebsüberprüfung
NetBox https://netbox.fullmoon.test VM/Device, Interface, primäre IP, Sammlungsstatus
Zabbix https://zabbix.fullmoon.test HA-Status, letzter Proxy-Zugriff, neueste Host-Daten
AWX https://awx.fullmoon.test Projektrevision, Inventory-Update, Workflow-/Job-Ergebnisse
Git ssh://fmlgit@git.fullmoon.test/srv/git/fullmoon-automation.git Schreibgeschützte SCM-Synchronisierung
Verwaltungs-SSH Loopback 22031~22038 labadmin-Public-Key-Authentifizierung der jeweiligen VM
Ziel-SSH Über Bastion je nach Umgebung Genehmigter Host-Key und Einschränkung auf .101:22

Tägliche Prüfungen werden in folgender Reihenfolge durchgeführt: Zeitsynchronisation und Festplatte/Arbeitsspeicher → DB-/Redis-Rolle → App/Worker → HA/VIP → Proxy → tatsächliche Agenten-Daten → letzte AWX-Fehler. Es wird nicht nur überprüft, ob ein Container läuft (Up).

df -h
free -m
chronyc tracking
docker ps --format '{{.Names}} {{.Status}}'
k3s kubectl -n awx get pods
systemctl is-active haproxy keepalived

Beim Hinzufügen neuer Server müssen das genehmigte Inventory, MAC/IP, Bastion PermitOpen und der SSH-Host-Key zuerst registriert und in Git commited werden. Nach der Projektsynchronisierung wird nur der jeweilige Host als Limit angegeben. Überprüfen Sie die primäre IP und die Umgebungsgruppe in NetBox, bevor Sie das System in den produktiven Betrieb übergeben. Ersetzen Sie nicht alle laufenden Server durch die unbeschränkte Zielangabe „all“.

Änderungen von Passwörtern und Token-Erneuerungen werden gemeinsam mit dem Umfang des Secret Stores, der AWX-Anmeldeinformationen und des Neustarts von Diensten verwaltet. Abgelaufene Token, geänderte SSH-Host-Keys oder andere Maschinen-IDs werden nicht automatisch umgangen. Nach einem Knotenausfall wird das Replica basierend auf dem verbleibenden Primärknoten wiederhergestellt; getrennte Knoten dürfen nicht willkürlich wieder mit Schreibrechten aktiviert werden.

12. Abschluss mit Backup, Updates und Validierung

Verwalten Sie logische PostgreSQL-Backups, NetBox-Medien, Git-Repositories, den AWX SECRET_KEY und die Datenbank sowie CA/Konfigurationen/Geheimdaten separat. Ein reines VM-Snapshot ersetzt kein anwendungskonsistentes Backup. Die Existenz einer Backup-Datei und das erfolgreiche Wiederherstellen in einer isolierten Datenbank zum Lesen derselben Assets sind zwei unterschiedliche Validierungen.

Updates werden zusammen mit Image-Tag/-Digest sowie EE/Collection dokumentiert und nach der Validierung durchgeführt. Da eine NetBox-Migration oder ein DB-Major-Upgrade möglicherweise nicht allein durch das Zurücksetzen auf das vorherige Image wiederhergestellt werden kann, müssen Datenbackup- und Wiederherstellungsverfahren vorbereitet werden. In geschlossenen Netzwerken (Air-Gapped) werden Update-Pakete samt Prüfsummen neu erstellt und vorherige Validierungspakete aufbewahrt.

Die Bestätigung eines erfolgreichen Setup umfasst die Asset-Registrierung, Inventory-Synchronisierung, neuesten Überwachungswerte, erneute Ausführung, Ablehnung von Adresskonflikten, Failover von Diensten, Wiederherstellung des Proxy-Puffers, Backup-Wiederherstellung sowie die Installation von Zielen ohne externe Kommunikation. Tatsächlich durchgeführte Tests und nicht ausgeführte Punkte werden getrennt im Validierungsprojekt dokumentiert.

Weiterführende Lektüre und Konfigurationsmaterialien

Portfolio-Original · Leitfaden zum Aufbau von Online- und geschlossenen Netzwerken · Fehlerszenarien und Validierungsprotokolle · Protokoll zur Behebung von VirtualBox-Konfigurationsproblemen

ZIP mit Lab-Konfigurationen und Automatisierungsquellen · ZIP SHA-256

Die öffentliche ZIP-Datei enthält Konfigurationsvorlagen und Automatisierungsquellen. Sie enthält keine Betriebssystem-, RPM- oder Container-Images sowie keine Anmeldeinformationen. Diese müssen vor der Anwendung mit Ihren eigenen Adressen, öffentlichen CAs, genehmigten SSH-Schlüsseln und dem Secret Store konfiguriert werden.