Splunk Universal Forwarder in Docker come collezionista di log di sistema

Splunk Universal Forwarder in Docker come collezionista di log di sistema

Splunk è uno dei pochi prodotti commerciali più riconoscibili per la raccolta e l'analisi dei log. Anche ora che le vendite in Russia non sono più effettuate, non è un motivo per non scrivere istruzioni/how-to su questo prodotto.

Compito: raccogliere i log di sistema da nodi Docker in Splunk senza modificare la configurazione della macchina host

Iniziamo con l'approccio ufficiale, che appare un po' strano quando si utilizza Docker.
Link su Docker Hub
Cosa abbiamo:

1. Pulliamo l'immagine

$ docker pull splunk/universalforwarder:latest

2. Avviamo il container con i parametri desiderati

$ docker run -d -p 9997:9997 -e 'SPLUNK_START_ARGS=--accept-license' -e 'SPLUNK_PASSWORD=' splunk/universalforwarder:latest

3. Accediamo al container

docker exec -it  /bin/bash

Successivamente, ci viene chiesto di seguire il link noto nella documentazione.

E configurare il container dopo il suo avvio:


./splunk add forward-server :
./splunk add monitor /var/log
./splunk restart

Aspetta. Cosa?

Ma le sorprese non finiscono qui. Se si avvia il container dall'immagine ufficiale in modalità interattiva, si vedrà quanto segue:

Un po' di delusione


$ docker run -it -p 9997:9997 -e 'SPLUNK_START_ARGS=--accept-license' -e 'SPLUNK_PASSWORD=password' splunk/universalforwarder:latest

PLAY [Esegui il provisioning predefinito di Splunk] *******************************************************************************************************************************************************************************************************
Martedì 09 Aprile 2019  13:40:38 +0000 (0:00:00.096)       0:00:00.096 *********

TASK [Raccolta informazioni] ***********************************************************************************************************************************************************************************************************************
ok: [localhost]
Martedì 09 Aprile 2019  13:40:39 +0000 (0:00:01.520)       0:00:01.616 *********

TASK [Ottieni il nome host attuale] *******************************************************************************************************************************************************************************************************************
changed: [localhost]
Martedì 09 Aprile 2019  13:40:40 +0000 (0:00:00.599)       0:00:02.215 *********
Martedì 09 Aprile 2019  13:40:40 +0000 (0:00:00.054)       0:00:02.270 *********

TASK [set_fact] ******************************************************************************************************************************************************************************************************************************
ok: [localhost]
Martedì 09 Aprile 2019  13:40:40 +0000 (0:00:00.075)       0:00:02.346 *********
Martedì 09 Aprile 2019  13:40:40 +0000 (0:00:00.067)       0:00:02.413 *********
Martedì 09 Aprile 2019  13:40:40 +0000 (0:00:00.060)       0:00:02.473 *********
Martedì 09 Aprile 2019  13:40:40 +0000 (0:00:00.051)       0:00:02.525 *********
Martedì 09 Aprile 2019  13:40:40 +0000 (0:00:00.056)       0:00:02.582 *********
Martedì 09 Aprile 2019  13:40:41 +0000 (0:00:00.216)       0:00:02.798 *********
included: /opt/ansible/roles/splunk_common/tasks/change_splunk_directory_owner.yml for localhost
Martedì 09 Aprile 2019  13:40:41 +0000 (0:00:00.087)       0:00:02.886 *********

TASK [splunk_common : Aggiorna il proprietario della directory di Splunk] *****************************************************************************************************************************************************************************************
ok: [localhost]
Martedì 09 Aprile 2019  13:40:41 +0000 (0:00:00.324)       0:00:03.210 *********
included: /opt/ansible/roles/splunk_common/tasks/get_facts.yml for localhost
Martedì 09 Aprile 2019  13:40:41 +0000 (0:00:00.094)       0:00:03.305 *********

e così via...

Ottimo. Nell'immagine non ci sono artefatti. Quindi, ogni volta che avviamo, ci vorrà del tempo per scaricare l'archivio con i binari, estrarlo e configurarlo.
E il docker-way e tutto il resto?

No, grazie. Seguiremo un'altra strada. E se eseguiamo tutte queste operazioni nella fase di build? Allora andiamo!

Per non allungare i tempi, mostrerò subito l'immagine finale:

Dockerfile

