OpenShift Logging 6.x con LokiStack
OpenShift Logging 6.x con LokiStack
Target: amministratori OpenShift che vogliono capire davvero come funziona OpenShift Logging 6.x, come si installa, quali CRD contano, come leggere e scrivere le Custom Resource, come ridurre il volume dei log, come fare tuning su Loki e come verificare che tutto sia corretto.
Versione di riferimento: contenuti allineati alla documentazione ufficiale Red Hat OpenShift Logging 6.4 e alla relativa documentazione di installazione/configurazione disponibile a oggi.
Indice
- Obiettivo del corso
- Come ragionare su OpenShift Logging 6
- Architettura logica
- Operatori coinvolti e ordine corretto di installazione
- Le CRD e le risorse che contano davvero
- ClusterLogForwarder: anatomia completa
- LokiStack: anatomia completa
- UIPlugin: come esporre i log nella console
- LogFileMetricExporter: a cosa serve e quando va creato
- AlertingRule e RecordingRule su Loki
- Strategia corretta per ridurre il volume dei log
- Esempio completo: CLF con drop di namespace rumorosi e debug/trace
- Esempio completo: tuning LokiStack per errori 429
- Esempio completo: filtro audit mirato
- Installazione e bootstrap minimo end-to-end
- Comandi di verifica e troubleshooting
- Errori concettuali più comuni
- Best practice operative
- Appendice: YAML pronti all’uso
- Riferimenti ufficiali Red Hat
1. Obiettivo del corso
OpenShift Logging 6.x non va pensato come “un unico prodotto con una sola CR”, ma come un insieme di componenti separati, ciascuno con una responsabilità precisa:
- raccolta dei log dal cluster;
- normalizzazione ed eventualmente filtraggio/trasformazione;
- instradamento dei log verso una o più destinazioni;
- storage dei log nel log store;
- visualizzazione e query via console OpenShift;
- metriche e regole collegate ai log.
La chiave per amministrarlo bene è separare mentalmente tre piani:
- collector plane → raccoglie e inoltra i log;
- storage plane → conserva e serve i log;
- access/UI plane → permette di consultarli e governarne l’accesso.
In OpenShift Logging 6.x questa separazione è molto più chiara rispetto al passato.
2. Come ragionare su OpenShift Logging 6
2.1 Il cambio di paradigma rispetto a Logging 5.x
In Logging 6, la configurazione di raccolta e forwarding non sta più nel vecchio modello ClusterLogging come centro della configurazione funzionale: la documentazione ufficiale chiarisce che la configurazione di raccolta/instradamento passa alla nuova API observability.openshift.io, con ClusterLogForwarder come risorsa principale.
Questo significa, in pratica:
- il collector si governa dal
ClusterLogForwarder; - il log store Loki si governa dal
LokiStack; - la UI si governa dal
UIPlugin; - eventuali metriche da file di log si governano col
LogFileMetricExporter; - le regole di alerting/recording legate a Loki hanno CR dedicate.
2.2 Il collector supportato è uno solo
Logging 6 documenta esplicitamente che Vector è l’unico collector supportato. Questo è importante perché molti esempi “vecchi” presenti online si riferiscono a Fluentd, ma per l’operatività attuale la base di verità va ricondotta a Vector.
2.3 Loki in OpenShift Logging non è pensato come storico infinito
La documentazione RH sottolinea che la configurazione Loki fornita da OpenShift Logging è un log store short-term, pensato soprattutto per troubleshooting rapido e query su log recenti. Tradotto in termini architetturali: Loki va dimensionato e usato in modo realistico; se il tuo obiettivo è conservazione lunghissima, compliance o analytics storico massivo, devi ragionare con retention, object storage, policy di lifecycle e, in alcuni casi, forwarding verso sistemi esterni.
3. Architettura logica
3.1 Disegnino mentale
[Pod / Node / API / auditd / OVN] | v [Collector: Vector] | +-------+--------+ | filters/transforms | +-------+--------+ | [Pipelines CLF] | +----------+-----------+ | | v v[LokiStack] [Output esterni] | v[Query / Observe / UIPlugin / LogQL]3.2 I tre tipi logici di log
OpenShift Logging ragiona nativamente con tre categorie:
- application
- infrastructure
- audit
È fondamentale ricordare questo perché:
- i permessi di raccolta cambiano;
- le pipeline possono gestirli separatamente;
- la retention può essere diversa;
- l’accesso ai log può essere differenziato per tenant;
- spesso il tuning corretto richiede di separare i tre flussi.
3.3 Regola d’oro sulle pipeline
Se un tipo di log non ha una pipeline che lo prende in carico, quel tipo di log viene di fatto scartato. Questo è utilissimo quando vuoi ridurre volume e costo: il modo più drastico per non mandare un flusso da nessuna parte è semplicemente non definirgli una pipeline.
4. Operatori coinvolti e ordine corretto di installazione
Per avere uno stack coerente servono almeno:
- Loki Operator → gestisce il log store
LokiStack; - Red Hat OpenShift Logging Operator → gestisce raccolta e forwarding;
- Cluster Observability Operator (COO) → abilita la UI di osservabilità/logs.
4.1 Ordine corretto
La documentazione è chiara su due punti:
- Loki Operator va configurato prima del Logging Operator;
- Loki Operator e Logging Operator devono avere la stessa major/minor version.
4.2 Namespace tipici
openshift-operators-redhat→ tipicamente per il Loki Operator;openshift-logging→ tipicamente per Logging Operator,ClusterLogForwarder,LokiStack, service account del collector e risorse correlate.
4.3 Perché l’ordine conta davvero
Perché il collector deve avere un log store coerente verso cui spedire i dati. Se prima definisci la raccolta ma non esiste ancora un Loki funzionante, la configurazione è incompleta e finirai a inseguire errori che in realtà sono sintomi di bootstrap incompleto.
5. Le CRD e le risorse che contano davvero
Queste sono le risorse da conoscere bene.
5.1 ClusterLogForwarder (observability.openshift.io/v1)
È il cervello della raccolta e del forwarding. Qui definisci:
- service account del collector;
- scheduling/tolerations/resources del collector;
- inputs;
- filters;
- outputs;
- pipelines;
- network policy del collector;
- management state.
5.2 LokiStack (loki.grafana.com/v1)
È il log store. Qui definisci:
- size;
- storage e secret dell’object store;
- schema storage;
- tenancy mode;
- retention;
- limiti di ingestione;
- network policies;
- pod placement / template / hash ring.
5.3 UIPlugin (observability.openshift.io/v1alpha1)
Abilita la sezione log nella console OpenShift Observe e punta a uno specifico LokiStack.
5.4 LogFileMetricExporter (logging.openshift.io/v1alpha1)
Genera metriche a partire dai file di log prodotti dai container. Non è più deployato di default col collector: va creato esplicitamente se ti servono le metriche correlate, ad esempio nel campo Produced Logs della console.
5.5 AlertingRule e RecordingRule (loki.grafana.com/v1)
Permettono di definire regole LogQL per alerting e recording nel contesto Loki.
5.6 RBAC e ServiceAccount
Non sono CRD di Logging, ma fanno parte della soluzione:
ServiceAccountdel collector;RoleBinding/ClusterRoleBindingper lettura/scrittura dei log;- ruoli viewer per l’accesso ai tenant application/infrastructure/audit.
6. ClusterLogForwarder: anatomia completa
Il ClusterLogForwarder è la risorsa che un admin deve saper leggere “a colpo d’occhio”.
6.1 Schema concettuale
spec: managementState serviceAccount collector inputs filters outputs pipelines6.2 spec.managementState
Valori principali:
ManagedUnmanaged
Logica:
- con
Managed, l’Operator riconcilia e mantiene la configurazione; - con
Unmanaged, smette di intervenire e tu ti assumi il governo manuale dei componenti.
Best practice: quasi sempre Managed.
6.3 spec.serviceAccount
Definisce con quale service account gira il collector.
Esempio:
serviceAccount: name: logging-collectorDietro questa riga c’è il tema più importante: i permessi. Il collector può leggere solo ciò per cui ha i ruoli appropriati.
6.4 RBAC minimo tipico per il collector
oc create sa logging-collector -n openshift-logging
oc adm policy add-cluster-role-to-user logging-collector-logs-writer \ -z logging-collector -n openshift-logging
oc adm policy add-cluster-role-to-user collect-application-logs \ -z logging-collector -n openshift-logging
oc adm policy add-cluster-role-to-user collect-infrastructure-logs \ -z logging-collector -n openshift-logging
oc adm policy add-cluster-role-to-user collect-audit-logs \ -z logging-collector -n openshift-loggingNota importante: audit non viene raccolto automaticamente solo perché esiste l’input; servono anche i permessi adeguati.
6.5 spec.collector
Questa sezione governa il comportamento operativo dei pod del collector.
Campi più importanti:
resourcesnodeSelectortolerationsnetworkPolicy
Esempio
collector: resources: requests: cpu: 100m memory: 256Mi limits: cpu: 1 memory: 2Gi tolerations: - effect: NoSchedule key: node-role.kubernetes.io/infra networkPolicy: ruleSet: RestrictIngressEgressLogica dietro questi campi
- resources: servono a evitare throttling, OOM e backlog del collector;
- nodeSelector/tolerations: servono a decidere dove far girare Vector;
- networkPolicy: serve quando il cluster ha policy restrittive. Se non la definisci, l’Operator non crea automaticamente una
NetworkPolicyper il collector.
Valori documentati per collector.networkPolicy.ruleSet:
RestrictIngressEgressAllowAllIngressEgress
6.6 spec.inputs
Gli input definiscono quali log vengono selezionati all’ingresso.
Puoi usare:
- input predefiniti:
application,infrastructure,audit; - input custom, per esempio application namespace-scoped o receiver (
http,syslog).
Esempio application custom con include/exclude
inputs: - name: app-selected type: application application: includes: - namespace: "mio-namespace-*" excludes: - namespace: "mio-namespace-test" - container: "sidecar-noisy*"Logica
- usa
includesquando vuoi stringere il perimetro all’origine; - usa
excludesquando vuoi togliere eccezioni rumorose; excludesha precedenza suincludes.
Questo è spesso il modo migliore per ridurre volume senza toccare il contenuto del messaggio.
6.7 spec.filters
I filtri sono trasformazioni o policy applicate alle pipeline.
Tipi importanti:
dropdetectMultilineExceptionkubeAPIAudit- altri filtri/trasformazioni a seconda del caso documentato
Concetto essenziale
I filtri non lavorano da soli: vanno sempre agganciati a una pipeline con filterRefs.
6.8 drop filter
È il filtro giusto quando vuoi eliminare log non desiderati.
Semantica ufficiale molto importante:
- un test passa se tutte le condizioni del test sono vere;
- se un test passa, il record viene droppato;
- se ci sono più test, il record viene droppato se uno qualunque dei test passa;
- se manca un campo, quella condizione vale
false.
Questa logica è utilissima per filtri come .level=debug|trace, perché non rischi di buttare log solo perché il campo non esiste.
Esempio semplice
filters: - name: drop-debug-trace type: drop drop: - test: - field: .level matches: "(?i)^debug$" - test: - field: .level matches: "(?i)^trace$"6.9 detectMultilineException
Serve a ricomporre stack trace o eccezioni multilinea in un singolo evento logico.
È utilissimo con Java, ma non solo.
Esempio
filters: - name: detect-multiline type: detectMultilineException6.10 kubeAPIAudit
Serve a ridurre o modulare il rumore degli audit log Kubernetes/OpenShift.
Puoi definire:
omitStagesrules- livelli come
None,Metadata,RequestResponse
Logica
Questo filtro non serve a “fare query meglio”, ma a decidere quanta informazione vuoi conservare del traffico audit. È una leva molto potente sia sul volume sia sulla sensibilità del dato raccolto.
6.11 spec.outputs
Gli output definiscono dove mandare i log.
Tipi comuni:
lokiStackhttpsyslogkafka- altri output supportati in base alla versione/documentazione
Per il tuo caso, il più importante è lokiStack.
Esempio lokiStack
outputs: - name: default-lokistack type: lokiStack lokiStack: authentication: token: from: serviceAccount target: name: logging-loki namespace: openshift-logging tls: ca: configMapName: openshift-service-ca.crt key: service-ca.crtLogica
target.nameetarget.namespacedevono puntare alLokiStackgiusto;- l’autenticazione via token di service account è il pattern più comune in-cluster;
- la sezione
tlsserve per la trust chain del servizio ricevente.
6.12 spec.pipelines
Le pipeline sono il cuore del routing.
Una pipeline collega:
- inputRefs
- filterRefs (opzionali ma potentissimi)
- outputRefs
Esempio
pipelines: - name: to-default-loki inputRefs: - application - infrastructure filterRefs: - detect-multiline - drop-debug-trace outputRefs: - default-lokistackLogica fondamentale
L’ordine dei filtri conta. Se un filtro iniziale droppa un record, quel record non arriva ai filtri successivi né all’output.
7. LokiStack: anatomia completa
Il LokiStack è la risorsa che governa storage, query, tenancy e limiti.
7.1 Schema concettuale
spec: managementState size replicationFactor storage storageClassName tenants limits template networkPolicies hashRing7.2 metadata.name
Nella pratica OpenShift Logging il nome tipico è:
metadata: name: logging-loki namespace: openshift-loggingMolti esempi ufficiali usano proprio questo nome.
7.3 spec.size
Definisce il sizing Loki. Esempi tipici documentati includono taglie come 1x.extra-small, 1x.small, ecc.
Logica:
- non è solo “quanti log posso tenere”, ma un preset di capacità/risorse del cluster Loki;
- per produzione, la scelta del size deve essere allineata al volume reale e all’oggettistica sottostante.
7.4 spec.storage
È la sezione cruciale per il log store.
Esempio
storage: schemas: - effectiveDate: "2024-10-01" version: v13 secret: name: logging-loki-s3 type: s3storageClassName: gp3-csiLogica
schemasdefinisce schema e data di efficacia;secretcontiene credenziali/config dell’object storage;storageClassNameriguarda lo storage temporaneo locale necessario ai componenti Loki.
7.5 spec.tenants.mode
Per OpenShift Logging il valore tipico è:
tenants: mode: openshift-loggingQuesto abilita la modalità multi-tenant orientata ai tre flussi logici application, infrastructure, audit, con controllo accessi coerente.
7.6 Accesso ai log e ruoli viewer
L’Operator non concede a tutti l’accesso ai log di default. La documentazione indica ruoli predefiniti:
cluster-logging-application-viewcluster-logging-infrastructure-viewcluster-logging-audit-view
Puoi usarli con RoleBinding o ClusterRoleBinding in base al perimetro desiderato.
7.7 adminGroups
In modalità openshift-logging, puoi definire gruppi admin custom nel LokiStack.
Esempio
tenants: mode: openshift-logging openshift: adminGroups: - cluster-admin - custom-admin-groupServe quando vuoi accesso amministrativo ai log per gruppi specifici, senza distribuire ruoli ad-hoc in modo manuale ovunque.
7.8 spec.limits.retention
La retention in LokiStack è una leva molto utile, ma va capita bene.
Due concetti fondamentali
- puoi definire retention globale;
- puoi definire retention per tenant e anche per stream, usando selector LogQL.
Esempio globale
limits: global: retention: days: 20 streams: - days: 4 priority: 1 selector: '{kubernetes_namespace_name=~"test.+"}' - days: 1 priority: 1 selector: '{log_type="infrastructure"}'Attenzione
La documentazione precisa che questa retention non impatta la retention dell’object storage. Quindi devi coordinare:
- retention interna Loki;
- lifecycle policy dell’object storage.
7.9 spec.limits.global.ingestion
Questa sezione è centrale quando compaiono errori 429 Too Many Requests lato Loki.
Esempio
limits: global: ingestion: ingestionBurstSize: 16 ingestionRate: 8Logica precisa
ingestionBurstSize: hard limit per replica distributor, in MB, della massima dimensione di campione rate-limited accettata in un singolo push;ingestionRate: soft limit sul volume ingerito per secondo.
In pratica:
- se il push singolo è più grande del burst, viene rifiutato;
- se il flusso medio supera il rate, iniziano i problemi di throttling/429.
7.10 spec.networkPolicies
Per LokiStack puoi definire una policy set, ad esempio:
networkPolicies: ruleSet: RestrictIngressEgressValori documentati:
NoneRestrictIngressEgress
7.11 spec.template
Serve per personalizzare scheduling/placement dei vari componenti Loki.
È utile, per esempio, quando vuoi mettere i componenti Loki su nodi infra dedicati con nodeSelector e tolerations.
7.12 spec.hashRing
Può servire in ambienti dove il memberlist di Loki fallisce usando solo range IP privati. La documentazione mostra il caso in cui conviene usare instanceAddrType: podIP.
8. UIPlugin: come esporre i log nella console
La UI dei log nella sezione Observe passa tramite UIPlugin.
8.1 Esempio base
apiVersion: observability.openshift.io/v1alpha1kind: UIPluginmetadata: name: loggingspec: type: Logging logging: lokiStack: name: logging-loki logsLimit: 50 timeout: 30s schema: viaq8.2 Campi importanti
metadata.name: tipicamentelogging;spec.type: deve essereLogging;logging.lokiStack.name: deve puntare al tuo LokiStack;logsLimit: quante righe vuoi mostrare di default;timeout: timeout query UI;schema: può essereotel,viaq, oselect.
8.3 Logica dietro schema
viaq: ottimo se lavori col modello classico OpenShift logging;otel: utile quando stai spingendo verso il data model OpenTelemetry;select: lascia scegliere in UI.
9. LogFileMetricExporter: a cosa serve e quando va creato
Il LogFileMetricExporter non è più deployato di default. Se vuoi metriche derivate dai log prodotti dai container, lo devi creare tu.
9.1 Quando ti serve
- vuoi vedere il campo Produced Logs nella dashboard;
- vuoi metriche di volume prodotte dai file di log;
- vuoi una base più concreta per capacity planning del logging.
9.2 Esempio base
apiVersion: logging.openshift.io/v1alpha1kind: LogFileMetricExportermetadata: name: instance namespace: openshift-loggingspec: nodeSelector: {} resources: limits: cpu: 500m memory: 256Mi requests: cpu: 200m memory: 128Mi tolerations: []9.3 Network policy del metric exporter
Se il cluster usa policy restrittive, puoi definire anche qui spec.networkPolicy.ruleSet con valori documentati come:
AllowAllIngressEgressAllowIngressMetrics
9.4 Troubleshooting: perché la dashboard mostra No datapoints found
Il caso più comune è questo:
- la query Prometheus è corretta;
- ma il
LogFileMetricExporternon è stato ancora creato; - quindi metriche come
log_logged_bytes_totalnon esistono ancora nel cluster.
Questo comportamento è coerente con la logica del prodotto: il LogFileMetricExporter non viene deployato di default, quindi va creato manualmente solo quando servono metriche di volume dei log.
Punto chiave da ricordare
C’è una differenza importante tra:
- CRD/API disponibile ma nessuna CR creata
In questo caso devi solo creare la risorsaLogFileMetricExporter. - CRD/API non disponibile proprio nel cluster
In questo caso non puoi creare la CR finché non chiarisci lo stato reale dell’Operator o delle CRD installate.
Attenzione al nome della resource
Quando fai i test CLI, usa il nome risorsa al plurale:
oc get logfilesmetricexporters.logging.openshift.io -APer capire se l’API esiste davvero:
oc api-resources | grep -i logfileoc get crd | grep -i logfileSe l’API esiste ma non hai ancora creato alcuna CR, vedrai semplicemente che non ci sono risorse.
Se invece il server risponde che il tipo risorsa non esiste, allora il problema non è la query PromQL: manca la CRD/API nel cluster.
Verifiche operative dopo la creazione della CR
Dopo aver creato la CR, controlla che partano i pod dedicati:
oc get pods -n openshift-logging -l app.kubernetes.io/component=logfilesmetricexporterPoi prova la metrica in quest’ordine:
log_logged_bytes_totalrate(log_logged_bytes_total[5m])topk(10, round(rate(log_logged_bytes_total[5m])))Questa sequenza è utile perché, se l’exporter è appena partito, la rate() potrebbe non avere ancora abbastanza campioni nei primi minuti.
Diagnosi rapida consigliata
oc api-resources | grep -i logfileoc get logfilesmetricexporters.logging.openshift.io -Aoc get pods -n openshift-logging -l app.kubernetes.io/component=logfilesmetricexporteroc get pods -n openshift-logging -l app.kubernetes.io/component=collectorInterpretazione:
- API presente + nessuna CR → crea la CR.
- API presente + CR presente ma nessun pod → problema di scheduling, risorse, tolerations o policy.
- API assente → verifica installazione/versione del Red Hat OpenShift Logging Operator e lo stato delle CRD.
10. AlertingRule e RecordingRule su Loki
Queste risorse servono per trasformare query LogQL in oggetti operativi.
10.1 AlertingRule
Usala quando vuoi scatenare un alert a partire dai log.
Casi d’uso
- numero di errori oltre soglia;
- pattern ricorrenti nei log applicativi;
- eventi di sicurezza;
- errori infrastrutturali ripetuti.
Nota importante
La documentazione delimita anche i namespace validi a seconda del tenant (application, infrastructure, audit). Quindi non basta scrivere una buona query: devi anche creare la risorsa nel namespace coerente.
10.2 RecordingRule
Usala quando vuoi registrare il risultato di una query come serie riutilizzabile.
Casi d’uso
- aggregazioni costose riusate spesso;
- semplificazione delle dashboard;
- basi per alert più leggibili.
11. Strategia corretta per ridurre il volume dei log
Questa è la parte più utile in pratica.
11.1 Regola aurea
Per ridurre volume e pressione su Loki, l’ordine corretto è:
- non raccogliere ciò che non serve;
- droppare il rumore noto;
- ridurre il dettaglio degli audit log;
- accorciare la retention dove opportuno;
- solo alla fine ritoccare
ingestionRate/ingestionBurstSizesu Loki.
11.2 Cosa NON fare come prima mossa
Non partire subito con tuning “cieco” di rate limit nel collector. Se hai ancora:
- namespace ultra-rumorosi;
- log
debug/traceinutili; - audit troppo dettagliato;
stai solo spostando il problema più a valle.
11.3 Prima leva: escludere namespace rumorosi
È quasi sempre la leva con miglior rapporto efficacia/rischio.
Esempi tipici:
- agenti di sicurezza;
- monitoraggi molto verbosi;
- storage operators molto chatty;
- namespace di test/lab.
11.4 Seconda leva: drop di debug e trace
È efficace solo se i log sono strutturati e hanno davvero un campo coerente, ad esempio:
.level.severity.log.level
Se il log è puro testo senza struttura, il filtro non farà match. Questo non è un problema: semplicemente non riduce quel flusso.
11.5 Terza leva: audit filter
Gli audit log possono crescere tantissimo.
Le tecniche più utili sono:
omitStages: ["RequestReceived"]level: Metadatadove non ti serve body request/responselevel: Noneper risorse notoriamente rumorose e poco rilevanti
11.6 Quarta leva: retention
Domanda tipica da farsi:
- tutti i log devono stare 20 giorni?
- i log application di ambienti test devono stare 4 ore, 1 giorno o 3 giorni?
- i log infrastructure davvero devono avere la stessa retention degli audit?
11.7 Quinta leva: tuning LokiStack
Quando compaiono 429, la documentazione RH indica chiaramente che i campi da ritoccare sono ingestionBurstSize e ingestionRate nel LokiStack.
Interpretazione pratica
- aumenti
ingestionBurstSizese singoli push sono troppo grossi; - aumenti
ingestionRatese il flusso medio supera il limite soft; - ma prima devi assicurarti che non stai ingestendo spazzatura evitabile.
12. Esempio completo: CLF con drop di namespace rumorosi e debug/trace
Questa è la configurazione più vicina al tuo caso pratico.
12.1 Obiettivo
- mantenere collector gestito;
- spedire tutto a
logging-loki; - ricomporre eccezioni multilinea;
- droppare
debug/tracedove esiste.level; - droppare namespace rumorosi
openshift-storage,sentinelone,zabbix.
12.2 CR completa
apiVersion: observability.openshift.io/v1kind: ClusterLogForwardermetadata: name: collector namespace: openshift-loggingspec: managementState: Managed
serviceAccount: name: logging-collector
collector: tolerations: - effect: NoSchedule key: node-role.kubernetes.io/infra - effect: NoSchedule key: node.ocs.openshift.io/storage value: "true"
filters: - name: detect-multiline type: detectMultilineException
- name: drop-debug-trace type: drop drop: - test: - field: .level matches: "(?i)^debug$" - test: - field: .level matches: "(?i)^trace$"
- name: drop-noisy-namespaces type: drop drop: - test: - field: .kubernetes.namespace_name matches: "^(openshift-storage|sentinelone|zabbix)$"
outputs: - name: default-lokistack type: lokiStack lokiStack: authentication: token: from: serviceAccount target: name: logging-loki namespace: openshift-logging tls: ca: configMapName: openshift-service-ca.crt key: service-ca.crt
pipelines: - name: enable-default-log-store inputRefs: - application - infrastructure - audit filterRefs: - detect-multiline - drop-debug-trace - drop-noisy-namespaces outputRefs: - default-lokistack12.3 Logica dietro questa CR
- il collector resta gestito dall’Operator;
- il service account è esplicito;
- i toleration mantengono il pattern di scheduling desiderato;
detect-multilinemigliora la leggibilità dei log applicativi con stack trace;drop-debug-tracetaglia il rumore dove il livello è strutturato;drop-noisy-namespaceselimina interi namespace rumorosi prima che arrivino a Loki;- una singola pipeline prende tutti i tre tipi di log e li manda al LokiStack.
12.4 Variante più raffinata
Se vuoi essere più preciso, puoi separare le pipeline per application, infrastructure e audit, così applichi filtri diversi ai tre flussi.
13. Esempio completo: tuning LokiStack per errori 429
Questa CR mostra solo la parte rilevante per il tuning di ingestione.
apiVersion: loki.grafana.com/v1kind: LokiStackmetadata: name: logging-loki namespace: openshift-loggingspec: managementState: Managed size: 1x.small storage: schemas: - effectiveDate: "2024-10-01" version: v13 secret: name: logging-loki-s3 type: s3 storageClassName: gp3-csi tenants: mode: openshift-logging limits: global: ingestion: ingestionBurstSize: 16 ingestionRate: 813.1 Come interpretare i numeri
Questi valori sono esempio di partenza, non valori universali.
Ragionamento operativo:
- se hai push singoli troppo grossi → alza prima
ingestionBurstSize; - se hai flusso medio costantemente oltre soglia → alza
ingestionRate; - se continui ad avere 429 ma stai ancora ingestendo log inutili → correggi prima il
ClusterLogForwarder.
13.2 Cosa osservare quando hai 429
Controlla:
- log del collector Vector;
- log degli ingester Loki;
- burst di volume in finestre brevi;
- eventuali namespace/tenant che dominano il traffico;
- pattern di backlog o retry.
14. Esempio completo: filtro audit mirato
Se vuoi ridurre il peso degli audit log, una CR in questo stile è spesso molto utile.
apiVersion: observability.openshift.io/v1kind: ClusterLogForwardermetadata: name: collector namespace: openshift-loggingspec: managementState: Managed serviceAccount: name: logging-collector
filters: - name: reduce-audit-noise type: kubeAPIAudit kubeAPIAudit: omitStages: - "RequestReceived" rules: - level: Metadata resources: - group: "" resources: ["pods/log", "pods/status"] - level: None resources: - group: "" resources: ["configmaps"] resourceNames: ["controller-leader"] - level: RequestResponse resources: - group: "" resources: ["pods"]
outputs: - name: default-lokistack type: lokiStack lokiStack: authentication: token: from: serviceAccount target: name: logging-loki namespace: openshift-logging tls: ca: configMapName: openshift-service-ca.crt key: service-ca.crt
pipelines: - name: audit-to-loki inputRefs: - audit filterRefs: - reduce-audit-noise outputRefs: - default-lokistack14.1 Quando usarlo
- audit ingest troppo voluminoso;
- necessità di ridurre dettaglio body request/response;
- casi in cui alcuni oggetti Kubernetes generano moltissimo rumore ma scarso valore operativo.
15. Installazione e bootstrap minimo end-to-end
Questa sezione ti dà una checklist ragionata.
15.1 Prerequisiti
- cluster admin;
- object storage supportato per Loki;
- namespace
openshift-loggingpronto; - installazione degli operatori corretta.
15.2 Sequenza consigliata
- installa Loki Operator;
- installa Red Hat OpenShift Logging Operator;
- installa Cluster Observability Operator se vuoi la UI Observe;
- crea il secret dell’object storage per Loki;
- crea il
LokiStack; - crea il service account del collector;
- assegna i ruoli al collector;
- crea il
UIPlugin; - crea il
ClusterLogForwarder; - opzionalmente crea il
LogFileMetricExporter.
15.3 Esempio minimale di LokiStack
apiVersion: loki.grafana.com/v1kind: LokiStackmetadata: name: logging-loki namespace: openshift-loggingspec: managementState: Managed size: 1x.extra-small storage: schemas: - effectiveDate: "2024-10-01" version: v13 secret: name: logging-loki-s3 type: s3 storageClassName: gp3-csi tenants: mode: openshift-logging15.4 Esempio minimale di UIPlugin
apiVersion: observability.openshift.io/v1alpha1kind: UIPluginmetadata: name: loggingspec: type: Logging logging: lokiStack: name: logging-loki logsLimit: 50 timeout: 30s schema: viaq15.5 Esempio minimale di ClusterLogForwarder
apiVersion: observability.openshift.io/v1kind: ClusterLogForwardermetadata: name: collector namespace: openshift-loggingspec: managementState: Managed serviceAccount: name: logging-collector outputs: - name: default-lokistack type: lokiStack lokiStack: authentication: token: from: serviceAccount target: name: logging-loki namespace: openshift-logging tls: ca: configMapName: openshift-service-ca.crt key: service-ca.crt pipelines: - name: all-to-loki inputRefs: - application - infrastructure outputRefs: - default-lokistackSe vuoi anche gli audit, devi:
- dare il ruolo
collect-audit-logsal service account; - aggiungere
auditininputRefs.
16. Comandi di verifica e troubleshooting
16.1 Verifica operatori e CRD
oc get csv -A | egrep 'logging|loki|observability'oc api-resources | egrep 'ClusterLogForwarder|LokiStack|UIPlugin|LogFileMetricExporter|AlertingRule|RecordingRule'16.2 Verifica LokiStack
oc get lokistack -n openshift-loggingoc describe lokistack logging-loki -n openshift-loggingoc get pods -n openshift-logging | egrep 'loki|gateway|ingester|distributor|querier|query-frontend|compactor|index-gateway|ruler'16.3 Verifica ClusterLogForwarder
oc get clusterlogforwarder -n openshift-loggingoc get clusterlogforwarder collector -n openshift-logging -o yaml16.4 Verifica pod collector
oc get pods -n openshift-logging -l component=collectoroc logs -n openshift-logging -l component=collector --since=30m16.5 Cerca errori 429 / retry / TLS
oc logs -n openshift-logging -l component=collector --since=30m | egrep -i '429|too many requests|retry|tls|error|warn'oc logs -n openshift-logging -l app.kubernetes.io/component=ingester --since=30m | egrep -i '429|rate limit|error|warn'16.6 Verifica UI plugin
oc get uiplugin logging -A -o yaml16.7 Verifica metric exporter
oc get logfilemetricexporter -n openshift-loggingoc get pods -n openshift-logging -l app.kubernetes.io/component=logfilesmetricexporter17. Errori concettuali più comuni
17.1 “Aggiungo rate limit nel collector e risolvo tutto”
No. Se stai ingerendo rumore inutile, stai solo mettendo un cerotto in un punto sbagliato.
17.2 “Il filtro drop su .level mi dropperà anche i log senza campo level”
No. La documentazione chiarisce che, se il campo non esiste, la condizione fallisce e vale false.
17.3 “Se definisco output ma non pipeline, il log arriva lo stesso”
No. L’output senza pipeline non viene usato.
17.4 “Se metto retention in LokiStack ho sistemato anche l’object storage”
No. La retention interna Loki non sostituisce la policy di lifecycle dell’object storage.
17.5 “Se la UI non mostra dati, Loki è rotto”
Non necessariamente. Potresti avere:
UIPluginmancante o mal configurato;- problemi di RBAC viewer;
- schema UI non coerente;
- query timeouts;
LogFileMetricExporterassente per alcune dashboard.
18. Best practice operative
18.1 Separa i flussi per categoria
In produzione conviene spesso avere pipeline separate:
applicationinfrastructureaudit
perché ti permettono di applicare filtri e policy diverse.
18.2 Togli rumore il prima possibile
Le esclusioni su input e i filtri drop precoci sono quasi sempre meglio del tuning del backend.
18.3 Mantieni YAML leggibili
Suggerimento pratico:
- nomi parlanti per
filters,outputs,pipelines; - una logica per blocchi;
- commenti solo dove servono davvero.
18.4 Verifica sempre con diff prima/dopo
Dopo ogni tuning chiediti:
- sono calati i volumi?
- sono spariti i 429?
- ho perso log importanti?
- ho ridotto solo il rumore o anche segnali utili?
18.5 Tieni distinti tre problemi diversi
- volume ingestito
- capacità di Loki
- retention/storage
Sono correlati, ma non sono la stessa cosa.
19. Appendice: YAML pronti all’uso
19.1 Service account e permessi collector
oc create sa logging-collector -n openshift-logging
oc adm policy add-cluster-role-to-user logging-collector-logs-writer \ -z logging-collector -n openshift-logging
oc adm policy add-cluster-role-to-user collect-application-logs \ -z logging-collector -n openshift-logging
oc adm policy add-cluster-role-to-user collect-infrastructure-logs \ -z logging-collector -n openshift-logging
oc adm policy add-cluster-role-to-user collect-audit-logs \ -z logging-collector -n openshift-logging19.2 LokiStack base
apiVersion: loki.grafana.com/v1kind: LokiStackmetadata: name: logging-loki namespace: openshift-loggingspec: managementState: Managed size: 1x.extra-small storage: schemas: - effectiveDate: "2024-10-01" version: v13 secret: name: logging-loki-s3 type: s3 storageClassName: gp3-csi tenants: mode: openshift-logging19.3 UIPlugin base
apiVersion: observability.openshift.io/v1alpha1kind: UIPluginmetadata: name: loggingspec: type: Logging logging: lokiStack: name: logging-loki logsLimit: 50 timeout: 30s schema: viaq19.4 LogFileMetricExporter base
apiVersion: logging.openshift.io/v1alpha1kind: LogFileMetricExportermetadata: name: instance namespace: openshift-loggingspec: nodeSelector: {} resources: limits: cpu: 500m memory: 256Mi requests: cpu: 200m memory: 128Mi tolerations: []19.5 ClusterLogForwarder minimale verso Loki
apiVersion: observability.openshift.io/v1kind: ClusterLogForwardermetadata: name: collector namespace: openshift-loggingspec: managementState: Managed serviceAccount: name: logging-collector outputs: - name: default-lokistack type: lokiStack lokiStack: authentication: token: from: serviceAccount target: name: logging-loki namespace: openshift-logging tls: ca: configMapName: openshift-service-ca.crt key: service-ca.crt pipelines: - name: app-infra-to-loki inputRefs: - application - infrastructure outputRefs: - default-lokistack19.6 ClusterLogForwarder tuned per rumore e debug/trace
apiVersion: observability.openshift.io/v1kind: ClusterLogForwardermetadata: name: collector namespace: openshift-loggingspec: managementState: Managed
serviceAccount: name: logging-collector
collector: tolerations: - effect: NoSchedule key: node-role.kubernetes.io/infra - effect: NoSchedule key: node.ocs.openshift.io/storage value: "true"
filters: - name: detect-multiline type: detectMultilineException
- name: drop-debug-trace type: drop drop: - test: - field: .level matches: "(?i)^debug$" - test: - field: .level matches: "(?i)^trace$"
- name: drop-noisy-namespaces type: drop drop: - test: - field: .kubernetes.namespace_name matches: "^(openshift-storage|sentinelone|zabbix)$"
outputs: - name: default-lokistack type: lokiStack lokiStack: authentication: token: from: serviceAccount target: name: logging-loki namespace: openshift-logging tls: ca: configMapName: openshift-service-ca.crt key: service-ca.crt
pipelines: - name: enable-default-log-store inputRefs: - application - infrastructure - audit filterRefs: - detect-multiline - drop-debug-trace - drop-noisy-namespaces outputRefs: - default-lokistack19.7 LokiStack con retention e tuning ingestione
apiVersion: loki.grafana.com/v1kind: LokiStackmetadata: name: logging-loki namespace: openshift-loggingspec: managementState: Managed size: 1x.small storage: schemas: - effectiveDate: "2024-10-01" version: v13 secret: name: logging-loki-s3 type: s3 storageClassName: gp3-csi tenants: mode: openshift-logging limits: global: ingestion: ingestionBurstSize: 16 ingestionRate: 8 retention: days: 20 streams: - days: 4 priority: 1 selector: '{kubernetes_namespace_name=~"test.+"}' - days: 1 priority: 1 selector: '{log_type="infrastructure"}'20. Riferimenti ufficiali Red Hat
Di seguito i riferimenti ufficiali usati come base del corso.
-
Installing logging | Red Hat OpenShift Logging 6.4
https://docs.redhat.com/en/documentation/red_hat_openshift_logging/6.4/html-single/installing_logging/index -
Configuring logging | Red Hat OpenShift Logging 6.4
https://docs.redhat.com/en/documentation/red_hat_openshift_logging/6.4/html-single/configuring_logging/index -
Configuring log forwarding | Red Hat OpenShift Logging 6.4
https://docs.redhat.com/en/documentation/red_hat_openshift_logging/6.4/html/configuring_logging/configuring-log-forwarding -
Configuring the log store | Red Hat OpenShift Logging 6.4
https://docs.redhat.com/en/documentation/red_hat_openshift_logging/6.4/html/configuring_logging/configuring-lokistack-storage -
About OpenShift logging | Red Hat OpenShift Logging 6.4
https://docs.redhat.com/en/documentation/red_hat_openshift_logging/6.4/html-single/about_openshift_logging/index -
Quick start | About OpenShift logging | Red Hat OpenShift Logging 6.4
https://docs.redhat.com/en/documentation/red_hat_openshift_logging/6.4/html/about_openshift_logging/quick-start -
Upgrading logging | Red Hat OpenShift Logging 6.4
https://docs.redhat.com/en/documentation/red_hat_openshift_logging/6.4/html-single/upgrading_logging/index
Conclusione
Se devo riassumere il corso in una frase:
ClusterLogForwarder decide cosa raccogliere, filtrare e dove inviarlo; LokiStack decide come conservarlo, servirlo e limitarlo.
Per ridurre il rumore:
- escludi i namespace inutili;
- droppa
debug/tracese i log sono strutturati; - riduci l’audit dove ha senso;
- abbassa la retention dove puoi;
- solo dopo fai tuning di
ingestionBurstSizeeingestionRate.
Questo è il percorso corretto, sia dal punto di vista architetturale sia dal punto di vista operativo.