Installation EFK · 17 min read · Dec 18, 2025

Comment installer la pile de journalisation Elasticsearch, Fluentd et Kibana (EFK) sur Ubuntu 22.04

La surveillance et l’analyse des journaux sont une partie essentielle de l’infrastructure des serveurs ou des conteneurs et sont utiles lors de la gestion d’applications complexes. L’une des solutions de journalisation populaires est la pile Elasticsearch, Fluentd et Kibana (EFK). Avant d’aller plus loin dans le tutoriel, apprenons à connaître les composants de la pile.

Elasticsearch est un moteur de recherche distribué, évolutif et en temps réel qui permet la recherche en texte intégral et l’analyse. Il est utilisé pour indexer et rechercher de grandes quantités de données. Il est couramment déployé aux côtés de Kibana, un puissant tableau de bord de visualisation de données pour Elasticsearch. Kibana vous permet d’explorer les données de journal d’Elasticsearch et de créer des tableaux de bord et des requêtes pour obtenir des informations sur votre application. Fluentd collecte, transforme et expédie les données de journal vers le backend d’Elasticsearch.

Dans ce tutoriel, nous allons installer la pile EFK en utilisant Docker sur une machine Ubuntu 22.04 et envoyer les journaux des conteneurs à Kibana après les avoir filtrés et transformés à l’aide de Fluentd.

Prérequis

  • Un serveur exécutant Ubuntu 22.04 avec un minimum de 6 Go de RAM.
  • Un utilisateur non-root avec des privilèges sudo.
  • Le pare-feu uncomplicated (UFW) est activé et en cours d’exécution.
  • Un nom de domaine entièrement qualifié (FQDN) pointant vers le serveur comme, kibana.example.com.
  • Tout est à jour. $ sudo apt update && sudo apt upgrade

Étape 1 - Configurer le pare-feu

Avant d’installer des paquets, la première étape consiste à configurer le pare-feu pour autoriser les connexions HTTP et HTTPS.

Vérifiez l’état du pare-feu.

$ sudo ufw status

Vous devriez voir quelque chose comme ce qui suit.

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)

Autorisez les ports HTTP et HTTPS.

$ sudo ufw allow http
$ sudo ufw allow https

Vérifiez à nouveau l’état pour confirmer.

$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere
80/tcp                     ALLOW       Anywhere
443                        ALLOW       Anywhere
OpenSSH (v6)               ALLOW       Anywhere (v6)
80/tcp (v6)                ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)

Étape 2 - Installer Docker et Docker Compose

Ajoutez la clé GPG officielle de Docker.

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg

Exécutez la commande suivante pour ajouter le dépôt Docker.

$ echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Mettez à jour le système pour inclure le dépôt de Docker.

$ sudo apt update

Installez Docker et le plugin Docker Compose.

$ sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin

Ce tutoriel utilisera le plugin Docker Compose v2 au lieu de l’ancien binaire hérité. Par conséquent, la commande pour l’exécuter a changé de docker-compose à docker compose et cela est reflété ici.

Docker fonctionne avec des privilèges élevés, vous devrez donc utiliser sudo fréquemment pour exécuter des commandes. La meilleure option est d’ajouter votre compte utilisateur Linux au groupe d’utilisateurs docker.

$ sudo usermod -aG docker ${USER}

La variable ${USER} prend le compte système actuellement connecté. Si vous n’êtes pas connecté avec l’utilisateur auquel vous souhaitez donner des privilèges, remplacez ${USER} par le nom d’utilisateur.

Pour appliquer la nouvelle appartenance au groupe, déconnectez-vous du serveur et reconnectez-vous, ou utilisez la commande suivante. Vous serez invité à entrer le mot de passe de l’utilisateur.

$ su - ${USER}

Étape 3 - Créer le fichier Docker Compose

Tout d’abord, créez le répertoire pour le projet EFK.

$ mkdir ~/efk

Passez au répertoire.

$ cd ~/efk

Créez et ouvrez le fichier docker-compose.yml pour l’édition.

$ nano docker-compose.yml

