Aller au contenu

Documentation

Agents

L’agent est la seule partie de Provibr qui tourne sur votre propre matériel. Il détient les identifiants des systèmes que vous connectez, exécute le travail demandé par le panneau et rapporte ce qu’il observe. La plateforme ne se connecte jamais chez vous.

Ce qu’est un agent

Un agent couvre un réseau : l’endroit depuis lequel vos hyperviseurs et vos panneaux sont joignables. Tout ce que Provibr fait à votre infrastructure passe par lui.

  • La connexion est sortante. C’est l’agent qui l’ouvre vers la plateforme et la maintient ouverte ; rien ne doit être joignable depuis Internet, et aucun port n’a besoin de lui être redirigé.
  • Les identifiants restent chez vous. Ils sont envoyés une seule fois à l’agent et scellés dans un coffre chiffré sur cet hôte ; la plateforme ne conserve que le nom des champs que vous avez renseignés.
  • Il rapporte ce qu’il observe. Les machines sont interrogées à un rythme rapproché et une comparaison complète a lieu toutes les quelques minutes : c’est ainsi que le panneau remarque une machine arrêtée en dehors de Provibr.
  • Il ne touche que ce que vous lui avez confié. Une ressource sans enregistrement dans Provibr est ignorée, comptée puis oubliée. L’agent ne reprend jamais une machine de lui-même.

L’hôte qu’il lui faut

Rien d’exotique, et rien à installer au préalable. L’agent est un unique binaire lié statiquement : il embarque sa propre bibliothèque C, si bien qu’il n’y a aucun environnement d’exécution, aucun interpréteur et aucun paquet de distribution à faire correspondre. Une petite machine virtuelle suffit. Les tailles que nous avons mesurées figurent plus bas sur cette page.

Ce qu’un hôte d’agent doit fournir
ExigenceCe qu’il vous fautPourquoi
Processeurx86 64 bits (x86_64, aussi appelé amd64)Nous publions une seule version Linux, et c’est pour cette architecture qu’elle est compilée. Le script d’installation commence par lire uname -m et s’arrête sur toute autre valeur, plutôt que d’installer quelque chose qui ne pourra pas tourner. Il n’existe pas encore de version ARM.
Système d’exploitationN’importe quelle distribution LinuxRien ne se lie à vos bibliothèques système : la distribution, sa version et son gestionnaire de paquets n’ont donc aucune importance. La section suivante énumère celles sur lesquelles cette version a réellement été démarrée.
Gestionnaire de servicessystemd, ou le vôtreLe script d’installation écrit une unité systemd et l’active. Sur un hôte sans systemd, tout est malgré tout installé et enregistré, et le script affiche ensuite la commande pour démarrer l’agent sous ce que vous utilisez à la place. Une demi-installation serait pire qu’une installation honnête.
Droits pendant l’installationroot, une seule foisL’installation crée le compte de service provibr-agent, deux répertoires et l’unité. Ensuite, l’agent tourne sous ce compte non privilégié, et c’est le script de mise à jour, qu’il n’a pas le droit de modifier, qui le maintient ainsi.
Connexions sortantesTCP 50051 et 50052 vers gw.provibr.netLe port 50051 ne sert qu’une fois, lors de l’enregistrement. Le port 50052 porte la session et reste ouvert. Les deux sont en TLS. Si votre pare-feu filtre le trafic sortant, il n’a que ces deux règles à autoriser.
Connexions entrantesAucuneC’est l’agent qui ouvre la connexion : rien ne doit être joignable depuis Internet et aucun port n’a besoin de lui être redirigé. L’installation de machines par le réseau est la seule exception, et même dans ce cas il n’écoute que sur le segment local.
Portée dans votre propre réseauVers les systèmes que vous connectezVotre hyperviseur, votre panneau de contrôle ou votre panneau de jeu est joint via sa propre API, depuis cet hôte. Ce que l’agent ne peut pas atteindre, Provibr ne peut pas le gérer.
Mémoire512 MB suffisent largementNous avons mesuré 18 MB avec un millier de machines réparties sur cinq systèmes, soit le cas le plus lourd du tableau ci-dessous. Le pic est ailleurs : déverrouiller le fichier de licence pendant l’enregistrement demande brièvement environ 70 MB, parce que cette étape est volontairement coûteuse à attaquer par force brute.
Disque1 GB suffit largementLe binaire fait 17 MB, et tout ce que l’agent conserve à côté est resté sous les 35 kB dans nos mesures. L’installation de machines par le réseau fait exception : elle met en cache des supports de démarrage, jusqu’à 20 GB par défaut.
HorlogeÀ peu près justeLes certificats et les fichiers de licence portent des dates de validité que les deux extrémités vérifient : un hôte dont l’horloge dérive de plusieurs jours ne peut donc pas s’enregistrer. N’importe quel client NTP fera l’affaire.
L’agent tourne sous son propre compte non privilégié, dans une unité systemd durcie. Il reçoit exactement deux capacités supplémentaires, uniquement pour pouvoir servir les installations par le réseau ; retirez-les et tout continue de fonctionner, sauf cela.

