Esaminiamo le basi dell'accesso a Docker e Kubernetes, quindi esaminiamo due strumenti che possono essere tranquillamente utilizzati in produzione: Grafana Loki e lo stack EFK (Elasticsearch + Fluent Bit + Kibana).
Il materiale dell'articolo è una compressione da . Se c'è un desiderio, e ancora di più se c'è un'esigenza di produzione, puoi seguire una formazione completa: iscriviti a un corso su .

Registrazione Docker
A livello di Kubernetes, le applicazioni vengono eseguite nei pod, ma a un livello inferiore continuano a funzionare normalmente in Docker. Pertanto, è necessario configurare la registrazione in modo tale da raccogliere i registri dai contenitori. I contenitori vengono lanciati da Docker, il che significa che devi capire come è organizzata la registrazione a livello di Docker.
Spero che ogni lettore lo sappia: i log dell'applicazione dovrebbero essere scritti in stdout / stderr e non all'interno del contenitore. I log vengono aggregati da Docker Daemon e funziona esattamente con quei log che vengono inviati a stdout/stderr. Inoltre, la scrittura di registri all'interno del contenitore è irta di problemi: il contenitore si gonfia dal registro in crescita (poiché molto probabilmente non c'è Logrotate nel contenitore) e il demone Docker non è a conoscenza di questo registro.
Docker ha diversi driver o plug-in di registrazione per la raccolta della registrazione del contenitore. La Docker Community Edition (CE) gratuita ha meno driver di registro rispetto alla Docker Enterprise Edition (EE) commerciale.

Non ho mai utilizzato Docker EE in pratica: in Southbridge cerchiamo di attenerci alle soluzioni Open Source e i clienti non hanno bisogno della maggior parte delle funzionalità aggiuntive di Docker EE.
Registra i driver in Docker CE:
locale - scrittura di log su file Docker Daemon interni;
json - creazione di json-log nella cartella di ciascun contenitore;
diario - invio di log a journald.
Le impostazioni di registrazione di Docker si trovano nel file daemon.json.
Il campo "log-driver" specifica il plug-in e il campo "log-opts" specifica le sue impostazioni. Nell'esempio sopra, viene specificato il plug-in "json-file", il limite della dimensione del registro è "max-size": "10m"; limite al numero di file (impostazioni di rotazione) — “max-file”: “3”; così come i valori che verranno allegati ai log.

Alcune impostazioni del driver di registro possono essere configurate tramite l'utilità di comando. Ciò è utile se è necessario avviare un contenitore separato con un driver di registro diverso.
Ecco come appare lo schema di registrazione in Docker:

Come funziona lo schema: un driver di log come json-file crea file. I raccoglitori di log (Rsyslog, Fluentd, Logagent e altri) raccolgono questi file e li trasferiscono nell'archiviazione in Elastic, Sematext o altri archivi.
Funzionalità di accesso a Kubernetes
Semplificato, lo schema di registrazione in Kubernetes si presenta così: c'è un pod, un contenitore è in esecuzione al suo interno, il contenitore invia i log a stdout / stderr. Docker quindi crea un file e scrive i log, che può quindi ruotare.

