Logging Stack · 16 min read · Dec 18, 2025

Come installare il stack di logging Elasticsearch, Fluentd e Kibana (EFK) su Ubuntu 22.04

Il monitoraggio e l’analisi dei log sono una parte essenziale dell’infrastruttura del server o del container e sono utili quando si gestiscono applicazioni complesse. Una delle soluzioni di logging più popolari è il stack Elasticsearch, Fluentd e Kibana (EFK). Prima di approfondire il tutorial, impariamo a conoscere i componenti del stack.

Elasticsearch è un motore di ricerca distribuito, scalabile e in tempo reale che consente la ricerca e l’analisi di testo completo. Viene utilizzato per indicizzare e cercare grandi quantità di dati. Viene comunemente distribuito insieme a Kibana, un potente cruscotto di visualizzazione dei dati per Elasticsearch. Kibana consente di esplorare i dati di log di Elasticsearch e di costruire cruscotti e query per ottenere informazioni sulla propria applicazione. Fluentd raccoglie, trasforma e invia i dati di log al backend di Elasticsearch.

In questo tutorial, installeremo il stack EFK utilizzando Docker su una macchina Ubuntu 22.04 e invieremo i log dei container a Kibana dopo averli filtrati e trasformati utilizzando Fluentd.

Requisiti

  • Un server che esegue Ubuntu 22.04 con un minimo di 6 GB di RAM.
  • Un utente non root con privilegi sudo.
  • Il firewall Uncomplicated Firewall (UFW) è abilitato e in esecuzione.
  • Un nome di dominio completamente qualificato (FQDN) che punta al server come kibana.example.com.
  • Tutto è aggiornato. $ sudo apt update && sudo apt upgrade

Passo 1 - Configurare il Firewall

Prima di installare qualsiasi pacchetto, il primo passo è configurare il firewall per consentire le connessioni HTTP e HTTPS.

Controlla lo stato del firewall.

$ sudo ufw status

Dovresti vedere qualcosa di simile al seguente.

Status: active

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

Consenti le porte HTTP e HTTPS.

$ sudo ufw allow http
$ sudo ufw allow https

Controlla di nuovo lo stato per confermare.

$ 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)

Passo 2 - Installare Docker e Docker Compose

Aggiungi la chiave GPG ufficiale di Docker.

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

Esegui il seguente comando per aggiungere il repository di 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

Aggiorna il sistema per includere il repository di Docker.

$ sudo apt update

Installa Docker e il plugin Docker compose.

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

Questo tutorial utilizzerà il plugin Docker Compose v2 invece del vecchio binario legacy. Pertanto, il comando per eseguirlo è cambiato da docker-compose a docker compose e questo è riflesso qui.

Docker viene eseguito con privilegi elevati, quindi dovrai usare sudo frequentemente per eseguire comandi. L’opzione migliore è aggiungere il tuo account utente Linux al gruppo utente docker.

$ sudo usermod -aG docker ${USER}

La variabile ${USER} raccoglie l’account di sistema attualmente connesso. Se non sei connesso con l’utente a cui vuoi dare privilegi, sostituisci ${USER} con il nome utente.

Per applicare la nuova appartenenza al gruppo, disconnettiti dal server e riconnettiti, oppure usa il seguente comando. Ti verrà chiesto di inserire la password dell’utente.

$ su - ${USER}

Passo 3 - Creare il file Docker Compose

Prima, crea la directory per il progetto EFK.

$ mkdir ~/efk

Passa alla directory.

$ cd ~/efk

Crea e apri il file docker-compose.yml per la modifica.

$ nano docker-compose.yml

Incolla il seguente codice in esso.

