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.
Was haben wir also:
1. Wir ziehen das Image
$ docker pull splunk/universalforwarder:latest2. 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:latest3. Wir betreten den Container
docker exec -it /bin/bashDanach 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 eofBeim 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:changemesplunkclouduf.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)
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 , 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)
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:roFazit
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:
Quelle: habr.com