Quel Linux

Il n’y a aucun paquet à installer et aucune distribution à faire correspondre : ce qui suit n’est donc pas une liste de systèmes pris en charge. C’est la liste des systèmes sur lesquels cette version a réellement été démarrée. Tout autre système doté d’un noyau Linux x86 64 bits devrait se comporter de la même façon, et si ce n’est pas le cas, nous aimerions le savoir.

Distributions Linux sur lesquelles l’agent a été exécuté
SystèmeVersionRemarques
Debian13 (Trixie)
Debian12 (Bookworm)La distribution sur laquelle le test complet a été mené : installé, enregistré, connecté et en cours d’interrogation.
Ubuntu24.04 LTSC’est à partir d’Ubuntu 24.04 que le noyau a commencé à restreindre précisément les espaces de noms dont les automatisations ont besoin. L’agent fournit un profil AppArmor à cet effet ; tout le reste fonctionne sans rien y toucher.
Ubuntu22.04 LTS
AlmaLinux9
AlmaLinux8Une bibliothèque C bien plus ancienne que celle sur laquelle cette version a été compilée. Cela ne change rien, puisque l’agent apporte la sienne.
Fedora42
openSUSE Leap15
Amazon Linux2023
Alpine Linux3.21musl et pas la moindre glibc, l’épreuve la plus tranchante qui soit pour un binaire lié statiquement.
Deux limites honnêtes à cette liste. Elle montre que le binaire démarre et effectue son travail cryptographique sur chacun de ces espaces utilisateur ; la session complète, avec les certificats et l’interrogation, n’a été mesurée que sur l’un d’eux. Et toutes les vérifications ont eu lieu sur des machines partageant un même noyau : ce que cela prouve, c’est l’indépendance vis-à-vis de la distribution, pas vis-à-vis de la version du noyau.

Quelle taille de machine

L’agent lui-même est petit et le reste. Ce qui grandit, c’est le parc qu’il surveille : toutes les vingt secondes, il lit la liste complète des machines de chaque système connecté, la compare au passage précédent et ne transmet que ce qui a changé. Toutes les cinq minutes, il transmet à la place l’état complet, qui sert de filet de sécurité pour tout ce qu’un message perdu aurait sinon coûté, et c’est aussi lors de ce passage qu’il demande à vos nœuds de quelle capacité ils disposent.

Mesuré sur un seul agent ; chaque ligne couvre une fenêtre de cinq minutes
SituationMémoireProcesseur
Connecté, rien encore rattaché8 MB0,02 % d’un cœur
Un système, 10 machines12 MB0,03 %
Un système, 250 machines14 MB0,06 %
Un système, 1 000 machines15 MB0,14 %
Cinq systèmes, 200 machines chacun18 MB0,19 %
Les écarts entre les lignes en disent plus que les lignes elles-mêmes. Rattacher le premier système coûte environ 4 MB, et chaque système suivant environ 0,75 MB, soit exactement l’écart entre les deux dernières lignes. Les machines coûtent d’autant moins cher qu’elles sont nombreuses : passer de 10 à 1 000 a ajouté 3 MB au total, soit quelque 3 kB chacune, et le saut de 250 à 1 000 est revenu moins cher encore. Mesuré en août 2026 sur des systèmes simulés d’exactement ces tailles, afin que les chiffres disent quelque chose de l’agent plutôt que du cluster de quelqu’un.

