Splunk est l'un des produits commerciaux les plus reconnus pour la collecte et l'analyse des logs. Même maintenant, alors que les ventes en Russie ne sont plus effectuées, cela ne signifie pas qu'il ne faut pas écrire des instructions / how-to sur ce produit.
La tâche: collecter des logs système depuis des nœuds docker dans Splunk sans changer la configuration de la machine hôte
Commençons par l'approche officielle, qui semble un peu étrange lorsque l'on utilise Docker.
Que avons-nous :
1. Tirons l'image
$ docker pull splunk/universalforwarder:latest2. Démarrons le conteneur avec les paramètres nécessaires
$ docker run -d -p 9997:9997 -e 'SPLUNK_START_ARGS=--accept-license' -e 'SPLUNK_PASSWORD=' splunk/universalforwarder:latest3. Accédons au conteneur
docker exec -it /bin/bashEnsuite, on nous demande de suivre une adresse bien connue dans la documentation.
Et de configurer le conteneur après son lancement :
./splunk add forward-server :
./splunk add monitor /var/log
./splunk restart
Attendez. Quoi?
Mais les surprises ne s'arrêtent pas là. Si vous lancez le conteneur à partir de l'image officielle en mode interactif, vous verrez ce qui suit :
Un peu de déception
$ docker run -it -p 9997:9997 -e 'SPLUNK_START_ARGS=--accept-license' -e 'SPLUNK_PASSWORD=password' splunk/universalforwarder:latest
PLAY [Exécuter le provisioning par défaut de Splunk] *******************************************************************************************************************************************************************************************************
Mardi 09 avril 2019 13:40:38 +0000 (0:00:00.096) 0:00:00.096 *********
TASK [Collecte des faits] ***********************************************************************************************************************************************************************************************************************
ok: [localhost]
Mardi 09 avril 2019 13:40:39 +0000 (0:00:01.520) 0:00:01.616 *********
TASK [Obtenir le nom d'hôte actuel] *******************************************************************************************************************************************************************************************************************
changé: [localhost]
Mardi 09 avril 2019 13:40:40 +0000 (0:00:00.599) 0:00:02.215 *********
Mardi 09 avril 2019 13:40:40 +0000 (0:00:00.054) 0:00:02.270 *********
TASK [set_fact] ******************************************************************************************************************************************************************************************************************************
ok: [localhost]
Mardi 09 avril 2019 13:40:40 +0000 (0:00:00.075) 0:00:02.346 *********
Mardi 09 avril 2019 13:40:40 +0000 (0:00:00.067) 0:00:02.413 *********
Mardi 09 avril 2019 13:40:40 +0000 (0:00:00.060) 0:00:02.473 *********
Mardi 09 avril 2019 13:40:40 +0000 (0:00:00.051) 0:00:02.525 *********
Mardi 09 avril 2019 13:40:40 +0000 (0:00:00.056) 0:00:02.582 *********
Mardi 09 avril 2019 13:40:41 +0000 (0:00:00.216) 0:00:02.798 *********
inclus: /opt/ansible/roles/splunk_common/tasks/change_splunk_directory_owner.yml pour localhost
Mardi 09 avril 2019 13:40:41 +0000 (0:00:00.087) 0:00:02.886 *********
TASK [splunk_common : Mettre à jour le propriétaire du répertoire Splunk] *****************************************************************************************************************************************************************************************
ok: [localhost]
Mardi 09 avril 2019 13:40:41 +0000 (0:00:00.324) 0:00:03.210 *********
inclus: /opt/ansible/roles/splunk_common/tasks/get_facts.yml pour localhost
Mardi 09 avril 2019 13:40:41 +0000 (0:00:00.094) 0:00:03.305 *********
et ainsi de suite...
Génial. L'image n'a même pas d'artefact. Cela signifie qu'à chaque fois que vous la lancez, du temps sera perdu à télécharger l'archive contenant les binaires, puis à décompresser et configurer.
Et le docker-way et tout ça ?
Non, merci. Nous allons prendre un autre chemin. Et si nous réalisions toutes ces opérations au moment de la construction ? Alors, allons-y !
Pour ne pas perdre de temps, je vous montre directement l'image finale :
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" ]Alors, que contient
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 eofLors du premier démarrage, Splunk demande un login/mot de passe, MAIS ces informations sont utilisées uniquement pour exécuter des commandes administratives de cette installation précise, c'est-à-dire, à l'intérieur du conteneur. Dans notre cas, nous voulons simplement démarrer le conteneur pour que tout fonctionne et que les journaux affluent en masse. Bien sûr, c'est du hardcoding, mais je n'ai trouvé aucun autre moyen.
Ensuite, le scénario se poursuit
/splunkforwarder/bin/splunk install app /splunkclouduf.spl -auth admin:changemesplunkclouduf.spl — C'est le fichier de crédentiels pour le Splunk Universal Forwarder, qui peut être téléchargé depuis l'interface Web.
Où cliquer pour télécharger (en images)
C'est une archive classique que l'on peut décompresser. À l'intérieur se trouvent les certificats et le mot de passe pour se connecter à notre SplunkCloud et outputs.conf avec la liste de nos instances d'input. Ce fichier sera valable jusqu'à ce que vous réinstalliez votre installation Splunk ou que vous ajoutiez des nœuds d'input, si l'installation est on-premise. Donc, il n'y a rien de grave à l'ajouter à l'intérieur du conteneur.
Et enfin — le redémarrage. Oui, pour appliquer les changements, il faut le redémarrer.
Dans notre inputs.conf nous ajoutons les logs que nous souhaitons envoyer à Splunk. Il n'est pas nécessaire d'ajouter ce fichier dans l'image, si par exemple, vous distribuez des configs via puppet. L'essentiel est que le Forwarder voit les configs lors du démarrage du démon, sinon vous aurez besoin de ./splunk restart.
Et quelles sont ces scripts docker stats ? Il existe une ancienne solution sur github de , les scripts ont été pris là-bas et retravaillés pour fonctionner avec les versions actuelles de Docker (ce-17.*) et Splunk (7.*).
Avec les données obtenues, il est possible de construire de tels
tableaux de bord : (quelques images)
Le code source des dashboards se trouve dans le dépôt indiqué à la fin de l'article. Notez qu'il y a 2 champs de sélection : 1 — choix de l'index (recherche par motif), sélection de l'hôte/conteneur. Vous devrez probablement mettre à jour le motif de l'index, en fonction des noms que vous utilisez.
Pour terminer, je veux attirer votre attention sur la fonction start() dans
entrypoint.sh
start() {
trap teardown EXIT
if [ -z $SPLUNK_INDEX ]; then
echo "La variable d'environnement 'SPLUNK_INDEX' est vide ou non définie. Elle doit être 'dev' ou '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 'démarrage' > /tmp/splunk-container.state"
${SPLUNK_HOME}/bin/splunk start
watch_for_failure
}Dans mon cas, pour chaque environnement et chaque entité distincte, que ce soit une application dans un conteneur ou une machine hôte, nous utilisons un index distinct. Ainsi, la vitesse de recherche ne sera pas affectée lors d'une accumulation significative de données. Pour nommer les index, nous utilisons une règle simple : _. Donc, pour que le conteneur soit universel, avant de démarrer le démon, nous remplaçons sed-le wildcard par le nom de l'environnement. La variable contenant le nom de l'environnement est transmise via les variables d'environnement. Cela sonne amusant.
Il convient également de noter que, pour une raison quelconque, la présence du paramètre docker n'affecte pas Splunk. nom d'hôteIl continuera à envoyer des journaux avec l'ID de son conteneur dans le champ host. Comme solution, vous pouvez monter /etc/hostname du serveur hôte et, au démarrage, effectuer un remplacement similaire aux noms des index.
Exemple 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:roConclusion
Oui, il est possible que la solution ne soit pas idéale et certainement pas universelle pour tous, car il y a beaucoup de «hardcoding». Mais sur cette base, chacun peut créer sa propre image et la placer dans son dépôt privé, si jamais vous avez besoin de Splunk Forwarder justement dans Docker.
Liens :
Source : habr.com
