Instalação EFK · 17 min read · Dec 18, 2025

Como Instalar o Stack de Logging Elasticsearch, Fluentd e Kibana (EFK) no Ubuntu 22.04

A monitoração e análise de logs é uma parte essencial da infraestrutura de servidores ou contêineres e é útil ao lidar com aplicações complexas. Uma das soluções de logging populares é o stack Elasticsearch, Fluentd e Kibana (EFK). Antes de prosseguir com o tutorial, vamos aprender sobre os componentes do stack.

O Elasticsearch é um mecanismo de busca distribuído, escalável e em tempo real que permite busca e análise de texto completo. Ele é usado para indexar e pesquisar grandes quantidades de dados. É comumente implantado junto com o Kibana, um poderoso painel de visualização de dados para o Elasticsearch. O Kibana permite que você explore os dados de log do Elasticsearch e crie painéis e consultas para obter insights sobre sua aplicação. O Fluentd coleta, transforma e envia os dados de log para o backend do Elasticsearch.

Neste tutorial, vamos instalar o stack EFK usando Docker em uma máquina Ubuntu 22.04 e enviar logs de contêiner para o Kibana após filtrá-los e transformá-los usando o Fluentd.

Pré-requisitos

  • Um servidor rodando Ubuntu 22.04 com um mínimo de 6GB de RAM.
  • Um usuário não-root com privilégios sudo.
  • O Firewall simples (UFW) está habilitado e em execução.
  • Um nome de domínio totalmente qualificado (FQDN) apontando para o servidor como, kibana.example.com.
  • Tudo está atualizado. $ sudo apt update && sudo apt upgrade

Passo 1 - Configurar o Firewall

Antes de instalar qualquer pacote, o primeiro passo é configurar o firewall para permitir conexões HTTP e HTTPS.

Verifique o status do firewall.

$ sudo ufw status

Você deve ver algo como o seguinte.

Status: ativo

Para                         Ação      De
--                         ------      ----
OpenSSH                    PERMITIR   Em qualquer lugar
OpenSSH (v6)               PERMITIR   Em qualquer lugar (v6)

Permita as portas HTTP e HTTPS.

$ sudo ufw allow http
$ sudo ufw allow https

Verifique o status novamente para confirmar.

$ sudo ufw status
Status: ativo

Para                         Ação      De
--                         ------      ----
OpenSSH                    PERMITIR   Em qualquer lugar
80/tcp                     PERMITIR   Em qualquer lugar
443                        PERMITIR   Em qualquer lugar
OpenSSH (v6)               PERMITIR   Em qualquer lugar (v6)
80/tcp (v6)                PERMITIR   Em qualquer lugar (v6)
443 (v6)                   PERMITIR   Em qualquer lugar (v6)

Passo 2 - Instalar Docker e Docker Compose

Adicione a chave GPG oficial do Docker.

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

Execute o seguinte comando para adicionar o repositório do 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

Atualize o sistema para incluir o repositório do Docker.

$ sudo apt update

Instale o Docker e o plugin Docker Compose.

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

Este tutorial usará o plugin Docker Compose v2 em vez do binário legado mais antigo. Portanto, o comando para executá-lo mudou de docker-compose para docker compose e isso é refletido aqui.

O Docker é executado com privilégios elevados, então você precisará usar sudo com frequência para executar comandos. A melhor opção é adicionar sua conta de usuário Linux ao grupo de usuários docker.

$ sudo usermod -aG docker ${USER}

A variável ${USER} pega a conta do sistema atualmente logada. Se você não estiver logado com o usuário que deseja conceder privilégios, substitua ${USER} pelo nome de usuário.

Para aplicar a nova associação ao grupo, faça logout do servidor e faça login novamente, ou use o seguinte comando. Você será solicitado a inserir a senha do usuário.

$ su - ${USER}

Passo 3 - Criar o Arquivo Docker Compose

Primeiro, crie o diretório para o projeto EFK.

$ mkdir ~/efk

Mude para o diretório.

$ cd ~/efk

Crie e abra o arquivo docker-compose.yml para edição.

$ nano docker-compose.yml

Cole o seguinte código nele.

