- ClickHouse 24.8 — archivio canonico per l’analisi di eventi e valutazioni (StatefulSet con volume persistente da 100Gi). Obbligatorio: il server rifiuta di avviarsi senza di esso.
- PostgreSQL 16 — archivio relazionale/metadati per organizzazioni, chiavi API, utenti, dashboard, query salvate e autenticazione (StatefulSet con volume persistente da 50Gi)
- Redis 7.2 — cache condivisa opzionale e backend di rate-limit; il server e la dashboard si degradano elegantemente se non disponibile
- AgentEye Server — API Rust per l’acquisizione di eventi, l’analisi e la gestione delle chiavi (2 repliche)
- AgentEye Dashboard — interfaccia utente Next.js (2 repliche)
- Assistente AI (servizio agent) — assistente opzionale in sola lettura all’interno della dashboard sulla porta 9100; inerte finché non viene configurato un endpoint LLM
- Traefik (pubblico) — controller di ingresso per il traffico del collector, protetto con mTLS
- Traefik (dashboard) — controller di ingresso per la dashboard, solo VPN/allowlist IP
- cert-manager — certificati TLS e CA mTLS
- Backup CronJob — dump combinato giornaliero di PostgreSQL + ClickHouse alle 03:00 UTC
- Cert Renewal Monitor — avvisi quando i certificati client stanno per scadere
Prerequisiti
Eseguite ogni comando di verifica prima di iniziare. Ogni controllo deve essere superato.| Requisito | Minimo | Comando di Verifica | Risultato atteso |
|---|---|---|---|
| Cluster Kubernetes | 1.27+ | kubectl version | Server Version >= v1.27 |
| Kustomize (incluso in kubectl) | Kustomize v1.14+ (incluso in kubectl 1.27+) | kubectl kustomize --help | Stampa il testo di utilizzo |
| Helm | v3 | helm version | Version:"v3.x.x" |
| RBAC cluster-admin | — | kubectl auth can-i create namespaces | yes |
| StorageClass predefinita | — | kubectl get storageclass | Almeno una riga contrassegnata come (default) |
| Supporto LoadBalancer | — | Dipende dal cloud (EKS, GKE, AKS supportano questo per impostazione predefinita) | — |
| GitHub PAT | — | echo $AGENTEYE_TOKEN | Non vuoto (vedere enterprise-docs/github-token.md) |
| openssl | — | openssl version | OpenSSL 1.x o 3.x |
| Bucket di archiviazione cloud | — | Per i backup di PostgreSQL + ClickHouse (S3, GCS o Azure Blob) | — |
Eseguire tutti i controlli contemporaneamente
Forma del deployment
L’endpoint di acquisizione è servito su un hostname che controllate (ad es.ingest.your-company.example). cert-manager richiede un certificato TLS pubblicamente attendibile da Let’s Encrypt tramite HTTP-01, pertanto i collector verificano il certificato del server rispetto all’archivio di trust del sistema, senza alcun pinning CA per cliente.
L’endpoint della dashboard funziona allo stesso modo: è servito su un secondo hostname che controllate (ad es. agenteye.your-company.example) che punta al LoadBalancer Traefik della dashboard, e cert-manager emette il suo certificato Let’s Encrypt attraverso quel LoadBalancer. I browser ottengono un certificato attendibile senza avvisi.
L’emissione del certificato e il rinnovo si convalidano su HTTP-01, quindi entrambi i LoadBalancer devono essere raggiungibili da Internet pubblico sulla porta 80. Se è necessario limitare l’IP del LoadBalancer della dashboard, coordinare un risolutore DNS-01 con il supporto in anticipo — altrimenti i rinnovi non riescono silenziosamente e il certificato scade.
Ottenere i Manifest
AGENTEYE_TOKEN.
Struttura directory:
Monitoraggio della salute (opzionale): il probe di readiness del server già riflette la salute di Postgres + ClickHouse, e third-party/robusta/ aggiunge avvisi facoltativi nativi di Kubernetes per i guasti dei pod a Slack. Consultate enterprise-docs/health-monitoring.md.
Fase 1 — Infrastruttura di terze parti (~30 min)
1.1 Installare cert-manager
cert-manager gestisce i certificati TLS per HTTPS e la CA privata utilizzata per i certificati client mTLS.Running — cert-manager, cert-manager-cainjector, cert-manager-webhook.
certificates.cert-manager.io, clusterissuers.cert-manager.io, issuers.cert-manager.io.
Se non riesce: i pod in CrashLoopBackOff di solito significano che i CRD non sono stati installati. Eseguite di nuovo con --set crds.install=true. Se i pod webhook non superano il controllo di readiness, aspettate 30 secondi e controllate di nuovo — possono impiegare un momento per avviarsi.
1.2 Installare Traefik — Controller di Acquisizione Pubblico
Questa istanza Traefik gestisce il traffico del collector su un LoadBalancer esterno. Termina TLS e applica mTLS (verifica del certificato client) sull’endpoint di acquisizione.Running.
kubectl describe pod -n traefik-public <pod-name> per errori di pull dell’immagine o vincoli di risorse.
1.3 Installare Traefik — Controller della Dashboard
Questa istanza Traefik serve la dashboard su un LoadBalancer dedicato, limitato da allowlist IP.Due meccanismi di allowlist vengono forniti per questa istanza. Questa guida utilizzaPrima dell’installazione, modificatevalues-dashboard.yaml, che limita l’accesso con il campo portatileservice.loadBalancerSourceRanges. Unvalues-internal.yamlparallelo è fornito anche per gli ambienti AWS che preferiscono l’annotazioneservice.beta.kubernetes.io/aws-load-balancer-source-ranges. Scegliete uno e usatelo coerentemente; i passaggi seguenti presuppongonovalues-dashboard.yaml.
third-party/traefik/values-dashboard.yaml per impostare gli IP sorgente consentiti. Il campo loadBalancerSourceRanges controlla quali IP possono raggiungere la dashboard. Per impostazione predefinita è impostato su 0.0.0.0/0 (tutti gli IP); limitatelo a VPN, ufficio o IP di uscita noti.
Allowlist di un singolo IP
Allowlist di più IP
Aggiungete una voce per IP o blocco CIDR. Un suffisso/32 corrisponde a un singolo indirizzo IPv4; un blocco CIDR (ad es. /24) corrisponde a un intervallo. Potete mescolare liberamente IP individuali e intervalli:
- Mantenete una voce per riga e aggiungete un commento breve
#identificando il proprietario o lo scopo di ogni IP; questo è ciò che gli operatori futuri utilizzano per decidere se una voce è ancora necessaria. - Usate sempre la notazione CIDR. Un IP bare come
203.0.113.10è rifiutato dal provider cloud; usate203.0.113.10/32. - Per gli intervalli IPv6, usate il CIDR equivalente
/128(singolo indirizzo) o più grande, ad es.2001:db8::1/128. Non tutti i provider cloud supportano gli intervalli di origine IPv6; controllate la documentazione del vostro provider su LoadBalancer. - La lista è un OR: il traffico è consentito se la sorgente corrisponde a qualsiasi voce.
helm install di seguito. Se il controller è già installato, eseguite helm upgrade con gli stessi flag, o applicate una patch al Service in fase di esecuzione (sezione successiva).
Aggiornare l’allowlist in fase di esecuzione
Potete modificare gli IP consentiti senza un upgrade Helm applicando una patch al Service direttamente. La patch sostituisce l’intera lista; includete sempre ogni IP che volete mantenere, non solo quello nuovo. Per sostituire la lista con una nuova serie di IP:
Le patch in fase di esecuzione non vengono mantenute in values-dashboard.yaml. Per mantenere il cambiamento nei futuri upgrade Helm, aggiornate anche il file di valori e committatelo.
Quindi installate:
Running.
1.4 Attendere i LoadBalancer
Entrambe le istanze Traefik hanno bisogno di IP esterni prima di procedere.EXTERNAL-IP (non <pending>).
Se ancora in sospeso, aspettate l’assegnazione:
Ctrl+C una volta che l’IP appare. L’assegnazione dell’IP di solito richiede 2-5 minuti.
Se non riesce: <pending> dopo 10 minuti di solito significa che il provider cloud non può provisioning un LoadBalancer. Controllate: tag della subnet (EKS richiede kubernetes.io/role/elb), configurazione VPC, quote di servizio e che l’annotazione LB interna corretta sia impostata per l’istanza interna.
Fase 2 — Creare Secret (~10 min)
Tutti i secret vengono creati manualmente prima di distribuire l’applicazione. Ciò garantisce che i valori sensibili non compaiano mai nei file manifest.2.1 Creare lo namespace
Active.
2.2 Secret di pull dell’immagine
Questo secret autentica conghcr.io per fare il pull delle immagini del container AgentEye. Consultate enterprise-docs/github-token.md per come generare il vostro PAT.
kubernetes.io/dockerconfigjson.
Testate (approfondimento) — verificate che il token possa effettivamente fare il pull delle immagini:
Usate il tag dell’immagine server fissato nel kustomization.yaml del vostro overlay (attualmente v0.0.1-beta.48 sia nell’overlay acme incluso che nel deployment base). Sostituite il tag di seguito con quello che state distribuendo in modo che questo controllo non diverga tra le versioni:
ok stampato nei log.
Se non riesce: ErrImagePull o 401 Unauthorized significa che il PAT è non valido o manca l’ambito read:packages. Ri-controllate enterprise-docs/github-token.md.
2.3 Credenziali PostgreSQL
Importante: utilizziamo-hex(non-base64) per generare la password. L’output in base64 può contenere+,/e=che interrompono la stringa di connessioneDATABASE_URL. Consultate enterprise-docs/troubleshooting.md per i dettagli.
Memorizzate POSTGRES_PASSWORD nel vostro gestore di segreti immediatamente. Ve ne avrete bisogno se dovete mai ripristinare da un backup o connettervi al database direttamente.
Testate:
48 (24 byte hex = 48 caratteri).
2.4 Chiave API Admin
Memorizzate ADMIN_KEY nel vostro gestore di segreti immediatamente.
Testate:
2.5 Configurazione dell’autenticazione (accesso alla dashboard)
La dashboard utilizza email + OTP per l’accesso dell’utente. Senza questo secret il server si avvia comunque e il percorso della chiave APIADMIN_KEY continua a funzionare, ma nessun utente può accedere tramite l’interfaccia utente.
Tutte le chiavi sono referenziate come optional: true nel manifest base, quindi i secret parziali (o nessun secret affatto) vanno bene; il server ritorna ai valori predefiniti documentati. Raggruppare tutto in un unico secret agenteye-auth mantiene la superficie di autenticazione ruotabile in un unico luogo.
| Chiave | Scopo |
|---|---|
ADMIN_EMAIL | Utente admin di bootstrap. Upserted a ogni avvio con tutti i permessi e protetto da eliminazione/modifiche di permessi tramite la dashboard. Senza di esso, nessun admin è seminato e il primo accesso è impossibile. |
ALLOWED_EMAILS | Allowlist separata da virgola. Supporta indirizzi esatti (user@example.com) e wildcard di dominio (*@example.com). Senza di esso, nessun utente può accedere o essere creato. |
SMTP_HOST, SMTP_PORT, SMTP_USERNAME, SMTP_PASSWORD, SMTP_FROM | Relè SMTP per inviare codici OTP. Se SMTP_HOST non è impostato, i codici OTP vengono registrati nello stdout del server anziché inviati tramite email (utile per i test di smoke del primo avvio). Fornite tutte le chiavi SMTP insieme per la consegna di email reale. |
SMTP_TLS | Uno di starttls (predefinito), tls o none. |
DEFAULT_ORG_NAME, DEFAULT_ORG_SLUG | Opzionale. Date all’organizzazione incorporata default un nome di visualizzazione amichevole e uno slug URL in modo che risieda ad es. in /acme anziché in /default. Applicato solo al primo avvio; una volta che rinominate l’organizzazione con agenteye-orgctl org rename (consultate §7.6) questi vengono ignorati. Lo slug deve essere 1-40 alfanumerici minuscoli con singoli trattini interni. Lasciate entrambi non impostati per mantenere il default generico. |
Memorizzate le credenziali SMTP nel vostro gestore di segreti.Testate:
2.6 Chiave di isolamento organizzazione multi-tenant (opzionale)
Saltate questo per un deployment a tenant singolo; il server funziona su un default incorporato dev e serve bene l’unica organizzazionedefault. Prima di creare una seconda organizzazione, impostate un forte e stabile ORG_CH_SECRET: la password ClickHouse di ogni organizzazione è derivata come HMAC(ORG_CH_SECRET, org_id), quindi il default dev pubblicamente noto produrrebbe credenziali per organizzazione pubblicamente derivabili. Il comando agenteye-orgctl org create (consultate §7.6 Provisioning di organizzazioni) rifiuta di eseguire mentre il server è ancora sul default dev incorporato.
secretKeyRef opzionale, quindi un cluster a tenant singolo che non lo crea mai si avvia comunque normalmente. Mantenete il valore stabile e identico su tutte le repliche; ruotarlo invalida la password ClickHouse derivata di ogni organizzazione finché il riconcile di avvio non ri-provisioning gli utenti (un riavvio rotante con il valore coerente ovunque lo guarisce). Consultate deploy/base/server/secret.example.yaml.
Memorizzate ORG_CH_SECRET nel vostro gestore di segreti e non rotelatelo casualmente.
2.7 Verificare tutti i secret
agenteye-admin-key, agenteye-auth, agenteye-image-pull, agenteye-postgres) devono essere presenti prima di continuare. agenteye-org-ch-secret è richiesto solo per deployment multi-tenant (consultate §2.6).
Fase 3 — Distribuire l’Applicazione (~5 min)
3.1 Configurare gli hostname pubblici
cert-manager ha bisogno degli hostname di acquisizione e della dashboard prima di poter richiedere i loro certificati Let’s Encrypt. Copiate il modello e impostate entrambi:domain.env è gitignored; rimane locale a ogni deployment. Il build kustomize non riesce in modo evidente se una delle due chiavi è mancante.
Il DNS deve risolvere prima. Non dovete puntare il DNS ai LB ancora (non esistono fino al completamento della Fase 1.2), ma l’emissione ACME nel passaggio 3.2 ripeterà il tentativo finché ogni hostname non si risolva al suo LoadBalancer. Potete impostare il DNS ora (usando i nomi host LB catturati nella Fase 1.4) o procedere e aggiungere i record nella Fase 4.
3.2 Applicare i manifest
Applicate la base direttamente per un’installazione pulita, o un overlay se ne avete ritagliato uno per questo ambiente (gli overlay fissano solo tag immagini, variabili env e limiti di risorse; ereditano i certificati e il routing della base):3.3 Aspettare i pod
agent (assistente AI) e redis vengono avviati insieme a loro; l’assistente rimane inerte fino a quando non fornite il suo endpoint LLM (consultate enterprise-docs/assistant.md), e Redis è una cache best-effort, quindi nessuno dei due ha bisogno di essere Ready affinché la piattaforma serva il traffico.
Testate:
agent e redis compaiono anche e raggiungono Running):
| Stato Pod | Causa probabile | Comando di Debug |
|---|---|---|
ImagePullBackOff | Secret di pull dell’immagine scadente o PAT | kubectl describe pod <name> -n agenteye |
CrashLoopBackOff | Variabili d’ambiente scadenti (ad es. DATABASE_URL) | kubectl logs <name> -n agenteye |
Pending | CPU/memoria insufficiente o nessun nodo | kubectl describe pod <name> -n agenteye (controllate Events) |
3.4 Verificare l’archiviazione
Bound:
| PVC | Capacità | Supporta |
|---|---|---|
postgres-data-postgres-0 | 50Gi | Archivio relazionale/metadati PostgreSQL |
clickhouse-data-clickhouse-0 | 100Gi | Archivio di analisi degli eventi ClickHouse + valutazioni |
redis-data-redis-0 (1Gi) appare anche per la cache opzionale.
Se non riesce: Pending significa che nessuna StorageClass può provisioning il volume. Controllate kubectl get storageclass e assicuratevi che esista un’impostazione predefinita. Per la produzione, applicate il volume ClickHouse a una StorageClass SSD veloce (ad es. gp3 su AWS, pd-ssd su GCP); la velocità di compattazione soffre su dischi lenti.
3.5 Verificare i certificati
Ready: True:
| Nome | Emittente | Scopo |
|---|---|---|
mtls-ca | selfsigned | CA privata per l’emissione di certificati client mTLS (validità 10 anni) |
ingest-tls | letsencrypt-prod | Certificato TLS pubblico per l’endpoint di acquisizione (90 giorni, rinnovato automaticamente) |
dashboard-tls | letsencrypt-prod | Certificato TLS pubblico per la dashboard (90 giorni, rinnovato automaticamente) |
ingest-tls o dashboard-tls non è Ready:
kubectl describe certificate <name> -n agenteye e leggete gli Events. Le cause comuni:
- DNS non ancora puntato al LB. Let’s Encrypt risolve l’hostname e colpisce la porta 80 per convalidare —
INGEST_DOMAINdeve risolvere al LB pubblico,DASHBOARD_DOMAINal LB della dashboard. Fino a quando il CNAME/Alias non si propaga, l’ordine rimanepending. Una volta che il DNS è corretto, cert-manager ritenta automaticamente (non è necessario eliminare il Certificate). - Hostname non sostituito. Se
dnsNamescontinua a leggereINGEST_DOMAIN_PLACEHOLDER/DASHBOARD_DOMAIN_PLACEHOLDER, avete saltato il passaggio 3.1 — createbase/certificates/domain.enve ri-applicate. - Il Traefik della dashboard non può servire la sfida (
dashboard-tlssolo). L’istanza Traefik della dashboard deve essere installata con il file di valori incluso (Fase 1.2), che abilita il provider Ingress scoped che serve il risolutore HTTP-01 di cert-manager. Un’istanza installata senza di esso lascia la sfida non instradabile e l’ordinependingper sempre.
mtls-ca non è Ready: cert-manager stesso non è salubre. Ri-controllate i pod cert-manager dal passaggio 1.1.
3.6 Verificare i CronJob
| Nome | Pianificazione | Scopo |
|---|---|---|
agenteye-backup | 0 3 * * * | Backup giornaliero di Postgres + ClickHouse alle 03:00 UTC |
cert-renewal-check | 0 3,15 * * * | Avvisi di scadenza certificato alle 03:00 e 15:00 UTC |
3.7 Verificare che il server sia stato avviato correttamente
POSTGRES_PASSWORD contenente caratteri non sicuri per URL che interrompono DATABASE_URL. Consultate enterprise-docs/troubleshooting.md.
3.8 Verificare che la dashboard sia connessa al server
Ready nell’output senza errori ECONNREFUSED o simili.
Se non riesce: verificate che il Service server esista (kubectl get svc server -n agenteye) e che AGENTEYE_SERVER_URL sia impostato su http://server:8080 nel deployment della dashboard.
Fase 4 — Accesso di rete (~5 min)
4.1 Recuperare gli indirizzi LoadBalancer
Su AWS EKS, i LoadBalancer restituiscono un hostname invece di un IP. SostituiteTestate:.ipcon.hostnamenei comandi di cui sopra.
4.2 Puntare DNS ai LoadBalancer
Create record DNS in modo che gli hostname dabase/certificates/domain.env si risolvano ai loro LoadBalancer — INGEST_DOMAIN al LB Traefik pubblico, DASHBOARD_DOMAIN al LB Traefik della dashboard:
- AWS Route 53: record
AconAlias = Yes, target = hostname LB. Non usate A semplice → IP; gli IP ELB ruotano. - Qualsiasi altro provider:
CNAMEdall’hostname all’hostname LB.
$PUBLIC_IP e $INTERNAL_IP rispettivamente (o, su EKS, risolvere agli stessi hostname *.elb.amazonaws.com).
Una volta che il DNS si risolve, cert-manager termina gli ordini ACME in sospeso dalla Fase 3.5 entro un minuto. Ri-eseguite kubectl get certificates -n agenteye finché sia ingest-tls che dashboard-tls non mostrano Ready: True.
4.3 Raggiungere l’endpoint di acquisizione
L’endpoint di acquisizione pubblico applica TLS reciproco, quindi ogni richiesta (incluso/health) deve presentare un certificato client. Emettete il vostro primo certificato client nella Fase 5; se ne avete uno già, verificate la raggiungibilità ora:
{"status":"ok"}. Non è necessario -k — il certificato del server è vincolato a una CA pubblica per INGEST_DOMAIN, quindi si convalida rispetto all’archivio di trust del sistema. Raggiungete l’endpoint di acquisizione dal suo hostname INGEST_DOMAIN (che corrisponde al certificato emesso), non dall’IP/hostname del LoadBalancer raw.
L’endpoint della dashboard è servito su DASHBOARD_DOMAIN con un certificato pubblicamente attendibile e non è dietro mTLS, quindi non -k e nessun certificato client è necessario:
DASHBOARD_DOMAIN, quindi l’indirizzo raw mostra una mancata corrispondenza del nome del certificato.
Se non riesce: se curl blocca, controllate che il LB sia raggiungibile dalla vostra macchina (VPN, security group, regole firewall). Un errore di handshake certificate required sull’hostname di acquisizione significa che nessun certificato client è stato presentato; completate prima la Fase 5. Un errore di convalida TLS sull’hostname di acquisizione significa che il certificato del server non ha finito di essere emesso; tornate a Fase 3.5 e risolvete il problema lì.
Fase 5 — Emettere Certificati Client mTLS (~10 min per cluster)
I collector si autenticano con due fattori: un certificato client (livello di trasporto, prove che la richiesta proviene da un cluster autorizzato) e una chiave API (livello applicazione, prova che la richiesta proviene da un collector con permessoevents:add). Una chiave persa è inutile senza il certificato; un certificato rubato è inutile senza una chiave valida.
5.1 Emettere un certificato
Ogni cluster che esegue collector ha bisogno del suo certificato client. Dalla directory dei manifest:<cluster-name> con un identificatore significativo (ad es. us-east-1-prod, staging).
Testate: lo script stampa ==> Done! ed elenca i file di output.
Ready: True.
File di output in issued/<cluster-name>/:
| File | Scopo |
|---|---|
client.crt | Certificato client (validità 90 giorni) |
client.key | Chiave privata client |
ca.crt | Certificato CA per la verifica del server |
collector-mtls-secret.yaml | Secret Kubernetes pronto da applicare per il cluster del collector |
5.1b Consegna alternativa: AWS Secrets Manager
Se il consumer del certificato è un Pod Kubernetes che ha bisogno diclient.crt e client.key su disco — il caso tipico quando eseguite il agenteye-collector come sidecar nel vostro pod applicazione — spingete il bundle del certificato in AWS Secrets Manager. Il pod dell’applicazione lo monta quindi tramite il Secrets Store CSI Driver con IRSA, e la rotazione del certificato è completamente senza mani.
PutSecretValue sullo stesso secret, quindi l’ARN e il nome rimangono stabili. Il CSI Driver raccoglie la nuova versione al suo prossimo poll di rotazione e riscrive i file all’interno del pod.
Prerequisiti:
awsCLI v2 autenticato al vostro account AWS.jqinstallato.- Variabile d’ambiente
AWS_REGIONimpostata. - Permessi IAM sulla vostra identità di caller (ambito
Resourceaarn:aws:secretsmanager:<region>:<account>:secret:agenteye/mtls-client/*):secretsmanager:CreateSecretsecretsmanager:DescribeSecretsecretsmanager:PutSecretValuesecretsmanager:TagResource
| Passaggio | Azione |
|---|---|
| 1 | Emette / ri-estrae il certificato tramite cert-manager (uguale alla modalità predefinita). |
| 2 | Chiama DescribeSecret su agenteye/mtls-client/<cluster-name> per decidere creare-vs-aggiornare. |
| 3 | Al primo avvio: CreateSecret con un payload JSON a tre chiavi (client.crt, client.key, ca.crt), taggato AgentEyeCluster=<cluster-name>. Sui successivi avvii: PutSecretValue per pubblicare una nuova versione; tag aggiornato tramite TagResource. |
| 4 | Cancella issued/<cluster-name>/ solo dopo un caricamento riuscito. In caso di errore, la directory viene conservata in modo che possiate ritentare. |
aws secretsmanager restore-secret --secret-id agenteye/mtls-client/<cluster-name> prima di ritentare.
Per il cablaggio completo del pod (SecretProviderClass, setup IRSA, comportamento di rotazione, troubleshooting) consultate enterprise-docs/single-pod-deployment.md.
5.2 Verificare che il certificato funzioni
Testate il certificato emesso rispetto all’ingresso mTLS:{"status":"ok"}
Se non riesce:
| Errore | Causa | Correzione |
|---|---|---|
certificate required | Certificato non presentato | Controllate i percorsi file nel comando curl |
bad certificate | Mancata corrispondenza CA | Verificate che mtls-ca-issuer abbia emesso il certificato: kubectl describe certificate mtls-client-<name> -n agenteye |
connection refused | Hostname sbagliato o LB non raggiungibile | Controllate /etc/hosts o DNS |
5.3 Consegnare al cluster del collector
Inviatecollector-mtls-secret.yaml al team che gestisce il cluster del collector. Loro lo applicano:
client.crt, client.key, ca.crt).
5.4 Ciclo di vita del certificato
| Proprietà | Valore |
|---|---|
| Validità certificato client | 90 giorni |
| Auto-rinnovo | cert-manager rinnova 15 giorni prima della scadenza |
| Validità CA | 10 anni |
| Avvisi di scadenza | CronJob avvisa 30 giorni prima della scadenza (Fase 6) |
issue-client-cert.sh e ri-applicate collector-mtls-secret.yaml prima che il vecchio certificato scada.
Se state usando --save-to aws-secrets-manager (consultate § 5.1b), ri-eseguite lo stesso comando. Lo script chiama PutSecretValue sullo stesso secret; i pod che montano il secret tramite il Secrets Store CSI Driver raccolgono la nuova versione al loro prossimo poll di rotazione (predefinito: ogni ora), senza riavvio del pod richiesto.
5.5 Revocare un certificato
Per bloccare immediatamente l’accesso del collector di un cluster:curl dal passaggio 5.2 ora non riesce con un errore di handshake TLS.
Fase 6 — Monitoraggio del Rinnovo dei Certificati (~2 min)
Un CronJob incorporato viene eseguito ogni 12 ore (03:00 e 15:00 UTC) e controlla tutti i certificati client etichettati comeagenteye.io/cert-type=mtls-client. Avvisa quando un certificato è entro 30 giorni dalla scadenza.
6.1 Abilita notifiche Slack (opzionale)
6.2 Testare il CronJob
get, list su risorse Certificate di cert-manager. Verificate con: kubectl describe role cert-renewal-check -n agenteye.
Pulite il job di test:
Fase 7 — Verificare End-to-End
Questa fase conferma che l’intero pipeline funziona: controllo di salute, creazione della chiave, acquisizione di eventi e visualizzazione della dashboard.Nota: gli esempi di seguito raggiungono l’endpoint di acquisizione dal suo indirizzo LoadBalancer raw (${PUBLIC_IP}) per comodità, motivo per cui passano-k; il certificato del server è vincolato aINGEST_DOMAIN, non all’IP LB, quindi il controllo del nome host è saltato. L’endpoint di acquisizione applica TLS reciproco su ogni percorso, quindi ogni chiamata deve presentare un certificato client (--cert/--key). Per convalidare il certificato pubblico pure, puntate ahttps://ingest.your-company.example/...anziché${PUBLIC_IP}e lasciate cadere-k.
7.1 Controllo di salute
{"status":"ok"} con HTTP 200.
7.2 Creare chiavi collector limitate
La chiave admin è per il bootstrap e la gestione. Create chiavi dedicateevents:add per i collector:
"id", "name": "prod-collector", "permissions": ["events:add"], "created_at".
Testate: verificate che la chiave appaia nell’elenco di chiavi:
prod-collector appare nella risposta.
Consultate enterprise-docs/api-keys.md per il riferimento di gestione completo delle chiavi.
7.3 Acquisire un evento di test
{"accepted":1,"skipped":0} con HTTP 200.
Se non riesce:
| Codice di stato HTTP | Causa |
|---|---|
| 401 | Chiave API non valida o mancante |
| 403 | La chiave manca del permesso events:add |
| Errore di handshake TLS | Problema del certificato client — consultate il troubleshooting della Fase 5 |
7.4 Verificare che l’evento appaia nella dashboard
Apritehttps://agenteye.your-company.example (il vostro DASHBOARD_DOMAIN) in un browser. Il certificato è pubblicamente attendibile, quindi non c’è avviso.
Se il LoadBalancer della dashboard è limitato dall’allowlist IP e non potete connettervi, verificate che il vostro IP sia consentito:Testate: l’evento smoke-test dovrebbe apparire nell’elenco di eventi con sessioneRicordate che Let’s Encrypt rinnova il certificato della dashboard su HTTP-01 sulla porta 80, e gli intervalli di origine si applicano all’intero LoadBalancer — prima di limitarlo agli intervalli aziendali, coordinare un risolutore DNS-01 con il supporto o i rinnovi non riescono silenziosamente.
test e agent smoke-test.
Se non riesce: controllate i log della dashboard (kubectl logs -n agenteye -l app=dashboard --tail=50). Verificate che AGENTEYE_SERVER_URL e AGENTEYE_API_KEY siano impostati correttamente.
7.5 Testare il CronJob di backup
Backup created: agenteye-YYYYMMDD-HHMMSS.tar.gz (NNN) nei log; l’archivio raggruppa il dump di Postgres e le tabelle ClickHouse.
Il passaggio di caricamento S3 è cablato nella CronJob e viene eseguito ogni volta chePulite:BACKUP_BUCKETè impostato (la base spedisce un valore di bucket predefinito). Viene saltato solo quandoBACKUP_BUCKETè vuoto o letteralmentePLACEHOLDER. Puntatealo al vostro bucket proprio e concedete al ServiceAccountagenteye-backupl’accesso in scrittura prima di fare affidamento su di esso (consultate la sezione Backup di seguito).
7.6 Provisioning di organizzazioni (multi-tenant)
Saltate questo per un deployment a tenant singolo; tutti i dati risiedono nell’organizzazionedefault incorporata e nulla qui è richiesto.
Se state eseguendo più tenant isolati, le organizzazioni e le loro appartenenze vengono create con la CLI agenteye-orgctl. Viene fornita all’interno dell’immagine del server (insieme a agenteye-server) e lo eseguite all’interno del Deployment server esistente con kubectl exec; non c’è un pod, Job o Deployment separato, e nessuna API HTTP o pulsante della dashboard per il ciclo di vita del tenant.** L’esecuzione nel pod del server significa che riusa DATABASE_URL, CLICKHOUSE_URL e il ORG_CH_SECRET dal pod §2.6.
Prerequisito: completate prima §2.6.Creare un’organizzazione e aggiungere il suo primo admin:org createrifiuta di eseguire mentre il server è ancora sulORG_CH_SECRETdev incorporato, e l’utente ClickHouse per organizzazione che provisioning dipende da quel secret essendo forte e stabile.
/acme/...).
Altri comandi (eseguiti nello stesso modo kubectl -n agenteye exec deploy/server -- agenteye-orgctl …):
| Comando | Cosa fa |
|---|---|
org list | Elenca le organizzazioni e il loro stato. |
org rename --slug <slug> --name <new name> | Rinomina un’organizzazione (slug invariato). |
org delete --slug <slug> | Soft-delete + rilascia l’utente ClickHouse dell’organizzazione; dati conservati. |
org purge --slug <slug> | Wipe dei dati irreversibile; l’organizzazione deve essere prima deleted; mai l’organizzazione default. |
member list --org <slug> | Elenca i membri e i loro permessi. |
member update --org <slug> --email <email> [--set ...] [--add ...] [--remove ...] | Modificare i permessi di un membro. |
member remove --org <slug> --email <email> | Rimuovere un membro dall’organizzazione. |
admin, standard e read-only. Le chiavi API per organizzazione sono comunque coniate nella dashboard/API dai membri dell’organizzazione (il §7.2 mostra l’API delle chiavi); solo il ciclo di vita dell’organizzazione + membro è solo per l’operatore. Riferimento completo e un esempio funzionante: enterprise-docs/tenant-management.md.
Checklist Post-Deployment
Usate questa checklist per confermare che tutto funziona. Ogni elemento dovrebbe essere controllato prima di consegnare ai collector.- Tutti i pod
Runningnello spazio dei nomiagenteye - PVC PostgreSQL bound (50Gi) e PVC ClickHouse bound (100Gi)
- Tutti e 3 i certificati
Ready: True - Entrambi gli IP LoadBalancer assegnati
- DNS o
/etc/hostsconfigurato e che si risolve -
/healthrestituisce HTTP 200 - Test del certificato mTLS superato (
curlcon certificato client a/health) - Chiave collector scoped creata e testata
- Evento di test acquisito (
accepted: 1) - Evento visibile nella dashboard
- Certificati client emessi per ogni cluster del collector
- CronJob di backup testato manualmente
- CronJob di rinnovo certificato testato manualmente
- Webhook Slack per avvisi di certificato configurato (opzionale)
- Bucket di backup configurato nell’overlay (consultate di seguito)
- Chiave admin e password Postgres memorizzate nel gestore di segreti
Backup
Un singoloagenteye-backup CronJob viene eseguito ogni giorno alle 03:00 UTC. Esegue il dump di entrambi gli archivi: PostgreSQL (stato relazionale) e ClickHouse (le tabelle di analisi events + evaluations), in un archivio compresso nel pod, quindi lo carica nello spazio di archiviazione che controllate nell’overlay.
Ogni esecuzione produce un oggetto, agenteye-<timestamp>.tar.gz, che si decomprime in:
agent_sessions, gli alias analytics.*) e le politiche di riga all’avvio, quindi quelle tabelle sono l’immagine completa.
Configurare il caricamento cloud
Il CronJob di backup viene fornito con il passaggio di caricamento S3 (aws s3 cp)
