Săriți la conținut

Documentație

Agenți

Agentul este singura parte din Provibr care rulează pe propriul dumneavoastră hardware. El deține datele de autentificare pentru sistemele pe care le conectați, execută munca cerută de panou și raportează înapoi ce vede. Platforma nu sună niciodată înăuntru.

Ce este un agent

Un agent acoperă o rețea: locul din care sunt accesibile hipervizoarele și panourile dumneavoastră. Tot ce face Provibr infrastructurii dumneavoastră trece prin el.

  • Conexiunea merge spre exterior. Agentul o deschide către platformă și o menține deschisă; nimic nu trebuie să fie accesibil din internet și niciun port nu trebuie redirecționat către el.
  • Datele de autentificare rămân la dumneavoastră. Sunt trimise agentului o singură dată și sigilate într-un seif criptat de pe acea gazdă; platforma stochează doar numele câmpurilor pe care le-ați completat.
  • El raportează ce observă. Mașinile sunt interogate într-un ritm scurt, iar o comparație completă rulează la câteva minute, așa observă panoul o mașină oprită în afara Provibr.
  • Atinge doar ce i-ați predat. O resursă fără înregistrare în Provibr este ignorată, numărată și uitată din nou. Agentul nu adoptă niciodată o mașină din proprie inițiativă.

Gazda de care are nevoie

Nimic exotic și nimic de instalat mai întâi. Agentul este un singur binar static: își aduce propria bibliotecă C, așa că nu există niciun mediu de execuție, niciun interpretor și niciun pachet de distribuție care să trebuiască să se potrivească. O mașină virtuală mică este suficientă. Dimensiunile pe care le-am măsurat se află mai jos în această pagină.

Ce trebuie să ofere o gazdă de agent
CerințăCe vă trebuieDe ce
Procesorx86 pe 64 de biți (x86_64, numit și amd64)Publicăm un singur binar pentru Linux, iar aceasta este arhitectura pentru care este compilat. Scriptul de instalare verifică uname -m înainte să descarce ceva și se oprește la orice altă arhitectură, în loc să instaleze ceva ce nu poate rula. Deocamdată nu există un binar pentru ARM.
Sistem de operareOrice distribuție LinuxNimic nu se leagă de bibliotecile dumneavoastră de sistem, așa că distribuția, versiunea ei și managerul ei de pachete nu contează. Secțiunea următoare enumeră sistemele pe care acest binar a fost pornit cu adevărat.
Manager de serviciisystemd sau al dumneavoastrăScriptul de instalare scrie un unit systemd și îl activează. Pe o gazdă fără systemd, tot instalează și înrolează totul, iar apoi afișează comanda cu care porniți agentul sub orice folosiți în locul lui. O instalare pe jumătate ar fi mai rea decât una sinceră.
Drepturi la instalareroot, o singură datăInstalarea creează contul de serviciu provibr-agent, două directoare și unitul. După aceea, agentul rulează sub acel cont neprivilegiat, iar scriptul de actualizare, în care nu are voie să scrie, este cel care menține lucrurile așa.
Conexiuni spre exteriorTCP 50051 și 50052 către gw.provibr.netPortul 50051 este folosit o singură dată, la înrolare. Portul 50052 poartă sesiunea și rămâne deschis. Ambele sunt TLS. Dacă firewallul dumneavoastră filtrează traficul de ieșire, aceste două reguli sunt tot ce trebuie să permită.
Conexiuni dinspre exteriorNiciunaAgentul deschide el însuși conexiunea, așa că nimic nu trebuie să fie accesibil din internet și niciun port nu trebuie redirecționat către el. Instalarea mașinilor prin rețea este singura excepție, și chiar și atunci ascultă doar pe segmentul local.
Acces în propria rețeaCătre sistemele pe care le conectațiHipervizorul dumneavoastră, panoul de control sau panoul de jocuri este contactat prin propriul lui API, de pe această gazdă. Ceea ce agentul nu poate accesa, nici Provibr nu poate administra.
Memorie512 MB sunt de ajunsAm măsurat 18 MB cu o mie de mașini împărțite pe cinci sisteme, cazul cel mai greu din tabelul de mai jos. Vârful se află în altă parte: deblocarea fișierului de licență în timpul înrolării consumă pentru scurt timp aproximativ 70 MB, pentru că acel pas este intenționat costisitor de spart prin forță brută.
Disc1 GB este de ajunsBinarul are 17 MB, iar tot ce păstrează agentul pe lângă el a rămas sub 40 kB în măsurătorile noastre. Instalarea mașinilor prin rețea este excepția: pune în cache fișierele de pornire, până la 20 GB în mod implicit.
CeasAproximativ corectCertificatele și fișierele de licență poartă date de valabilitate, iar ambele capete le verifică, așa că o gazdă al cărei ceas este greșit cu zile întregi nu se poate înrola. Orice client NTP este suficient.
Agentul rulează sub propriul cont neprivilegiat, într-un unit systemd securizat. Primește exact două capabilități suplimentare, și doar ca să poată servi instalările prin rețea; înlăturați-le și totul, în afară de asta, continuă să funcționeze.

