Zum Inhalt springen

Dokumentation

Agenten

Der Agent ist der einzige Teil von Provibr, der auf Ihrer eigenen Hardware läuft. Er hält die Zugangsdaten für die Systeme, die Sie verbinden, führt die Arbeit aus, um die das Panel bittet, und meldet zurück, was er sieht. Die Plattform wählt sich nie bei Ihnen ein.

Was ein Agent ist

Ein Agent deckt ein Netzwerk ab: die Stelle, von der aus Ihre Hypervisoren und Panels erreichbar sind. Alles, was Provibr mit Ihrer Infrastruktur tut, läuft über ihn.

  • Die Verbindung ist ausgehend. Der Agent öffnet sie zur Plattform und hält sie offen; nichts muss aus dem Internet erreichbar sein, und es muss kein Port zu ihm weitergeleitet werden.
  • Die Zugangsdaten bleiben auf Ihrer Seite. Sie gehen einmalig an den Agenten und werden in einem verschlüsselten Tresor auf diesem Host verschlossen; die Plattform speichert nur die Namen der Felder, die Sie ausgefüllt haben.
  • Er meldet, was er beobachtet. Maschinen werden in kurzem Takt abgefragt, und alle paar Minuten läuft ein vollständiger Abgleich, und so bemerkt das Panel eine Maschine, die außerhalb von Provibr gestoppt wurde.
  • Er fasst nur an, was Sie übergeben haben. Eine Ressource ohne Eintrag in Provibr wird ignoriert, gezählt und wieder vergessen. Der Agent übernimmt nie von sich aus eine Maschine.

Der Host, den er braucht

Nichts Exotisches, und nichts, das Sie vorher installieren müssten. Der Agent ist ein einzelnes statisch gelinktes Binary: Er bringt seine eigene C-Bibliothek mit, es gibt also keine Laufzeitumgebung, keinen Interpreter und kein Distributionspaket, das passen müsste. Eine kleine virtuelle Maschine reicht völlig. Die Größen, die wir gemessen haben, stehen weiter unten auf dieser Seite.

Was ein Agent-Host mitbringen muss
AnforderungWas Sie brauchenWarum
Prozessor64-Bit-x86 (x86_64, auch amd64 genannt)Wir veröffentlichen einen Linux-Build, und das ist die Architektur, für die er gebaut ist. Der Installer prüft uname -m, bevor er überhaupt etwas herunterlädt, und bricht bei jeder anderen Architektur ab, statt etwas zu installieren, das nicht laufen kann. Einen ARM-Build gibt es noch nicht.
BetriebssystemJede Linux-DistributionNichts wird gegen Ihre Systembibliotheken gelinkt, die Distribution, ihre Version und ihr Paketmanager spielen also keine Rolle. Der nächste Abschnitt listet die auf, auf denen dieser Build tatsächlich gestartet wurde.
Init-Systemsystemd, oder Ihr eigenesDer Installer schreibt eine systemd-Unit und aktiviert sie. Auf einem Host ohne systemd installiert und registriert er trotzdem alles und schreibt dann den Befehl aus, mit dem Sie den Agenten unter dem starten, was Sie stattdessen verwenden. Eine halbe Installation wäre schlechter als eine ehrliche.
Rechte bei der Installationroot, einmaligDie Installation legt den Systembenutzer provibr-agent, zwei Verzeichnisse und die Unit an. Danach läuft der Agent unter diesem unprivilegierten Benutzer, und dass er das Update-Skript nicht beschreiben darf, ist genau das, was ihn dort hält.
Ausgehende VerbindungenTCP 50051 und 50052 zu gw.provibr.netPort 50051 wird einmal verwendet, bei der Registrierung. Port 50052 trägt die Sitzung und bleibt offen. Beide sind TLS. Filtert Ihre Firewall ausgehenden Verkehr, sind diese zwei Regeln alles, was sie durchlassen muss.
Eingehende VerbindungenKeineDer Agent baut die Verbindung selbst auf; nichts muss aus dem Internet erreichbar sein, und es muss kein Port zu ihm weitergeleitet werden. Maschinen über das Netzwerk zu installieren ist die eine Ausnahme, und selbst dann lauscht er nur im lokalen Segment.
Zugriff ins eigene NetzwerkZu den Systemen, die Sie verbindenIhr Hypervisor, Ihr Hosting-Panel oder Ihr Game-Panel wird über seine eigene API angesprochen, von diesem Host aus. Was der Agent nicht erreicht, kann Provibr nicht verwalten.
Arbeitsspeicher512 MB reichen völligWir haben 18 MB gemessen, mit tausend Maschinen verteilt über fünf Systeme; das ist der schwerste Fall in der Tabelle weiter unten. Die Spitze liegt woanders: Die Lizenzdatei bei der Registrierung aufzuschließen braucht kurz etwa 70 MB, weil dieser Schritt bewusst aufwendig ist, damit sich der Code nicht einfach durchprobieren lässt.
Festplatte1 GB reicht völligDas Binary ist 17 MB groß, und alles, was der Agent daneben ablegt, blieb in unseren Messungen unter 40 kB. Die Ausnahme ist die Installation über das Netzwerk: Dabei werden Boot-Medien zwischengespeichert, standardmäßig bis zu 20 GB.
UhrUngefähr richtigZertifikate und Lizenzdateien tragen Gültigkeitsdaten, und beide Seiten prüfen sie; ein Host, dessen Uhr Tage danebenliegt, kann sich deshalb nicht registrieren. Jeder NTP-Client genügt.
Der Agent läuft unter einem eigenen unprivilegierten Systembenutzer in einer gehärteten systemd-Unit. Er erhält genau zwei zusätzliche Capabilities, und zwar nur, damit er Netzwerkinstallationen bedienen kann; entfernen Sie sie, funktioniert alles außer diesem weiter.