# Тут у кого какие предпочтения
FROM centos:7

# Задаём переменные, чтобы каждый раз при старте не указывать их
ENV SPLUNK_HOME /splunkforwarder
ENV SPLUNK_ROLE splunk_heavy_forwarder
ENV SPLUNK_PASSWORD changeme
ENV SPLUNK_START_ARGS --accept-license

# Ставим пакеты
# wget - чтобы скачать артефакты
# expect - понадобится для первоначального запуска Splunk на этапе сборки
# jq - используется в скриптах, которые собирают статистику докера
RUN yum install -y epel-release 
    && yum install -y wget expect jq

# Качаем, распаковываем, удаляем
RUN wget -O splunkforwarder-7.2.4-8a94541dcfac-Linux-x86_64.tgz 'https://www.splunk.com/bin/splunk/DownloadActivityServlet?architecture=x86_64&platform=linux&version=7.2.4&product=universalforwarder&filename=splunkforwarder-7.2.4-8a94541dcfac-Linux-x86_64.tgz&wget=true' 
    && wget -O docker-18.09.3.tgz 'https://download.docker.com/linux/static/stable/x86_64/docker-18.09.3.tgz' 
    && tar -xvf splunkforwarder-7.2.4-8a94541dcfac-Linux-x86_64.tgz 
    && tar -xvf docker-18.09.3.tgz  
    && rm -f splunkforwarder-7.2.4-8a94541dcfac-Linux-x86_64.tgz 
    && rm -f docker-18.09.3.tgz

# С shell скриптами всё понятно, а вот inputs.conf, splunkclouduf.spl и first_start.sh нуждаются в пояснении. Об этом расскажу после source тэга.
COPY [ "inputs.conf", "docker-stats/props.conf", "/splunkforwarder/etc/system/local/" ]
COPY [ "docker-stats/docker_events.sh", "docker-stats/docker_inspect.sh", "docker-stats/docker_stats.sh", "docker-stats/docker_top.sh", "/splunkforwarder/bin/scripts/" ]
COPY splunkclouduf.spl /splunkclouduf.spl
COPY first_start.sh /splunkforwarder/bin/

