Ir para o conteúdo

Documentação

Agentes

O agente é a única parte do Provibr que corre no seu próprio hardware. Guarda as credenciais dos sistemas que liga, executa o trabalho que o painel pede e comunica o que vê. A plataforma nunca liga de fora para dentro.

O que é um agente

Um agente cobre uma rede: o local a partir do qual os seus hipervisores e painéis estão acessíveis. Tudo o que o Provibr faz à sua infraestrutura passa por ele.

  • A ligação é de saída. É o agente que a abre para a plataforma e a mantém aberta; nada tem de estar acessível a partir da internet e não é preciso encaminhar nenhuma porta para ele.
  • As credenciais ficam do seu lado. São enviadas ao agente uma única vez e seladas num cofre cifrado nesse host; a plataforma guarda apenas os nomes dos campos que preencheu.
  • Comunica o que observa. As máquinas são sondadas num ritmo curto e, de poucos em poucos minutos, corre uma comparação completa, que é como o painel repara numa máquina que foi parada fora do Provibr.
  • Só toca no que lhe foi entregue. Um recurso sem registo no Provibr é ignorado, contado e novamente esquecido. O agente nunca adota uma máquina por sua conta.

O host de que precisa

Nada de exótico, e nada para instalar primeiro. O agente é um único binário estático: traz consigo a sua própria biblioteca C, por isso não há ambiente de execução, nem interpretador, nem pacote de distribuição que tenha de corresponder. Uma máquina virtual pequena chega bem. Os tamanhos que medimos estão mais abaixo nesta página.

O que um host de agente tem de oferecer
RequisitoO que é precisoPorquê
Processadorx86 de 64 bits (x86_64, também chamado amd64)Publicamos uma única compilação para Linux e é esta a arquitetura para a qual foi construída. O instalador verifica o uname -m antes de descarregar seja o que for e para perante qualquer outra arquitetura, em vez de instalar algo que não consegue executar. Ainda não existe uma compilação para ARM.
Sistema operativoQualquer distribuição LinuxNada está ligado às bibliotecas do seu sistema, por isso a distribuição, a sua versão e o seu gestor de pacotes não fazem diferença. A secção seguinte enumera aquelas em que esta compilação foi realmente iniciada.
Gestor de serviçossystemd, ou o seu próprioO instalador escreve uma unidade systemd e ativa-a. Num host sem systemd tudo é na mesma instalado e inscrito, e o instalador indica depois o comando para iniciar o agente com aquilo que usar em alternativa. Meia instalação seria pior do que uma instalação honesta.
Direitos durante a instalaçãoroot, uma vezA instalação cria a conta de serviço provibr-agent, dois diretórios e a unidade. Depois disso o agente corre com essa conta sem privilégios, e é o script de atualização, no qual não tem autorização para escrever, que o mantém assim.
Ligações de saídaTCP 50051 e 50052 para gw.provibr.netA porta 50051 é usada uma única vez, durante a inscrição. A porta 50052 transporta a sessão e mantém-se aberta. Ambas são TLS. Se a sua firewall filtrar o tráfego de saída, essas duas regras são tudo o que ela tem de permitir.
Ligações de entradaNenhumaÉ o agente que abre a ligação, por isso nada tem de estar acessível a partir da internet e não é preciso encaminhar nenhuma porta para ele. Instalar máquinas através da rede é a única exceção e, mesmo aí, o agente só fica à escuta no segmento local.
Alcance dentro da sua própria redeAté aos sistemas que ligaO seu hipervisor, painel de controlo ou painel de jogos é contactado através da sua própria API, a partir deste host. O que o agente não alcança, o Provibr não consegue gerir.
Memória512 MB chegam bemMedimos 18 MB com mil máquinas distribuídas por cinco sistemas, que é o caso mais pesado da tabela abaixo. O pico está noutro sítio: desbloquear o ficheiro de licença durante a inscrição ocupa por instantes cerca de 70 MB, porque esse passo é propositadamente caro de atacar por força bruta.
Disco1 GB chega bemO binário tem 17 MB e tudo o que o agente guarda ao lado dele ficou abaixo de 40 kB nas nossas medições. Instalar máquinas através da rede é a exceção: guarda ficheiros de arranque em cache, até 20 GB por predefinição.
RelógioAproximadamente certoOs certificados e os ficheiros de licença têm datas de validade e ambos os lados as verificam, por isso um host cujo relógio tenha dias de desvio não se consegue inscrever. Qualquer cliente NTP serve.
O agente corre com a sua própria conta sem privilégios, sob uma unidade systemd reforçada. Recebe exatamente duas capacidades adicionais, e apenas para poder servir instalações através da rede; se forem retiradas, tudo continua a funcionar exceto isso.