services:
  # Implantar usando a imagem personalizada que será criada automaticamente durante o processo de construção.
  fluentd:
    build: ./fluentd
    volumes:
      - ./fluentd/conf:/fluentd/etc
    links: # Envia logs recebidos para o contêiner elasticsearch.
      - elasticsearch
    depends_on:
      - elasticsearch
    ports: # Expõe a porta 24224 em ambos os protocolos TCP e UDP para agregação de logs
      - 24224:24224
      - 24224:24224/udp

  elasticsearch:
    image: elasticsearch:8.7.1
    expose:
      - 9200
    environment:
      - discovery.type=single-node # Executa como um único nó
      - xpack.security.enabled=false
    volumes: # Armazena dados do elasticsearch localmente no volume Docker esdata
      - esdata:/usr/share/elasticsearch/data

  kibana:
    image: kibana:8.7.1
    links: # Liga o serviço kibana ao contêiner elasticsearch
      - elasticsearch
    depends_on:
      - elasticsearch
    ports:
      - 5601:5601
    environment: # Configuração do host definida
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200

# Defina o volume Docker chamado esdata para o contêiner Elasticsearch.
volumes:
  esdata:

Salve o arquivo pressionando Ctrl + X e digitando Y quando solicitado. Configuramos para iniciar três serviços, um para cada, Fluentd, Elasticsearch e Kibana.

Para Fluentd, vamos construir um contêiner em vez de uma imagem pronta. Os arquivos de construção para o Fluentd serão configurados no próximo passo. Montamos um diretório para seus arquivos de construção e um volume para os arquivos de configuração, e expomos a porta 24224 em ambos os protocolos TCP e UDP para agregação de logs.

O próximo serviço é o Elasticsearch e estamos usando a versão mais recente disponível no momento da redação deste tutorial. Expomos via porta 9200 e configuramos algumas variáveis de ambiente para que possamos executá-lo como um cluster de nó único e desativamos os recursos de segurança. Isso não é geralmente recomendado, mas habilitar a segurança está fora do escopo deste tutorial. Também montamos um volume local para os dados do Elasticsearch.

Finalmente, configuramos o Kibana e o expomos via porta 5601, que será usada para acessar o painel. Também configuramos uma variável para configurar o host Elasticsearch para que ele possa acessar.

Passo 4 - Configurar os Arquivos de Construção do Fluentd

Crie o diretório Fluentd e o diretório de configuração.

$ mkdir fluentd/conf -p

Execute o comando tree para verificar a estrutura do diretório.

$ tree

Deve parecer com o seguinte.

Saída do comando tree

Mude para o diretório Fluentd.

$ cd fluentd

Crie e abra o Dockerfile para edição.

$ nano Dockerfile

Cole o seguinte código nele. Este código puxa a imagem Docker Debian do Fluentd e instala o plugin Fluentd para 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

Salve o arquivo pressionando Ctrl + X e digitando Y quando solicitado.

Mude para o diretório de configuração.

$ cd conf

Crie e abra o arquivo fluentd.conf para edição.

$ nano fluentd.conf

Cole o seguinte código nele.

# bind fluentd no IP 0.0.0.0
# porta 24224

  @type forward
  port 24224
  bind 0.0.0.0


# envia log para o elasticsearch
# o host deve corresponder ao elasticsearch
# serviço do contêiner

  @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
  

Salve o arquivo pressionando Ctrl + X e digitando Y quando solicitado.

A diretiva source acima usa o plugin forward, que transforma o Fluentd em um ponto de extremidade TCP para aceitar pacotes TCP.

A diretiva match procura eventos com tags correspondentes, que neste caso significa que corresponde a todos os eventos. Usaremos o plugin elasticsearch_dynamic para armazenamento, que permite que valores de configuração sejam especificados dinamicamente. O campo hosts especifica o nome do host para a aplicação Elasticsearch, que é o nome do serviço no arquivo de composição Docker. O logstash_format é definido como verdadeiro, o que significa que o Fluentd usa o formato de nome convencional logstash-%Y.%m.%dlogstash-%Y.%m.%d. O nome do prefixo para gravar os eventos é definido como fluend. A variável include_tag_key é definida como verdadeira, o que adiciona a tag do Fluentd no formato JSON. A tag_key é o nome do campo a ser extraído para a tag. Definindo a variável include_timestamp como verdadeira, adiciona um campo de timestamp ao log. O flush_interval especifica o intervalo entre as descargas de dados. Também usamos o plugin stdout para imprimir eventos/logs na saída padrão.

