Splunk is one of the most recognizable commercial products for collecting and analyzing logs. Even now, when sales in Russia are no longer taking place, it doesn't mean we shouldn't write instructions/how-to for this product.
Task: collecting system logs from docker nodes in Splunk without changing the host machine configuration
I'd like to start with the official approach, which seems a bit odd when using Docker.
So, what do we have:
1. We pull the image
$ docker pull splunk/universalforwarder:latest2. We start the container with the required parameters
$ docker run -d -p 9997:9997 -e 'SPLUNK_START_ARGS=--accept-license' -e 'SPLUNK_PASSWORD=' splunk/universalforwarder:latest3. We enter the container
docker exec -it /bin/bashNext, we're asked to go to a well-known address in the documentation.
And configure the container after it starts:
./splunk add forward-server :
./splunk add monitor /var/log
./splunk restart
Wait. What?
But the surprises don’t end here. If you run the container from the official image in interactive mode, you'll see the following:
A bit of disappointment
$ docker run -it -p 9997:9997 -e 'SPLUNK_START_ARGS=--accept-license' -e 'SPLUNK_PASSWORD=password' splunk/universalforwarder:latest
PLAY [Run default Splunk provisioning] *******************************************************************************************************************************************************************************************************
Dinsdag 09 April 2019 13:40:38 +0000 (0:00:00.096) 0:00:00.096 *********
TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [localhost]
Dinsdag 09 April 2019 13:40:39 +0000 (0:00:01.520) 0:00:01.616 *********
TASK [Get actual hostname] *******************************************************************************************************************************************************************************************************************
changed: [localhost]
Dinsdag 09 April 2019 13:40:40 +0000 (0:00:00.599) 0:00:02.215 *********
Dinsdag 09 April 2019 13:40:40 +0000 (0:00:00.054) 0:00:02.270 *********
TASK [set_fact] ******************************************************************************************************************************************************************************************************************************
ok: [localhost]
Dinsdag 09 April 2019 13:40:40 +0000 (0:00:00.075) 0:00:02.346 *********
Dinsdag 09 April 2019 13:40:40 +0000 (0:00:00.067) 0:00:02.413 *********
Dinsdag 09 April 2019 13:40:40 +0000 (0:00:00.060) 0:00:02.473 *********
Dinsdag 09 April 2019 13:40:40 +0000 (0:00:00.051) 0:00:02.525 *********
Dinsdag 09 April 2019 13:40:40 +0000 (0:00:00.056) 0:00:02.582 *********
Dinsdag 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
Dinsdag 09 April 2019 13:40:41 +0000 (0:00:00.087) 0:00:02.886 *********
TASK [splunk_common : Update Splunk directory owner] *****************************************************************************************************************************************************************************************
ok: [localhost]
Dinsdag 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
Dinsdag 09 April 2019 13:40:41 +0000 (0:00:00.094) 0:00:03.305 *********
Enzovoort...
Uitstekend. Er is zelfs geen artefact in de afbeelding. Dat betekent dat er elke keer wanneer het wordt uitgevoerd tijd verloren gaat om het archief met binaire bestanden te downloaden, uit te pakken en in te stellen.
Maar wat is er met de docker-way en dat soort dingen?
Nee, bedankt. Wij gaan een andere weg. Wat als we al deze bewerkingen tijdens de bouwfase uitvoeren? Laten we beginnen!
Om het niet te lang te maken, laat ik meteen de uiteindelijke afbeelding zien:
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" ]En dus, wat zit er 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 eofBij de eerste start vraagt Splunk om een gebruikersnaam/wachtwoord in te voeren, MAAR deze gegevens worden gebruikt van voor het uitvoeren van administratieve commando's voor deze specifieke installatie, dat wil zeggen, binnen de container. In ons geval willen we gewoon de container starten zodat alles werkt en de logbestanden blijven stromen. Natuurlijk, dit is hardcoded, maar ik heb geen andere manieren gevonden.
De volgende stap in het script wordt uitgevoerd
/splunkforwarder/bin/splunk install app /splunkclouduf.spl -auth admin:changemesplunkclouduf.spl — Dit is een credential-bestand voor Splunk Universal Forwarder, dat kan worden gedownload via de webinterface.
Waar te klikken om te downloaden (in afbeeldingen)
Dit is een standaardarchief dat kan worden uitgepakt. Binnenin vindt u certificaten en het wachtwoord voor verbinding met onze SplunkCloud en outputs.conf met een lijst van onze inputinstanties. Dit bestand blijft geldig totdat u uw Splunk-installatie opnieuw installeert of input-nodes toevoegt, als de installatie on-premise is. Dus het is geen probleem om dit bestand in de container te plaatsen.
En tenslotte — herstarten. Ja, om de wijzigingen toe te passen, moet het opnieuw worden opgestart.
In onze inputs.conf voegen we de logs toe die we naar Splunk willen verzenden. Het is niet noodzakelijk om dit bestand in de afbeelding op te nemen, als u bijvoorbeeld configuraties via puppet verspreidt. Het belangrijkste is dat de Forwarder de configuraties ziet bij het starten van de daemon, anders is .\/splunk restart.
Wat zijn de docker stats scripts? Op GitHub is er een oude oplossing van , de scripts zijn daarvandaan gehaald en aangepast voor gebruik met de huidige versies van Docker (ce-17.*) en Splunk (7.*).
Met de verkregen gegevens kunnen dergelijke
dashboards worden opgebouwd: (paar afbeeldingen)
De broncode van de dashboards bevindt zich in de repository die aan het eind van het artikel is genoemd. Let op dat er daar 2 select velden zijn: 1 — selectie van de index (wordt gezocht op patroon), selectie van host/container. U moet waarschijnlijk het patroon van de index bijwerken, afhankelijk van de namen die u gebruikt.
Tot slot wil ik de aandacht vestigen op de functie start() in
entrypoint.sh
start() {
trap teardown EXIT
if [ -z $SPLUNK_INDEX ]; then
echo "'SPLUNK_INDEX' omgevingsvariabele is leeg of niet gedefinieerd. Moet 'dev' of 'prd' zijn." >&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 'starting' > /tmp/splunk-container.state"
${SPLUNK_HOME}/bin/splunk start
watch_for_failure
}In mijn geval, voor elke omgeving en elke afzonderlijke entiteit, of het nu een applicatie in een container is of een hostmachine, gebruiken we een afzonderlijke index. Zo blijft de zoek snelheid behouden bij aanzienlijke data accumulatie. Voor de naamgeving van indexen wordt een eenvoudig principe gebruikt: _. Dus, om de container universeel te maken, vervangen we vóór het starten van de daemon sed- de wildcard door de naam van de omgeving. De variabele met de naam van de omgeving wordt doorgegeven via omgevingsvariabelen. Klinkt grappig.
Ook is het vermeldenswaard dat om een of andere reden de aanwezigheid van de docker-parameter geen invloed heeft op Splunk. hostnameHet zal nog steeds onvermoeibaar logs met de id van zijn container naar het host-veld sturen. Als oplossing kun je /etc/hostname vanuit de hostmachine monteren en bij het opstarten een vervangingen doen, vergelijkbaar met indexnamen.
Voorbeeld 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:roConclusie
Ja, mogelijk is de oplossing niet perfect en zeker niet universeel voor iedereen, aangezien er veel ‘hardcoded’. Maar op basis daarvan kan iedereen zijn eigen image samenstellen en deze in zijn privé-artifactory plaatsen, mocht het zo zijn dat je Splunk Forwarder juist in Docker nodig hebt.
Links:
Bron: habr.com