Collez le code suivant dedans.

services:
  # Déployer en utilisant l'image personnalisée qui sera automatiquement créée lors du processus de construction.
  fluentd:
    build: ./fluentd
    volumes:
      - ./fluentd/conf:/fluentd/etc
    links: # Envoie les journaux entrants vers le conteneur elasticsearch.
      - elasticsearch
    depends_on:
      - elasticsearch
    ports: # Expose le port 24224 sur les protocoles TCP et UDP pour l'agrégation des journaux
      - 24224:24224
      - 24224:24224/udp

  elasticsearch:
    image: elasticsearch:8.7.1
    expose:
      - 9200
    environment:
      - discovery.type=single-node # Fonctionne comme un nœud unique
      - xpack.security.enabled=false
    volumes: # Stocke les données d'Elasticsearch localement sur le volume Docker esdata
      - esdata:/usr/share/elasticsearch/data

  kibana:
    image: kibana:8.7.1
    links: # Lien du service kibana au conteneur elasticsearch
      - elasticsearch
    depends_on:
      - elasticsearch
    ports:
      - 5601:5601
    environment: # Configuration d'hôte définie
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200

# Définir le volume Docker nommé esdata pour le conteneur Elasticsearch.
volumes:
  esdata:

Enregistrez le fichier en appuyant sur Ctrl + X et en entrant Y lorsque vous y êtes invité. Nous avons configuré le démarrage de trois services, un pour chacun, Fluentd, Elasticsearch et Kibana.

Pour Fluentd, nous allons construire un conteneur au lieu d’une image prête à l’emploi. Les fichiers de construction pour Fluentd seront configurés à l’étape suivante. Nous avons monté un répertoire pour ses fichiers de construction, et un volume pour les fichiers de configuration, et exposé le port 24224 sur les protocoles TCP et UDP pour l’agrégation des journaux.

Le prochain service est Elasticsearch et nous utilisons la dernière version disponible au moment de la rédaction de ce tutoriel. Nous l’avons exposé via le port 9200 et avons configuré quelques variables d’environnement afin que nous puissions le faire fonctionner comme un cluster à nœud unique et avoir désactivé les fonctionnalités de sécurité. Cela n’est généralement pas recommandé mais l’activation de la sécurité est hors du champ d’application de ce tutoriel. Nous avons également monté un volume local pour les données d’Elasticsearch.

Enfin, nous configurons Kibana et l’exposons via le port 5601 qui sera utilisé pour accéder au tableau de bord. Nous avons également configuré une variable pour configurer l’hôte Elasticsearch afin qu’il puisse y accéder.

Étape 4 - Configurer les fichiers de construction de Fluentd

Créez Fluentd et le répertoire de configuration.

$ mkdir fluentd/conf -p

Exécutez la commande tree pour vérifier la structure du répertoire.

$ tree

Cela devrait ressembler à ce qui suit.

Sortie de la commande Tree

Passez au répertoire Fluentd.

$ cd fluentd

Créez et ouvrez le Dockerfile pour l’édition.

$ nano Dockerfile

Collez le code suivant dedans. Ce code tire l’image Docker Debian de Fluentd et installe le plugin Fluentd pour Elasticsearch.

# fluentd/Dockerfile
FROM fluent/fluentd:v1.16-debian-1
USER root
RUN ["gem", "install", "fluent-plugin-elasticsearch", "--no-document", "--version", "5.3.0"]
USER fluent

Enregistrez le fichier en appuyant sur Ctrl + X et en entrant Y lorsque vous y êtes invité.

Passez au répertoire de configuration.

$ cd conf

Créez et ouvrez le fichier fluentd.conf pour l’édition.

$ nano fluentd.conf

Collez le code suivant dedans.

# bind fluentd sur IP 0.0.0.0
# port 24224

  @type forward
  port 24224
  bind 0.0.0.0


# envoyer les journaux à Elasticsearch
# l'hôte doit correspondre au service du conteneur Elasticsearch

  @type copy
  
    @type elasticsearch_dynamic
    hosts elasticsearch:9200
    logstash_format true
    logstash_prefix fluentd
    logstash_dateformat %Y%m%d
    include_tag_key true
    tag_key @log_name
    include_timestamp true
    flush_interval 30s
  
  
    @type stdout
  