services:
  # Distribuisci utilizzando l'immagine personalizzata creata automaticamente durante il processo di build.
  fluentd:
    build: ./fluentd
    volumes:
      - ./fluentd/conf:/fluentd/etc
    links: # Invia i log in arrivo al container elasticsearch.
      - elasticsearch
    depends_on:
      - elasticsearch
    ports: # Espone la porta 24224 sia sul protocollo TCP che UDP per l'aggregazione dei log
      - 24224:24224
      - 24224:24224/udp

  elasticsearch:
    image: elasticsearch:8.7.1
    expose:
      - 9200
    environment:
      - discovery.type=single-node # Esegue come un nodo singolo
      - xpack.security.enabled=false
    volumes: # Memorizza i dati di elasticsearch localmente sul volume Docker esdata
      - esdata:/usr/share/elasticsearch/data

  kibana:
    image: kibana:8.7.1
    links: # Collega il servizio kibana al container elasticsearch
      - elasticsearch
    depends_on:
      - elasticsearch
    ports:
      - 5601:5601
    environment: # Configurazione dell'host definita
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200

# Definisci il volume Docker chiamato esdata per il container Elasticsearch.
volumes:
  esdata:

Salva il file premendo Ctrl + X e inserendo Y quando richiesto. Abbiamo configurato per avviare tre servizi, uno per ciascuno, Fluentd, Elasticsearch e Kibana.

Per Fluentd, costruiremo un container invece di un’immagine pronta. I file di build per Fluentd saranno impostati nel passo successivo. Abbiamo montato una directory per i suoi file di build, e un volume per i file di configurazione, e abbiamo esposto la porta 24224 sia sul protocollo TCP che UDP per l’aggregazione dei log.

Il servizio successivo è Elasticsearch e stiamo utilizzando l’ultima versione disponibile al momento della scrittura di questo tutorial. L’abbiamo esposto tramite la porta 9200 e impostato alcune variabili ambientali in modo da poterlo eseguire come un cluster a nodo singolo e abbiamo disabilitato le funzionalità di sicurezza. Questo non è generalmente raccomandato, ma abilitare la sicurezza è al di fuori dell’ambito di questo tutorial. Abbiamo anche montato un volume locale per i dati di Elasticsearch.

Infine, configuriamo Kibana e lo esponiamo tramite la porta 5601 che sarà utilizzata per accedere al cruscotto. Abbiamo anche impostato una variabile per configurare l’host Elasticsearch per accedervi.

Passo 4 - Configurare i file di build di Fluentd

Crea Fluentd e la directory di configurazione.

$ mkdir fluentd/conf -p

Esegui il comando tree per verificare la struttura della directory.

$ tree

Dovrebbe apparire simile al seguente.

Output del comando tree

Passa alla directory Fluentd.

$ cd fluentd

Crea e apri il Dockerfile per la modifica.

$ nano Dockerfile

Incolla il seguente codice in esso. Questo codice estrae l’immagine Docker Debian di Fluentd e installa il plugin Fluentd per 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

Salva il file premendo Ctrl + X e inserendo Y quando richiesto.

Passa alla directory di configurazione.

$ cd conf

Crea e apri il file fluentd.conf per la modifica.

$ nano fluentd.conf

Incolla il seguente codice in esso.

# bind fluentd su IP 0.0.0.0
# porta 24224

  @type forward
  port 24224
  bind 0.0.0.0


# invia log a elasticsearch
# l'host deve corrispondere al servizio del container 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
  

Salva il file premendo Ctrl + X e inserendo Y quando richiesto.

La direttiva source sopra utilizza il plugin forward che trasforma Fluentd in un endpoint TCP per accettare pacchetti TCP.

La direttiva match cerca eventi con tag corrispondenti, il che in questo caso significa che corrisponde a tutti gli eventi. Utilizzeremo il plugin elasticsearch_dynamic per la memorizzazione, che consente di specificare i valori di configurazione in modo dinamico. Il campo hosts specifica il nome host per l’applicazione Elasticsearch, che è il nome del servizio nel file Docker compose. Il logstash_format è impostato su true, il che significa che Fluentd utilizza il formato di nome convenzionale logstash-%Y.%m.%dlogstash-%Y.%m.%d. Il nome del prefisso per scrivere gli eventi è impostato su fluend. L’opzione include_tag_key è impostata su true, il che aggiunge il tag Fluentd nel formato JSON. La tag_key è il nome del campo da estrarre per il tag. Impostando la variabile include_timestamp su true, viene aggiunto un campo timestamp al log. L’intervallo flush_interval specifica l’intervallo tra i flush dei dati. Utilizziamo anche il plugin stdout per stampare eventi/log al output standard.