Ce Linux

Nu există niciun pachet de instalat și nicio distribuție cu care să se potrivească, așa că ce urmează nu este o listă de sisteme acceptate, ci lista sistemelor pe care acest binar a fost pornit cu adevărat. Orice altceva cu un kernel Linux x86 pe 64 de biți ar trebui să se comporte la fel, iar dacă nu o face, am vrea să aflăm.

Distribuțiile Linux pe care a fost rulat agentul
SistemVersiuneNote
Debian13 (Trixie)
Debian12 (Bookworm)Distribuția pe care a rulat testul complet: instalare, înrolare, conexiune și interogare.
Ubuntu24.04 LTSUbuntu 24.04 este versiunea de la care kernelul a început să restricționeze exact spațiile de nume de care au nevoie automatizările. Agentul livrează un profil AppArmor pentru asta; restul funcționează neatins.
Ubuntu22.04 LTS
AlmaLinux9
AlmaLinux8O bibliotecă C mult mai veche decât cea pe care a fost construit acest binar. Nu are nicio importanță, pentru că agentul o aduce pe a lui.
Fedora42
openSUSE Leap15
Amazon Linux2023
Alpine Linux3.21musl și deloc glibc, cel mai dur test care există pentru un binar static.
Două limite sincere ale acelei liste. Ea arată că binarul pornește și își face munca criptografică pe fiecare dintre aceste medii de utilizator; sesiunea completă, cu certificate și interogare, a fost măsurată pe unul singur dintre ele. Iar toate verificările au rulat pe mașini care împart un singur kernel, așa că ce dovedește lista este independența față de distribuție, nu față de versiunea kernelului.

Cât de mare trebuie să fie mașina

Agentul în sine este mic și rămâne mic. Ce crește este inventarul pe care îl urmărește: la fiecare douăzeci de secunde citește lista completă de mașini din fiecare sistem conectat, o compară cu runda anterioară și trimite mai departe doar ce s-a schimbat. La fiecare cinci minute trimite în schimb mai departe imaginea completă, care este plasa de siguranță pentru tot ce ar fi costat altfel un mesaj pierdut, iar aceasta este și runda în care întreabă nodurile dumneavoastră câtă capacitate au.

Măsurat pe un singur agent; fiecare rând este o fereastră de cinci minute
SituațieMemorieProcesor
Conectat, încă nimic atașat8 MB0,02% dintr-un nucleu
Un sistem, 10 mașini12 MB0,03%
Un sistem, 250 de mașini14 MB0,06%
Un sistem, 1.000 de mașini15 MB0,14%
Cinci sisteme, câte 200 de mașini18 MB0,19%
Pașii dintre rânduri spun mai mult decât rândurile în sine. Atașarea primului sistem costă aproximativ 4 MB, iar fiecare sistem de după el aproximativ 0,75 MB. Tocmai de aici vine diferența dintre ultimele două rânduri. Mașinile devin mai ieftine cu cât sunt mai multe: trecerea de la 10 la 1.000 a adăugat 3 MB în total, cam 3 kB fiecare, iar pasul de la 250 la 1.000 a fost și mai ieftin. Măsurat în august 2026 pe sisteme simulate exact de acele dimensiuni, astfel încât cifrele să spună ceva despre agent, nu despre clusterul cuiva.