Enregistrez le fichier en appuyant sur Ctrl + X et en entrant Y lorsque vous y êtes invité.

La directive source ci-dessus utilise le plugin forward qui transforme Fluentd en un point de terminaison TCP pour accepter les paquets TCP.

La directive match recherche des événements avec des balises correspondantes, ce qui dans ce cas signifie qu’elle correspond à tous les événements. Nous utiliserons le plugin elasticsearch_dynamic pour le stockage, ce qui permet de spécifier des valeurs de configuration dynamiquement. Le champ hosts spécifie le nom d’hôte pour l’application Elasticsearch qui est le nom du service dans le fichier Docker compose. Le logstash_format est défini sur true, ce qui signifie que Fluentd utilise le format de nom conventionnel logstash-%Y.%m.%dlogstash-%Y.%m.%d. Le nom de préfixe pour écrire les événements est défini sur fluend. Le include_tag_key est défini sur true, ce qui ajoute la balise Fluentd au format JSON. Le tag_key est le nom de champ à extraire pour la balise. La définition de la variable include_timestamp sur true ajoute un champ d’horodatage au journal. L’intervalle flush_interval spécifie l’intervalle entre les vidanges de données. Nous utilisons également le plugin stdout pour imprimer les événements/journaux à la sortie standard.

Étape 5 - Exécuter les conteneurs Docker

Retournez au répertoire EFK.

$ cd ~/efk

Démarrez les conteneurs en utilisant la commande suivante.

$ docker compose up -d

Vérifiez l’état des conteneurs en cours d’exécution.

$ docker ps
b3780c311154   efk-fluentd           "tini -- /bin/entryp…"   9 seconds ago   Up 8 seconds   5140/tcp, 0.0.0.0:24224->24224/tcp, 0.0.0.0:24224->24224/udp, :::24224->24224/tcp, :::24224->24224/udp   efk-fluentd-1
5a48f0a9ade1   kibana:8.7.1          "/bin/tini -- /usr/l…"   9 seconds ago   Up 7 seconds   0.0.0.0:5601->5601/tcp, :::5601->5601/tcp                                                                efk-kibana-1
dab3a0ab0312   elasticsearch:8.7.1   "/bin/tini -- /usr/l…"   9 seconds ago   Up 8 seconds   9200/tcp, 9300/tcp                                                                                       efk-elasticsearch-1

Vous pouvez également utiliser la commande suivante pour cela.

$ docker compose ps
NAME                  IMAGE                 COMMAND                  SERVICE             CREATED             STATUS              PORTS
efk-elasticsearch-1   elasticsearch:8.7.1   "/bin/tini -- /usr/l…"   elasticsearch       37 seconds ago      Up 36 seconds       9200/tcp, 9300/tcp
efk-fluentd-1         efk-fluentd           "tini -- /bin/entryp…"   fluentd             37 seconds ago      Up 36 seconds       5140/tcp, 0.0.0.0:24224->24224/tcp, 0.0.0.0:24224->24224/udp, :::24224->24224/tcp, :::24224->24224/udp
efk-kibana-1          kibana:8.7.1          "/bin/tini -- /usr/l…"   kibana              37 seconds ago      Up 36 seconds       0.0.0.0:5601->5601/tcp, :::5601->5601/tcp

Exécutez les commandes suivantes pour vérifier les journaux du processus de construction EFK.

$ docker logs efk-fluentd-1
$ docker logs efk-kibana-1
$ docker logs efk-elasticsearch-1

Inspectez le conteneur Elasticsearch. Il affichera les paramètres détaillés du conteneur.

$ docker inspect efk-elasticsearch-1

Vous pouvez remarquer l’adresse IP attribuée au conteneur.