Welches Linux

Es gibt kein Paket zu installieren und keine Distribution, die passen müsste; was folgt, ist deshalb keine Liste unterstützter Systeme. Es ist die Liste der Systeme, auf denen dieser Build tatsächlich gestartet wurde. Alles andere mit einem 64-Bit-x86-Linux-Kernel sollte sich genauso verhalten, und wenn nicht, würden wir das gern erfahren.

Linux-Distributionen, auf denen der Agent gelaufen ist
SystemVersionAnmerkungen
Debian13 (Trixie)
Debian12 (Bookworm)Die Distribution, auf der der vollständige Test lief: installiert, registriert, verbunden, und die Abfragen liefen.
Ubuntu24.04 LTSMit Ubuntu 24.04 hat der Kernel begonnen, genau die Namespaces einzuschränken, die Automatisierungen brauchen. Der Agent bringt dafür ein AppArmor-Profil mit; alles andere funktioniert unverändert.
Ubuntu22.04 LTS
AlmaLinux9
AlmaLinux8Eine deutlich ältere C-Bibliothek als die, auf der dieser Build entstanden ist. Das macht keinen Unterschied, weil der Agent seine eigene mitbringt.
Fedora42
openSUSE Leap15
Amazon Linux2023
Alpine Linux3.21musl und überhaupt kein glibc, die schärfste Probe, die es für ein statisch gelinktes Binary gibt.
Zwei ehrliche Grenzen dieser Liste. Sie zeigt, dass das Binary auf jedem dieser Userlands startet und seine kryptografische Arbeit tut; die vollständige Sitzung, mit Zertifikaten und Abfragen, wurde auf einem davon gemessen. Und jede Prüfung lief auf Maschinen, die sich einen Kernel teilen, sodass damit die Unabhängigkeit von der Distribution belegt ist, nicht die von der Kernel-Version.

Wie viel Maschine

Der Agent selbst ist klein und bleibt klein. Was wächst, ist der Bestand, den er beobachtet: Alle zwanzig Sekunden liest er von jedem verbundenen System die vollständige Liste der Maschinen, vergleicht sie mit der Runde davor und leitet nur weiter, was sich geändert hat. Alle fünf Minuten leitet er stattdessen das ganze Bild weiter, das Sicherheitsnetz für alles, was eine verlorene Nachricht sonst gekostet hätte. In derselben Runde fragt er Ihre Nodes, wie viel Kapazität sie haben.

Gemessen an einem Agenten; jede Zeile ist ein Fünf-Minuten-Fenster
SituationArbeitsspeicherProzessor
Verbunden, noch nichts angebunden8 MB0,02 % eines Kerns
Ein System, 10 Maschinen12 MB0,03 %
Ein System, 250 Maschinen14 MB0,06 %
Ein System, 1000 Maschinen15 MB0,14 %
Fünf Systeme, je 200 Maschinen18 MB0,19 %
Die Schritte zwischen den Zeilen sagen mehr als die Zeilen selbst. Das erste System anzubinden kostet etwa 4 MB, jedes weitere etwa 0,75 MB, und genau darin unterscheiden sich die letzten beiden Zeilen. Maschinen werden billiger, je mehr es sind: Von 10 auf 1000 kamen insgesamt 3 MB dazu, also rund 3 kB pro Stück, und der Schritt von 250 auf 1000 war noch günstiger. Gemessen im August 2026 gegen simulierte Systeme genau dieser Größen, damit die Zahlen etwas über den Agenten aussagen und nicht über irgendjemandes Cluster.

Der Datenverkehr ist die andere Zahl, die man haben will. Diese tausend Maschinen kosten alle zwanzig Sekunden etwa 250 kB in Richtung Ihrer eigenen Systeme, also rund ein Gigabyte pro Tag in Ihrem eigenen Netzwerk, während zehn Maschinen 2,5 kB pro Runde kosten. Von dieser Zahl für tausend Maschinen reisen etwa 17 kB pro Runde zu uns weiter, rund 70 MB pro Tag, weil nur weitergeleitet wird, was sich geändert hat.