Passo 5 - Executar os Contêineres Docker

Mude de volta para o diretório EFK.

$ cd ~/efk

Inicie os contêineres usando o seguinte comando.

$ docker compose up -d

Verifique o status dos contêineres em execução.

$ 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

Você também pode usar o seguinte comando para isso.

$ 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

Execute os seguintes comandos para verificar os logs do processo de construção do EFK.

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

Inspecione o contêiner Elasticsearch. Ele imprimirá as configurações detalhadas do contêiner.

$ docker inspect efk-elasticsearch-1

Você pode notar o endereço IP atribuído ao contêiner.

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

Como você pode ver, o contêiner recebeu 172.23.0.2 como o endereço IP. Execute o seguinte comando para verificar se o Elasticsearch está funcionando corretamente.

$ 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" : "Você sabe, para busca"
}

Passo 6 - Configurar o Kibana

Agora que o stack EFK está implantado, é hora de configurar o Kibana. Abra a URL http://:5601 no navegador.

Página de Boas-Vindas do Kibana

Clique no botão Explorar por conta própria para prosseguir para o painel do Kibana.

Painel do Kibana

Clique no link Gerenciamento do Stack para configurar a visualização de dados do Kibana. Selecione a opção Kibana >> Visualizações de Dados na barra lateral esquerda para abrir a página de visualização de dados.

Página de Visualização de Dados do Kibana

Clique no botão Criar visualização de dados para prosseguir.

Criar Visualização de Dados do Kibana

Digite o nome da visualização de dados e o padrão de índice como fluentd-*. Certifique-se de que o campo Timestamp esteja definido como @timestamp. O campo de origem será atualizado automaticamente. Clique no botão Salvar visualização de dados no Kibana para finalizar a criação da visualização de dados.

Em seguida, clique no menu superior (reticências) e clique na opção Descobrir para mostrar a monitoração dos logs.

Você obterá a seguinte página confirmando que sua configuração está funcionando perfeitamente. Os logs são todos retirados do Elasticsearch e enviados pela agregação de logs do Fluentd.

Logs de Monitoramento do Fluentd no Kibana

Passo 7 - Instalar o Nginx

O Ubuntu 22.04 vem com uma versão mais antiga do Nginx. Você precisa baixar o repositório oficial do Nginx para instalar a versão mais recente.

Importe a chave de assinatura do Nginx.

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

Adicione o repositório para a versão estável do 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

Atualize os repositórios do sistema.

$ sudo apt update

Instale o Nginx.

$ sudo apt install nginx

Verifique a instalação.

$ nginx -v
nginx version: nginx/1.24.0

Inicie o servidor Nginx.

$ sudo systemctl start nginx

Passo 8 - Instalar SSL

O primeiro passo é instalar o Certificado SSL Let’s Encrypt. Precisamos instalar o Certbot para gerar o certificado SSL. Você pode instalar o Certbot usando o repositório do Ubuntu ou pegar a versão mais recente usando a ferramenta Snapd. Usaremos a versão Snapd.

O Ubuntu 22.04 vem com o Snapd instalado por padrão. Execute os seguintes comandos para garantir que sua versão do Snapd esteja atualizada.

$ sudo snap install core && sudo snap refresh core

Instale o Certbot.

$ sudo snap install --classic certbot

Use o seguinte comando para garantir que o comando Certbot possa ser executado criando um link simbólico para o diretório /usr/bin.

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

Gere o certificado SSL para o domínio kibana.example.com.

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

O comando acima fará o download de um certificado para o diretório /etc/letsencrypt/live/kibana.example.com em seu servidor.

Gere um certificado de grupo Diffie-Hellman.

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

Verifique o serviço agendador de renovação do Certbot.

$ sudo systemctl list-timers