[
    {
        "Id": "dab3a0ab03120d3a7192045e1ea84fdd0f8fdb7819cc6d6780e05109d61e0b66",
        "Created": "2023-05-04T09:58:00.256169904Z",
        "Path": "/bin/tini",
        "Args": [
            "--",
            "/usr/local/bin/docker-entrypoint.sh",
            "eswrapper"
        ],
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 23619,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2023-05-04T09:58:00.563700803Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        },
        "Image": "sha256:59075530be34d3a06866f894ae9735f6d739a7a751ad45efb86dec3c9bd16836",
        "ResolvConfPath": "/var/lib/docker/containers/dab3a0ab03120d3a7192045e1ea84fdd0f8fdb7819cc6d6780e05109d61e0b66/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/dab3a0ab03120d3a7192045e1ea84fdd0f8fdb7819cc6d6780e05109d61e0b66/hostname",
        "HostsPath": "/var/lib/docker/containers/dab3a0ab03120d3a7192045e1ea84fdd0f8fdb7819cc6d6780e05109d61e0b66/hosts",
        "LogPath": "/var/lib/docker/containers/dab3a0ab03120d3a7192045e1ea84fdd0f8fdb7819cc6d6780e05109d61e0b66/dab3a0ab03120d3a7192045e1ea84fdd0f8fdb7819cc6d6780e05109d61e0b66-json.log",
        "Name": "/efk-elasticsearch-1",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "docker-default",
        "ExecIDs": null,
        "HostConfig": {
            "Binds": null,
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            },
            "NetworkMode": "efk_default",
            "PortBindings": {},
            "RestartPolicy": {
                "Name": "",
                "MaximumRetryCount": 0
            },
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "ConsoleSize": [
                0,
                0
            ],
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "private",
            "Dns": null,
            "DnsOptions": null,
            "DnsSearch": null,
            "ExtraHosts": [],
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": false,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": null,
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": null,
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": null,
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": null,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "Mounts": [
                {
                    "Type": "volume",
                    "Source": "efk_esdata",
                    "Target": "/usr/share/elasticsearch/data",
                    "VolumeOptions": {}
                }
            ],
            "MaskedPaths": [
                "/proc/asound",
                "/proc/acpi",
                "/proc/kcore",
                "/proc/keys",
                "/proc/latency_stats",
                "/proc/timer_list",
                "/proc/timer_stats",
                "/proc/sched_debug",
                "/proc/scsi",
                "/sys/firmware"
            ],
            "ReadonlyPaths": [
                "/proc/bus",
                "/proc/fs",
                "/proc/irq",
                "/proc/sys",
                "/proc/sysrq-trigger"
            ]
        },
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/ee03648cf34e03601848b1769569b4d3bb7192db118102ca050215ba87060bbf-init/diff:/var/lib/docker/overlay2/51d6cfcb59e473a3f163e68984a1ba1325a2c816ed7925c4dffdefcf2e104d11/diff:/var/lib/docker/overlay2/b9c096454bda31f1cb2ea33f108be8b29b2e94827ebe94cc17563eb596b7cab1/diff:/var/lib/docker/overlay2/effe604c5b015ba02cf3b7a238bd3ff5dad7970a72e689ef5275fcf03fd0bcd1/diff:/var/lib/docker/overlay2/72fbf23251467ea2f6af8d9458c7fdd8fa3ef716eeafd9319ceff59d07d96788/diff:/var/lib/docker/overlay2/02094ec9e4ebb04371f782744a3a46852a00bf6fd7e8820d466a3576aeb9d5fc/diff:/var/lib/docker/overlay2/ce364cdd636b67e10c879aa152360d965d08fe456663ed8fbe78c3bd37bde6c7/diff:/var/lib/docker/overlay2/33bf44b475ea5ea249845b7eed75ded47dd9dc7877b9231fa4195b4753071945/diff:/var/lib/docker/overlay2/4f19bd8089599ef879075012c710ec464d8e0446fc0a0813850657dddd23a5dc/diff:/var/lib/docker/overlay2/a39a61b12d8565c6d5b33c17a04d47c8bd47609a787e0548fbac0d47d00eecc8/diff:/var/lib/docker/overlay2/cbd9d77eb9ed6b600511f9a676aab511d2aa2b3dbd18d5403559699558546996/diff",
                "MergedDir": "/var/lib/docker/overlay2/ee03648cf34e03601848b1769569b4d3bb7192db118102ca050215ba87060bbf/merged",
                "UpperDir": "/var/lib/docker/overlay2/ee03648cf34e03601848b1769569b4d3bb7192db118102ca050215ba87060bbf/diff",
                "WorkDir": "/var/lib/docker/overlay2/ee03648cf34e03601848b1769569b4d3bb7192db118102ca050215ba87060bbf/work"
            },
            "Name": "overlay2"
        },
        "Mounts": [
            {
                "Type": "volume",
                "Name": "efk_esdata",
                "Source": "/var/lib/docker/volumes/efk_esdata/_data",
                "Destination": "/usr/share/elasticsearch/data",
                "Driver": "local",
                "Mode": "z",
                "RW": true,
                "Propagation": ""
            }
        ],
        "Config": {
            "Hostname": "dab3a0ab0312",
            "Domainname": "",
            "User": "elasticsearch:root",
            "AttachStdin": false,
            "AttachStdout": true,
            "AttachStderr": true,
            "ExposedPorts": {
                "9200": {},
                "9200/tcp": {},
                "9300/tcp": {}
            },
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
                "xpack.security.enabled=false",
                "discovery.type=single-node",
                "PATH=/usr/share/elasticsearch/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
                "ELASTIC_CONTAINER=true"
            ],
            "Cmd": [
                "eswrapper"
            ],
            "Image": "elasticsearch:8.7.1",
            "Volumes": null,
            "WorkingDir": "/usr/share/elasticsearch",
            "Entrypoint": [
                "/bin/tini",
                "--",
                "/usr/local/bin/docker-entrypoint.sh"
            ],
            "OnBuild": null,
            "Labels": {
                "com.docker.compose.config-hash": "51c818791aa87ea7eccc389578c76ec4d596265eba8baefb8833bf5df13777e3",
                "com.docker.compose.container-number": "1",
                "com.docker.compose.depends_on": "",
                "com.docker.compose.image": "sha256:59075530be34d3a06866f894ae9735f6d739a7a751ad45efb86dec3c9bd16836",
                "com.docker.compose.oneoff": "False",
                "com.docker.compose.project": "efk",
                "com.docker.compose.project.config_files": "/home/navjot/efk/docker-compose.yml",
                "com.docker.compose.project.working_dir": "/home/navjot/efk",
                "com.docker.compose.service": "elasticsearch",
                "com.docker.compose.version": "2.17.3",
                "org.label-schema.build-date": "2023-04-27T04:33:42.127815583Z",
                "org.label-schema.license": "Elastic-License-2.0",
                "org.label-schema.name": "Elasticsearch",
                "org.label-schema.schema-version": "1.0",
                "org.label-schema.url": "https://www.elastic.co/products/elasticsearch",
                "org.label-schema.usage": "https://www.elastic.co/guide/en/elasticsearch/reference/index.html",
                "org.label-schema.vcs-ref": "f229ed3f893a515d590d0f39b05f68913e2d9b53",
                "org.label-schema.vcs-url": "https://github.com/elastic/elasticsearch",
                "org.label-schema.vendor": "Elastic",
                "org.label-schema.version": "8.7.1",
                "org.opencontainers.image.created": "2023-04-27T04:33:42.127815583Z",
                "org.opencontainers.image.documentation": "https://www.elastic.co/guide/en/elasticsearch/reference/index.html",
                "org.opencontainers.image.licenses": "Elastic-License-2.0",
                "org.opencontainers.image.ref.name": "ubuntu",
                "org.opencontainers.image.revision": "f229ed3f893a515d590d0f39b05f68913e2d9b53",
                "org.opencontainers.image.source": "https://github.com/elastic/elasticsearch",
                "org.opencontainers.image.title": "Elasticsearch",
                "org.opencontainers.image.url": "https://www.elastic.co/products/elasticsearch",
                "org.opencontainers.image.vendor": "Elastic",
                "org.opencontainers.image.version": "8.7.1"
            }
        },
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "bf47cd7764585766349085d35100611e086cf233fc9fc655c6eb9e086f1cd59a",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "9200/tcp": null,
                "9300/tcp": null
            },
            "SandboxKey": "/var/run/docker/netns/bf47cd776458",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "efk_default": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "efk-elasticsearch-1",
                        "elasticsearch",
                        "dab3a0ab0312"
                    ],
                    "NetworkID": "1bc8ac0185982b84a24a201852f2cddc0432a3ffff1a2bd4008074875f696cac",
                    "EndpointID": "e1c67199e679f350d1da47f0b1e208ec6a7767eb57d60f773ba08b88a6962dcf",
                    "Gateway": "172.23.0.1",
                    "IPAddress": "172.23.0.2",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:17:00:02",
                    "DriverOpts": null
                }
            }
        }
    }
]

