Splunk Universal Forwarder in Docker als Systemprotokollsammler

Splunk Universal Forwarder in Docker als Systemprotokollsammler

Splunk gehört zu den bekanntesten kommerziellen Produkten für die Sammlung und Analyse von Protokollen. Auch wenn der Verkauf in Russland mittlerweile eingestellt wurde, gibt es keinen Grund, keine Anleitungen zu diesem Produkt zu schreiben.

Ziel: Systemprotokolle von Docker-Knoten in Splunk zu sammeln, ohne die Konfiguration der Host-Maschine zu ändern.

Beginnen wir mit dem offiziellen Ansatz, der bei der Nutzung von Docker etwas seltsam anmutet.
Link zum Docker Hub
Was haben wir?

1. Das Image herunterladen

$ docker pull splunk/universalforwarder:latest

2. Den Container mit den notwendigen Parametern starten

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

3. In den Container einloggen

docker exec -it  /bin/bash

Anschließend werden wir aufgefordert, die bekannte Adresse in der Dokumentation aufzusuchen.

Und den Container nach dessen Start zu konfigurieren:


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

Warten Sie. Was?

Aber damit enden die Überraschungen nicht. Wenn Sie den Container aus dem offiziellen Image im interaktiven Modus starten, werden Sie Folgendes sehen:

Ein wenig Enttäuschung


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

SPIEL [Standard-Splunk-Provisionierung ausführen] *******************************************************************************************************************************************************************************************************
Dienstag, 09. April 2019  13:40:38 +0000 (0:00:00.096)       0:00:00.096 *********

AUFGABE [Fakten sammeln] ***********************************************************************************************************************************************************************************************************************
ok: [localhost]
Dienstag, 09. April 2019  13:40:39 +0000 (0:00:01.520)       0:00:01.616 *********

AUFGABE [Aktuellen Hostnamen abrufen] *******************************************************************************************************************************************************************************************************************
geändert: [localhost]
Dienstag, 09. April 2019  13:40:40 +0000 (0:00:00.599)       0:00:02.215 *********
Dienstag, 09. April 2019  13:40:40 +0000 (0:00:00.054)       0:00:02.270 *********

AUFGABE [set_fact] ******************************************************************************************************************************************************************************************************************************
ok: [localhost]
Dienstag, 09. April 2019  13:40:40 +0000 (0:00:00.075)       0:00:02.346 *********
Dienstag, 09. April 2019  13:40:40 +0000 (0:00:00.067)       0:00:02.413 *********
Dienstag, 09. April 2019  13:40:40 +0000 (0:00:00.060)       0:00:02.473 *********
Dienstag, 09. April 2019  13:40:40 +0000 (0:00:00.051)       0:00:02.525 *********
Dienstag, 09. April 2019  13:40:40 +0000 (0:00:00.056)       0:00:02.582 *********
Dienstag, 09. April 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
Dienstag, 09. April 2019  13:40:41 +0000 (0:00:00.087)       0:00:02.886 *********

AUFGABE [splunk_common : Splunk-Verzeichnisinhaber aktualisieren] *****************************************************************************************************************************************************************************************
ok: [localhost]
Dienstag, 09. April 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
Dienstag, 09. April 2019  13:40:41 +0000 (0:00:00.094)       0:00:03.305 *********

und so weiter...

Ausgezeichnet. Im Image gibt es nicht einmal Artefakte. Das bedeutet, dass beim Start jedes Mal Zeit benötigt wird, um das Archiv mit den Binaries herunterzuladen, zu entpacken und einzurichten.
Und wie sieht es mit Docker-Way und all dem aus?

Nein, danke. Wir gehen einen anderen Weg. Was, wenn wir all diese Operationen bereits während des Build-Schrittes durchführen?

Um nicht lange herumzureden, zeige ich sofort das finale Image:

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" ]

Und was befindet sich in

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

Beim ersten Start fragt Splunk nach einem Benutzername/Passwort, ABER diese Daten werden nur für die Ausführung administrativer Befehle dieser spezifischen Installation verwendet, also innerhalb des Containers. In unserem Fall wollen wir einfach den Container starten, damit alles funktioniert und die Logs fleißig fließen. Natürlich ist das Hardcoding, aber ich habe keine anderen Lösungen gefunden.

Weiter im Skript wird

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

splunkclouduf.spl ausgeführt – das ist die Credential-Datei für den Splunk Universal Forwarder, die man aus der Web-Oberfläche herunterladen kann.