Você encontrará snap.certbot.renew.service como um dos serviços agendados para execução.

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

Faça um teste do processo para verificar se a renovação do SSL está funcionando bem.

$ sudo certbot renew --dry-run

Se você não ver erros, está tudo pronto. Seu certificado será renovado automaticamente.

Passo 9 - Configurar o Nginx

Crie e abra o arquivo de configuração do Nginx para o Kibana.

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

Cole o seguinte código nele. Substitua o endereço IP pelo endereço IP privado do seu servidor 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;
        }
}

Salve o arquivo pressionando Ctrl + X e digitando Y quando solicitado.

Abra o arquivo /etc/nginx/nginx.conf para edição.

$ sudo nano /etc/nginx/nginx.conf

Adicione a seguinte linha antes da linha include /etc/nginx/conf.d/*.conf;.

server_names_hash_bucket_size  64;

Salve o arquivo pressionando Ctrl + X e digitando Y quando solicitado.

Verifique a configuração.

$ sudo nginx -t
nginx: o arquivo de configuração /etc/nginx/nginx.conf a sintaxe está ok
nginx: teste do arquivo de configuração /etc/nginx/nginx.conf foi bem-sucedido

Reinicie o serviço Nginx.

$ sudo systemctl restart nginx

Há mais um passo necessário. Abra o arquivo de composição Docker para edição.

$ nano ~/docker-compose.yml

Cole a linha SERVER_PUBLICBASEURL=https://kibana.example.com na seção de ambiente sob o serviço Kibana da seguinte forma.

    environment: # Configuração do host definida
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
      - SERVER_PUBLICBASEURL=https://kibana.example.com

Salve o arquivo pressionando Ctrl + X e digitando Y quando solicitado, uma vez que você terminar.

Pare e remova os contêineres.

$ docker compose down --remove-orphans

Inicie os contêineres novamente com a configuração atualizada.

$ docker compose up -d

Seu painel do Kibana deve estar acessível via a URL https://kibana.example.com de qualquer lugar que você desejar.

Passo 10 - Executando um contêiner Docker com o Driver de Log Fluentd

Agora, vamos executar um contêiner Docker com o driver de log Fluentd, enviando automaticamente logs para o stack. Vamos testar usando o contêiner Nginx.

Puxe a imagem do Nginx do registro do Docker Hub. Estamos usando a versão alpine porque é a versão menor da imagem.

$ docker pull nginx:alpine

Execute o seguinte comando para criar e iniciar o contêiner Nginx. Definimos o driver de log como Fluentd e a porta como 8080 porque a porta padrão 80 já está em uso pelo servidor Nginx em modo proxy.

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

Verifique o status do contêiner.

$ 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

Execute o seguinte comando para acessar o contêiner Nginx e gerar logs de acesso.

$ curl localhost:8080



Bem-vindo ao nginx!



Bem-vindo ao nginx!

Se você vê esta página, o servidor web nginx está instalado e funcionando com sucesso. Mais configurações são necessárias.

Para documentação online e suporte, consulte nginx.org.
Suporte comercial está disponível em nginx.com.

Obrigado por usar o nginx.

Alternativamente, você pode abrir a URL http://:8080 no seu navegador e você obterá a seguinte página.

Página inicial do Nginx

Abra o painel do Kibana e clique no link Descobrir no menu da barra lateral esquerda. Clique no sinal + no menu superior para abrir o popup Adicionar filtro.

Popup Adicionar Filtro do Kibana

Selecione o campo container_name no dropdown, é como o operador e preencha o nome do contêiner (nginx-fluentd-test) como o valor do campo.

Consulta de Seleção de Contêiner do Kibana

Clique no botão Adicionar filtro para visualizar os dados do contêiner Nginx.

Log do Contêiner Nginx Fluentd

Conclusão

Isso conclui nosso tutorial sobre a instalação do stack de logging Elasticsearch, Fluentd e Kibana (EFK) em uma máquina Ubuntu 22.04. Se você tiver alguma dúvida, poste nos comentários abaixo.

Share: X/Twitter LinkedIn

Receba novas postagens na sua caixa de entrada

Sem spam. Cancele a assinatura a qualquer momento.