Que Linux

Não há pacote para instalar nem distribuição a que corresponder, por isso o que se segue não é uma lista de sistemas suportados. É a lista de sistemas em que esta compilação foi realmente iniciada. Qualquer outro com um kernel Linux x86 de 64 bits deve comportar-se da mesma maneira e, se não for esse o caso, gostaríamos de saber.

Distribuições Linux em que o agente foi executado
SistemaVersãoNotas
Debian13 (Trixie)
Debian12 (Bookworm)A distribuição em que decorreu o teste completo: instalado, inscrito, ligado e a sondar.
Ubuntu24.04 LTSÉ no Ubuntu 24.04 que o kernel começou a restringir exatamente os espaços de nomes de que as automatizações precisam. O agente inclui um perfil AppArmor para isso; tudo o resto funciona sem qualquer alteração.
Ubuntu22.04 LTS
AlmaLinux9
AlmaLinux8Uma biblioteca C muito mais antiga do que aquela em que esta compilação foi feita. Não faz diferença, porque o agente traz a sua.
Fedora42
openSUSE Leap15
Amazon Linux2023
Alpine Linux3.21musl e nem sequer glibc, o teste mais exigente que existe para um binário ligado estaticamente.
Dois limites honestos a essa lista. Ela mostra que o binário arranca e faz o seu trabalho criptográfico em cada um destes espaços de utilizador; a sessão completa, com certificados e sondagem, foi medida num deles. E todas as verificações correram em máquinas que partilhavam um único kernel, por isso o que fica provado é a independência da distribuição, não da versão do kernel.

Que tamanho de máquina

O agente em si é pequeno e assim se mantém. O que cresce é o inventário que vigia: de vinte em vinte segundos lê a lista completa de máquinas de cada sistema ligado, compara-a com a sondagem anterior e envia apenas o que mudou. De cinco em cinco minutos envia antes o quadro completo, que é a rede de segurança para tudo aquilo que, de outro modo, uma mensagem perdida teria custado, e é também nessa sondagem que pergunta aos seus nós quanta capacidade têm.

Medido num único agente; cada linha é uma janela de cinco minutos
SituaçãoMemóriaProcessador
Ligado, ainda sem nada associado8 MB0,02% de um núcleo
Um sistema, 10 máquinas12 MB0,03%
Um sistema, 250 máquinas14 MB0,06%
Um sistema, 1000 máquinas15 MB0,14%
Cinco sistemas, 200 máquinas cada18 MB0,19%
Os saltos entre as linhas dizem mais do que as próprias linhas. Associar o primeiro sistema custa cerca de 4 MB e cada sistema seguinte cerca de 0,75 MB, que é exatamente aquilo em que as duas últimas linhas diferem. As máquinas ficam mais baratas quanto mais forem: passar de 10 para 1000 acrescentou 3 MB no total, uns 3 kB cada, e o salto de 250 para 1000 foi ainda mais barato. Medido em agosto de 2026 contra sistemas simulados exatamente com esses tamanhos, para que os números digam algo sobre o agente e não sobre o cluster de alguém.

O tráfego é o outro número que vale a pena ter. Essas mil máquinas custam cerca de 250 kB de vinte em vinte segundos em direção aos seus próprios sistemas, mais ou menos um gigabyte por dia na sua própria rede, enquanto dez máquinas custam 2,5 kB por sondagem. Desse valor das mil máquinas, cerca de 17 kB por sondagem seguem até nós, uns 70 MB por dia, porque só é enviado o que mudou.

O tipo de sistema faz diferença? Quase nenhuma. Quer o agente esteja a falar com um hipervisor, com um painel de controlo de alojamento ou com um painel de jogos, o trabalho é o mesmo: uma chamada por sistema em cada sondagem, uma comparação, uma mensagem. Há duas diferenças reais, mas pequenas: a um hipervisor são pedidos também os endereços dentro dos seus sistemas convidados, no máximo uma vez de cinco em cinco minutos por máquina em execução, e um painel que não mede nada não envia números de utilização. O que difere enormemente é a máquina do outro lado, e essa é dimensionada pelo que executa, não pelo agente.