Traficul este cealaltă cifră care merită știută. Cele o mie de mașini costă aproximativ 250 kB la fiecare douăzeci de secunde către propriile dumneavoastră sisteme, adică aproximativ un gigabait pe zi în propria dumneavoastră rețea, în timp ce zece mașini costă 2,5 kB pe rundă. Din cifra pentru o mie de mașini, aproximativ 17 kB pe rundă ajung mai departe la noi (vreo 70 MB pe zi), pentru că se trimite mai departe doar ce s-a schimbat.

Contează tipul de sistem? Aproape deloc. Fie că agentul vorbește cu un hipervizor, cu un panou de control de găzduire sau cu un panou de jocuri, munca este aceeași: un apel pe sistem pe rundă, o comparație, un mesaj. Două diferențe sunt reale, dar mici: unui hipervizor i se cer și adresele din interiorul sistemelor sale oaspete, cel mult o dată la cinci minute pentru fiecare mașină pornită, iar un panou care nu măsoară nimic nu trimite cifre de utilizare. Ce diferă enorm este mașina de cealaltă parte, iar aceea se dimensionează după ce rulează pe ea, nu după agent.

Dimensiunile de mai jos nu sunt, așadar, minime măsurate; agentul încape în mult mai puțin de atât. Sunt ceea ce am comanda noi, pentru că un sistem de operare, jurnalele lui și propriile dumneavoastră instrumente vor mai mult loc decât agentul.

Ce i-am da noi unei gazde de agent
Ce trebuie să susținăvCPUMemorieDisc
Până la câteva sute de mașini11 GB10 GB
Până la câteva mii de mașini22 GB10 GB
Și instalarea mașinilor prin rețea22 GB40 GB

Ce cer funcțiile suplimentare

Tot ce este mai sus este ceea ce îi trebuie unui agent ca să vă urmărească și să vă controleze sistemele. Patru dintre capacitățile lui merită un cuvânt în plus, iar fiecare dintre ele cedează sincer: lăsați o cerință neîndeplinită, iar agentul face în continuare restul și vă spune ce capacitate nu oferă.

Instalarea mașinilor prin rețea
Aceasta cere ca agentul să se afle pe același segment de rețea cu mașina care se instalează, pentru că răspunde direct cererii de boot a acelei mașini. Unitul lui poartă deja cele două capabilități de care are nevoie pentru porturile de boot; sunt acordate strict și folosite doar cât timp rulează o instalare. Ce adaugă totuși este disc: fișierele de pornire sunt păstrate în cache pe gazdă, până la 20 GB în mod implicit, cele mai vechi fiind aruncate primele.
Rularea automatizărilor
Automatizările sunt propriul dumneavoastră TypeScript, așa că rulează într-un sandbox construit din spații de nume ale kernelului, iar mediul de execuție pentru asta nu face parte din agent: o versiune fixată de Bun trebuie să se afle în directorul deținut de root al agentului, unde contul sub care rulează agentul nu o poate înlocui. Ubuntu 24.04 și versiunile ulterioare restricționează exact spațiul de nume de care este nevoie aici; agentul livrează un profil AppArmor care redă acea unică permisiune pentru acel unic binar. Dacă lipsește oricare dintre cele două piese, agentul o spune la pornire, nu oferă această capacitate și merge mai departe. Fiecare execuție primește cel puțin 4 GB de spațiu de adrese (acesta este virtual, nu memorie care trebuie să existe), iar cât costă cu adevărat o automatizare în execuție pe gazda dumneavoastră este ceva ce nu am măsurat.
Repornirea gazdei din panou
Repornirea este mai degrabă o chestiune de autorizare decât una de privilegii: agentul îl întreabă pe logind, logind îl întreabă pe polkit, iar scriptul de instalare lasă în urmă o regulă care permite exact două acțiuni pentru exact acest cont. Gazdele instalate înainte ca acea regulă să existe au nevoie de o nouă rulare a scriptului de instalare, pentru că actualizarea agentului din panou înlocuiește binarul și nimic din /etc. Până atunci, panoul refuză și spune de ce.
Consolă și diagnosticare
Nimic de instalat. Ping și traceroute folosesc un socket ICMP care nu are nevoie de privilegii atât timp cât gazda îl permite pentru grupul contului de serviciu, ceea ce s-a întâmplat pe fiecare gazdă pe care am măsurat-o; acolo unde nu îl permite, agentul măsoară în schimb cu TCP și vă spune ce metodă a folosit. Consola este transmisă prin conexiunea care este deja deschisă.

