Splunk е един от най-разпознаваемите търговски продукти за събиране и анализ на логове. Дори сега, когато продажбите в Русия вече не се извършват, това не е причина да не пишем инструкции/how-to за този продукт.
Задача: събиране на системни логове от docker възли в Splunk, без да променяте конфигурацията на хост машината
Искам да започна с официалния подход, който изглежда странно при използването на Docker.
Какво имаме:
1. Изтеглете образа
$ docker pull splunk/universalforwarder:latest2. Стартирайте контейнера с необходимите параметри
$ docker run -d -p 9997:9997 -e 'SPLUNK_START_ARGS=--accept-license' -e 'SPLUNK_PASSWORD=' splunk/universalforwarder:latest3. Влезте в контейнера
docker exec -it /bin/bashСлед това ни молят да посетим известен адрес в документацията.
И да конфигурираме контейнера след неговото стартиране:
./splunk add forward-server :
./splunk add monitor /var/log
./splunk restart
Изчакайте. Какво?
Но изненадите не свършват тук. Ако стартирате контейнер от официалния образ в интерактивен режим, ще видите следното:
Няколко разочарования
$ docker run -it -p 9997:9997 -e 'SPLUNK_START_ARGS=--accept-license' -e 'SPLUNK_PASSWORD=password' splunk/universalforwarder:latest
PLAY [Run default Splunk provisioning] *******************************************************************************************************************************************************************************************************
Tuesday 09 April 2019 13:40:38 +0000 (0:00:00.096) 0:00:00.096 *********
TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [localhost]
Tuesday 09 April 2019 13:40:39 +0000 (0:00:01.520) 0:00:01.616 *********
TASK [Get actual hostname] *******************************************************************************************************************************************************************************************************************
changed: [localhost]
Tuesday 09 April 2019 13:40:40 +0000 (0:00:00.599) 0:00:02.215 *********
Tuesday 09 April 2019 13:40:40 +0000 (0:00:00.054) 0:00:02.270 *********
TASK [set_fact] ******************************************************************************************************************************************************************************************************************************
ok: [localhost]
Tuesday 09 April 2019 13:40:40 +0000 (0:00:00.075) 0:00:02.346 *********
Tuesday 09 April 2019 13:40:40 +0000 (0:00:00.067) 0:00:02.413 *********
Tuesday 09 April 2019 13:40:40 +0000 (0:00:00.060) 0:00:02.473 *********
Tuesday 09 April 2019 13:40:40 +0000 (0:00:00.051) 0:00:02.525 *********
Tuesday 09 April 2019 13:40:40 +0000 (0:00:00.056) 0:00:02.582 *********
Tuesday 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
Tuesday 09 April 2019 13:40:41 +0000 (0:00:00.087) 0:00:02.886 *********
TASK [splunk_common : Update Splunk directory owner] *****************************************************************************************************************************************************************************************
ok: [localhost]
Tuesday 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
Tuesday 09 April 2019 13:40:41 +0000 (0:00:00.094) 0:00:03.305 *********
и так нататък...
Отлично. В образа дори няма артефакт. Тоест, всеки път при стартиране ще се губи време, за да се изтегли архив с бинарните файлове, да се разархивира и настрои.
А какво стана с docker-way и всичко такова?
Не, благодаря. Ние ще поемем по друг път. Какво ще стане, ако извършим всички тези операции по време на етапа на изграждане? Тогава да започваме!
За да не се бавим, ще покажа веднага крайния образ:
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" ]И така, какво съдържа
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При първото стартиране Splunk иска да зададете потребителско име/парола, НО тези данни се използват само за изпълнение на административни команди за тази конкретна инсталация, тоест, вътре в контейнера. В нашия случай искаме просто да стартираме контейнера, за да работи всичко и логовете да текат на воля. Разбира се, това е хардкод, но не намерих други начини.
По-нататък в сценария се изпълнява
/splunkforwarder/bin/splunk install app /splunkclouduf.spl -auth admin:changemesplunkclouduf.spl — Това е файл с кредити за Splunk Universal Forwarder, който може да бъде изтеглен от уеб интерфейса.
Къде да натиснете, за да изтеглите (в картинки)
Това е обикновен архив, който може да бъде разпакован. Вътре има сертификати и парола за свързване с нашия SplunkCloud и outputs.conf със списък на нашите входни инстанции. Този файл ще бъде актуален, докато не преинсталирате вашата инсталация на Splunk или не добавите входни нодове, ако инсталацията е on-premise. Затова няма нищо страшно в добавянето му в контейнера.
И накрая - рестарт. Да, за да се приложат промените, той трябва да бъде рестартиран.
В нашия inputs.conf добавяме логовете, които искаме да изпратим в Splunk. Не е задължително да добавяте този файл в образа, ако, например, разпределяте конфигурации чрез puppet. Най-важното е Forwarder-ът да вижда конфигурациите при стартирането на демона, иначе ще е необходим ./splunk restart.
А какво представляват скриптите за docker stats? В GitHub има старо решение от , скриптите са взети оттам и доработени за работа с актуалните версии на Docker (ce-17.*) и Splunk (7.*).
С получените данни може да се строят такива
табла за управление: (няколко картинки)
Изходният код на таблата се намира в репозиторият, посочен в края на статията. Обърнете внимание, че там има 2 полета за избор: 1 - избор на индекс (търсят се по маска), избор на хост/контейнер. Маската на индекса вероятно ще трябва да бъде актуализирана в зависимост от имената, които използвате.
В завършек, искам да обърна внимание на функцията start() в
entrypoint.sh
start() {
trap teardown EXIT
if [ -z $SPLUNK_INDEX ]; then
echo "'SPLUNK_INDEX' env variable is empty or not defined. Should be 'dev' or '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
}В моя случай, за всяка среда и всяка отделна единица, било то приложение в контейнер или хост-машина, използваме отделен индекс. Така скоростта на търсене няма да пострада при значително натрупване на данни. За именуването на индексите се използва просто правило: _. Затова, за да е контейнерът универсален, преди стартирането на демона, заменяме sed- wildcard с името на средата. Променливата с името на средата се предава чрез променливи на средата. Звучи забавно.
Също така е важно да се отбележи, че по някаква причина наличието на параметър docker не влияе на Splunk. hostnameТой все пак ще продължи да изпраща логовете с идентификатора на своя контейнер в полето host. Като решение, може да се монтира /etc/hostname от хост машината и при стартиране да се извърши замяна, подобна на имената на индексите.
Пример 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Резюме
Да, възможно е решението да не е идеално и определено да не е универсално за всички, тъй като присъства много «хардкод». Но на базата на него всеки може да създаде свой образ и да го постави в своя приватен артефактор, ако случайно ви е необходим Splunk Forwarder точно в Docker.
Връзки:
Източник: habr.com