Os tamanhos abaixo não são, portanto, mínimos que tenhamos medido; o agente cabe em muito menos do que isto. São o que encomendaríamos, porque um sistema operativo, os seus registos e as suas próprias ferramentas querem mais espaço do que o agente.

O que daríamos a um host de agente
O que tem de aguentarvCPUMemóriaDisco
Até algumas centenas de máquinas11 GB10 GB
Até alguns milhares de máquinas22 GB10 GB
Também a instalar máquinas através da rede22 GB40 GB

O que os extras exigem

Tudo o que está acima é aquilo de que um agente precisa para vigiar e controlar os seus sistemas. Quatro das suas funcionalidades merecem ainda uma palavra, e cada uma delas falha com honestidade: se um requisito não estiver cumprido, o agente continua a fazer o resto e indica qual a funcionalidade que não está a oferecer.

Instalar máquinas através da rede
Esta precisa que o agente esteja no mesmo segmento de rede que a máquina a instalar, porque responde diretamente ao pedido de arranque dessa máquina. A sua unidade já traz as duas capacidades de que precisa para as portas de arranque; são concedidas de forma restrita e só usadas enquanto uma instalação estiver a decorrer. O que acrescenta mesmo é disco: os ficheiros de arranque ficam em cache no host, até 20 GB por predefinição, sendo os mais antigos os primeiros a sair.
Executar automatizações
As automatizações são TypeScript escrito por si, por isso correm dentro de uma sandbox construída a partir de espaços de nomes do kernel, e o ambiente de execução necessário para isso não faz parte do agente: uma versão fixa do Bun tem de estar no diretório do agente pertencente ao root, onde a conta com que o agente corre não a pode substituir. O Ubuntu 24.04 e posteriores restringem exatamente o espaço de nomes de que isto precisa; o agente inclui um perfil AppArmor que devolve essa única permissão a esse único binário. Se faltar uma das duas peças, o agente di-lo no arranque, não oferece a funcionalidade e continua. Cada execução recebe pelo menos 4 GB de espaço de endereçamento. Isso é virtual, não memória que tenha de existir. O que uma automatização em execução custa realmente no seu host é algo que não medimos.
Reiniciar o host a partir do painel
Reiniciar é uma questão de autorização e não de privilégios: o agente pergunta ao logind, o logind pergunta ao polkit, e o instalador deixa uma regra que permite exatamente duas ações exatamente a esta conta. Os hosts instalados antes de essa regra existir precisam de executar o instalador mais uma vez, porque atualizar o agente a partir do painel substitui o binário e nada em /etc. Até lá, o painel recusa e indica o motivo.
Consola e diagnóstico
Nada para instalar. O ping e o traceroute usam um socket ICMP que não precisa de privilégios, desde que o host o permita ao grupo da conta de serviço, o que aconteceu em todos os hosts que medimos; onde não acontece, o agente mede antes com TCP e indica que método usou. A consola é retransmitida pela ligação que já está aberta.

Instalar com o comando de uma linha

No separador de definições do agente, o painel constrói um único comando com uma ligação de instalação. Execute-o como root no host. A ligação funciona uma única vez: deixa de funcionar assim que o agente se inscreve, e no máximo ao fim de 72 horas. Pode criar uma nova a qualquer momento.

shell
curl -fsSL https://app.provibr.com/api/install/<token> | sh
Convém tratar essa ligação como uma credencial. Quem a tiver pode inscrever este agente em concreto, tal como aconteceria com uma chave de autenticação. Nunca fica guardada no painel, por isso é melhor criar uma nova do que procurar a anterior.
Os comandos e a saída do terminal estão em inglês em todo o lado, no painel e nestas páginas. Um só texto, uma só verdade: o que aqui se lê é literalmente o que o seu host vai devolver.

O que o comando faz, por ordem:

  • Verifica que corre como root num host x86 de 64 bits e escolhe curl ou wget, consoante o que existir.
  • Descarrega o binário e a sua soma de verificação e verifica-os. Se o host não tiver ferramenta nenhuma para calcular uma soma de verificação, para em vez de saltar a verificação.
  • Cria a conta de serviço e os dois diretórios, instala o binário e coloca o script de atualização e a sua chave pública, ambos pertencentes ao root, para que a conta com que o agente corre não os possa substituir.
  • Pede o código de ativação no terminal, obtém o ficheiro de licença com esse código como cabeçalho do pedido e instala-o.
  • Faz a inscrição com a conta de serviço e instala depois a unidade systemd e inicia o serviço.

