Splunk es uno de los productos comerciales más reconocibles para la recolección y análisis de registros. Aunque actualmente no se realizan ventas en Rusia, eso no significa que no debamos escribir guías sobre este producto.
Tarea: recopilar registros del sistema desde nodos de docker en Splunk sin cambiar la configuración de la máquina host
Me gustaría comenzar con el enfoque oficial, que resulta un tanto extraño al utilizar Docker.
Entonces, ¿qué tenemos?
1. Descargar la imagen
$ docker pull splunk/universalforwarder:latest2. Iniciar el contenedor con los parámetros necesarios
$ docker run -d -p 9997:9997 -e 'SPLUNK_START_ARGS=--accept-license' -e 'SPLUNK_PASSWORD=' splunk/universalforwarder:latest3. Acceder al contenedor
docker exec -it /bin/bashA continuación, se nos pide que vayamos a la dirección conocida en la documentación.
Y configurar el contenedor después de su inicio:
./splunk add forward-server :
./splunk add monitor /var/log
./splunk restart
Espera. ¿Qué?
Pero las sorpresas no terminan aquí. Si inicias el contenedor desde la imagen oficial en modo interactivo, verás lo siguiente:
Un poco de decepción
$ docker run -it -p 9997:9997 -e 'SPLUNK_START_ARGS=--accept-license' -e 'SPLUNK_PASSWORD=password' splunk/universalforwarder:latest
PLAY [Ejecutar la provisión predeterminada de Splunk] *******************************************************************************************************************************************************************************************************
Martes 09 de abril de 2019 13:40:38 +0000 (0:00:00.096) 0:00:00.096 *********
TASK [Recolección de Hechos] ***********************************************************************************************************************************************************************************************************************
ok: [localhost]
Martes 09 de abril de 2019 13:40:39 +0000 (0:00:01.520) 0:00:01.616 *********
TASK [Obtener el hostname actual] *******************************************************************************************************************************************************************************************************************
changed: [localhost]
Martes 09 de abril de 2019 13:40:40 +0000 (0:00:00.599) 0:00:02.215 *********
Martes 09 de abril de 2019 13:40:40 +0000 (0:00:00.054) 0:00:02.270 *********
TASK [set_fact] ******************************************************************************************************************************************************************************************************************************
ok: [localhost]
Martes 09 de abril de 2019 13:40:40 +0000 (0:00:00.075) 0:00:02.346 *********
Martes 09 de abril de 2019 13:40:40 +0000 (0:00:00.067) 0:00:02.413 *********
Martes 09 de abril de 2019 13:40:40 +0000 (0:00:00.060) 0:00:02.473 *********
Martes 09 de abril de 2019 13:40:40 +0000 (0:00:00.051) 0:00:02.525 *********
Martes 09 de abril de 2019 13:40:40 +0000 (0:00:00.056) 0:00:02.582 *********
Martes 09 de abril de 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
Martes 09 de abril de 2019 13:40:41 +0000 (0:00:00.087) 0:00:02.886 *********
TASK [splunk_common : Actualizar el propietario del directorio de Splunk] *****************************************************************************************************************************************************************************************
ok: [localhost]
Martes 09 de abril de 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
Martes 09 de abril de 2019 13:40:41 +0000 (0:00:00.094) 0:00:03.305 *********
y así sucesivamente...
Excelente. La imagen ni siquiera tiene un artefacto. Es decir, cada vez que se inicie, se perderá tiempo descargando el archivo con los binarios, descomprimiéndolo y configurándolo.
¿Y qué pasa con el docker-way y todo eso?
No, gracias. Vamos a optar por otro camino. ¿Qué tal si realizamos todas estas operaciones en la etapa de construcción? ¡Vamos allá!
Para no hacer esperar demasiado, mostraré directamente la imagen final:
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" ]Entonces, ¿qué contiene
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 eofEn el primer inicio, Splunk solicita que se le asigne un usuario/contraseña, PERO estos datos se utilizan solo para ejecutar comandos administrativos en esta instalación específica, es decir, dentro del contenedor. En nuestro caso, solo queremos iniciar el contenedor para que todo funcione y los registros fluyan sin cesar. Por supuesto, esto es un hardcode, pero no encontré otras alternativas.
A continuación, se ejecuta el script
/splunkforwarder/bin/splunk install app /splunkclouduf.spl -auth admin:changemesplunkclouduf.spl — Este es el archivo de credenciales para Splunk Universal Forwarder, que se puede descargar desde la interfaz web.
Dónde hacer clic para descargar (en las imágenes)
Es un archivo comprimido común que se puede descomprimir. Dentro hay certificados y la contraseña para conectarse a nuestro SplunkCloud y outputs.conf con la lista de nuestras instancias de entrada. Este archivo será válido hasta que reinstales tu instalación de Splunk o agregues nodos de entrada, si la instalación es local. Por lo tanto, no hay nada de malo en agregarlo dentro del contenedor.
Y por último, reiniciar. Sí, para aplicar los cambios, es necesario reiniciar.
En nuestro inputs.conf agregamos los registros que queremos enviar a Splunk. No es necesario agregar este archivo a la imagen, si, por ejemplo, distribuyes la configuración a través de Puppet. Lo principal es que el Forwarder vea las configuraciones al iniciar el daemon, de lo contrario será necesario .\/splunk restart.
¿Y qué hay de los scripts de docker stats? En GitHub hay una solución antigua de , los scripts se tomaron de allí y se modificaron para funcionar con las versiones actuales de Docker (ce-17.*) y Splunk (7.*).
Con los datos obtenidos se pueden construir estos
tableros: (un par de imágenes)
El código fuente de los tableros está en el repositorio mencionado al final del artículo. Ten en cuenta que hay 2 campos de selección: 1 — selección del índice (se buscan según la máscara), selección de host/contenedor. Es probable que tengas que actualizar la máscara del índice, dependiendo de los nombres que utilices.
Para concluir, quiero resaltar la función start() en
entrypoint.sh
start() {
trap teardown EXIT
if [ -z $SPLUNK_INDEX ]; then
echo "La variable de entorno 'SPLUNK_INDEX' está vacía o no está definida. Debe ser 'dev' o '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 'iniciando' > /tmp/splunk-container.state"
${SPLUNK_HOME}/bin/splunk start
watch_for_failure
}En mi caso, para cada entorno y cada entidad individual, ya sea una aplicación en un contenedor o una máquina anfitriona, utilizamos un índice separado. De este modo, no se verá afectada la velocidad de búsqueda con una acumulación significativa de datos. La nomenclatura de los índices sigue una regla simple: _. Por lo tanto, para que el contenedor sea universal, antes de iniciar el daemon, reemplazamos sed-el wildcard por el nombre del entorno. La variable con el nombre del entorno se pasa a través de variables de entorno. Suena divertido.
También hay que destacar que, por alguna razón, el parámetro docker no afecta a Splunk. hostname. De todos modos, seguirá enviando logs con el id de su contenedor al campo host. Como solución, se puede montar /etc/hostname desde la máquina host y al iniciar hacer un reemplazo, similar a los nombres de índices.
Ejemplo de 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"Summary
Sí, es posible que la solución no sea perfecta y desde luego no universal para todos, ya que hay mucho «hardcode». Pero sobre esa base, cada uno puede construir su propia imagen y guardarla en su propio artefacto privado, si acaso necesita un Splunk Forwarder específicamente en Docker.
Enlaces:
Fuente: habr.com