Macht die Art des Systems einen Unterschied? Kaum. Ob der Agent mit einem Hypervisor, einem Hosting-Panel oder einem Game-Panel spricht: Die Arbeit ist dieselbe, ein Aufruf pro System und Runde, ein Vergleich, eine Nachricht. Zwei Unterschiede sind echt, aber klein: Ein Hypervisor wird zusätzlich nach den Adressen in seinen Gastsystemen gefragt, höchstens alle fünf Minuten pro laufender Maschine, und ein Panel, das nichts misst, schickt keine Verbrauchszahlen. Was sich enorm unterscheidet, ist die Maschine auf der anderen Seite, und die wird nach dem bemessen, was auf ihr läuft, nicht nach dem Agenten.

Die Größen unten sind deshalb keine gemessenen Mindestwerte; der Agent passt in weit weniger. Es ist das, was wir bestellen würden, denn ein Betriebssystem, seine Logs und Ihre eigenen Werkzeuge wollen mehr Platz als der Agent.

Was wir einem Agent-Host geben würden
Wofür er reichen mussvCPUArbeitsspeicherFestplatte
Bis zu einigen hundert Maschinen11 GB10 GB
Bis zu einigen tausend Maschinen22 GB10 GB
Auch Netzwerkinstallationen22 GB40 GB

Was die Extras verlangen

Alles oben ist das, was ein Agent braucht, um Ihre Systeme zu beobachten und zu steuern. Vier seiner Fähigkeiten verdienen darüber hinaus ein eigenes Wort, und jede davon fällt ehrlich zurück: Ist eine Voraussetzung nicht erfüllt, macht der Agent den Rest weiter und sagt Ihnen, welche Fähigkeit er nicht anbietet.

Maschinen über das Netzwerk installieren
Dafür muss der Agent im selben Netzwerksegment stehen wie die Maschine, die installiert wird, denn er beantwortet deren Boot-Anfrage direkt. Seine Unit trägt die zwei Capabilities, die er für die Boot-Ports braucht, bereits; sie sind eng gefasst und werden nur verwendet, solange eine Installation läuft. Was wirklich dazukommt, ist Festplattenplatz: Boot-Medien werden auf dem Host zwischengespeichert, standardmäßig bis zu 20 GB, das Älteste fliegt zuerst raus.
Automatisierungen ausführen
Automatisierungen sind Ihr eigenes TypeScript und laufen deshalb in einer Sandbox aus Kernel-Namespaces; die Laufzeitumgebung dafür gehört nicht zum Agenten: Eine festgelegte Version von Bun muss in dem Verzeichnis des Agenten liegen, das root gehört und in dem der Benutzer, unter dem der Agent läuft, sie nicht ersetzen kann. Ubuntu 24.04 und neuer schränken genau den Namespace ein, den das braucht; der Agent bringt ein AppArmor-Profil mit, das genau diese eine Erlaubnis für genau dieses eine Binary zurückgibt. Fehlt eines von beidem, sagt der Agent das beim Start, bietet die Fähigkeit nicht an und macht weiter. Jeder Lauf bekommt mindestens 4 GB Adressraum. Der ist virtuell und kein Arbeitsspeicher, der vorhanden sein müsste. Was eine laufende Automatisierung auf Ihrem Host wirklich kostet, haben wir nicht gemessen.
Den Host aus dem Panel neu starten
Ein Neustart ist eher eine Frage der Autorisierung als der Privilegien: Der Agent fragt logind, logind fragt polkit, und der Installer hinterlässt eine Regel, die genau zwei Aktionen für genau diesen Benutzer erlaubt. Hosts, die vor dieser Regel installiert wurden, brauchen einen erneuten Lauf des Installers, denn ein Update aus dem Panel ersetzt das Binary und nichts in /etc. Bis dahin lehnt das Panel ab und nennt den Grund.
Konsole und Diagnose
Nichts zu installieren. Ping und Traceroute verwenden einen ICMP-Socket, der keine Privilegien braucht, solange der Host ihn für die Gruppe des Systembenutzers erlaubt, was auf jedem Host, den wir gemessen haben, der Fall war. Wo nicht, misst der Agent stattdessen mit TCP und sagt Ihnen, welche Methode er verwendet hat. Die Konsole wird über die ohnehin schon offene Verbindung durchgereicht.

Installation mit dem Einzeiler

Auf dem Einstellungen-Tab des Agenten baut das Panel einen einzigen Befehl mit einem Installationslink darin. Führen Sie ihn als root auf dem Host aus. Der Link funktioniert einmal: Er hört auf zu funktionieren, sobald der Agent registriert ist, und spätestens nach 72 Stunden. Sie können jederzeit einen neuen erzeugen.

shell
curl -fsSL https://app.provibr.com/api/install/<token> | sh
Behandeln Sie den Link wie ein Geheimnis. Wer ihn hat, kann genau diesen einen Agenten registrieren, so wie es auch ein Authentifizierungsschlüssel erlauben würde. Im Panel wird er nie gespeichert, erzeugen Sie also einen neuen, statt den alten nachzuschlagen.
Befehle und Terminal-Ausgaben sind überall auf Englisch, im Panel und auf diesen Seiten. Ein Text, eine Wahrheit: Was Sie hier lesen, ist wörtlich das, was Ihr Host zurückschreibt.