Verifique o resultado no host:

shell
systemctl status provibr-agent
journalctl -u provibr-agent -f
Voltar a executar o comando é seguro, com uma nova ligação: a antiga deixou de funcionar quando o agente se inscreveu. Se o host já estiver inscrito, só o binário e a unidade são renovados; a identidade, o certificado e o cofre de credenciais ficam intactos. Num host sem systemd tudo é na mesma instalado e inscrito, e o comando indica como executar o agente à mão.

Instalar à mão

Tudo o que o comando de uma linha faz resume-se também a alguns comandos, e o painel imprime-os já com os valores atuais preenchidos. É este o esquema.

  1. Prepare o host: a conta de serviço, os diretórios e o binário.

    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. Coloque o ficheiro de licença no sítio. Descarrega-se na página do agente; está cifrado com o código de ativação e só pode ser descarregado uma vez por token.

    shell
    sudo install -o root -g provibr-agent -m 0640 \
      ./provibr-<agent>.plic /etc/provibr-agent/license.plic
  3. Faça a inscrição com a conta de serviço e o código de ativação.

    shell
    sudo -u provibr-agent /usr/local/bin/provibr-agent enroll \
      --license /etc/provibr-agent/license.plic --code XXXXX-XXXXX
  4. Instale a unidade e inicie o serviço.

    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
O download do binário oferece também a sua soma de verificação e a sua assinatura. Verificar a assinatura é o passo que um simples download não dá, e é a mesma verificação que o passo de atualização faz em cada nova versão.

Docker e Kubernetes

O agente também é executado como contentor. A imagem contém o mesmo binário assinado da transferência para Linux e mais nada: sem shell nem gestor de pacotes, e é executado como utilizador sem privilégios de root. Liga-se apenas para fora, por isso não precisa de portas publicadas nem de um service.

A inscrição acontece no primeiro arranque. Dê ao contentor a ligação de instalação do painel e o código de ativação; ele obtém o seu ficheiro de licença, inscreve-se e guarda a sua identidade no volume. Em cada arranque seguinte é usada essa identidade e os dois valores já não são lidos.

A ligação de instalação e o código estão no ambiente do contentor, e portanto no docker inspect, no histórico da shell ou no secret do Kubernetes. É a mesma exposição que no comando de uma linha, e dura até o agente se inscrever: a partir daí a ligação deixa de funcionar. Retire-a na mesma do secret; o agente não a volta a ler.
Tudo o que o agente guarda está no volume, em /var/lib/provibr-agent: o seu certificado, o cofre cifrado com as suas credenciais e a chave desse cofre. Sem volume, cada novo contentor é um agente novo e não inscrito. Com volume, esse volume é o segredo todo: trate uma cópia dele como uma cópia do agente.

Docker

O painel mostra este comando com a ligação e o código do seu agente já preenchidos. O volume com nome herda o proprietário da imagem, por isso o agente pode escrever nele sem 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 o mesmo como ficheiro 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:
Prefere um bind mount a um volume com nome? Crie primeiro o diretório e atribua-o ao utilizador do agente: mkdir -p /srv/provibr-agent && chown 65532:65532 /srv/provibr-agent. Um bind mount começa por pertencer ao root, e o agente, que não é executado como root, não conseguiria escrever nele.

Kubernetes

Manifestos simples, sem Helm: um namespace, um secret com a ligação e o código, um volume claim e um deployment. O painel preenche o secret para o seu agente.

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
Mantenha replicas em 1 e a estratégia em Recreate. Um agente é uma identidade: dois pods no mesmo volume partilham um certificado e afastam-se mutuamente da plataforma, e dois pods com volume próprio inscrevem-se ambos, ficando válido apenas o último. Uma atualização progressiva faria exatamente isso durante um momento.
A verificação de ping usa um socket ICMP sem privilégios, não a capability NET_RAW. Alguns runtimes de contentores mantêm esses sockets fechados; medido com eles fechados, um ping de diagnóstico recorreu a TCP e a verificação de monitorização reportou um erro de origem. O manifesto abre-os para o grupo do agente com o sysctl seguro net.ipv4.ping_group_range. Adicionar NET_RAW não ajuda: o agente não é executado como root, por isso não obtém capabilities efetivas.