Le trafic est l’autre chiffre à connaître. Ce millier de machines représente environ 250 kB toutes les vingt secondes vers vos propres systèmes, soit environ 1 GB par jour sur votre propre réseau, tandis que dix machines représentent 2,5 kB par passage. Sur ces 250 kB, environ 17 kB par passage poursuivent leur route jusqu’à nous, quelque 70 MB par jour, parce que seul ce qui a changé est transmis.

Le type de système compte-t-il ? À peine. Que l’agent parle à un hyperviseur, à un panneau de contrôle d’hébergement ou à un panneau de jeu, le travail est le même : un appel par système et par passage, une comparaison, un message. Deux différences sont réelles mais minimes. On demande aussi à un hyperviseur les adresses présentes dans ses invités, au plus une fois toutes les cinq minutes par machine en fonctionnement, et un panneau qui ne mesure rien n’envoie aucun chiffre d’utilisation. Ce qui diffère énormément, c’est la machine en face, et celle-là se dimensionne d’après ce qu’elle fait tourner, pas d’après l’agent.

Les tailles ci-dessous ne sont donc pas des minimums que nous aurions mesurés ; l’agent tient dans bien moins que cela. Ce sont celles que nous commanderions, parce qu’un système d’exploitation, ses journaux et vos propres outils réclament plus de place que l’agent.

Ce que nous donnerions à un hôte d’agent
Ce qu’il doit gérervCPUMémoireDisque
Jusqu’à quelques centaines de machines11 GB10 GB
Jusqu’à quelques milliers de machines22 GB10 GB
Avec en plus les installations par le réseau22 GB40 GB

Ce que demandent les fonctions supplémentaires

Tout ce qui précède est ce qu’il faut à un agent pour surveiller et piloter vos systèmes. Quatre de ses fonctions méritent un mot de plus, et chacune se dégrade honnêtement : si une exigence n’est pas remplie, l’agent continue de faire tout le reste et vous indique quelle fonction il ne propose pas.

Installer des machines par le réseau
Celle-ci exige que l’agent se trouve sur le même segment de réseau que la machine en cours d’installation, car c’est lui qui répond directement à sa requête d’amorçage. Son unité porte déjà les deux capacités dont elle a besoin pour les ports d’amorçage ; elles sont accordées de façon étroite et ne servent que pendant une installation. Ce qu’elle ajoute, c’est du disque : les supports de démarrage sont mis en cache sur l’hôte, jusqu’à 20 GB par défaut, les plus anciens étant supprimés en premier.
Exécuter des automatisations
Les automatisations sont votre propre TypeScript : elles s’exécutent donc dans un bac à sable construit à partir des espaces de noms du noyau, et l’environnement d’exécution correspondant ne fait pas partie de l’agent. Une version figée de Bun doit se trouver dans le répertoire de l’agent appartenant à root, là où le compte sous lequel tourne l’agent ne peut pas la remplacer. Ubuntu 24.04 et les versions suivantes restreignent précisément l’espace de noms nécessaire ici ; l’agent fournit un profil AppArmor qui rend cette unique permission à cet unique binaire. S’il manque l’un ou l’autre, l’agent le signale au démarrage, ne propose pas la fonction et poursuit. Chaque exécution réserve 4 GB d’espace d’adressage. C’est du virtuel, pas de la mémoire qui doit exister. Ce qu’une automatisation en cours d’exécution coûte réellement sur votre hôte, nous ne l’avons pas mesuré.
Redémarrer l’hôte depuis le panneau
Redémarrer relève d’une question d’autorisation plutôt que de privilège : l’agent s’adresse à logind, logind s’adresse à polkit, et le script d’installation laisse derrière lui une règle qui autorise exactement deux actions pour exactement ce compte. Les hôtes installés avant l’existence de cette règle doivent repasser une fois par le script d’installation, car mettre l’agent à jour depuis le panneau remplace le binaire et rien dans /etc. D’ici là, le panneau refuse et en explique la raison.
Console et diagnostics
Rien à installer. Le ping et le traceroute utilisent une socket ICMP qui ne demande aucun privilège, à condition que l’hôte l’autorise pour le groupe du compte de service, ce qui était le cas sur chaque hôte que nous avons mesuré ; là où ce n’est pas le cas, l’agent mesure avec TCP à la place et vous indique la méthode employée. La console est relayée par la connexion déjà ouverte.