Was der Befehl der Reihe nach tut:

  • Prüft, dass er als root auf einem 64-Bit-x86-Host läuft, und wählt curl oder wget, je nachdem, was vorhanden ist.
  • Lädt das Binary und seine Prüfsumme herunter und prüft sie. Hat der Host überhaupt kein Werkzeug, um eine Prüfsumme zu berechnen, bricht er ab, statt die Prüfung zu überspringen.
  • Legt den Systembenutzer und die beiden Verzeichnisse an, installiert das Binary und legt das Update-Skript samt seinem öffentlichen Schlüssel ab; beide gehören root, damit der Benutzer, unter dem der Agent läuft, sie nicht ersetzen kann.
  • Fragt den Aktivierungscode im Terminal ab, holt damit die Lizenzdatei, wobei der Code als Request-Header mitreist, und installiert sie.
  • Registriert sich als Systembenutzer, installiert dann die systemd-Unit und startet den Dienst.

Prüfen Sie das Ergebnis auf dem Host:

shell
systemctl status provibr-agent
journalctl -u provibr-agent -f
Den Befehl erneut auszuführen ist unbedenklich, mit einem neuen Link: Der alte funktioniert nicht mehr, seit der Agent registriert ist. Ist der Host bereits registriert, werden nur das Binary und die Unit erneuert; Identität, Zertifikat und Zugangsdaten-Tresor bleiben unangetastet. Auf einem Host ohne systemd wird trotzdem alles installiert und registriert, und der Befehl schreibt aus, wie Sie den Agenten selbst starten.

Installation von Hand

Alles, was der Einzeiler tut, sind auch nur eine Handvoll Befehle, und das Panel schreibt sie Ihnen mit den aktuellen Werten aus. So sieht es aus.

  1. Den Host vorbereiten: Systembenutzer, Verzeichnisse und Binary.

    shell
    # System user without a shell and without a home directory
    id -u provibr-agent >/dev/null 2>&1 || \
      sudo useradd --system --no-create-home --shell /usr/sbin/nologin provibr-agent
    
    # Directories for configuration (license, key) and state (identity, vault)
    sudo install -d -o provibr-agent -g provibr-agent -m 0750 /etc/provibr-agent
    sudo install -d -o provibr-agent -g provibr-agent -m 0700 /var/lib/provibr-agent
    
    # The binary from the download
    sudo install -o root -g root -m 0755 ./provibr-agent-linux-x86_64 /usr/local/bin/provibr-agent
    /usr/local/bin/provibr-agent version
  2. Die Lizenzdatei ablegen. Sie laden sie auf der Agentenseite herunter; sie ist mit dem Aktivierungscode verschlüsselt und lässt sich pro Token einmal herunterladen.

    shell
    sudo install -o root -g provibr-agent -m 0640 \
      ./provibr-<agent>.plic /etc/provibr-agent/license.plic
  3. Als Systembenutzer registrieren, mit dem Aktivierungscode.

    shell
    sudo -u provibr-agent /usr/local/bin/provibr-agent enroll \
      --license /etc/provibr-agent/license.plic --code XXXXX-XXXXX
  4. Die Unit installieren und den Dienst starten.

    shell
    sudo install -o root -g root -m 0644 provibr-agent.service /etc/systemd/system/provibr-agent.service
    sudo systemctl daemon-reload
    sudo systemctl enable --now provibr-agent
Zum Download des Binarys gehören auch seine Prüfsumme und seine Signatur. Die Signatur zu prüfen ist der Schritt, den ein einfacher Download nicht mitbringt, und es ist dieselbe Prüfung, die der Update-Schritt bei jedem neuen Release durchführt.

Docker und Kubernetes

Der Agent läuft auch als Container. Das Image enthält dieselbe signierte Release-Binärdatei wie der Linux-Download und sonst nichts: keine Shell, keinen Paketmanager, und er läuft als Benutzer ohne Root-Rechte. Er verbindet sich nur ausgehend, braucht also keine veröffentlichten Ports und keinen Service.

Die Registrierung geschieht beim ersten Start. Geben Sie dem Container den Installationslink aus dem Panel und den Aktivierungscode; er holt seine Lizenzdatei, registriert sich und speichert seine Identität auf dem Volume. Bei jedem weiteren Start wird diese Identität verwendet, und die beiden Werte werden nicht mehr gelesen.

Der Installationslink und der Code stehen in der Umgebung des Containers und damit in docker inspect, Ihrem Shell-Verlauf oder dem Kubernetes-Secret. Das ist dieselbe Offenlegung wie beim Einzeiler, und sie dauert, bis der Agent registriert ist: Ab dann funktioniert der Link nicht mehr. Entfernen Sie ihn danach trotzdem aus dem Secret; der Agent liest ihn nicht erneut.
Alles, was der Agent aufbewahrt, liegt auf dem Volume unter /var/lib/provibr-agent: sein Zertifikat, der verschlüsselte Tresor mit Ihren Zugangsdaten und der Schlüssel zu diesem Tresor. Ohne Volume ist jeder neue Container ein neuer, nicht registrierter Agent. Mit Volume ist dieses Volume das ganze Geheimnis: Behandeln Sie eine Kopie davon wie eine Kopie des Agenten.

