Splunk Universal Forwarder დოკერში, როგორც სისტემის ჟურნალის შემგროვებელი

Splunk Universal Forwarder დოკერში, როგორც სისტემის ჟურნალის შემგროვებელი

Splunk является одним из нескольких наиболее узнаваемых коммерческих продуктов для сбора и анализа логов. Даже сейчас, когда продажи в России больше не производятся, это не повод не писать инструкции/how-to по этому продукту.

დავალება: собирать системные логи с docker нод в Splunk не меняя конфигурацию хост-машины

Начать хотелось бы с официального подхода, который выглядит странноватым при использовании докера.
Ссылка на Docker hub
Что же мы имеем:

1. Пуллим образ

$ docker pull splunk/universalforwarder:latest

2. Стартуем контейнер с нужными параметрами

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

3. Заходим в контейнер

docker exec -it <container-id> /bin/bash

Далее нас просят пройти по известному адресу в документацию.

И конфигурировать контейнер после его запуска:


./splunk add forward-server <host name or ip address>:<listening port>
./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:changeme

splunkclouduf.spl — Это файл креды для Splunk Universal Forwarder, которые можно загрузить из веб интерфейса.

Куда нажимать чтобы скачать (в картинках)Splunk Universal Forwarder დოკერში, როგორც სისტემის ჟურნალის შემგროვებელი

Splunk Universal Forwarder დოკერში, როგორც სისტემის ჟურნალის შემგროვებელი
Это обычный архив, который можно распаковать. Внутри — сертификаты и пароль для подключения к нашему SplunkCloud и outputs.conf со списком наших input инстансов. Этот файл будет актуален до тех пор, пока вы не переустановите свою инсталляцию Splunk или не добавите input нод, если инсталляция on-premise. Поэтому ничего страшного нет в том, чтобы добавить его внутрь контейнера.

И последнее — restart. Да, для применения изменений, нужно его рестартануть.

В наш inputs.conf добавляем логи, которые мы хотим отправлять в Splunk. Необязательно добавлять этот файл в образ, если вы, к примеру, раскидываете конфиги через puppet. Главное лишь в том, чтобы Forwarder видел конфиги, при старте демона, иначе будет нужен ./splunk restart.

А что за docker stats скрипты? На гитхабе есть старое решение от outcoldman, скрипты взяты оттуда и доработаны для работы с актуальными версиями Docker (ce-17.*) и Splunk (7.*).

С полученными данными можно строить такие

дэшборды: (пара картинок)Splunk Universal Forwarder დოკერში, როგორც სისტემის ჟურნალის შემგროვებელი

Splunk Universal Forwarder დოკერში, როგორც სისტემის ჟურნალის შემგროვებელი
Исходный код дэшей лежит в репе, указанной в конце статьи. Обратите внимание, что там присутствует 2 select поля: 1 — выбор индекса (ищутся по маске), выбор хоста/контейнера. Маску индекса скорее всего вам придётся обновить, в зависимости от имён, которые вы используете.

В завершение, хочу обратить внимание на функцию დაწყება () в

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
}

В моём случае, для каждого окружения и каждой отдельной сущности, будь то приложение в контейнере или хост-машина, мы используем отдельный индекс. Так не будет страдать скорость поиска при значительном накоплении данных. Для именования индексов используется простое правило: <environment_name>_<service/application/etc>. Поэтому, чтобы контейнер был универсальным, мы перед запуском непосредственно демона, заменяем sed-ом wildcard на имя окружения. Переменная с именем окружения передается через переменные окружения. Звучит забавно.

Также стоит отметить момент, что по какой-то причине на Splunk не влияет наличие docker параметра მასპინძლის სახელი. Он всё равно будет упорото слать логи с id своего контейнера в поле 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 именно в докере.

ბმულები:

Решение из статьи
Решение от outcoldman вдохновившее переиспользовать часть функционала
Оф. документация по настройке Universal Forwarder

წყარო: www.habr.com

ახალი კომენტარის დამატება