Installer avec la commande d’une seule ligne

Dans l’onglet des paramètres de l’agent, le panneau construit une commande unique contenant un lien d’installation. Exécutez-la en tant que root sur l’hôte. Le lien ne fonctionne qu’une fois : il cesse de fonctionner dès que l’agent est enregistré, et au plus tard au bout de 72 heures. Vous pouvez en créer un nouveau à tout moment.

shell
curl -fsSL https://app.provibr.com/api/install/<token> | sh
Traitez ce lien comme un identifiant. Quiconque le détient peut enregistrer cet agent-là, exactement comme le permettrait une clé d’authentification. Il n’est jamais conservé dans le panneau : créez-en un nouveau plutôt que de chercher l’ancien.
Les commandes et les sorties de terminal sont en anglais partout, dans le panneau comme dans ces pages. Un seul texte, une seule vérité : ce que vous lisez ici est littéralement ce que votre hôte affichera.

Ce que fait la commande, dans l’ordre :

  • Vérifie qu’elle s’exécute en tant que root sur un hôte x86 64 bits et choisit curl ou wget, selon ce qui est présent.
  • Télécharge le binaire et sa somme de contrôle, puis les vérifie. Si l’hôte ne dispose d’aucun outil pour calculer une somme de contrôle, elle s’arrête au lieu de sauter la vérification.
  • Crée le compte de service et les deux répertoires, installe le binaire, et met en place le script de mise à jour et sa clé publique, tous deux appartenant à root, afin que le compte sous lequel tourne l’agent ne puisse pas les remplacer.
  • Demande le code d’activation dans le terminal, récupère le fichier de licence en transmettant ce code dans un en-tête de requête, et l’installe.
  • Effectue l’enregistrement sous le compte de service, puis installe l’unité systemd et démarre le service.

Vérifiez le résultat sur l’hôte :

shell
systemctl status provibr-agent
journalctl -u provibr-agent -f
Relancer la commande est sans danger, avec un nouveau lien : l’ancien ne fonctionne plus depuis l’enregistrement de l’agent. Si l’hôte est déjà enregistré, seuls le binaire et l’unité sont rafraîchis ; l’identité, le certificat et le coffre d’identifiants restent intacts. Sur un hôte sans systemd, tout est malgré tout installé et enregistré, et la commande affiche comment lancer l’agent vous-même.

Installer à la main

Tout ce que fait la commande d’une seule ligne tient aussi en une poignée de commandes, et le panneau les affiche pour vous avec les valeurs actuelles déjà renseignées. En voici la trame.

  1. Préparez l’hôte : le compte de service, les répertoires et le binaire.

    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. Mettez le fichier de licence en place. Vous le téléchargez depuis la page de l’agent ; il est chiffré avec le code d’activation, et il ne peut être téléchargé qu’une seule fois par jeton.

    shell
    sudo install -o root -g provibr-agent -m 0640 \
      ./provibr-<agent>.plic /etc/provibr-agent/license.plic
  3. Effectuez l’enregistrement sous le compte de service, avec le code d’activation.

    shell
    sudo -u provibr-agent /usr/local/bin/provibr-agent enroll \
      --license /etc/provibr-agent/license.plic --code XXXXX-XXXXX
  4. Installez l’unité et démarrez le service.

    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
Le téléchargement du binaire propose aussi sa somme de contrôle et sa signature. Vérifier la signature est l’étape qu’un simple téléchargement ne vous donne pas, et c’est le contrôle que l’étape de mise à jour effectue sur chaque nouvelle version.

Docker et Kubernetes