Docker

Das Panel zeigt diesen Befehl mit dem Link und dem Code Ihres Agenten bereits ausgefüllt. Das Named Volume übernimmt den Eigentümer aus dem Image, sodass der Agent ohne chown hineinschreiben kann.

shell
docker run -d --name provibr-agent --restart unless-stopped \
  --hostname provibr-agent \
  --read-only --cap-drop ALL --security-opt no-new-privileges \
  -v provibr-agent-data:/var/lib/provibr-agent \
  -e PROVIBR_INSTALL_URL='https://app.provibr.com/api/install/<token>' \
  -e PROVIBR_ACTIVATION_CODE='XXXXX-XXXXX' \
  ghcr.io/provibr/provibr-agent:latest

Oder dasselbe als Docker-Compose-Datei:

docker-compose.yml
# Provibr agent — Docker Compose.
#
# The agent connects outbound to the platform; it needs no published ports.
# On the first start it enrolls itself with the installation link and the
# activation code below, and stores its identity on the volume. After that the
# two values are no longer read; the link expires 72 hours after it was made.
#
# Update: change the image tag, then `docker compose up -d`. The volume keeps
# identity and credentials.
services:
  provibr-agent:
    image: ghcr.io/provibr/provibr-agent:latest
    container_name: provibr-agent
    hostname: provibr-agent
    restart: unless-stopped
    read_only: true
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    environment:
      PROVIBR_INSTALL_URL: "https://app.provibr.com/api/install/<token>"
      PROVIBR_ACTIVATION_CODE: "XXXXX-XXXXX"
    volumes:
      - provibr-agent-data:/var/lib/provibr-agent

volumes:
  provibr-agent-data:
Lieber einen Bind-Mount als ein Named Volume? Legen Sie das Verzeichnis dann zuerst an und übergeben Sie es dem Benutzer des Agenten: mkdir -p /srv/provibr-agent && chown 65532:65532 /srv/provibr-agent. Ein Bind-Mount gehört anfangs root, und der Agent, der nicht als root läuft, kann dann nicht hineinschreiben.

Kubernetes

Einfache Manifeste, kein Helm: ein Namespace, ein Secret mit Link und Code, ein Volume Claim und ein Deployment. Das Panel füllt das Secret für Ihren Agenten aus.

provibr-agent.yaml
# Provibr agent — Kubernetes (plain manifests, no Helm).
#
# kubectl apply -f provibr-agent.yaml
#
# The agent connects outbound to the platform; there is no Service and no port.
# On the first start it enrolls itself with the installation link and the
# activation code from the Secret, and stores its identity on the volume. After
# that the Secret is no longer read; the link expires 72 hours after it was made.
#
# Exactly one replica, and Recreate: one agent is one identity (one
# certificate). Two pods would be two agents fighting over it.
apiVersion: v1
kind: Namespace
metadata:
  name: provibr-agent
---
apiVersion: v1
kind: Secret
metadata:
  name: provibr-agent-enrollment
  namespace: provibr-agent
type: Opaque
stringData:
  PROVIBR_INSTALL_URL: "https://app.provibr.com/api/install/<token>"
  PROVIBR_ACTIVATION_CODE: "XXXXX-XXXXX"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: provibr-agent-data
  namespace: provibr-agent
spec:
  # One pod, and only one, may mount this volume. On clusters older than
  # Kubernetes 1.29 (or storage without it), use ReadWriteOnce instead; the
  # agent also refuses to start a second time on the same data directory.
  accessModes:
    - ReadWriteOncePod
  resources:
    requests:
      storage: 1Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: provibr-agent
  namespace: provibr-agent
  labels:
    app.kubernetes.io/name: provibr-agent
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app.kubernetes.io/name: provibr-agent
  template:
    metadata:
      labels:
        app.kubernetes.io/name: provibr-agent
    spec:
      hostname: provibr-agent
      automountServiceAccountToken: false
      enableServiceLinks: false
      securityContext:
        runAsNonRoot: true
        runAsUser: 65532
        runAsGroup: 65532
        fsGroup: 65532
        # Only when the volume root does not match yet; otherwise the kubelet
        # widens the modes on the private keys at every mount.
        fsGroupChangePolicy: OnRootMismatch
        seccompProfile:
          type: RuntimeDefault
        # The ping check uses an unprivileged ICMP socket. Some container
        # runtimes keep those closed, and then the check reports a source
        # error. This safe sysctl opens them for the agent's group only.
        sysctls:
          - name: net.ipv4.ping_group_range
            value: "65532 65532"
      containers:
        - name: agent
          image: ghcr.io/provibr/provibr-agent:latest
          args: ["run"]
          envFrom:
            # optional: the agent reads it on its first start only, so you can
            # delete the Secret once it is enrolled.
            - secretRef:
                name: provibr-agent-enrollment
                optional: true
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop: ["ALL"]
          resources:
            requests:
              cpu: 50m
              memory: 32Mi
            limits:
              memory: 256Mi
          volumeMounts:
            - name: data
              mountPath: /var/lib/provibr-agent
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: provibr-agent-data
Belassen Sie replicas auf 1 und die Strategie auf Recreate. Ein Agent ist eine Identität: Zwei Pods auf demselben Volume teilen ein Zertifikat und verdrängen sich gegenseitig von der Plattform, und zwei Pods mit eigenem Volume registrieren sich beide, danach ist nur der letzte gültig. Ein Rolling Update würde genau das kurz tun.
Die Ping-Prüfung nutzt einen ICMP-Socket ohne Rechte, nicht die Capability NET_RAW. Manche Container-Runtimes halten diese Sockets geschlossen; gemessen mit geschlossenen Sockets fiel ein Diagnose-Ping auf TCP zurück, und die Monitoring-Prüfung meldete einen Quellfehler. Das Manifest öffnet sie für die Gruppe des Agenten mit dem sicheren sysctl net.ipv4.ping_group_range. NET_RAW hinzuzufügen hilft nicht: Der Agent läuft nicht als root und erhält daher keine wirksamen Capabilities.

