Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Cloud-native Netbox auf Google Cloud Platform (GCP)

By Mike SparrJan 24, 20236 min read

Diese Seite ist auch in English, Español, Français, Italiano, 日本語 und Português verfügbar.

Netzwerke und Equipment per IP Address Management (IPAM) im Griff behalten

In letzter Zeit melden sich auffällig viele Kunden mit Netzwerkproblemen – vor allem beim Peering –, weil sich IP-Adressbereiche überschneiden. Ein deutliches Signal dafür, dass IP-Adressen unternehmensweit geplant und verwaltet werden sollten.

Sie können Ihre IPs zwar in einer geteilten Tabelle pflegen, doch dafür gibt es auch spezialisierte Tools. Dieser Beitrag zeigt, wie Sie das beliebte Open-Source-Tool für IP Address Management (IPAM) Netbox cloud-native auf der Google Cloud Platform (GCP) betreiben.

Klassischer Stack

Klassisch läuft Netbox auf einer oder mehreren virtuellen Maschinen hinter einem Webserver. Es gibt zwar ein von der Community gepflegtes Docker-Image, doch die einzige Anleitung beschreibt den Betrieb über docker compose. Diese Architektur ähnelt vielen selbst entwickelten oder betriebenen Anwendungen – und eignet sich daher hervorragend, um eine Migration in die Public Cloud zu illustrieren.

Quelle: Netbox – Standardinstallation von Netbox

Cloud-native Design

Ich wollte herausfinden, wie das Docker-Image funktioniert, welche Abhängigkeiten und Konfigurationsparameter es mitbringt – und es stattdessen ausschließlich mit Managed Services auf GCP bereitstellen. Das Beispiel zeigt anschaulich, wie Sie Anwendungen bei der Migration in die Public Cloud entweder per "move and improve" oder "rip and replace" angehen können.

Überarbeitete Netbox-Installation auf GCP mit Managed Services

Anwendungskomponenten

  • Netbox-Anwendung (Python-App auf Basis des Django-Frameworks)
  • PostgreSQL-Datenbank (Cloud SQL)
  • Redis (Cloud Memorystore)

Designentscheidungen

  • Managed Database und Cache (Cloud SQL, Cloud Memorystore)
  • Ausschließlich private IPs für Datenbanken und Cache (Private Service Access)
  • Private DNS-Auflösung für Datenbank-Hostnamen (Cloud DNS)
  • Secrets im Secret Manager (Secret Manager)
  • Serverlose Container-Runtime (Cloud Run, Artifact Registry)
  • Globaler Load Balancer mit TLS (HTTP(S) Load Balancing, Managed Certificate)
  • WAF-Firewall (Cloud Armor)

Eine Hürde, an der ich viele Organisationen scheitern sehe, ist die Anbindung von Managed Services und serverlosen Apps über private IP-Adressen. Dieses Beispiel zeigt, wie Sie private Bereiche in Ihrem VPC-Netzwerk reservieren und sie anschließend den Managed Services zuweisen, um eine Konnektivitätsbrücke zu schlagen.

Cloud DNS sorgt für private Hostnamen, über die die Apps mit den Datenbanken kommunizieren. Das schafft Flexibilität: Wenn Sie Datenbanken später austauschen oder ein Failover durchführen müssen, passen Sie einfach die DNS-Einträge an, und die Anwendungen verweisen weiterhin auf dieselbe Domain. Theoretisch hätte ich DNS Forwarding nutzen und alles an meine öffentliche Domain anbinden können – intern war das aber nicht nötig, daher habe ich example.com verwendet.

Eine Bastion (oder Jump Host) wäre eigentlich nicht erforderlich gewesen, doch ich habe während des Aufbaus eine VM hochgezogen, um Verbindungen zu testen. Im Regelbetrieb würde man eine Bastion in einer Managed Instance Group (MIG) der Größe 1 ohne externe IP-Adressen betreiben.

Sichere, lastverteilte Webanwendung

Gehostete Netbox-Anwendung, ausgeliefert über einen Global Load Balancer vor einem Cloud Run-Service

Um das Zusammenspiel anschaulich zu zeigen, habe ich eine eigene Domain genutzt und einen A-Record für die statische IP-Adresse des Global Load Balancers angelegt – ein Managed Certificate wurde automatisch bereitgestellt.

Für zusätzliche Sicherheit habe ich eine Cloud Armor-Policy (WAF-Firewall) auf den Load Balancer angewendet und IP-Bereiche eingeschränkt (siehe unten).

Implementierungs-Code

Der folgende Code zeigt Schritt für Schritt die Befehle, mit denen ich alles aufgesetzt habe – inklusive Networking, Umgebungsvariablen und Secrets, Datenbanken, Artifact Registry und Docker-Images, Cloud Run, Load Balancing sowie WAF-Firewall.

Zusätzliche Komplexität und Überlegungen

Einer der Gründe, warum ich Netbox als Beispiel für die cloud-native Modernisierung und Bereitstellung von Anwendungen gewählt habe, ist die technische Komplexität. Die Anwendung umfasst Dateisystem, Sessions, Worker und sogar tägliche Cron-Cleanups.

Docker-Compose-Ausschnitt für die Netbox-Anwendung (man beachte netbox-worker und netbox-housekeeping)

Der oben gezeigte Ausschnitt aus der docker-compose.yaml nutzt ein YAML-Feature namens Anchors – das nicht spezifisch für docker-compose ist.

Beispiel für YAML-Anchors und Merge-Keys

So lassen sich Konfigurationen kompakt duplizieren und anschließend per Override-Befehl zur Laufzeit unterschiedliche Skripte ausführen.