L’agent fonctionne aussi en conteneur. L’image contient le même binaire signé que le téléchargement Linux, et rien d’autre : ni shell ni gestionnaire de paquets, et il s’exécute sous un utilisateur sans droits root. Il ne se connecte que vers l’extérieur, il n’a donc besoin ni de ports publiés ni de service.

L’enregistrement a lieu au premier démarrage. Donnez au conteneur le lien d’installation du panneau et le code d’activation ; il récupère son fichier de licence, s’enregistre et conserve son identité sur le volume. À chaque démarrage suivant, cette identité est utilisée et les deux valeurs ne sont plus lues.

Le lien d’installation et le code se trouvent dans l’environnement du conteneur, et donc dans docker inspect, dans l’historique de votre shell ou dans le secret Kubernetes. C’est la même exposition qu’avec la commande en une ligne, et elle dure jusqu’à l’enregistrement de l’agent : à partir de là, le lien ne fonctionne plus. Retirez-le quand même du secret ensuite ; l’agent ne le relit pas.
Tout ce que l’agent conserve se trouve sur le volume, dans /var/lib/provibr-agent : son certificat, le coffre chiffré contenant vos identifiants et la clé de ce coffre. Sans volume, chaque nouveau conteneur est un nouvel agent non enregistré. Avec un volume, ce volume est tout le secret : traitez-en une copie comme une copie de l’agent.

Docker

Le panneau affiche cette commande avec le lien et le code de votre agent déjà remplis. Le volume nommé reprend le propriétaire de l’image, donc l’agent peut y écrire sans 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

Ou la même chose sous forme de fichier 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:
Vous préférez un montage lié à un volume nommé ? Créez d’abord le répertoire et donnez-le à l’utilisateur de l’agent : mkdir -p /srv/provibr-agent && chown 65532:65532 /srv/provibr-agent. Un montage lié appartient d’abord à root, et l’agent, qui ne s’exécute pas en root, ne pourrait pas y écrire.

Kubernetes

Des manifestes simples, sans Helm : un namespace, un secret avec le lien et le code, un volume claim et un deployment. Le panneau remplit le secret pour votre agent.

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
Gardez replicas à 1 et la stratégie sur Recreate. Un agent est une identité : deux pods sur le même volume partagent un certificat et s’écartent mutuellement de la plateforme, et deux pods avec chacun leur volume s’enregistrent tous les deux, après quoi seul le dernier est valide. Une mise à jour progressive ferait exactement cela pendant un instant.
La vérification ping utilise une socket ICMP sans privilèges, pas la capability NET_RAW. Certains environnements d’exécution de conteneurs gardent ces sockets fermées ; mesuré avec les sockets fermées, un ping de diagnostic s’est rabattu sur TCP et la vérification de supervision a signalé une erreur de source. Le manifeste les ouvre pour le groupe de l’agent avec le sysctl sûr net.ipv4.ping_group_range. Ajouter NET_RAW n’aide pas : l’agent ne s’exécute pas en root, il n’obtient donc aucune capability effective.

Pour Kubernetes, le fichier de licence est la meilleure voie : placez dans le secret le fichier de licence et le code au lieu du lien d’installation, montez le fichier dans le pod et faites pointer PROVIBR_LICENSE_FILE vers son chemin. Le jeton contenu dans le fichier ne fonctionne qu’une seule fois, le secret ne contient donc rien qui permette d’enregistrer l’agent une seconde fois.

Mettre à jour un conteneur

Par défaut, un conteneur ne se met pas à jour lui-même : l’image est la version publiée. Le panneau indique quelle image est actuelle ; récupérez-la et recréez le conteneur, ou appliquez le nouveau tag au deployment. Le volume conserve l’identité et les identifiants. Les mises à jour automatiques ignorent ces agents ; l’option ci-dessous change cela.

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 : se mettre à jour depuis le volume

Définissez PROVIBR_SELF_UPDATE=volume, ou cochez l’option dans le panneau. Le conteneur participe alors au bouton de mise à jour et aux mises à jour nocturnes : une nouvelle version est téléchargée, sa signature est vérifiée avec la clé de la plateforme intégrée à l’image, puis elle est stockée sur le volume. Le conteneur s’arrête avec le code de sortie 0, Docker ou le kubelet le redémarre, et le binaire de l’image démarre la nouvelle version depuis le volume après avoir vérifié sa signature une fois de plus.

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