Für Kubernetes ist die Lizenzdatei der bessere Weg: Legen Sie statt des Installationslinks die Lizenzdatei und den Code in das Secret, binden Sie die Datei im Pod ein und setzen Sie PROVIBR_LICENSE_FILE auf ihren Pfad. Das Token in der Datei funktioniert genau einmal, das Secret enthält also nichts, womit sich der Agent ein zweites Mal registrieren ließe.

Einen Container aktualisieren

Standardmäßig aktualisiert sich ein Container nicht selbst: Das Image ist das Release. Das Panel zeigt, welches Image aktuell ist; laden Sie es und erstellen Sie den Container neu, oder setzen Sie den neuen Tag auf das Deployment. Das Volume behält Identität und Zugangsdaten. Automatische Updates überspringen diese Agenten; die Option unten ändert das.

shell
docker pull ghcr.io/provibr/provibr-agent:latest
docker stop provibr-agent && docker rm provibr-agent
# then run the same docker run command again with the new image
shell
kubectl -n provibr-agent set image deployment/provibr-agent agent=ghcr.io/provibr/provibr-agent:latest

Option: Selbstaktualisierung vom Volume

Setzen Sie PROVIBR_SELF_UPDATE=volume oder aktivieren Sie die Option im Panel. Der Container nimmt dann an der Update-Schaltfläche und an den nächtlichen Updates teil: Eine neue Version wird heruntergeladen, ihre Signatur wird gegen den im Image eingebauten Plattformschlüssel geprüft, und sie wird auf dem Volume abgelegt. Der Container beendet sich mit Exitcode 0, Docker oder das Kubelet startet ihn neu, und die Binärdatei im Image startet die neue Version vom Volume, nachdem sie die Signatur noch einmal geprüft hat.

shell
docker run -d --name provibr-agent --restart unless-stopped \
  --hostname provibr-agent \
  --read-only --cap-drop ALL --security-opt no-new-privileges \
  -v provibr-agent-data:/var/lib/provibr-agent \
  -e PROVIBR_INSTALL_URL='https://app.provibr.com/api/install/<token>' \
  -e PROVIBR_ACTIVATION_CODE='XXXXX-XXXXX' \
  -e PROVIBR_SELF_UPDATE=volume \
  ghcr.io/provibr/provibr-agent:latest

Eine neue Version hat 60 Sekunden Zeit, die Plattform zu erreichen. Gelingt das nicht, wird sie auf dem Volume als fehlerhaft markiert und nie wieder gestartet, und der Container kommt mit der vorherigen Version zurück. Wenn Sie ein neueres Image ausrollen, gilt das Image: Was für das alte Image auf dem Volume lag, wird nicht mehr verwendet.

Was Sie dafür eintauschen: Der Image-Tag sagt nicht mehr, welche Version läuft (das Panel schon), Image-Scanner prüfen die Binärdatei im Image und nicht die auf dem Volume, und ein GitOps-Werkzeug sieht einen Pod, der etwas anderes ausführt, als sein Manifest sagt. Für Cluster, die ein GitOps-Werkzeug verwaltet, empfehlen wir es nicht.

Option: das Tools-Image für Automatisierungen

Das Standard-Image enthält keine Automatisierungs-Runtime. Das Tools-Image mit dem Tag-Suffix -tools enthält denselben signierten Agenten auf Debian, ergänzt um die festgelegte Automatisierungs-Runtime, sodass Automatisierungen im Container laufen können. Die Docker-Beispiele geben ihm ein kleines /tmp und ein pids-Limit (--pids-limit); auf Kubernetes ist /tmp ein emptyDir im Arbeitsspeicher, und ein pids-Limit setzen Sie am Kubelet (podPidsLimit), nicht im Manifest. Das Root-Dateisystem bleibt schreibgeschützt.