Worker auf Cloud Run nachbauen

Um diese Funktionalität auf Cloud Run nachzubilden, gibt es die Flags -- cmd und - -args. Ich dupliziere einfach die Befehle für das Deployment der Hauptanwendung, ändere den Namen und überschreibe das CMD, um wie unten ein anderes Entrypoint-Skript auszuführen:

gcloud run deploy $WORKER_NAME \
    --platform managed \
    --allow-unauthenticated \
    --vpc-connector $CONNECTOR_NAME \
    --ingress=internal-and-cloud-load-balancing \
    --region $GCP_REGION \
    --image $IMAGE_PATH \
    --set-env-vars "ALLOWED_HOSTS=$ALLOWED_HOSTS" \

    ...

    --cmd "/opt/netbox/venv/bin/python" \
    --args "/opt/netbox/netbox/manage.py" \
    --args "rqworker"

Tägliche Housekeeping-Jobs mit Cloud Run und Cloud Scheduler

Den täglichen Housekeeping-Job lässt man über einen weiteren Cloud Run-Service laufen und plant ihn anschließend mit Cloud Scheduler täglich ein.

gcloud run deploy $HOUSEKEEPING_NAME \
    --platform managed \
    --allow-unauthenticated \
    --vpc-connector $CONNECTOR_NAME \
    --ingress=internal-and-cloud-load-balancing \
    --region $GCP_REGION \
    --image $IMAGE_PATH \
    --set-env-vars "ALLOWED_HOSTS=$ALLOWED_HOSTS" \

    ...

    --cmd "/opt/netbox/housekeeping.sh"

Nach dem Deployment des Housekeeping-Service aktivieren wir die Cloud Scheduler API:

gcloud services enable cloudscheduler.googleapis.com

Anschließend legen wir einen Service Account an, weisen ihm Invoker-Rechte zu und erstellen den geplanten Job:

# fetch the service URL
export SVC_URL=$(gcloud run services describe $HOUSEKEEPING_NAME \
  --platform managed --region $GCP_REGION --format="value(status.url)")

#########################################################
# create cloud scheduler job
#########################################################
export SA_NAME="cloud-scheduler-runner"
export SA_EMAIL="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com"

# create service account
gcloud iam service-accounts create $SA_NAME \
    --display-name "${SA_NAME}"

# add sa binding to cloud run app
gcloud run services add-iam-policy-binding $HOUSEKEEPING_NAME \
    --platform managed \
    --region $GCP_REGION \
    --member=serviceAccount:$SA_EMAIL \
    --role=roles/run.invoker

# create the job to invoke service every day at 2:30 AM
gcloud scheduler jobs create http housekeeping-job --schedule "30 2 * * *" \
    --http-method=GET \
    --uri=$SVC_URL \
    --oidc-service-account-email=$SA_EMAIL \
    --oidc-token-audience=$SVC_URL

Dateisysteme

Mein Ziel war es zu zeigen, dass sich auch eine komplexe Anwendung wie Netbox aufteilen und mit Cloud Run sowie weiteren Managed Services in der Cloud betreiben lässt. Für diese spezielle App ist das vielleicht nicht die optimale Lösung – aber es ist machbar.

Wenn Sie auf das Dateisystem angewiesen sind, sind die serverlosen Plattformen aktuell limitiert. In dem Fall lohnt sich eher der Betrieb auf Kubernetes Engine oder einer schlichten Compute Engine VM. Sie können sogar eine VM als Container betreiben – sehr elegant – und nach Bedarf Disks bzw. Volumes anhängen.

Ein Trick für ein einfaches "Dateisystem" auf Cloud Run: den Secret Manager nutzen, wie ich es im Beispielcode und im folgenden Snippet vorgemacht habe.

# create secret for all vars
gcloud secrets create $SECRET_ID --replication-policy="automatic"
gcloud secrets versions add $SECRET_ID --data-file=${PWD}/$SECRET_FILE

# mount file path in cloud run
gcloud run deploy $SERVICE --image $IMAGE_URL \
    --update-secrets="/env/netbox.env"=$SECRET_ID:$SECRET_VERSION

Best Practice: getrennte Service Accounts

Auch wenn meine Beispiele nur einen separaten Service Account für das Cloud Scheduler-Add-on zeigen, ist es Best Practice, für jeden Dienst und für die Bastion (VM) eigene Service Accounts anzulegen und ihnen jeweils nur die minimal nötigen IAM-Rollen zuzuweisen. Das entspricht dem Least-Privilege-Prinzip.

Für den Cloud Run-Service sollten wir einen eigenen Service Account "netbox-runner" erstellen und ihm nur die nötigen Rollen geben, etwa:

Ich hoffe, dieses Beispiel zeigt anschaulich, wie Sie bestehende Anwendungen modernisieren und Managed Services in der Public Cloud nutzen können. Wenn es Ihnen lediglich darum geht, Netbox zum Laufen zu bringen, reichen die obigen Code-Snippets – alternativ können Sie es aber auch auf einer VM oder mit K8s betreiben.

Sie können das funktionierende Beispiel zudem in Terraform überführen, etwa mit Drittanbieter-Lösungen wie Terraformer oder mit den hauseigenen Bulk-Export-Tools von GCP, die Ihre bestehende Infrastruktur per Reverse Engineering erfassen und passenden Terraform-Code erzeugen.

Falls Ihre Organisation beim Aufbau ihrer Netzwerke mit ähnlichen IP-Kollisionen zu kämpfen hat, ist es vielleicht an der Zeit, IPAM aktiv zu betreiben – sei es per geteilter Tabelle oder mit einem etablierten Tool wie Netbox.