Para o Kubernetes, o ficheiro de licença é o melhor caminho: coloque no secret o ficheiro de licença e o código em vez da ligação de instalação, monte o ficheiro no pod e aponte PROVIBR_LICENSE_FILE para o seu caminho. O token dentro do ficheiro funciona exatamente uma vez, por isso o secret não contém nada que permita inscrever o agente uma segunda vez.

Atualizar um contentor

Por predefinição, um contentor não se atualiza sozinho: a imagem é a versão publicada. O painel mostra qual é a imagem atual; descarregue-a e volte a criar o contentor, ou defina a nova tag no deployment. O volume guarda a identidade e as credenciais. As atualizações automáticas ignoram estes agentes; a opção abaixo muda isso.

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ção: atualizar-se a partir do volume

Defina PROVIBR_SELF_UPDATE=volume, ou assinale a opção no painel. O contentor passa então a participar no botão de atualização e nas atualizações noturnas: é descarregada uma nova versão, a sua assinatura é verificada com a chave da plataforma incluída na imagem, e fica guardada no volume. O contentor para com o código de saída 0, o Docker ou o kubelet volta a iniciá-lo, e o binário da imagem arranca a nova versão a partir do volume depois de verificar a assinatura mais uma vez.

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

Uma nova versão tem 60 segundos para chegar à plataforma. Se não conseguir, é marcada como defeituosa no volume e nunca mais é iniciada, e o contentor volta com a versão anterior. Quando implementa uma imagem mais recente, prevalece a imagem: o que estava guardado no volume para a imagem antiga deixa de ser usado.

O que se perde: a tag da imagem deixa de indicar que versão está a correr (o painel indica), os scanners de imagens analisam o binário da imagem e não o do volume, e uma ferramenta GitOps vê um pod que executa algo diferente do que diz o seu manifesto. Não o recomendamos para clusters geridos por uma ferramenta GitOps.

Opção: a imagem tools para automatizações

A imagem padrão não inclui o runtime das automatizações. A imagem tools, com o sufixo de tag -tools, contém o mesmo agente assinado sobre Debian com o runtime das automatizações fixado, para que as automatizações possam correr no contentor. Os exemplos de Docker dão-lhe um /tmp pequeno e um limite de pids (--pids-limit); no Kubernetes /tmp é um emptyDir em memória, e um limite de pids define-se no kubelet (podPidsLimit), não no manifesto. O sistema de ficheiros raiz continua só de leitura.

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
Num anfitrião Linux, uma automatização corre numa sandbox com namespaces próprios: sem rede, sem ficheiros do anfitrião, com a sua própria árvore de processos. Um contentor não consegue criar esses namespaces, por isso na imagem tools o agente limita o runtime de duas outras formas. Um filtro seccomp, que funciona em qualquer kernel, bloqueia todos os sockets de rede (TCP e UDP), os sinais para outros processos, o arranque de novos processos e a leitura da memória de outro processo. O Landlock (Linux 5.13 ou posterior) limita os ficheiros: um script só pode ler o runtime e as bibliotecas do sistema e não pode escrever nada. O agente testa ambos ao arrancar; se o kernel ou o perfil seccomp do runtime de contentores não os permitirem, as automatizações ficam desligadas no contentor. O que resta é mais fraco do que num anfitrião: um script ainda pode ver que processos correm no contentor. Escolher a imagem tools é escolher isso.

O que não funciona num contentor

Algumas funções precisam do próprio anfitrião, e um contentor restrito não o tem:

  • Instalações pela rede (PXE): precisam da rede do anfitrião e de portas abaixo de 1024.
  • Reiniciar o anfitrião a partir do painel: o contentor não tem acesso ao sistema de init do anfitrião.
  • Automatizações na imagem padrão: não inclui o runtime das automatizações, e a sandbox que recebem num anfitrião precisa de namespaces de utilizador, que um contentor restrito não concede. A imagem tools executa-as, em vez disso, dentro do contentor.
  • Métricas do anfitrião: CPU, memória e tempo de atividade descrevem a máquina em que o contentor é executado, não os limites do próprio contentor.

O código de ativação e o ficheiro de licença