#  Даём права на исполнение, добавляем пользователя и выполняем первоначальную настройку
RUN chmod +x /splunkforwarder/bin/scripts/*.sh 
    && groupadd -r splunk 
    && useradd -r -m -g splunk splunk 
    && echo "%sudo ALL=NOPASSWD:ALL" >> /etc/sudoers 
    && chown -R splunk:splunk $SPLUNK_HOME 
    && /splunkforwarder/bin/first_start.sh 
    && /splunkforwarder/bin/splunk install app /splunkclouduf.spl -auth admin:changeme 
    && /splunkforwarder/bin/splunk restart

# Копируем инит скрипты
COPY [ "init/entrypoint.sh", "init/checkstate.sh", "/sbin/" ]

# По желанию. Кому нужно локально иметь конфиги/логи, кому нет.
VOLUME [ "/splunkforwarder/etc", "/splunkforwarder/var" ]

HEALTHCHECK --interval=30s --timeout=30s --start-period=3m --retries=5 CMD /sbin/checkstate.sh || exit 1

ENTRYPOINT [ "/sbin/entrypoint.sh" ]
CMD [ "start-service" ]

E quindi, cosa contiene

first_start.sh

#!/usr/bin/expect -f
set timeout -1
spawn /splunkforwarder/bin/splunk start --accept-license
expect "Please enter an administrator username: "
send -- "adminr"
expect "Please enter a new password: "
send -- "changemer"
expect "Please confirm new password: "
send -- "changemer"
expect eof

Alla prima esecuzione, Splunk chiede di impostare un nome utente/password, MA questi dati vengono utilizzati solo per eseguire comandi amministrativi di questa specifica installazione, cioè, all'interno del container. Nel nostro caso, vogliamo semplicemente avviare il container affinché tutto funzioni e i log fluiscano a fiumi. Certamente, questo è hardcoded, ma non ho trovato altri modi.

Successivamente, nel nostro script viene eseguito

/splunkforwarder/bin/splunk install app /splunkclouduf.spl -auth admin:changeme

splunkclouduf.spl — Questo è il file di credenziali per Splunk Universal Forwarder, che può essere scaricato dall'interfaccia web.

Dove cliccare per scaricare (nelle immagini)Splunk Universal Forwarder in Docker come collezionista di log di sistema

Splunk Universal Forwarder in Docker come collezionista di log di sistema
È un normale archivio che può essere estratto. All'interno ci sono certificati e la password per connettersi al nostro SplunkCloud e outputs.conf con un elenco delle nostre istanze di input. Questo file sarà valido fino a quando non reinstallate la vostra installazione di Splunk o non aggiungete nodi di input, se l'installazione è on-premise. Quindi non è un problema inserirlo all'interno del contenitore.

E infine, il riavvio. Sì, per applicare le modifiche, è necessario riavviarlo.

Nel nostro inputs.conf aggiungiamo i log che vogliamo inviare a Splunk. Non è necessario aggiungere questo file all'immagine, se ad esempio distribuite le configurazioni tramite puppet. L'importante è che il Forwarder veda le configurazioni all'avvio del demone, altrimenti sarà necessario ./splunk restart.

E quali sono gli script docker stats? Su GitHub c'è una vecchia soluzione di outcoldman, gli script sono stati presi da lì e modificati per funzionare con le versioni attuali di Docker (ce-17.*) e Splunk (7.*).

Con i dati ottenuti si possono costruire dei

dashboard: (alcune immagini)Splunk Universal Forwarder in Docker come collezionista di log di sistema

Splunk Universal Forwarder in Docker come collezionista di log di sistema
Il codice sorgente dei dashboard si trova nel repository indicato alla fine dell'articolo. Si noti che ci sono 2 campi di selezione: 1 - selezione dell'indice (cercati per maschera), selezione dell'host/contenitore. Probabilmente dovrete aggiornare la maschera dell'indice, a seconda dei nomi che utilizzate.

In conclusione, vorrei richiamare l'attenzione sulla funzione start() in

entrypoint.sh

start() {
    trap teardown EXIT
	if [ -z $SPLUNK_INDEX ]; then
	echo "La variabile d'ambiente 'SPLUNK_INDEX' è vuota o non definita. Deve essere 'dev' o 'prd'." >&2
	exit 1
	else
	sed -e "s/@index@/$SPLUNK_INDEX/" -i ${SPLUNK_HOME}/etc/system/local/inputs.conf
	fi
	sed -e "s/@hostname@/$(cat /etc/hostname)/" -i ${SPLUNK_HOME}/etc/system/local/inputs.conf
    sh -c "echo 'avvio in corso' > /tmp/splunk-container.state"
	${SPLUNK_HOME}/bin/splunk start
    watch_for_failure
}

Nel mio caso, per ogni ambiente e ogni singola entità, sia essa un'applicazione in container o una macchina host, utilizziamo un indice separato. Questo impedisce che la velocità di ricerca ne risenta in caso di accumulo significativo di dati. La nomenclatura degli indici segue una semplice regola: _. Pertanto, affinché il container sia universale, prima di avviare direttamente il demone, sostituiamo sed-wildcard con il nome dell'ambiente. La variabile con il nome dell'ambiente viene passata attraverso le variabili d'ambiente. Suona divertente.

Vale anche la pena notare che, per qualche motivo, su Splunk non influisce la presenza del parametro docker hostname. Continuerà comunque a inviare log con l'id del suo container nel campo host. Come soluzione, è possibile montare /etc/hostname dal server host e durante l'avvio effettuare una sostituzione simile ai nomi degli indici.

Esempio di docker-compose.yml

version: '2'
services:
  splunk-forwarder:
    image: "${IMAGE_REPO}/docker-stats-splunk-forwarder:${IMAGE_VERSION}"
    environment:
      SPLUNK_INDEX: ${ENVIRONMENT}
    volumes:
    - /etc/hostname:/etc/hostname:ro
    - /var/log:/var/log
    - /var/run/docker.sock:/var/run/docker.sock:ro

Risultato

Sì, potrebbe non essere la soluzione ideale e sicuramente non universale per tutti, poiché ci sono molte «hardcoded». Tuttavia, basandosi su di essa, ognuno può creare la propria immagine e posizionarla nel proprio archivio privato, se mai aveste bisogno del Splunk Forwarder proprio in Docker.

Link:

Soluzione dell'articolo
Soluzione di outcoldman che ha ispirato il riutilizzo di parte della funzionalità
Documentazione ufficiale sulla configurazione di Universal Forwarder

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster