Splunk Universal Forwarder im Docker als Sammler von Systemprotokollen

Splunk Universal Forwarder im Docker als Sammler von Systemprotokollen

Splunk ist eines der bekanntesten kommerziellen Produkte zur Sammlung und Analyse von Protokolldaten. Selbst jetzt, da der Verkauf in Russland nicht mehr stattfindet, ist dies kein Grund, keine Anleitungen/How-tos zu diesem Produkt zu schreiben.

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

Beginnen wir mit dem offiziellen Ansatz, der bei der Verwendung von Docker etwas merkwürdig erscheint.
Link zum Docker Hub
Was haben wir also:

1. Wir ziehen das Image

$ docker pull splunk/universalforwarder:latest

2. Wir starten den Container mit den erforderlichen Parametern

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

3. Wir betreten den Container

docker exec -it  /bin/bash

Danach werden wir gebeten, die bekannte Adresse in der Dokumentation zu besuchen.

Und den Container nach dem 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 im interaktiven Modus aus dem offiziellen Image starten, sehen Sie Folgendes:

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-Bereitstellung 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 [Fakten setzen] ***************************************************************************************************************************************************************************************************************************
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 *********
eingeschlossen: /opt/ansible/roles/splunk_common/tasks/change_splunk_directory_owner.yml für localhost
Dienstag 09. April 2019  13:40:41 +0000 (0:00:00.087)       0:00:02.886 *********

AUFGABE [splunk_common : Splunk-Verzeichnisbesitzer aktualisieren] *********************************************************************************************************************************************************************************
ok: [localhost]
Dienstag 09. April 2019  13:40:41 +0000 (0:00:00.324)       0:00:03.210 *********
eingeschlossen: /opt/ansible/roles/splunk_common/tasks/get_facts.yml für localhost
Dienstag 09. April 2019  13:40:41 +0000 (0:00:00.094)       0:00:03.305 *********

na und so weiter...

Ausgezeichnet. Im Image gibt es nicht einmal ein Artefakt. Das bedeutet, dass jedes Mal beim Start Zeit vergeudet wird, um das Archiv mit den Binärdateien herunterzuladen, zu entpacken und zu konfigurieren.
Und wie steht es um den Docker-Weg und so weiter?

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

Um es nicht zu lange hinauszuziehen, zeige ich sofort das endgültige 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 fordert Splunk zur Eingabe eines Benutzernamens/Passworts auf, ABER diese Daten werden verwendet nur um administrative Befehle dieser speziellen Installation auszuführen, also innerhalb des Containers. In unserem Fall möchten wir einfach den Container starten, damit alles funktioniert und die Logs in Strömen fließen. Natürlich ist das Hardcoding, aber ich habe keine anderen Möglichkeiten gefunden.

Weiter im Skript wird ausgeführt

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

splunkclouduf.spl — Dies ist die Datei mit den Anmeldeinformationen für den Splunk Universal Forwarder, die über die Weboberfläche heruntergeladen werden kann.

Wohin klicken, um herunterzuladen (in Bildern)Splunk Universal Forwarder im Docker als Sammler von Systemprotokollen

Splunk Universal Forwarder im Docker als Sammler von Systemprotokollen
Das ist ein gewöhnliches Archiv, das entpackt werden kann. Darin befinden sich Zertifikate und ein Passwort für die Verbindung zu unserem SplunkCloud und outputs.conf mit einer Liste unserer Input-Instanzen. Diese Datei bleibt aktuell, bis Sie Ihre Splunk-Installation neu installieren oder Input-Knoten hinzufügen, wenn es sich um eine on-premise-Installation handelt. Daher ist es unproblematisch, sie in den Container einzufügen.

Und schließlich — Neustart. Ja, um die Änderungen anzuwenden, muss es neu gestartet werden.

In unser inputs.conf fügen wir die Logs hinzu, die wir an Splunk senden möchten. Es ist nicht nötig, diese Datei im Image hinzuzufügen, wenn Sie beispielsweise Konfigurationen über Puppet bereitstellen. Wichtig ist nur, dass der Forwarder die Konfigurationen beim Start des Daemons sieht, sonst wird benötigt .\/splunk restart.

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

Mit den erhaltenen Daten können solche

Dashboards erstellt werden: (ein paar Bilder)Splunk Universal Forwarder im Docker als Sammler von Systemprotokollen

Splunk Universal Forwarder im Docker als Sammler von Systemprotokollen
Der Quellcode der Dashboards befindet sich im Repository, das am Ende des Artikels angegeben wird. Bitte beachten Sie, dass dort 2 Auswahlfelder vorhanden sind: 1 — Indexauswahl (werden nach Maske gesucht), Auswahl von Host/Container. Die Indexmaske müssen Sie wahrscheinlich aktualisieren, abhängig von den Namen, die Sie verwenden.

Abschließend möchte ich auf die Funktion 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. So wird die Suchgeschwindigkeit bei erheblichem Datenwachstum nicht beeinträchtigt. Für die Benennung der Indizes gilt eine einfache Regel: <environment_name>_<service/application/etc>. Daher ersetzen wir, damit der Container universell ist, vor dem direkten Start des Daemons sed-Das Wildcard durch den Namen der Umgebung. Die Variable mit dem Namen der Umgebung wird über Umgebungsvariablen übergeben. Klingt lustig.

Es ist auch erwähnenswert, dass aus irgendeinem Grund das Vorhandensein des Docker-Parameters keinen Einfluss auf Splunk hat. hostnameEs wird trotzdem weiterhin die Protokolle mit der ID seines Containers in das Feld host senden. Als Lösung kann man /etc/hostname von der Host-Maschine mounten und beim Start eine Ersetzung vornehmen, ähnlich wie bei den Indexnamen.

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

Fazit

Ja, es mag sein, dass die Lösung nicht ideal und definitiv nicht universell für alle ist, da viel "Hardcoding". Aber auf dieser Basis kann jeder sein eigenes Image erstellen und es in sein privates Artifact-Repository legen, falls Sie Splunk Forwarder genau im Docker benötigen.

Links:

Die Lösung aus dem Artikel
Die Lösung von outcoldman, die inspiriert hat, einen Teil der Funktionalität wiederzuverwenden
Offizielle Dokumentation zur Konfiguration des Universal Forwarder

Quelle: habr.com

60GB SSD 8Gb DDR4