Wohin klicken, um es herunterzuladen (in Bildern)Splunk Universal Forwarder in Docker als Systemprotokollsammler

Splunk Universal Forwarder in Docker als Systemprotokollsammler
Das ist ein normales Archiv, das entpackt werden kann. Darin befinden sich die Zertifikate und das Passwort für die Verbindung zu unserem SplunkCloud sowie outputs.conf mit der Liste unserer Input-Instanzen. Diese Datei bleibt aktuell, bis Sie Ihre Splunk-Installation neu installieren oder Input-Nodes hinzufügen, falls es sich um eine On-Premise-Installation handelt. Daher ist es kein Problem, sie im Container hinzuzufügen.

Und zuletzt — Neustart. Ja, um die Änderungen anzuwenden, muss er neu gestartet werden.

In unsere inputs.conf fügen wir die Logs hinzu, die wir an Splunk senden möchten. Es ist nicht notwendig, diese Datei ins Image aufzunehmen, wenn Sie zum Beispiel die Konfigurationen über Puppet verteilen. Wichtig ist nur, dass der Forwarder die Konfigurationen beim Start des Daemons erkennen kann, andernfalls wird folgender Befehl benötigt: ./splunk restart.

Was sind das für Docker-Stats-Skripte? Es gibt eine alte Lösung auf GitHub von outcoldman, die Skripte stammen dort und wurden für die Arbeit mit den aktuellen Versionen von Docker (ce-17.*) und Splunk (7.*) angepasst.

Mit den erhaltenen Daten lassen sich solche

Dashboards erstellen: (ein paar Bilder)Splunk Universal Forwarder in Docker als Systemprotokollsammler

Splunk Universal Forwarder in Docker als Systemprotokollsammler
Der Quellcode der Dashboards befindet sich im Repository, das am Ende des Artikels angegeben ist. Beachten Sie, dass dort zwei Auswahlfelder vorhanden sind: 1 — Auswahl des Index (wird anhand einer Maske gesucht), Auswahl von Host/Container. Wahrscheinlich müssen Sie die Indexmaske aktualisieren, je nach den Namen, die Sie verwenden.

Abschließend möchte ich auf die Funktion hinweisen start() in

entrypoint.sh

start() {
    trap teardown EXIT
	if [ -z $SPLUNK_INDEX ]; then
	echo "'SPLUNK_INDEX'-Umgebungsvariable ist leer oder nicht definiert. Sollte 'dev' oder 'prd' sein." >&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 'starten' > /tmp/splunk-container.state"
	${SPLUNK_HOME}/bin/splunk start
    watch_for_failure
}

In meinem Fall verwenden wir für jede Umgebung und jede einzelne Entität, sei es eine Anwendung im Container oder eine Host-Maschine, einen separaten Index. Dadurch leidet die Suchgeschwindigkeit nicht bei erheblichem Datenaufkommen. Für die Benennung der Indizes gilt eine einfache Regel: _. Um den Container universell zu gestalten, ersetzen wir vor dem Start des Daemons sed-Wildcard durch den Namen der Umgebung. Die Umgebungsvariable wird über Umgebungsvariablen übergeben. Klingt lustig.

Es ist auch zu beachten, dass die Anwesenheit des Docker-Parameters aus irgendeinem Grund keinen Einfluss auf Splunk hat. hostnameEs wird dennoch ständig Logs mit der ID seines Containers ins Feld host senden. Eine Lösung könnte sein, diese zu montieren. /etc/hostname Von der Hostmaschine aus starten und eine Ersetzung vornehmen, die den Indexnamen ähnelt.

Beispiel 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

Zusammenfassung

Ja, es ist möglich, dass die Lösung nicht perfekt und sicher nicht universell für alle ist, da es viele «Hardcodes». Aber jeder kann darauf basierend sein eigenes Image erstellen und es in sein privates Artifactory legen, falls Sie dringend einen Splunk Forwarder genau in Docker benötigen.

Links:

Lösung aus dem Artikel
Lösung von outcoldman, die inspiriert hat, Teile der Funktionalität wiederzuverwenden
Offizielle Dokumentation zur Konfiguration des Universal Forwarders

Quelle: habr.com

Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server 🔥 Kaufen Sie zuverlässiges Hosting für Websites mit DDoS-Schutz, VPS VDS-Server | ProHoster