Instalarea cu comanda dintr-o singură linie

În fila de setări a agentului, panoul construiește o singură comandă care conține un link de instalare. Rulați-o ca root pe gazdă. Linkul funcționează o singură dată: nu mai funcționează de îndată ce agentul este înrolat, și cel târziu după 72 de ore. Puteți crea oricând unul nou.

shell
curl -fsSL https://app.provibr.com/api/install/<token> | sh
Tratați linkul ca pe date de autentificare. Oricine îl are poate înrola acest singur agent, la fel cum ar putea-o face cu o cheie de autentificare. Nu este stocat niciodată în panou, așa că generați unul nou în loc să îl căutați pe cel vechi.
Comenzile și ieșirea din terminal sunt în engleză peste tot, în panou și în aceste pagini. Un singur text, un singur adevăr: ce citiți aici este literalmente ce va afișa gazda dumneavoastră.

Ce face comanda, în ordine:

  • Verifică dacă rulează ca root pe o gazdă x86 pe 64 de biți și alege curl sau wget, care dintre ele există.
  • Descarcă binarul și suma lui de control și le verifică. Dacă gazda nu are niciun instrument pentru calcularea unei sume de control, se oprește în loc să sară peste verificare.
  • Creează contul de serviciu și cele două directoare, instalează binarul și pune la locul lor scriptul de actualizare și cheia lui publică, ambele deținute de root, astfel încât contul sub care rulează agentul să nu le poată înlocui.
  • Cere codul de activare în terminal, preia fișierul de licență cu acel cod ca antet de cerere și îl instalează.
  • Se înrolează sub contul de serviciu, apoi instalează unitul systemd și pornește serviciul.

Verificați rezultatul pe gazdă:

shell
systemctl status provibr-agent
journalctl -u provibr-agent -f
Rularea din nou a comenzii este sigură, cu un link nou: cel vechi nu mai funcționează de când agentul s-a înrolat. Dacă gazda este deja înrolată, se reîmprospătează doar binarul și unitul; identitatea, certificatul și seiful cu date de autentificare rămân neatinse. Pe o gazdă fără systemd, totul este oricum instalat și înrolat, iar comanda afișează cum să rulați singur agentul.

Instalarea manuală

Tot ce face comanda dintr-o singură linie înseamnă și câteva comenzi, iar panoul le afișează pentru dumneavoastră cu valorile curente completate. Aceasta este forma lor.

  1. Pregătiți gazda: contul de serviciu, directoarele și binarul.

    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. Puneți fișierul de licență la locul lui. Îl descărcați din pagina agentului; este criptat cu codul de activare și poate fi descărcat o singură dată pentru fiecare token.

    shell
    sudo install -o root -g provibr-agent -m 0640 \
      ./provibr-<agent>.plic /etc/provibr-agent/license.plic
  3. Înrolați-vă sub contul de serviciu, cu codul de activare.

    shell
    sudo -u provibr-agent /usr/local/bin/provibr-agent enroll \
      --license /etc/provibr-agent/license.plic --code XXXXX-XXXXX
  4. Instalați unitul și porniți serviciul.

    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
Descărcarea binarului oferă și suma lui de control și semnătura lui. Verificarea semnăturii este pasul pe care o descărcare simplă nu vi-l dă, aceeași verificare pe care pasul de actualizare o face la fiecare versiune nouă.

Docker și Kubernetes

Agentul rulează și ca container. Imaginea conține același binar semnat ca descărcarea pentru Linux și nimic altceva: fără shell, fără manager de pachete, iar agentul rulează ca utilizator fără drepturi de root. Se conectează doar spre exterior, deci nu are nevoie de porturi publicate și nici de un service.

Înrolarea are loc la prima pornire. Dați containerului linkul de instalare din panou și codul de activare; își descarcă fișierul de licență, se înrolează și își păstrează identitatea pe volum. La fiecare pornire ulterioară se folosește acea identitate, iar cele două valori nu mai sunt citite.

Linkul de instalare și codul se află în mediul containerului, deci în docker inspect, în istoricul shellului sau în secretul Kubernetes. Este aceeași expunere ca la comanda pe o singură linie și durează până la înrolarea agentului: de atunci linkul nu mai funcționează. Scoateți-l totuși din secret după aceea; agentul nu îl mai citește.
Tot ce păstrează agentul se află pe volum, în /var/lib/provibr-agent: certificatul său, seiful criptat cu datele dumneavoastră de autentificare și cheia acelui seif. Fără volum, fiecare container nou este un agent nou, neînrolat. Cu volum, acel volum este întregul secret: tratați o copie a lui ca pe o copie a agentului.

Docker

Panoul afișează această comandă cu linkul și codul agentului dumneavoastră deja completate. Volumul cu nume preia proprietarul din imagine, deci agentul poate scrie în el fără chown.

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

Sau același lucru ca fișier Docker Compose:

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:
Preferați un bind mount în locul unui volum cu nume? Creați mai întâi directorul și dați-l utilizatorului agentului: mkdir -p /srv/provibr-agent && chown 65532:65532 /srv/provibr-agent. Un bind mount aparține la început lui root, iar agentul, care nu rulează ca root, nu ar putea scrie în el.

Kubernetes

Manifeste simple, fără Helm: un namespace, un secret cu linkul și codul, un volume claim și un deployment. Panoul completează secretul pentru agentul dumneavoastră.

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
Păstrați replicas la 1 și strategia pe Recreate. Un agent este o identitate: două poduri pe același volum împart un certificat și se scot reciproc de pe platformă, iar două poduri cu volum propriu se înrolează amândouă, după care doar ultimul este valid. O actualizare progresivă ar face exact asta pentru o clipă.
Verificarea ping folosește un socket ICMP fără privilegii, nu capability-ul NET_RAW. Unele medii de rulare pentru containere țin aceste socketuri închise; măsurat cu ele închise, un ping de diagnostic a trecut pe TCP, iar verificarea de monitorizare a raportat o eroare de sursă. Manifestul le deschide pentru grupul agentului cu sysctl-ul sigur net.ipv4.ping_group_range. Adăugarea NET_RAW nu ajută: agentul nu rulează ca root, deci nu primește capabilities efective.

Pentru Kubernetes, fișierul de licență este calea mai bună: puneți în secret fișierul de licență și codul în locul linkului de instalare, montați fișierul în pod și setați PROVIBR_LICENSE_FILE la calea lui. Tokenul din fișier funcționează exact o dată, deci secretul nu conține nimic cu care agentul să poată fi înrolat a doua oară.

Actualizarea unui container

Implicit, un container nu se actualizează singur: imaginea este versiunea publicată. Panoul arată care imagine este curentă; descărcați-o și recreați containerul sau setați tagul nou pe deployment. Volumul păstrează identitatea și datele de autentificare. Actualizările automate omit acești agenți; opțiunea de mai jos schimbă asta.

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

Opțiune: actualizare automată de pe volum

Setați PROVIBR_SELF_UPDATE=volume sau bifați opțiunea în panou. Containerul participă atunci la butonul de actualizare și la actualizările de noapte: o versiune nouă este descărcată, semnătura ei este verificată cu cheia platformei inclusă în imagine și este păstrată pe volum. Containerul se oprește cu codul de ieșire 0, Docker sau kubelet îl pornește din nou, iar binarul din imagine pornește versiunea nouă de pe volum după ce îi verifică încă o dată semnătura.

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

O versiune nouă are 60 de secunde ca să ajungă la platformă. Dacă nu reușește, este marcată ca defectă pe volum și nu mai este pornită niciodată, iar containerul revine cu versiunea anterioară. Când implementați o imagine mai nouă, imaginea are prioritate: ce era păstrat pe volum pentru imaginea veche nu mai este folosit.

Ce cedați: tagul imaginii nu mai spune ce versiune rulează (panoul o spune), scanerele de imagini verifică binarul din imagine și nu pe cel de pe volum, iar un instrument GitOps vede un pod care rulează altceva decât spune manifestul său. Nu îl recomandăm pentru clusterele administrate de un instrument GitOps.

Opțiune: imaginea tools pentru automatizări

Imaginea standard nu conține runtime-ul pentru automatizări. Imaginea tools, cu sufixul de tag -tools, conține același agent semnat pe Debian, cu runtime-ul fixat pentru automatizări adăugat, ca automatizările să poată rula în container. Exemplele Docker îi dau un /tmp mic și o limită de pids (--pids-limit); pe Kubernetes /tmp este un emptyDir în memorie, iar o limită de pids se setează pe kubelet (podPidsLimit), nu în manifest. Sistemul de fișiere rădăcină rămâne doar pentru citire.

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
Pe o gazdă Linux, o automatizare rulează într-un sandbox cu propriile namespace-uri: fără rețea, fără fișierele gazdei, cu propriul arbore de procese. Un container nu poate crea acele namespace-uri, așa că în imaginea tools agentul limitează runtime-ul în alte două feluri. Un filtru seccomp, care funcționează pe orice kernel, blochează orice socket de rețea (TCP și UDP), semnalele către alte procese, pornirea de procese noi și citirea memoriei altui proces. Landlock (Linux 5.13 sau mai nou) limitează fișierele: un script poate citi doar runtime-ul și bibliotecile de sistem și nu poate scrie nimic. Agentul le testează pe amândouă la pornire; dacă nucleul sau profilul seccomp al runtime-ului de containere nu le permite, automatizările rămân oprite în container. Ce rămâne este mai slab decât pe o gazdă: un script poate vedea în continuare ce procese rulează în container. Alegerea imaginii tools înseamnă alegerea acestui compromis.

Ce nu funcționează într-un container

Unele funcții au nevoie de gazda însăși, iar un container restricționat nu o are:

  • Instalările prin rețea (PXE): au nevoie de rețeaua gazdei și de porturi sub 1024.
  • Repornirea gazdei din panou: containerul nu are acces la sistemul de inițializare al gazdei.
  • Automatizările în imaginea standard: nu conține runtime-ul pentru automatizări, iar sandboxul pe care îl primesc pe o gazdă are nevoie de user namespaces, pe care un container restricționat nu le acordă. Imaginea tools le rulează în schimb chiar în container.
  • Metricile gazdei: procesorul, memoria și timpul de funcționare descriu mașina pe care rulează containerul, nu limitele proprii ale containerului.

Codul de activare și fișierul de licență

Când creați un agent, panoul afișează un cod de activare o singură dată. El nu este scris nicăieri, nici măcar ca hash. Codul este cel care criptează fișierul de licență, așa că fișierul de pe gazda dumneavoastră este criptat cu ceva ce nu se află pe acea gazdă.

Ați pierdut codul sau fișierul? Generați un token nou în pagina agentului. Asta îl invalidează pe cel anterior, inclusiv un fișier de licență aflat deja pe drum, și vă dă un cod nou și o descărcare nouă.

Fișierul de licență în sine nu conține niciun secret despre infrastructura dumneavoastră. El îi spune agentului cărei platforme îi aparține, în ce autoritate de certificare să aibă încredere și care este tokenul de unică folosință cu care se înrolează.

Administrarea agenților în panou