Passo 5 - Eseguire i container Docker

Torna alla directory EFK.

$ cd ~/efk

Avvia i container utilizzando il seguente comando.

$ docker compose up -d

Controlla lo stato dei container in esecuzione.

$ 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

Puoi anche usare il seguente comando per questo.

$ 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

Esegui i seguenti comandi per controllare i log del processo di build di EFK.

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

Ispeziona il container Elasticsearch. Stampa le impostazioni dettagliate del container.

$ docker inspect efk-elasticsearch-1

Puoi notare l’indirizzo IP assegnato al container.

[
    {
        "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
                }
            }
        }
    }
]

Come puoi vedere, il container ha ricevuto 172.23.0.2 come indirizzo IP. Esegui il seguente comando per verificare se Elasticsearch sta funzionando correttamente.

$ 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"
}

Passo 6 - Configurare Kibana

Ora che il stack EFK è stato distribuito, è tempo di configurare Kibana. Apri l’URL http://:5601 nel browser.

Pagina di benvenuto di Kibana

Clicca sul pulsante Esplora da solo per procedere al cruscotto di Kibana.

Cruscotto di Kibana

Clicca sul link Gestione stack per impostare la vista dei dati di Kibana. Seleziona l’opzione Kibana >> Viste dati dalla barra laterale sinistra per aprire la pagina della vista dei dati.

Pagina della vista dati di Kibana

Clicca sul pulsante Crea vista dati per procedere.

Crea vista dati di Kibana

Inserisci il nome della vista dati e il modello di indice come fluentd-*. Assicurati che il campo Timestamp sia impostato su @timestamp. Il campo sorgente verrà aggiornato automaticamente. Clicca sul pulsante Salva vista dati in Kibana per completare la creazione della vista dati.

Successivamente, clicca sul menu in alto (ellissi) e clicca sull’opzione Scopri per mostrare il monitoraggio dei log.

Otterrai la seguente pagina che conferma che la tua configurazione sta funzionando perfettamente. I log vengono tutti presi da Elasticsearch e inviati dall’aggregazione dei log di Fluentd.

Monitoraggio dei log di Fluentd in Kibana

Passo 7 - Installare Nginx

Ubuntu 22.04 viene fornito con una versione più vecchia di Nginx. Devi scaricare il repository ufficiale di Nginx per installare l’ultima versione.

Importa la chiave di firma di Nginx.

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

Aggiungi il repository per la versione stabile di 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

Aggiorna i repository di sistema.

$ sudo apt update

Installa Nginx.

$ sudo apt install nginx

Verifica l’installazione.

$ nginx -v
nginx version: nginx/1.24.0

Avvia il server Nginx.

$ sudo systemctl start nginx

Passo 8 - Installare SSL

Il primo passo è installare il certificato SSL di Let’s Encrypt. Dobbiamo installare Certbot per generare il certificato SSL. Puoi installare Certbot utilizzando il repository di Ubuntu o scaricare l’ultima versione utilizzando lo strumento Snapd. Utilizzeremo la versione Snapd.

Ubuntu 22.04 viene fornito con Snapd installato per impostazione predefinita. Esegui i seguenti comandi per assicurarti che la tua versione di Snapd sia aggiornata.

$ sudo snap install core && sudo snap refresh core

Installa Certbot.

$ sudo snap install --classic certbot

Usa il seguente comando per assicurarti che il comando Certbot possa essere eseguito creando un collegamento simbolico alla directory /usr/bin.

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

Genera il certificato SSL per il dominio kibana.example.com.

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

Il comando sopra scaricherà un certificato nella directory /etc/letsencrypt/live/kibana.example.com sul tuo server.

Genera un certificato di gruppo Diffie-Hellman.

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

Controlla il servizio di pianificazione del rinnovo di Certbot.

$ sudo systemctl list-timers

Troverai snap.certbot.renew.service come uno dei servizi programmati per l’esecuzione.

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