Comme vous pouvez le voir, le conteneur a obtenu 172.23.0.2 comme adresse IP. Exécutez la commande suivante pour vérifier si Elasticsearch fonctionne correctement.

$ curl 172.23.0.2:9200
{
  "name" : "dab3a0ab0312",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "gldMFBtQSxS5sL93rBAdzA",
  "version" : {
    "number" : "8.7.1",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "f229ed3f893a515d590d0f39b05f68913e2d9b53",
    "build_date" : "2023-04-27T04:33:42.127815583Z",
    "build_snapshot" : false,
    "lucene_version" : "9.5.0",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

Étape 6 - Configurer Kibana

Maintenant que la pile EFK est déployée, il est temps de configurer Kibana. Ouvrez l’URL http://:5601 dans le navigateur.

Page d'accueil de Kibana

Cliquez sur le bouton Explorer par moi-même pour accéder au tableau de bord Kibana.

Tableau de bord Kibana

Cliquez sur le lien Gestion de la pile pour configurer la vue de données Kibana. Sélectionnez l’option Kibana >> Vues de données dans la barre latérale gauche pour ouvrir la page de vue de données.

Page de vue de données Kibana

Cliquez sur le bouton Créer une vue de données pour continuer.

Créer une vue de données Kibana

Entrez le nom de la vue de données et le modèle d’index comme fluentd-*. Assurez-vous que le champ Timestamp est défini sur @timestamp. Le champ source sera mis à jour automatiquement. Cliquez sur le bouton Enregistrer la vue de données dans Kibana pour terminer la création de la vue de données.

Ensuite, cliquez sur le menu supérieur (ellipse), et cliquez sur l’option Découvrir pour afficher la surveillance des journaux.

Vous obtiendrez la page suivante confirmant que votre configuration fonctionne parfaitement. Les journaux sont tous pris d’Elasticsearch et expédiés par l’agrégation de journaux Fluentd.

Surveillance des journaux Fluentd Kibana

Étape 7 - Installer Nginx

Ubuntu 22.04 est livré avec une version plus ancienne de Nginx. Vous devez télécharger le dépôt officiel de Nginx pour installer la dernière version.

Importez la clé de signature de Nginx.

$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null

Ajoutez le dépôt pour la version stable de Nginx.

$ echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg arch=amd64] \
http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
| sudo tee /etc/apt/sources.list.d/nginx.list

Mettez à jour les dépôts du système.

$ sudo apt update

Installez Nginx.

$ sudo apt install nginx

Vérifiez l’installation.

$ nginx -v
nginx version: nginx/1.24.0

Démarrez le serveur Nginx.

$ sudo systemctl start nginx

Étape 8 - Installer SSL

La première étape consiste à installer le certificat SSL Let’s Encrypt. Nous devons installer Certbot pour générer le certificat SSL. Vous pouvez soit installer Certbot en utilisant le dépôt d’Ubuntu, soit obtenir la dernière version en utilisant l’outil Snapd. Nous utiliserons la version Snapd.

Ubuntu 22.04 est livré avec Snapd installé par défaut. Exécutez les commandes suivantes pour vous assurer que votre version de Snapd est à jour.

$ sudo snap install core && sudo snap refresh core

Installez Certbot.

$ sudo snap install --classic certbot

Utilisez la commande suivante pour vous assurer que la commande Certbot peut être exécutée en créant un lien symbolique vers le répertoire /usr/bin.

$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

Générez le certificat SSL pour le domaine kibana.example.com.

$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m [email protected] -d kibana.example.com

La commande ci-dessus téléchargera un certificat dans le répertoire /etc/letsencrypt/live/kibana.example.com sur votre serveur.

Générez un certificat de groupe Diffie-Hellman.

$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096

Vérifiez le service de planification de renouvellement de Certbot.

$ sudo systemctl list-timers

Vous trouverez snap.certbot.renew.service comme l’un des services programmés pour s’exécuter.

NEXT                        LEFT          LAST                        PASSED         UNIT                     ACTIVATES
------------------------------------------------------------------------------------------------------------------------------------
Mon 2023-05-06 13:37:57 UTC 3h 45min left Mon 2023-05-01 07:20:42 UTC 2h 31min ago   ua-timer.timer           ua-timer.service
Mon 2023-05-06 14:39:29 UTC 4h 47min left Sat 2023-02-04 16:04:18 UTC 2 months ago   motd-news.timer          motd-news.service
Mon 2023-05-06 15:53:00 UTC 6h left       n/a                         n/a            snap.certbot.renew.timer snap.certbot.renew.service

Faites un essai à sec du processus pour vérifier si le renouvellement SSL fonctionne correctement.

$ sudo certbot renew --dry-run

Si vous ne voyez aucune erreur, vous êtes prêt. Votre certificat se renouvellera automatiquement.

Étape 9 - Configurer Nginx

Créez et ouvrez le fichier de configuration Nginx pour Kibana.

$ sudo nano /etc/nginx/conf.d/kibana.conf

Collez le code suivant dedans. Remplacez l’adresse IP par l’adresse IP privée de votre serveur Elasticsearch.

server {
        listen 80; listen [::]:80;
        server_name kibana.example.com;
        return 301 https://$host$request_uri;
}

server {
        server_name kibana.example.com;
        charset utf-8;

        listen 443 ssl http2;
        listen [::]:443 ssl http2;

        access_log /var/log/nginx/kibana.access.log;
        error_log /var/log/nginx/kibana.error.log;

        ssl_certificate /etc/letsencrypt/live/kibana.example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/kibana.example.com/privkey.pem;
        ssl_trusted_certificate /etc/letsencrypt/live/kibana.example.com/chain.pem;
        ssl_session_timeout 1d;
        ssl_session_cache shared:MozSSL:10m;
        ssl_session_tickets off;

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;

    resolver 8.8.8.8;

        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_dhparam /etc/ssl/certs/dhparam.pem;

        location / {
                proxy_pass http://localhost:5601;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
        }
}

Enregistrez le fichier en appuyant sur Ctrl + X et en entrant Y lorsque vous y êtes invité.

Ouvrez le fichier /etc/nginx/nginx.conf pour l’édition.

$ sudo nano /etc/nginx/nginx.conf

Ajoutez la ligne suivante avant la ligne include /etc/nginx/conf.d/*.conf;.

server_names_hash_bucket_size  64;

Enregistrez le fichier en appuyant sur Ctrl + X et en entrant Y lorsque vous y êtes invité.

Vérifiez la configuration.

$ sudo nginx -t
nginx: le fichier de configuration /etc/nginx/nginx.conf a une syntaxe correcte
nginx: le test du fichier de configuration /etc/nginx/nginx.conf a réussi

Redémarrez le service Nginx.

$ sudo systemctl restart nginx

Il reste une étape à faire. Ouvrez le fichier Docker compose pour l’édition.

$ nano ~/docker-compose.yml

Collez la ligne SERVER_PUBLICBASEURL=https://kibana.example.com sous la section environnement sous le service Kibana comme suit.

    environment: # Configuration d'hôte définie
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - SERVER_PUBLICBASEURL=https://kibana.example.com

Enregistrez le fichier en appuyant sur Ctrl + X et en entrant Y lorsque vous y êtes invité une fois que vous avez terminé.

Arrêtez et supprimez les conteneurs.

$ docker compose down --remove-orphans

Démarrez à nouveau les conteneurs avec la configuration mise à jour.

$ docker compose up -d

Votre tableau de bord Kibana devrait être accessible via l’URL https://kibana.example.com de n’importe où.

Étape 10 - Exécuter un conteneur Docker avec le pilote de journal Fluentd

Maintenant, nous allons exécuter un conteneur Docker avec le pilote de journal Fluentd, envoyant automatiquement les journaux à la pile. Nous allons tester en utilisant le conteneur Nginx.

Tirez l’image Nginx du registre Docker Hub. Nous utilisons la version alpine car c’est la plus petite version de l’image.

$ docker pull nginx:alpine

Exécutez la commande suivante pour créer et démarrer le conteneur Nginx. Nous avons défini le pilote de journal sur Fluentd et le port sur 8080 car le port par défaut 80 est déjà utilisé par le serveur Nginx en mode proxy.

$ docker run --name nginx-fluentd-test -d --log-driver=fluentd -p 8080:80 nginx:alpine

Vérifiez l’état du conteneur.

$ docker ps
CONTAINER ID   IMAGE                 COMMAND                  CREATED          STATUS          PORTS                                                                                                    NAMES
038c43e4e1a3   nginx:alpine          "/docker-entrypoint.…"   12 seconds ago   Up 11 seconds   0.0.0.0:8080->80/tcp, :::8080->80/tcp                                                                    nginx-fluentd-test
a94ca706bd0c   efk-fluentd           "tini -- /bin/entryp…"   8 hours ago      Up 8 hours      5140/tcp, 0.0.0.0:24224->24224/tcp, 0.0.0.0:24224->24224/udp, :::24224->24224/tcp, :::24224->24224/udp   efk-fluentd-1
0cf04a446425   kibana:8.7.1          "/bin/tini -- /usr/l…"   8 hours ago      Up 8 hours      0.0.0.0:5601->5601/tcp, :::5601->5601/tcp                                                                efk-kibana-1
7c7ad8f9b123   elasticsearch:8.7.1   "/bin/tini -- /usr/l…"   8 hours ago      Up 8 hours      9200/tcp, 9300/tcp                                                                                       efk-elasticsearch-1

Exécutez la commande suivante pour accéder au conteneur Nginx et générer des journaux d’accès.

$ curl localhost:8080



Bienvenue sur nginx!



Bienvenue sur nginx!

Si vous voyez cette page, le serveur web nginx est installé avec succès et fonctionne. Une configuration supplémentaire est requise.

Pour la documentation en ligne et le support, veuillez vous référer à nginx.org.
Un support commercial est disponible sur nginx.com.

Merci d'utiliser nginx.

Alternativement, vous pouvez ouvrir l’URL http://:8080 dans votre navigateur et vous obtiendrez la page suivante.

Page d'accueil Nginx

Ouvrez le tableau de bord Kibana et cliquez sur le lien Découvrir dans le menu de la barre latérale gauche. Cliquez sur le signe + dans le menu supérieur pour faire apparaître la popup Ajouter un filtre.

Popup Ajouter un filtre Kibana

Sélectionnez le champ container_name dans le menu déroulant, is comme opérateur et remplissez le nom du conteneur (nginx-fluentd-test) comme valeur du champ.

Sélection de conteneur Kibana

Cliquez sur le bouton Ajouter un filtre pour visualiser les données du conteneur Nginx.

Journal Fluentd Conteneur Nginx

Conclusion

Cela conclut notre tutoriel sur l’installation de la pile de journalisation Elasticsearch, Fluentd et Kibana (EFK) sur une machine Ubuntu 22.04. Si vous avez des questions, posez-les dans les commentaires ci-dessous.

Share: X/Twitter LinkedIn

Recevez de nouveaux articles dans votre boîte de réception.

Aucun spam. Désabonnez-vous à tout moment.