Une nouvelle version dispose de 60 secondes pour atteindre la plateforme. Sinon, elle est marquée comme défectueuse sur le volume et n’est plus jamais démarrée, et le conteneur revient avec la version précédente. Quand vous déployez une image plus récente, c’est l’image qui l’emporte : ce qui était stocké sur le volume pour l’ancienne image n’est plus utilisé.

Ce que vous cédez : le tag de l’image n’indique plus quelle version tourne (le panneau, si), les scanners d’images examinent le binaire de l’image et non celui du volume, et un outil GitOps voit un pod qui exécute autre chose que ce que dit son manifeste. Nous ne le recommandons pas pour les clusters gérés par un outil GitOps.

Option : l’image tools pour les automatisations

L’image standard ne contient pas de runtime d’automatisation. L’image tools, avec le suffixe de tag -tools, contient le même agent signé sur Debian, avec en plus le runtime d’automatisation épinglé, pour que les automatisations puissent s’exécuter dans le conteneur. Les exemples Docker lui donnent un petit /tmp et une limite de pids (--pids-limit) ; sur Kubernetes, /tmp est un emptyDir en mémoire, et une limite de pids se règle sur le kubelet (podPidsLimit), pas dans le manifeste. Le système de fichiers racine reste en lecture seule.

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
Sur un hôte Linux, une automatisation s’exécute dans un bac à sable avec ses propres espaces de noms : pas de réseau, aucun fichier de l’hôte, sa propre arborescence de processus. Un conteneur ne peut pas créer ces espaces de noms ; dans l’image tools, l’agent limite donc le runtime de deux autres façons. Un filtre seccomp, qui fonctionne sur tout noyau, bloque toute socket réseau (TCP et UDP), les signaux vers d’autres processus, le lancement de nouveaux processus et la lecture de la mémoire d’un autre processus. Landlock (Linux 5.13 ou plus récent) limite les fichiers : un script ne peut lire que le runtime et les bibliothèques système et ne peut rien écrire. L’agent teste les deux au démarrage ; si le noyau ou le profil seccomp du runtime de conteneurs ne les autorise pas, les automatisations restent désactivées dans le conteneur. Ce qui reste est plus faible que sur un hôte : un script peut encore voir quels processus tournent dans le conteneur. Choisir l’image tools, c’est faire ce choix.

Ce qui ne fonctionne pas en conteneur

Certaines fonctions ont besoin de l’hôte lui-même, et un conteneur verrouillé ne l’a pas :

  • Les installations réseau (PXE) : elles ont besoin du réseau de l’hôte et de ports inférieurs à 1024.
  • Redémarrer l’hôte depuis le panneau : le conteneur n’a pas accès au système d’init de l’hôte.
  • Les automatisations dans l’image standard : elle ne contient pas de runtime d’automatisation, et le bac à sable qu’elles reçoivent sur un hôte a besoin des espaces de noms utilisateur, qu’un conteneur verrouillé n’accorde pas. L’image tools les exécute plutôt dans le conteneur même.
  • Les mesures de l’hôte : le processeur, la mémoire et la durée de fonctionnement décrivent la machine sur laquelle tourne le conteneur, pas ses propres limites.

Le code d’activation et le fichier de licence

Lorsque vous créez un agent, le panneau affiche un code d’activation une seule fois. Il n’est jamais consigné, pas même sous forme d’empreinte. C’est ce code qui chiffre le fichier de licence : le fichier présent sur votre hôte est donc chiffré avec quelque chose qui ne s’y trouve pas.

Code ou fichier perdu ? Générez un nouveau jeton sur la page de l’agent. Cela invalide le précédent, y compris un fichier de licence déjà en route, et vous fournit un nouveau code ainsi qu’un nouveau téléchargement.

Le fichier de licence lui-même ne porte aucun secret sur votre infrastructure. Il indique à l’agent à quelle plateforme il appartient, quelle autorité de certification approuver, et le jeton à usage unique avec lequel il s’enregistre.