Fai un tentativo di prova del processo per controllare se il rinnovo SSL funziona correttamente.

$ sudo certbot renew --dry-run

Se non vedi errori, sei a posto. Il tuo certificato si rinnoverà automaticamente.

Passo 9 - Configurare Nginx

Crea e apri il file di configurazione Nginx per Kibana.

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

Incolla il seguente codice in esso. Sostituisci l’indirizzo IP con l’indirizzo IP privato del tuo server 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;
        }
}

Salva il file premendo Ctrl + X e inserendo Y quando richiesto.

Apri il file /etc/nginx/nginx.conf per la modifica.

$ sudo nano /etc/nginx/nginx.conf

Aggiungi la seguente riga prima della riga include /etc/nginx/conf.d/*.conf;.

server_names_hash_bucket_size  64;

Salva il file premendo Ctrl + X e inserendo Y quando richiesto.

Verifica la configurazione.

$ sudo nginx -t
nginx: il file di configurazione /etc/nginx/nginx.conf ha una sintassi corretta
nginx: il test del file di configurazione /etc/nginx/nginx.conf è riuscito

Riavvia il servizio Nginx.

$ sudo systemctl restart nginx

C’è un ulteriore passo necessario. Apri il file Docker compose per la modifica.

$ nano ~/docker-compose.yml

Incolla la riga SERVER_PUBLICBASEURL=https://kibana.example.com sotto la sezione ambiente del servizio Kibana come segue.

    environment: # Configurazione dell'host definita
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - SERVER_PUBLICBASEURL=https://kibana.example.com

Salva il file premendo Ctrl + X e inserendo Y quando richiesto una volta completato.

Ferma e rimuovi i container.

$ docker compose down --remove-orphans

Avvia di nuovo i container con la configurazione aggiornata.

$ docker compose up -d

Il tuo cruscotto Kibana dovrebbe essere accessibile tramite l’URL https://kibana.example.com da qualsiasi luogo tu voglia.

Passo 10 - Eseguire un container Docker con il driver di log Fluentd

Ora, eseguiremo un container Docker con il driver di log Fluentd, inviando automaticamente i log allo stack. Testeremo utilizzando il container Nginx.

Scarica l’immagine Nginx dal registro Docker Hub. Stiamo utilizzando la versione alpine perché è la versione più piccola dell’immagine.

$ docker pull nginx:alpine

Esegui il seguente comando per creare e avviare il container Nginx. Abbiamo impostato il driver di log su Fluentd e la porta su 8080 perché la porta predefinita 80 è già in uso dal server Nginx in modalità proxy.

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

Controlla lo stato del container.

$ 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

Esegui il seguente comando per accedere al container Nginx e generare log di accesso.

$ curl localhost:8080



Benvenuto in nginx!



Benvenuto in nginx!

Se vedi questa pagina, il server web nginx è stato installato e funziona correttamente. Ulteriori configurazioni sono necessarie.

Per documentazione e supporto online, si prega di fare riferimento a nginx.org.
Il supporto commerciale è disponibile su nginx.com.

Grazie per aver utilizzato nginx.

In alternativa, puoi aprire l’URL http://:8080 nel tuo browser e otterrai la seguente pagina.

Homepage di Nginx

Apri il cruscotto Kibana e clicca sul link Scopri nel menu della barra laterale sinistra. Clicca sul segno + nel menu in alto per far apparire il popup Aggiungi filtro.

Popup Aggiungi filtro di Kibana

Seleziona il campo container_name dal menu a discesa, è come operatore e compila il nome del container (nginx-fluentd-test) come valore del campo.

Query di selezione del container di Kibana

Clicca sul pulsante Aggiungi filtro per visualizzare i dati dal container Nginx.

Log Fluentd del container Nginx

Conclusione

Questo conclude il nostro tutorial sull’installazione del stack di logging Elasticsearch, Fluentd e Kibana (EFK) su una macchina Ubuntu 22.04. Se hai domande, postale nei commenti qui sotto.

Share: X/Twitter LinkedIn

Ricevi i nuovi post nella tua casella di posta.

Nessuno spam. Disiscriviti in qualsiasi momento.