Splunk jest jednym z kilku najbardziej rozpoznawalnych komercyjnych produktów do zbierania i analizy logów. Nawet teraz, gdy sprzedaż w Rosji już nie ma miejsca, to nie powód, aby nie pisać instrukcji / jak-to do tego produktu.
Zadanie: zbieranie logów systemowych z węzłów docker w Splunk bez zmiany konfiguracji maszyny hosta
Chciałbym zacząć od oficjalnego podejścia, które wydaje się nieco dziwne podczas korzystania z dockera.
Cóż, co mamy:
1. Pobierz obraz
$ docker pull splunk/universalforwarder:latest2. Uruchamiamy kontener z odpowiednimi parametrami
$ docker run -d -p 9997:9997 -e 'SPLUNK_START_ARGS=--accept-license' -e 'SPLUNK_PASSWORD=' splunk/universalforwarder:latest3. Wchodzimy do kontenera
docker exec -it /bin/bashNastępnie proszą nas o przejście pod znany adres w dokumentacji.
I skonfigurowanie kontenera po uruchomieniu:
./splunk add forward-server :
./splunk add monitor /var/log
./splunk restart
Czekaj. Co?
Ale to nie koniec niespodzianek. Jeśli uruchomisz kontener z oficjalnego obrazu w trybie interaktywnym, zobaczysz coś takiego:
Odrobina rozczarowania
$ docker run -it -p 9997:9997 -e 'SPLUNK_START_ARGS=--accept-license' -e 'SPLUNK_PASSWORD=password' splunk/universalforwarder:latest
GRA ZASADNICZA [Uruchomienie domyślnej procedury wdrażania Splunk] *******************************************************************************************************************************************************************************************************
Wtorek 09 Kwiecień 2019 13:40:38 +0000 (0:00:00.096) 0:00:00.096 *********
ZADANIE [Zbieranie faktów] ***********************************************************************************************************************************************************************************************************************
ok: [localhost]
Wtorek 09 Kwiecień 2019 13:40:39 +0000 (0:00:01.520) 0:00:01.616 *********
ZADANIE [Uzyskaj aktualną nazwę hosta] *******************************************************************************************************************************************************************************************************************
zmieniono: [localhost]
Wtorek 09 Kwiecień 2019 13:40:40 +0000 (0:00:00.599) 0:00:02.215 *********
Wtorek 09 Kwiecień 2019 13:40:40 +0000 (0:00:00.054) 0:00:02.270 *********
ZADANIE [ustaw_fakt] ******************************************************************************************************************************************************************************************************************************
ok: [localhost]
Wtorek 09 Kwiecień 2019 13:40:40 +0000 (0:00:00.075) 0:00:02.346 *********
Wtorek 09 Kwiecień 2019 13:40:40 +0000 (0:00:00.067) 0:00:02.413 *********
Wtorek 09 Kwiecień 2019 13:40:40 +0000 (0:00:00.060) 0:00:02.473 *********
Wtorek 09 Kwiecień 2019 13:40:40 +0000 (0:00:00.051) 0:00:02.525 *********
Wtorek 09 Kwiecień 2019 13:40:40 +0000 (0:00:00.056) 0:00:02.582 *********
Wtorek 09 Kwiecień 2019 13:40:41 +0000 (0:00:00.216) 0:00:02.798 *********
załączono: /opt/ansible/roles/splunk_common/tasks/change_splunk_directory_owner.yml dla localhost
Wtorek 09 Kwiecień 2019 13:40:41 +0000 (0:00:00.087) 0:00:02.886 *********
ZADANIE [splunk_common : Zaktualizuj właściciela katalogu Splunk] *****************************************************************************************************************************************************************************************
ok: [localhost]
Wtorek 09 Kwiecień 2019 13:40:41 +0000 (0:00:00.324) 0:00:03.210 *********
załączono: /opt/ansible/roles/splunk_common/tasks/get_facts.yml dla localhost
Wtorek 09 Kwiecień 2019 13:40:41 +0000 (0:00:00.094) 0:00:03.305 *********
no i tak dalej...
Świetnie. W obrazie nawet nie ma artefaktów. To znaczy, że za każdym razem przy uruchamianiu będzie tracić czas na pobieranie archiwum z binarkami, jego rozpakowanie i konfigurację.
A co z docker-way i całą resztą?
Nie, dziękuję. Pójdziemy inną drogą. Co, jeśli wszystkie te operacje wykonamy na etapie budowy? Zaczynajmy!
Aby nie przedłużać, od razu pokażę końcowy obraz:
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" ]I tak, co zawiera
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 eofPodczas pierwszego uruchomienia Splunk prosi o podanie loginu/hasła, ALE te dane są używane tylko do wykonywania poleceń administracyjnych tej konkretnej instalacji, to znaczy, wewnątrz kontenera. W naszym przypadku chcemy po prostu uruchomić kontener, aby wszystko działało i logi płynęły jak rzeka. Oczywiście, to jest hardkod, ale nie znalazłem innych sposobów.
Dalej w scenariuszu wykonuje się
/splunkforwarder/bin/splunk install app /splunkclouduf.spl -auth admin:changemesplunkclouduf.spl — To jest plik kredy dla Splunk Universal Forwarder, który można pobrać z interfejsu webowego.
Gdzie kliknąć, aby pobrać (w obrazkach)
To jest zwykły archiwum, które można rozpakować. Wewnątrz znajdują się certyfikaty i hasło do połączenia z naszym SplunkCloud i outputs.conf ze wskaźnikiem naszych instancji input. Ten plik będzie aktualny, dopóki nie przeinstalujesz swojej instalacji Splunk lub nie dodasz węzłów input, jeśli instalacja jest on-premise. Dlatego nie ma problemu, aby umieścić go wewnątrz kontenera.
I na koniec — restart. Tak, aby zastosować zmiany, trzeba go zrestartować.
W naszym inputs.conf dodajemy logi, które chcemy przesłać do Splunk. Nie ma potrzeby dodawania tego pliku do obrazu, jeśli na przykład roznosicie konfiguracje przez puppet. Ważne jest, aby Forwarder widział konfiguracje przy uruchomieniu demona, w przeciwnym razie będzie potrzebny .\/splunk restart.
A co to za skrypty docker stats? Na GitHubie znajduje się stare rozwiązanie od , skrypty są stamtąd i zostały dostosowane do współpracy z aktualnymi wersjami Dockera (ce-17.*) i Splunk (7.*).
Z uzyskanymi danymi można tworzyć takie
dashboardy: (para obrazków)
Kod źródłowy dashboardów znajduje się w repie wskazanej na końcu artykułu. Zwróć uwagę, że znajdują się tam 2 pola select: 1 — wybór indeksu (szukane po masce), wybór hosta/kontenera. Maska indeksu najprawdopodobniej będzie musiała zostać zaktualizowana, w zależności od nazw, których używasz.
Na zakończenie, chciałbym zwrócić uwagę na funkcję start() do
entrypoint.sh
start() {
trap teardown EXIT
if [ -z $SPLUNK_INDEX ]; then
echo "'SPLUNK_INDEX' zmienna środowiskowa jest pusta lub niezdefiniowana. Powinna być 'dev' lub '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 'starting' > /tmp/splunk-container.state"
${SPLUNK_HOME}/bin/splunk start
watch_for_failure
}W moim przypadku dla każdego środowiska i każdej pojedynczej jednostki, czy to aplikacji w kontenerze, czy maszyny hosta, używamy oddzielnego indeksu. Dzięki temu nie ucierpi prędkość wyszukiwania przy znacznym gromadzeniu danych. Do nazewnictwa indeksów stosuje się prostą zasadę: _. Dlatego, aby kontener był uniwersalny, przed uruchomieniem samego demona zamieniamy sed-em wildcard na nazwę środowiska. Zmienna z nazwą środowiska jest przekazywana przez zmienne środowiskowe. Brzmi zabawnie.
Warto również zauważyć, że z jakiegoś powodu posiadanie parametru docker nie wpływa na Splunk nazwa hosta. I tak czy inaczej będzie bezustannie wysyłał logi z identyfikatorem swojego kontenera w polu host. Jako rozwiązanie można zamontować /etc/hostname z maszyny hosta i przy uruchamianiu dokonać zamiany podobnej do nazw indeksów.
Przykład 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:roPodsumowanie
Tak, możliwe, że to rozwiązanie nie jest idealne i z pewnością nie jest uniwersalne dla wszystkich, ponieważ występuje wiele „twardego kodowania”. Ale na jego podstawie każdy może stworzyć własny obraz i umieścić go w swoim prywatnym repozytorium artefaktów, jeśli zdarzyło się, że potrzebujesz Splunk Forwarder właśnie w Dockerze.
Linki:
Źródło: habr.com