Gérer les agents dans le panneau

La liste des agents montre tout d’un coup d’œil : le statut, la version, s’il est connecté à cet instant, quand il a été vu pour la dernière fois et quand son certificat expire.

  • Le nom et la description sont à vous et ne sont que des libellés. Un nom déjà présent dans un fichier de licence livré reste tel quel : c’est cosmétique et ce n’est pas une raison de réenregistrer l’agent.
  • L’état connecté ou non est lu depuis un signal en direct à durée de vie courte, pas depuis la dernière écriture d’une ligne. Si nous ne pouvons pas le déterminer, le panneau le dit au lieu d’affirmer que votre agent est hors service.
  • La version et le système d’exploitation sont ce que l’agent a signalé lors de sa dernière connexion. Un agent qui ne s’est jamais connecté affiche un tiret plutôt qu’une supposition.
  • Sélectionnez plusieurs agents dans la liste pour les mettre à jour d’un coup. Le bouton ne compte que les agents qui peuvent effectivement être mis à jour à cet instant : vous voyez donc avant de cliquer que douze agents sélectionnés en donneront trois mis à jour.
  • La progression est lue depuis la commande en cours, pas depuis quelque chose que votre navigateur a retenu : un rechargement la reprend donc là où elle en était.

Les trois états

En attente
Créé dans le panneau, pas encore enregistré. Un jeton et un code d’activation l’attendent, et il n’a pas encore de certificat.
Enregistré
Il possède son propre certificat et peut se connecter. C’est le seul état dans lequel on peut lui confier du travail, et le seul dans lequel il ne peut pas être supprimé.
Révoqué
Retiré par vous. Sa session est fermée, les jetons en circulation sont annulés, et il ne peut pas revenir.

Révoquer un agent

La révocation est le levier à actionner lorsqu’un hôte est compromis, mis hors service ou simplement plus le vôtre. Elle prend effet sans que vous ayez à toucher à l’hôte.

  • Une session en cours est fermée dans la minute. L’agent est informé du motif au lieu d’être simplement coupé.
  • L’agent efface ensuite sa propre identité, son certificat et son coffre d’identifiants. Les identifiants de votre hyperviseur ont disparu de cet hôte.
  • Les jetons d’enregistrement en circulation sont annulés : un fichier de licence déjà téléchargé ne permet donc pas de revenir.
Il n’y a pas de retour en arrière. Un agent révoqué par erreur doit être recréé, réinstallé et doté à nouveau de ses identifiants.

Supprimer un agent

La suppression retire l’agent du panneau. C’est une étape distincte de la révocation, et elle est volontairement pointilleuse sur les cas où elle est autorisée.

  • Un agent enregistré ne peut pas être supprimé. Révoquez-le d’abord, sinon vous supprimeriez la trace de quelque chose qui est encore connecté.
  • Un agent auquel sont rattachés des intégrations ou des serveurs ne peut pas non plus être supprimé, et le refus indique les deux nombres. Ces lignes dépendent de l’agent : un seul clic emporterait votre parc avec lui.
  • Si l’agent n’a jamais exécuté de commande et n’a jamais eu de serveur, la ligne disparaît réellement. Sinon, il est masqué partout mais son historique de commandes est conservé, car une piste d’audit que l’on peut effacer en supprimant son sujet n’est pas une piste d’audit.

Le retirer de l’hôte

La révocation efface les secrets de l’agent mais laisse les fichiers. Pour nettoyer l’hôte, le panneau propose une seconde commande d’une seule ligne, ainsi que les mêmes quatre étapes à la main.

Ce script ne révoque rien. Révoquez d’abord dans le panneau, puis nettoyez l’hôte, dans cet ordre. L’inverse laisse un hôte qui détient encore une identité valable.
  1. Arrêtez le service, désactivez-le et supprimez l’unité.

    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. Supprimez le binaire, le script de mise à jour et la clé de mise à jour.

    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. Supprimez les données. C’est l’étape qui compte : la licence, la clé du coffre et les identifiants chiffrés se trouvent ici.

    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. Supprimez le compte de service.

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

Ensuite, ces deux commandes ne doivent rien afficher du tout :

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