Ao criar um agente, o painel mostra um código de ativação uma única vez. Nunca fica registado, nem sequer como hash. É o código que cifra o ficheiro de licença, por isso o ficheiro que está no seu host está cifrado com algo que não está nesse host.

Perdeu o código, ou o ficheiro? Gere um novo token na página do agente. Isso invalida o anterior, incluindo um ficheiro de licença que já estivesse a caminho, e dá um código novo e um download novo.

O ficheiro de licença em si não transporta nenhum segredo sobre a sua infraestrutura. Diz ao agente a que plataforma pertence, em que autoridade de certificação deve confiar e com que token de utilização única se inscreve.

Gerir agentes no painel

A lista de agentes mostra tudo de uma vez: estado, versão, se está ligado neste momento, quando foi visto pela última vez e quando expira o certificado.

  • O nome e a descrição podem ser alterados e são apenas etiquetas. Um nome que já esteja dentro de um ficheiro de licença entregue fica como estava, o que é cosmético e não é motivo para nova inscrição.
  • Se está ligado ou não é lido de um sinal em direto com validade curta, não do momento em que uma linha foi escrita pela última vez. Se não for possível determinar, o painel di-lo em vez de afirmar que o seu agente está em baixo.
  • A versão e o sistema operativo são o que o agente comunicou na sua última ligação. Um agente que nunca se ligou mostra um traço em vez de um palpite.
  • Selecione vários agentes na lista para os atualizar de uma vez. O botão conta apenas os agentes que podem mesmo ser atualizados neste momento, por isso vê-se antes de clicar que doze selecionados significam três atualizados.
  • O progresso é lido do comando em execução, não de algo que o seu navegador tenha memorizado, por isso um recarregamento retoma-o.

Os três estados

Pendente
Criado no painel, ainda sem inscrição. Tem um token e um código de ativação à sua espera, e ainda não tem certificado.
Inscrito
Tem o seu próprio certificado e pode ligar-se. É o único estado em que lhe pode ser atribuído trabalho e o único em que não pode ser eliminado.
Revogado
Retirado por si. A sessão está fechada, os tokens pendentes ficam anulados e não pode voltar.

Revogar um agente

Revogar é o interruptor a que se recorre quando um host está comprometido, foi desativado ou simplesmente já não é seu. Produz efeito sem ser preciso tocar no host.

  • Uma sessão em curso é fechada dentro do minuto. O agente é informado do motivo em vez de ser simplesmente cortado.
  • O agente apaga depois a sua própria identidade, o seu certificado e o seu cofre de credenciais. As credenciais do seu hipervisor desaparecem desse host.
  • Os tokens de inscrição pendentes ficam anulados, por isso um ficheiro de licença já descarregado não serve para voltar.
Não é possível desfazer. Um agente revogado por engano tem de ser criado outra vez, instalado outra vez e receber outra vez as suas credenciais.

Eliminar um agente

Eliminar retira o agente do painel. É um passo distinto de revogar e é propositadamente exigente quanto ao momento em que é permitido.

  • Um agente inscrito não pode ser eliminado. Revogue-o primeiro, caso contrário estaria a retirar o registo de algo que continua ligado.
  • Um agente com integrações ou servidores associados também não pode ser eliminado, e a recusa indica as duas contagens. Essas linhas dependem do agente, por isso um único clique levaria o seu inventário com ele.
  • Se o agente nunca executou um comando nem teve um servidor, o registo desaparece mesmo. Caso contrário, fica escondido em todo o lado mas o seu histórico de comandos é conservado, porque um registo de auditoria que se apaga ao eliminar o seu objeto não é um registo de auditoria.

Removê-lo do host

Revogar limpa os segredos do agente mas deixa os ficheiros. Para limpar o host, o painel oferece um segundo comando de uma linha e os mesmos quatro passos à mão.

Este script não revoga nada. Revogue primeiro no painel e só depois limpe o host, por esta ordem. Ao contrário, fica um host que ainda guarda uma identidade válida.
  1. Pare o serviço, desative-o e remova a unidade.

    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. Remova o binário, o script de atualização e a chave de atualização.

    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. Remova os dados. É este o passo que conta: a licença, a chave do cofre e as credenciais cifradas estão aqui.

    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. Remova a conta de serviço.

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

Depois disto, nenhum dos dois deve mostrar absolutamente nada:

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