So installierst du Elasticsearch, Fluentd und Kibana (EFK) Logging Stack auf Ubuntu 22.04
Die Log-Überwachung und -Analyse ist ein wesentlicher Bestandteil der Server- oder Container-Infrastruktur und ist nützlich, wenn es um komplexe Anwendungen geht. Eine der beliebtesten Logging-Lösungen ist der Elasticsearch, Fluentd und Kibana (EFK) Stack. Bevor wir uns dem Tutorial zuwenden, wollen wir die Komponenten des Stacks kennenlernen.
Elasticsearch ist eine verteilte und skalierbare Echtzeit-Suchmaschine, die eine Volltextsuche und Analysen ermöglicht. Sie wird zum Indizieren und Durchsuchen großer Datenmengen verwendet. In der Regel wird sie zusammen mit Kibana eingesetzt, einem leistungsstarken Dashboard zur Datenvisualisierung für Elasticsearch. Mit Kibana kannst du die Elasticsearch-Logdaten untersuchen und Dashboards und Abfragen erstellen, um Einblicke in deine Anwendung zu erhalten. Fluentd sammelt und transformiert die Logdaten und sendet sie an das Elasticsearch-Backend.
In diesem Lernprogramm werden wir den EFK-Stack mit Docker auf einem Ubuntu 22.04-Rechner installieren und die Container-Logs an Kibana senden, nachdem wir sie mit Fluentd gefiltert und umgewandelt haben.
Voraussetzungen
- Ein Server mit Ubuntu 22.04 und mindestens 6 GB RAM.
- Ein Nicht-Root-Benutzer mit sudo-Rechten.
- Die Unkomplizierte Firewall (UFW) ist aktiviert und läuft.
- Ein Fully Qualified Domain Name (FQDN), der auf den Server zeigt, z.B.
kibana.example.com
. - Alles ist auf dem neuesten Stand.
$ sudo apt update && sudo apt upgrade
Schritt 1 – Firewall konfigurieren
Bevor du die Pakete installierst, musst du zunächst die Firewall so konfigurieren, dass HTTP- und HTTPS-Verbindungen zugelassen werden.
Überprüfe den Status der Firewall.
$ sudo ufw status
Du solltest etwas wie das Folgende sehen.
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Erlaube HTTP- und HTTPs-Ports.
$ sudo ufw allow http
$ sudo ufw allow https
Überprüfe den Status zur Bestätigung noch einmal.
$ 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)
Schritt 2 – Installiere Docker und Docker Compose
Füge den offiziellen GPG-Schlüssel von Docker hinzu.
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker.gpg
Führe den folgenden Befehl aus, um das Docker-Repository hinzuzufügen.
$ 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
Aktualisiere das System, um das Docker Repository einzubinden.
$ sudo apt update
Installiere Docker und das Docker Compose Plugin.
$ sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
In diesem Lehrgang wird das Docker Compose v2 Plugin anstelle des älteren Legacy Binary verwendet. Daher hat sich der Befehl zum Ausführen des Plugins von docker-compose
auf docker compose
geändert, was sich hier widerspiegelt.
Docker läuft mit erhöhten Rechten, daher musst du sudo
häufig verwenden, um Befehle auszuführen. Die bessere Option ist, dein Linux-Benutzerkonto zur Benutzergruppe docker
hinzuzufügen.
$ sudo usermod -aG docker ${USER}
Die Variable ${USER}
nimmt das aktuell eingeloggte Systemkonto auf. Wenn du nicht mit dem Benutzer eingeloggt bist, dem du Privilegien geben willst, ersetze ${USER}
durch den Benutzernamen.
Um die neue Gruppenmitgliedschaft zu beantragen, melde dich vom Server ab und wieder an oder verwende den folgenden Befehl. Du wirst aufgefordert, das Passwort des Benutzers einzugeben.
$ su - ${USER}
Schritt 3 – Docker Compose-Datei erstellen
Erstelle zunächst das Verzeichnis für das EFK-Projekt.
$ mkdir ~/efk
Wechsle in das Verzeichnis.
$ cd ~/efk
Erstelle und öffne die Datei docker-compose.yml
zum Bearbeiten.
$ nano docker-compose.yml
Füge den folgenden Code in die Datei ein.
services:
# Deploy using the custom image automatically be created during the build process.
fluentd:
build: ./fluentd
volumes:
- ./fluentd/conf:/fluentd/etc
links: # Sends incoming logs to the elasticsearch container.
- elasticsearch
depends_on:
- elasticsearch
ports: # Exposes the port 24224 on both TCP and UDP protocol for log aggregation
- 24224:24224
- 24224:24224/udp
elasticsearch:
image: elasticsearch:8.7.1
expose:
- 9200
environment:
- discovery.type=single-node # Runs as a single-node
- xpack.security.enabled=false
volumes: # Stores elasticsearch data locally on the esdata Docker volume
- esdata:/usr/share/elasticsearch/data
kibana:
image: kibana:8.7.1
links: # Links kibana service to the elasticsearch container
- elasticsearch
depends_on:
- elasticsearch
ports:
- 5601:5601
environment: # Defined host configuration
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
# Define the Docker volume named esdata for the Elasticsearch container.
volumes:
esdata:
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst. Wir haben drei Dienste konfiguriert, jeweils einen für Fluentd, Elasticsearch und Kibana.
Für Fluentd werden wir einen Container bauen, anstatt ein fertiges Image. Die Build-Dateien für Fluentd werden im nächsten Schritt eingerichtet. Wir haben ein Verzeichnis für die Build-Dateien und ein Volume für die Konfigurationsdateien eingerichtet und den Port 24224 sowohl auf dem TCP- als auch auf dem UDP-Protokoll für die Log-Aggregation freigegeben.
Der nächste Dienst ist Elasticsearch und wir verwenden die neueste Version, die zum Zeitpunkt der Erstellung dieses Tutorials verfügbar war. Wir haben ihn über Port 9200 zugänglich gemacht und ein paar Umgebungsvariablen eingerichtet, damit wir ihn als Single-Node-Cluster betreiben können. Dies wird normalerweise nicht empfohlen, aber die Aktivierung der Sicherheitsfunktionen ist nicht Gegenstand dieses Lehrgangs. Außerdem haben wir ein lokales Volume für die Elasticsearch-Daten eingerichtet.
Schließlich konfigurieren wir Kibana und stellen es über Port 5601 bereit, über den wir auf das Dashboard zugreifen werden. Außerdem richten wir eine Variable ein, um den Elasticsearch-Host zu konfigurieren, auf den er zugreifen soll.
Schritt 4 – Fluentd Build-Dateien einrichten
Erstelle Fluentd und das Konfigurationsverzeichnis.
$ mkdir fluentd/conf -p
Führe den Befehl tree
aus, um die Verzeichnisstruktur zu überprüfen.
$ tree
Sie sollte wie die folgende aussehen.
Wechsle in das Fluentd-Verzeichnis.
$ cd fluentd
Erstelle und öffne die Dockerfile
zur Bearbeitung.
$ nano Dockerfile
Füge den folgenden Code darin ein. Dieser Code zieht das Fluentd Debian Docker Image und installiert das Fluentd Plugin für 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
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Wechsle in das Konfigurationsverzeichnis.
$ cd conf
Erstelle und öffne die Datei fluentd.conf
zum Bearbeiten.
$ nano fluentd.conf
Füge den folgenden Code in die Datei ein.
# bind fluentd on IP 0.0.0.0
# port 24224
<source>
@type forward
port 24224
bind 0.0.0.0
</source>
# sendlog to the elasticsearch
# the host must match to the elasticsearch
# container service
<match *.**>
@type copy
<store>
@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
</store>
<store>
@type stdout
</store>
</match>
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Die obige Quellrichtlinie verwendet das Plugin forward
, das Fluentd in einen TCP-Endpunkt verwandelt, um TCP-Pakete zu akzeptieren.
Die Match-Direktive sucht nach Ereignissen mit übereinstimmenden Tags, was in diesem Fall bedeutet, dass sie mit allen Ereignissen übereinstimmt. Zur Speicherung verwenden wir das Plugin elasticsearch_dynamic
, mit dem Konfigurationswerte dynamisch angegeben werden können. Das Feld hosts
gibt den Hostnamen für die Elasticsearch-Anwendung an, der der Dienstname in der Docker Compose-Datei ist. Das Feld logstash_format
ist auf true gesetzt, was bedeutet, dass Fluentd das konventionelle Namensformat logstash-%Y.%m.%dlogstash-%Y.%m.%d
verwendet. Der Präfixname zum Schreiben der Ereignisse wird auf fluend
gesetzt. include_tag_key
wird auf true gesetzt, wodurch das Fluentd-Tag im JSON-Format hinzugefügt wird. tag_key
ist der Feldname, der für das Tag extrahiert werden soll. Wenn du die Variable include_timestamp
auf true setzt, wird dem Protokoll ein Zeitstempelfeld hinzugefügt. Die Variable flush_interval
legt das Intervall zwischen den Datenflushs fest. Wir verwenden das Plugin stdout
auch, um Ereignisse/Protokolle auf der Standardausgabe auszugeben.
Schritt 5 – Ausführen der Docker-Container
Wechsle zurück in das EFK-Verzeichnis.
$ cd ~/efk
Starte die Container mit dem folgenden Befehl.
$ docker compose up -d
Überprüfe den Status der laufenden Container.
$ 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
Du kannst dafür auch den folgenden Befehl verwenden.
$ 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
Führe die folgenden Befehle aus, um die Logs des EFK-Build-Prozesses zu überprüfen.
$ docker logs efk-fluentd-1
$ docker logs efk-kibana-1
$ docker logs efk-elasticsearch-1
Überprüfe den Elasticsearch-Container. Er wird die detaillierten Einstellungen des Containers ausgeben.
$ docker inspect efk-elasticsearch-1
Du kannst die IP-Adresse sehen, die dem Container zugewiesen wurde.
[
{
"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
}
}
}
}
]
Wie du sehen kannst, hat der Container 172.23.0.2
als IP-Adresse erhalten. Führe den folgenden Befehl aus, um zu überprüfen, ob Elasticsearch richtig funktioniert.
$ 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"
}
Schritt 6 – Kibana konfigurieren
Jetzt, wo der EFK-Stack eingesetzt wird, ist es an der Zeit, Kibana zu konfigurieren. Öffne die URL http://<yourserverIP>:5601
im Browser.
Klicke auf die Schaltfläche Eigenständig erkunden, um zum Kibana-Dashboard zu gelangen.
Klicke auf den Link Stack Management, um die Kibana-Datenansicht einzurichten. Wähle die Option Kibana >> Datenansichten in der linken Seitenleiste, um die Seite mit den Datenansichten zu öffnen.
Klicke auf die Schaltfläche Datenansicht erstellen, um fortzufahren.
Gib den Namen der Datenansicht und das Indexmuster als fluentd-*
ein. Stelle sicher, dass das Feld Zeitstempel auf @timestamp
eingestellt ist. Das Feld Quelle wird automatisch aktualisiert. Klicke auf die Schaltfläche Datenansicht in Kibana speichern, um die Erstellung der Datenansicht abzuschließen.
Klicke als Nächstes auf das obere Menü (Ellipse) und klicke auf die Option Entdecken, um die Überwachung der Logs anzuzeigen.
Du erhältst die folgende Seite, die bestätigt, dass dein Setup perfekt funktioniert. Die Logs stammen alle von Elasticsearch und werden von der Fluentd-Log-Aggregation ausgeliefert.
Schritt 7 – Nginx installieren
Ubuntu 22.04 wird mit einer älteren Version von Nginx ausgeliefert. Du musst das offizielle Nginx-Repository herunterladen, um die neueste Version zu installieren.
Importiere den Signierschlüssel von Nginx.
$ curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \
| sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null
Füge das Repository für die stabile Version von Nginx hinzu.
$ 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
Aktualisiere die System-Repositories.
$ sudo apt update
Installiere Nginx.
$ sudo apt install nginx
Überprüfe die Installation.
$ nginx -v
nginx version: nginx/1.24.0
Starte den Nginx-Server.
$ sudo systemctl start nginx
Schritt 8 – SSL installieren
Der erste Schritt ist die Installation des Let’s Encrypt SSL-Zertifikats. Wir müssen Certbot installieren, um das SSL-Zertifikat zu erstellen. Du kannst Certbot entweder über das Ubuntu-Repository installieren oder die neueste Version mit dem Snapd-Tool herunterladen. Wir werden die Snapd-Version verwenden.
Bei Ubuntu 22.04 ist Snapd standardmäßig installiert. Führe die folgenden Befehle aus, um sicherzustellen, dass deine Version von Snapd auf dem neuesten Stand ist.
$ sudo snap install core && sudo snap refresh core
Installiere Certbot.
$ sudo snap install --classic certbot
Verwende den folgenden Befehl, um sicherzustellen, dass der Certbot-Befehl ausgeführt werden kann, indem du einen symbolischen Link zum Verzeichnis /usr/bin
erstellst.
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
Erstelle das SSL-Zertifikat für die Domain kibana.example.com
.
$ sudo certbot certonly --nginx --agree-tos --no-eff-email --staple-ocsp --preferred-challenges http -m name@example.com -d kibana.example.com
Mit dem obigen Befehl wird ein Zertifikat in das Verzeichnis /etc/letsencrypt/live/kibana.example.com
auf deinem Server heruntergeladen.
Erstelle ein Diffie-Hellman-Gruppenzertifikat.
$ sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096
Überprüfe den Certbot-Erneuerungsplanerdienst.
$ sudo systemctl list-timers
Du findest snap.certbot.renew.service
als einen der Dienste, die für die Ausführung vorgesehen sind.
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
Führe einen Probelauf des Prozesses durch, um zu prüfen, ob die SSL-Erneuerung einwandfrei funktioniert.
$ sudo certbot renew --dry-run
Wenn du keine Fehler siehst, bist du bereit. Dein Zertifikat wird automatisch erneuert.
Schritt 9 – Nginx konfigurieren
Erstelle und öffne die Nginx-Konfigurationsdatei für Kibana.
$ sudo nano /etc/nginx/conf.d/kibana.conf
Füge den folgenden Code in die Datei ein. Ersetze die IP-Adresse durch die private IP-Adresse deines Elasticsearch-Servers.
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;
}
}
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Öffne die Datei /etc/nginx/nginx.conf
zum Bearbeiten.
$ sudo nano /etc/nginx/nginx.conf
Füge die folgende Zeile vor der Zeile include /etc/nginx/conf.d/*.conf;
ein.
server_names_hash_bucket_size 64;
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst.
Überprüfe die Konfiguration.
$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Starte den Nginx-Dienst neu.
$ sudo systemctl restart nginx
Es ist noch ein weiterer Schritt erforderlich. Öffne die Docker compose Datei zum Bearbeiten.
$ nano ~/docker-compose.yml
Füge die Zeile SERVER_PUBLICBASEURL=https://kibana.example.com
unter dem Abschnitt environment für den Kibana-Dienst wie folgt ein.
environment: # Defined host configuration
- ELASTICSEARCH_HOSTS=http://elasticsearch:9200
- SERVER_PUBLICBASEURL=https://kibana.example.com
Speichere die Datei, indem du Strg + X drückst und Y eingibst, wenn du dazu aufgefordert wirst, sobald du fertig bist.
Stoppe und entferne die Container.
$ docker compose down --remove-orphans
Starte die Container erneut mit der aktualisierten Konfiguration.
$ docker compose up -d
Dein Kibana-Dashboard sollte über die URL https://kibana.example.com
von jedem beliebigen Ort aus zugänglich sein.
Schritt 10 – Ausführen eines Docker-Containers mit Fluentd Log Driver
Jetzt lassen wir einen Docker-Container mit dem Fluentd Log-Treiber laufen, der automatisch Logs an den Stack sendet. Wir testen mit dem Nginx-Container.
Ziehe das Nginx-Image aus der Docker Hub Registry. Wir verwenden die Version alpine
, weil sie die kleinste Version des Images ist.
$ docker pull nginx:alpine
Führe den folgenden Befehl aus, um den Nginx-Container zu erstellen und zu starten. Wir haben den Log-Treiber auf Fluentd
und den Port auf 8080 gesetzt, weil der Standard-Port 80 bereits vom Nginx-Server im Proxy-Modus verwendet wird.
$ docker run --name nginx-fluentd-test -d --log-driver=fluentd -p 8080:80 nginx:alpine
Überprüfe den Status des Containers.
$ 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
Führe den folgenden Befehl aus, um auf den Nginx-Container zuzugreifen und Zugriffsprotokolle zu erstellen.
$ curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Alternativ kannst du die URL http://<yourserverIP>:8080
in deinem Browser öffnen und du erhältst die folgende Seite.
Öffne das Kibana Dashboard und klicke auf den Link Entdecken in der linken Seitenleiste. Klicke auf das +-Zeichen im oberen Menü, um das Popup-Fenster Filter hinzufügen aufzurufen.
Wähle das Feld container_name
aus dem Dropdown, is
als Operator und gib den Containernamen ( nginx-fluentd-test
) als Feldwert ein.
Klicke auf die Schaltfläche Filter hinzufügen, um die Daten aus dem Nginx-Container zu visualisieren.
Fazit
Damit ist unser Tutorial zur Installation von Elasticsearch, Fluentd und Kibana (EFK) auf einem Ubuntu 22.04 Rechner abgeschlossen. Wenn du Fragen hast, schreibe sie unten in die Kommentare.