shell
docker run -d --name provibr-agent --restart unless-stopped \
  --hostname provibr-agent \
  --read-only --cap-drop ALL --security-opt no-new-privileges \
  --tmpfs /tmp:rw,noexec,nosuid,size=16m --pids-limit 256 \
  -v provibr-agent-data:/var/lib/provibr-agent \
  -e PROVIBR_INSTALL_URL='https://app.provibr.com/api/install/<token>' \
  -e PROVIBR_ACTIVATION_CODE='XXXXX-XXXXX' \
  ghcr.io/provibr/provibr-agent:latest-tools
Auf einem Linux-Host läuft eine Automatisierung in einer Sandbox mit eigenen Namespaces: kein Netzwerk, keine Dateien des Hosts, ein eigener Prozessbaum. Ein Container kann diese Namespaces nicht anlegen, deshalb begrenzt der Agent die Runtime im Tools-Image auf zwei andere Arten. Ein seccomp-Filter, der auf jedem Kernel funktioniert, sperrt jeden Netzwerk-Socket (TCP und UDP), Signale an andere Prozesse, das Starten neuer Prozesse und das Lesen des Speichers eines anderen Prozesses. Landlock (Linux 5.13 oder neuer) begrenzt die Dateien: Ein Skript kann nur die Runtime und die Systembibliotheken lesen und nichts schreiben. Der Agent prüft beides beim Start; erlauben der Kernel oder das seccomp-Profil der Container-Runtime es nicht, bleiben Automatisierungen im Container aus. Was bleibt, ist schwächer als auf einem Host: Ein Skript kann noch sehen, welche Prozesse im Container laufen. Wer das Tools-Image wählt, entscheidet sich dafür.

Was im Container nicht funktioniert

Manche Funktionen brauchen den Host selbst, und den hat ein abgeschotteter Container nicht:

  • Netzwerkinstallationen (PXE): Sie brauchen das Host-Netzwerk und Ports unter 1024.
  • Den Host aus dem Panel neu starten: Der Container hat keinen Zugriff auf das Init-System des Hosts.
  • Automatisierungen im Standard-Image: Es enthält keine Automatisierungs-Runtime, und die Sandbox, die sie auf einem Host bekommen, braucht User-Namespaces, die ein abgeschotteter Container nicht gewährt. Das Tools-Image führt sie stattdessen im Container selbst aus.
  • Host-Messwerte: CPU, Speicher und Laufzeit beschreiben die Maschine, auf der der Container läuft, nicht seine eigenen Limits.

Aktivierungscode und Lizenzdatei

Wenn Sie einen Agenten anlegen, zeigt das Panel den Aktivierungscode genau einmal. Er wird nirgends festgehalten, auch nicht als Hash. Mit diesem Code ist die Lizenzdatei verschlüsselt, sodass die Datei auf Ihrem Host mit etwas verschlüsselt ist, das nicht auf diesem Host liegt.

Code oder Datei verloren? Erzeugen Sie auf der Agentenseite ein neues Token. Das macht das vorherige ungültig, einschließlich einer bereits unterwegs befindlichen Lizenzdatei, und liefert Ihnen einen neuen Code und einen neuen Download.

Die Lizenzdatei selbst trägt kein Geheimnis über Ihre Infrastruktur. Sie sagt dem Agenten, zu welcher Plattform er gehört, welcher Zertifizierungsstelle er vertrauen soll und mit welchem einmalig gültigen Token er sich registriert.

Agenten im Panel verwalten

Die Agentenliste zeigt alles auf einmal: Status, Version, ob er gerade verbunden ist, wann er zuletzt gesehen wurde und wann sein Zertifikat abläuft.

  • Name und Beschreibung können Sie jederzeit ändern; sie sind nur Bezeichnungen. Ein Name, der schon in einer ausgelieferten Lizenzdatei steht, bleibt, wie er war, was kosmetisch ist und kein Grund, neu zu registrieren.
  • Ob er verbunden ist, wird aus einem Live-Signal mit kurzer Gültigkeit gelesen und nicht daraus, wann zuletzt eine Zeile geschrieben wurde. Lässt es sich nicht feststellen, sagt das Panel das, statt zu behaupten, Ihr Agent sei ausgefallen.
  • Version und Betriebssystem sind das, was der Agent bei seiner letzten Verbindung gemeldet hat. Ein Agent, der sich nie verbunden hat, zeigt einen Strich statt einer Vermutung.
  • Wählen Sie mehrere Agenten in der Liste aus, um sie in einem Zug zu aktualisieren. Die Schaltfläche zählt nur die Agenten, die sich gerade wirklich aktualisieren lassen, sodass Sie vor dem Klick sehen, dass zwölf ausgewählte drei aktualisierte bedeuten.
  • Der Fortschritt wird aus dem laufenden Befehl gelesen und nicht aus etwas, das sich Ihr Browser gemerkt hat. Ein Neuladen nimmt ihn also wieder auf.

Die drei Zustände