Lista de agenți arată totul dintr-o privire: starea, versiunea, dacă este conectat chiar acum, când a fost văzut ultima dată și când îi expiră certificatul.

  • Numele și descrierea vă aparțin și sunt doar etichete. Un nume aflat deja într-un fișier de licență livrat rămâne cum a fost, ceea ce este cosmetic și nu un motiv de reînrolare.
  • Faptul că este sau nu conectat se citește dintr-un semnal live cu expirare scurtă, nu din momentul în care a fost scris ultimul rând. Dacă nu putem ști, panoul o spune în loc să pretindă că agentul dumneavoastră este căzut.
  • Versiunea și sistemul de operare sunt cele raportate de agent la ultima lui conectare. Un agent care nu s-a conectat niciodată afișează o liniuță în loc de o presupunere.
  • Selectați mai mulți agenți în listă pentru a-i actualiza dintr-o singură mișcare. Butonul numără doar agenții care pot fi actualizați chiar acum, așa că vedeți înainte de a apăsa că din doisprezece selectați se actualizează trei.
  • Progresul se citește din comanda care rulează, nu din ceva memorat de browserul dumneavoastră, așa că o reîncărcare îl reia de unde a rămas.

Cele trei stări

În așteptare
Creat în panou, încă neînrolat. Are un token și un cod de activare care îl așteaptă și încă niciun certificat.
Înrolat
Are propriul certificat și se poate conecta. Este singura stare în care i se poate da de lucru și singura stare în care nu poate fi șters.
Revocat
Retras de dumneavoastră. Sesiunea lui este închisă, tokenurile în curs sunt anulate și nu mai poate reveni.

Revocarea unui agent

Revocarea este comutatorul la care apelați când o gazdă este compromisă, scoasă din uz sau pur și simplu nu mai este a dumneavoastră. Ea are efect fără să atingeți gazda.

  • O sesiune activă este închisă în decurs de un minut. Agentului i se spune de ce, nu este pur și simplu deconectat.
  • Agentul își șterge apoi propria identitate, certificatul și seiful cu date de autentificare. Datele de autentificare pentru hipervizorul dumneavoastră dispar de pe acea gazdă.
  • Tokenurile de înrolare în curs sunt anulate, așa că un fișier de licență deja descărcat nu poate fi folosit pentru a reveni.
Nu există anulare. Un agent revocat din greșeală trebuie creat din nou, instalat din nou și înzestrat din nou cu datele lui de autentificare.

Ștergerea unui agent

Ștergerea înlătură agentul din panou. Este un pas separat de revocare și este intenționat pretențioasă în privința momentului în care este permisă.

  • Un agent înrolat nu poate fi șters. Revocați-l mai întâi, altfel ați înlătura înregistrarea a ceva ce este încă conectat.
  • Nici un agent cu integrări sau servere atașate nu poate fi șters, iar refuzul numește ambele numere. Acele rânduri atârnă de agent, așa că un singur clic v-ar lua cu el și inventarul.
  • Dacă agentul nu a rulat niciodată o comandă și nu a avut niciodată un server, înregistrarea chiar dispare. Altfel este ascunsă peste tot, dar istoricul lui de comenzi se păstrează, pentru că o pistă de audit pe care o puteți șterge ștergându-i subiectul nu este o pistă de audit.

Înlăturarea lui de pe gazdă

Revocarea șterge secretele agentului, dar lasă fișierele. Pentru a curăța gazda, panoul oferă o a doua comandă dintr-o singură linie și aceiași patru pași făcuți manual.

Acest script nu revocă nimic. Revocați mai întâi în panou și abia apoi curățați gazda, în această ordine. Invers rămâne o gazdă care încă deține o identitate valabilă.
  1. Opriți serviciul, dezactivați-l și înlăturați unitul.

    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. Înlăturați binarul, scriptul de actualizare și cheia de actualizare.

    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. Înlăturați datele. Acesta este pasul care contează: licența, cheia seifului și datele de autentificare criptate se află aici.

    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. Înlăturați contul de serviciu.

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

După aceea, ambele de mai jos nu ar trebui să afișeze absolut nimic:

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