Considera le funzionalità di accesso a Kubernetes.
Salva i log tra le distribuzioni. Questo è un prerequisito per le impostazioni di registrazione corrette. Se non si salvano i registri tra le distribuzioni, quando viene rilasciata una nuova versione dell'applicazione, i registri della precedente verranno sovrascritti, anche il ricaricamento del contenitore sarà irto di perdita di registri. Kubernetes ha la chiave --previous, ti consente di visualizzare i log dell'applicazione prima dell'ultimo riavvio del pod, ma non più in profondità.
Aggrega i log di tutte le istanze. Se i microservizi sono ospitati nei cloud, il provider cloud è responsabile del controllo del sistema. Se i microservizi si trovano sul proprio hardware, oltre ai log dai contenitori, è necessario raccogliere anche i log di sistema.
In precedenza, non esistevano strumenti convenienti per la raccolta dei log sia dal sistema che dai microservizi. In genere, uno strumento raccoglieva i log di sistema (ad esempio, Rsyslog) e un altro raccoglieva i log da Docker (ad esempio, journal-bit con il driver di log Docker configurato su journald). Abbiamo provato a utilizzare journal-bit per raccogliere i log sia dai container (specificando nel driver di log Docker che i log devono essere scritti su journald) sia dal sistema (in CentOS 7 ha già systemd e journald. La soluzione funziona, ma non è ideale. Se ci sono molti log, journal-bit inizia a rallentare e i messaggi vengono persi.
Gli esperimenti continuarono e venne trovato un altro metodo. CentOS 7 log di sistema principali (messaggi, audit, sicurezza) sono duplicati nel log delle variabili come file. Docker può anche essere configurato per salvare i log in file JSON. Di conseguenza, questi file sono CentOS 7 e Docker possono essere compilati insieme.
Nel tempo, la soluzione ELK Stack è diventata popolare. È una combinazione di diversi strumenti: Elasticsearch, Logstash e Kibana.
Elasticsearch memorizza i log dai container, Logstash raccoglie i log dalle istanze, Kibana consente di elaborare i log ricevuti e costruire grafici basati su di essi. ELK Stack è stato utilizzato attivamente per un po 'di tempo, ma, secondo me, il suo tempo sta passando. Ti dirò perché dopo.
Aggiungi metadati. Pod, applicazioni e container possono essere eseguiti ovunque. Inoltre, un'applicazione può avere diverse istanze. I log sono scritti nello stesso formato e dobbiamo capire che tipo di replica è, in quale pod la scrive, in quale spazio dei nomi si trova. Ecco perché i log devono aggiungere metadati.
Analizza i log. È divertente, ma il costo di manutenzione di un sistema di registrazione e monitoraggio può superare il costo dell'applicazione principale. Quando hai decine e centinaia di migliaia di registri che volano al secondo, questo sembra naturale, ma devi comunque conoscere la linea. Un modo per trovare questo vantaggio è analizzare i log.
Di norma, non è necessario raccogliere e archiviare tutti i registri, è necessario inviarne solo una parte per l'archiviazione, ad esempio registri con lo stato "avviso" o "errore". Se parliamo di nginx o log del controller di ingresso, è possibile inviare per l'archiviazione solo quelli il cui stato è diverso da 200. Ma questo non è un consiglio universale: se in qualche modo crei analisi basate sui log di Nginx, vale ovviamente la pena raccoglierli.
Non è consigliabile filtrare sconsideratamente i log, perché i dati filtrati potrebbero non essere sufficienti per la normale analisi. D'altra parte, forse l'analisi dovrebbe essere eseguita non a livello di registrazione, ma a livello di raccolta delle metriche. Quindi non è necessario archiviare centinaia di migliaia di righe con il codice 200. Un approccio consiste nell'ottenere informazioni sul traffico e sugli errori dalle metriche dei controller di ingresso.
In generale, qui devi pensare attentamente: cosa vuoi memorizzare e per quanto tempo, perché altrimenti si verificherà una situazione in cui il sistema di registrazione richiederà più risorse del progetto principale.
Non esiste ancora una soluzione standard per la registrazione. A differenza del monitoraggio, dove esiste una soluzione Prometheus più comune, non esiste uno standard nella registrazione.
In questa lezione esamineremo due strumenti: uno è popolare e il secondo sta guadagnando popolarità. Oltre a loro, ce ne sono altri, ma in questo articolo non li toccheremo.
Considerando tutte le funzionalità discusse sopra, l'accesso a Kubernetes può ora essere rappresentato nel modo seguente:

Il registro del contenitore rimane, rotazione, ma viene visualizzato un agente di raccolta, che preleva i registri e li invia per l'archiviazione (nel diagramma - nel back-end di registrazione). L'agente viene eseguito su ciascun nodo e in genere viene eseguito su Kubernetes.
Consideriamo ora gli strumenti per la registrazione.
Grafa Loki
è apparso di recente, ma è già diventato piuttosto famoso. I suoi vantaggi: facile da installare, consuma poche risorse, non richiede l'installazione di Elasticsearch, poiché memorizza i dati in TSDB (database di serie temporali). Nell'ultimo articolo ho scritto che Prometheus memorizza i dati in un tale database, e questa è una delle tante somiglianze tra i due prodotti. Gli sviluppatori affermano addirittura che Loki è "Prometheus per il mondo del disboscamento".
Una piccola digressione su TSDB per chi non ha letto : TSDB svolge un ottimo lavoro nell'archiviazione di grandi quantità di dati, serie temporali, ma non è progettato per l'archiviazione a lungo termine. Se per qualche motivo è necessario archiviare i registri per più di due settimane, è meglio configurarne il trasferimento in un altro database.
Un altro vantaggio di Loki è che Grafana viene utilizzato per la visualizzazione dei dati. È molto comodo: a Grafana guardiamo i dati di monitoraggio e nello stesso posto, collegando Loki, guardiamo i log. I log possono essere utilizzati per creare grafici.
L'architettura di Loki è simile a questa:

Utilizzando DaemonSet, un agente viene distribuito su tutti i server del cluster: Promtail o Fluent Bit. L'agente raccoglie i log. Loki li raccoglie e li memorizza nel suo TSDB. I metadati vengono immediatamente aggiunti ai log, il che è comodo: puoi filtrare per pod, spazi dei nomi, nomi di container e persino etichette.
Loki funziona nella familiare interfaccia di Grafana. Loki ha persino il proprio linguaggio di query chiamato LogQL, che è simile per nome e sintassi a PromQL in Prometheus. L'interfaccia di Loki ha prompt con domande, quindi non è necessario conoscerle a memoria.

Loki nell'interfaccia di Grafana
Utilizzando i filtri, Loki può trovare i codici ("400", "404" e qualsiasi altro); visualizzare i log dall'intero nodo; filtrare tutti i log contenenti la parola "errore". Cliccando sul log si aprirà una scheda con tutte le informazioni sull'evento.
Ci sono abbastanza strumenti in Loki che ti consentono di estrarre i registri necessari, anche se ad essere onesti, tecnicamente potrebbero essercene di più. Ora Loki sta attivamente sviluppando e guadagnando popolarità.
Elastico + Morso Fluente + Kibana (Stack EFK)
Lo stack EFK è uno strumento di registrazione più classico ma ugualmente popolare.
All'inizio dell'articolo è stato menzionato ELK (Elasticsearch + Logstash + Kibana), ma questo stack è obsoleto a causa del Logstash poco produttivo e allo stesso tempo ad alta intensità di risorse. Invece, iniziarono a usare il più leggero e produttivo Fluentd, e dopo un po' venne in soccorso - un collettore di agenti ancora più leggero e ancora più produttivo.
Secondo gli sviluppatori, Fluent Bit è più di 100 volte migliore in termini di prestazioni rispetto a Fluentd: "dove Fluentd consuma 20 MB di RAM, Fluent Bit consumerà 150 KB" - una citazione diretta dalla documentazione. Guardando questo, Fluent Bit è diventato più ampiamente utilizzato.
Fluent Bit ha meno funzionalità di Fluentd, ma copre le esigenze principali, quindi utilizziamo principalmente Fluent Bit.
Come funziona lo stack EFK: l'agente raccoglie i log da tutti i pod (di solito un DaemonSet in esecuzione su tutti i server del cluster) e li invia allo storage (Elasticsearch, PostgreSQL o Kafka). Kibana si connette al repository e da lì recupera tutte le informazioni necessarie.

presenta le informazioni in un'interfaccia web user-friendly. Ci sono grafici, filtri e altro.

I log possono essere utilizzati per creare interi dashboard.

Funzioni Fluent Bit
Poiché Fluent Bit è solitamente meno sentito di Logstash, diamo un'occhiata più da vicino. Fluent Bit può essere suddiviso logicamente in 6 moduli e ad alcuni dei moduli possono essere collegati plug-in che estendono le funzionalità di Fluent Bit.

Modulo di ingresso raccoglie i log da file, servizi systemd e persino da tcp-socket (devi solo specificare un endpoint e Fluent Bit inizierà ad andare lì). Queste funzionalità sono sufficienti per raccogliere i log sia dal sistema che dai container.
Nella produzione, utilizziamo molto spesso i plug-in (può essere impostato su una cartella con i registri) e (gli si può dire da quali servizi raccogliere i log).
Modulo analizzatore porta i log in una vista comune. Per impostazione predefinita, i log Nginx sono una stringa. Usando il plugin, questa stringa può essere convertita in JSON: imposta i campi e i loro valori. JSON è molto più facile da usare rispetto a un log di stringhe perché ci sono opzioni di ordinamento più flessibili.
Modulo filtro. A questo livello, i log non necessari vengono eliminati. Ad esempio, i registri vengono inviati per l'archiviazione solo con il valore "avviso" o con determinate etichette. I registri selezionati vengono memorizzati nel buffer.
Modulo tampone. Fluent Bit ha due tipi di buffer: un buffer di memoria e un buffer del disco. Un buffer è una memoria di registro temporanea necessaria in caso di errori o malfunzionamenti. Tutti vogliono risparmiare sulla RAM, quindi di solito scelgono un buffer del disco. Ma tieni presente che prima di andare su disco, i log vengono ancora scaricati in memoria.
Modulo di instradamento/uscita contiene regole e indirizzi per l'invio dei log. Come già accennato, i log possono essere inviati a Elasticsearch, PostgreSQL o, ad esempio, Kafka.
È interessante notare che i log possono essere inviati da Fluent Bit a Fluentd. Poiché il primo è più leggero e meno funzionale, è possibile raccogliere i registri tramite esso e inviarli a Fluentd, e già lì, con l'ausilio di plug-in aggiuntivi, possono essere ulteriormente elaborati e inviati agli archivi.
Se prevedi di utilizzare Elasticsearch...
Infine, due suggerimenti per coloro che intendono utilizzare Elasticsearch come repository di log in produzione.
- Imposta avvisi con . Questo programma isola i messaggi importanti dal flusso generale dei registri e crea avvisi su di essi nella posta o in un altro canale. È vero, non molto tempo fa .
- Ruota i registri con l'app o chiamate all'API Elasticsearch. La stessa Elastic, in linea di principio, sta ora adottando misure significative per gestire la vita degli indici senza l'uso di strumenti di terze parti. In generale, non ha senso conservare i registri per molto tempo: è improbabile che un registro sia necessario dopo due settimane - se è davvero critico, verrà sicuramente elaborato in due settimane. In casi estremi, i vecchi registri possono essere archiviati e inviati da qualche parte per l'archiviazione a lungo termine. Ho sentito parlare di registri speciali che per legge devono essere conservati per un massimo di 5 anni. Personalmente, non mi sono imbattuto in questo, ma non equiparerei tali informazioni ai normali registri e forse le memorizzerei anche separatamente.
To be continued ...
Autore: Marcel Ibraev, amministratore Kubernetes certificato, ingegnere praticante in azienda , relatore e sviluppatore di corsi .
Fonte: habr.com