Registrierung ausstehend
Im Panel angelegt, noch nicht registriert. Ein Token und ein Aktivierungscode warten auf ihn, ein Zertifikat gibt es noch nicht.
Registriert
Er hat ein eigenes Zertifikat und darf sich verbinden. Das ist der einzige Zustand, in dem er Arbeit bekommen kann, und der einzige, in dem er sich nicht löschen lässt.
Widerrufen
Von Ihnen zurückgezogen. Seine Sitzung ist geschlossen, offene Token verfallen, und er darf nicht zurückkommen.

Einen Agenten widerrufen

Widerrufen ist der Schalter für den Fall, dass ein Host kompromittiert, außer Betrieb genommen oder schlicht nicht mehr Ihrer ist. Es wirkt, ohne dass Sie den Host anfassen.

  • Eine laufende Sitzung wird innerhalb einer Minute geschlossen. Dem Agenten wird der Grund genannt, statt ihn einfach zu trennen.
  • Der Agent löscht daraufhin seine eigene Identität, sein Zertifikat und seinen Zugangsdaten-Tresor. Die Zugangsdaten für Ihren Hypervisor sind damit von diesem Host verschwunden.
  • Offene Registrierungs-Token verfallen, sodass eine bereits heruntergeladene Lizenzdatei nicht mehr für eine Rückkehr taugt.
Das lässt sich nicht rückgängig machen. Ein versehentlich widerrufener Agent muss neu angelegt, neu installiert und erneut mit Zugangsdaten versorgt werden.

Einen Agenten löschen

Löschen entfernt den Agenten aus dem Panel. Das ist ein eigener Schritt neben dem Widerrufen, und er ist bewusst wählerisch damit, wann er erlaubt ist.

  • Ein registrierter Agent lässt sich nicht löschen. Widerrufen Sie ihn zuerst, sonst würden Sie den Eintrag zu etwas entfernen, das noch verbunden ist.
  • Ein Agent, an dem Integrationen oder Server hängen, lässt sich ebenfalls nicht löschen, und die Ablehnung nennt beide Anzahlen. Diese Einträge hängen am Agenten, ein Klick würde also Ihren Bestand mitnehmen.
  • Hat der Agent nie einen Befehl ausgeführt und nie einen Server gehabt, verschwindet der Eintrag wirklich. Sonst wird er überall ausgeblendet, seine Befehlshistorie bleibt aber erhalten, denn ein Audit-Trail, den man durch Löschen seines Gegenstands beseitigen kann, ist keiner.

Vom Host entfernen

Das Widerrufen räumt die Geheimnisse des Agenten ab, lässt die Dateien aber liegen. Um den Host zu säubern, bietet das Panel einen zweiten Einzeiler an, und dieselben vier Schritte von Hand.

Dieses Skript widerruft nichts. Widerrufen Sie zuerst im Panel und säubern Sie danach den Host, in dieser Reihenfolge. Umgekehrt bleibt ein Host zurück, der noch eine gültige Identität hält.
  1. Den Dienst stoppen, deaktivieren und die Unit entfernen.

    shell
    # Stop the service and forget the unit
    sudo systemctl disable --now provibr-agent
    sudo rm -f /etc/systemd/system/provibr-agent.service
    sudo systemctl daemon-reload
    sudo systemctl reset-failed provibr-agent 2>/dev/null || true
  2. Das Binary, das Update-Skript und den Update-Schlüssel entfernen.

    shell
    # Binary, update script and the trust anchor of the update step
    sudo rm -f /usr/local/bin/provibr-agent
    sudo rm -f /usr/local/lib/provibr-agent/apply-update.sh /usr/local/lib/provibr-agent/license-signing.pub
    
    # The polkit rule that allowed host.reboot (and its 0.105 fallback)
    sudo rm -f /etc/polkit-1/rules.d/49-provibr-agent-reboot.rules /etc/polkit-1/localauthority/50-local.d/49-provibr-agent-reboot.pkla
    
    # Only if nothing else lives in there
    sudo rmdir /usr/local/lib/provibr-agent 2>/dev/null || true
  3. Die Daten entfernen. Das ist der Schritt, auf den es ankommt: Hier liegen die Lizenz, der Tresorschlüssel und die verschlüsselten Zugangsdaten.

    shell
    # License and vault key
    sudo rm -rf /etc/provibr-agent
    
    # Identity, encrypted credential vault, outbox and staged updates
    sudo rm -rf /var/lib/provibr-agent
  4. Den Systembenutzer entfernen.

    shell
    sudo userdel provibr-agent
    sudo groupdel provibr-agent 2>/dev/null || true

Danach sollten beide Befehle überhaupt nichts ausgeben:

shell
ls -d /etc/provibr-agent /var/lib/provibr-agent /usr/local/lib/provibr-agent /usr/local/bin/provibr-agent /etc/systemd/system/provibr-agent.service /etc/polkit-1/rules.d/49-provibr-agent-reboot.rules /etc/polkit-1/localauthority/50-local.d/49-provibr-agent-reboot.pkla 2>/dev/null
id provibr-agent 2>/dev/null
# Both commands should print nothing at all