Erste Schritte mit dem Elastic Stack und Docker Compose: Teil 1

blog-thumb-charts-laptop.png

Der Elastic Stack ist im Laufe der Jahre gewachsen – und mit ihm der Umfang seiner Funktionen. Das bringt natürlich auch eine erhöhte Komplexität beim Einstieg oder beim Versuch eines lokalen Proof-of-Concept (POC) mit sich. Auch wenn der Einstieg in Elastic nach wie vor am schnellsten und einfachsten über Elastic Cloud gelingt, besteht doch weiterhin ein großer Bedarf an Möglichkeiten für lokale Entwicklungsarbeiten und Tests. Für uns Entwickler:innen geht doch nichts über eine einfache Einrichtung und schnelles Entwickeln mit Ergebnissen, die ohne viel Aufwand erzielt wurden. Und nichts ist so eng mit einer einfachen Einrichtung und schnellen POCs verbunden wie Docker. Und genau darauf werden wir uns konzentrieren, um einen ganzen Elastic Stack an den Start zu bringen, an dem Sie lokal Ihre Freude haben werden. 

In Teil 1 dieser zweiteiligen Serie beschäftigen wir uns mit dem Konfigurieren der Komponenten eines Standard-Elastic Stack, bestehend aus Elasticsearch, Logstash, Kibana und Beats (ELK-B), auf dem wir sofort mit dem Entwickeln beginnen können.

In Teil 2 werden wir unsere Basiskonfiguration verbessern und viele der verschiedenen Features wie APM, Agent, Fleet, Integrations und Enterprise Search hinzufügen, die unseren wachsenden Stack leistungsfähiger machen. Außerdem werden wir uns ansehen, wie wir diese Features für Entwicklungs- und POC-Zwecke in unserer neuen lokalen Umgebung instrumentieren können.

Diejenigen unter Ihnen, die sich mit diesen Themen bereits beschäftigt haben, können diesen Teil einfach überspringen und direkt zum Repo gehen, um sich die Dateien dort zu holen.

Voraussetzung ist, dass Docker Desktop oder Docker Engine mit Docker Compose installiert und konfiguriert ist. In diesem Tutorial verwenden wir Docker Desktop.

Unser Fokus bei diesen Docker-Containern liegt hauptsächlich auf Elasticsearch und Kibana. Wir werden aber auch Metricbeat verwenden, um uns den Cluster genauer anzusehen, und Logstash, um ein paar Grundlagen des Ingestierens zu erklären.

Dateistruktur

Beginnen wir damit, die Grundzüge unserer Dateistruktur zu definieren.

├── .env

├── docker-compose.yml

├── filebeat.yml

├── logstash.conf

└── metricbeat.yml

Zunächst halten wir die Struktur einfach. Elasticsearch und Kibana können aus der Datei docker-compose heraus starten, während Filebeat, Metricbeat und Logstash alle zusätzliche Konfigurationsinformationen aus yml-Dateien benötigen. 

Umgebungsdatei

Als Nächstes definieren wir Variablen, die über die .env-Datei an Docker Compose übergeben werden. Mithilfe dieser Parameter können wir Ports, Arbeitsspeicherlimits, Komponentenversionen usw. festlegen.

.env

# Project namespace (defaults to the current folder name if not set)
#COMPOSE_PROJECT_NAME=myproject


# Password for the 'elastic' user (at least 6 characters)
ELASTIC_PASSWORD=changeme


# Password for the 'kibana_system' user (at least 6 characters)
KIBANA_PASSWORD=changeme


# Version of Elastic products
STACK_VERSION=8.7.1


# Set the cluster name
CLUSTER_NAME=docker-cluster


# Set to 'basic' or 'trial' to automatically start the 30-day trial
LICENSE=basic
#LICENSE=trial


# Port to expose Elasticsearch HTTP API to the host
ES_PORT=9200


# Port to expose Kibana to the host
KIBANA_PORT=5601


# Increase or decrease based on the available host memory (in bytes)
ES_MEM_LIMIT=1073741824
KB_MEM_LIMIT=1073741824
LS_MEM_LIMIT=1073741824


# SAMPLE Predefined Key only to be used in POC environments
ENCRYPTION_KEY=c34d38b3a14956121ff2170e5030b471551370178f43e5626eec58b04a30fae2

Für Platzhalter und den Beispielschlüssel verwenden wir hier das Platzhalterwort „changeme“. Dieses dient lediglich der Demonstration und sollte selbst für Ihre lokalen POC-Anforderungen geändert werden. 

Wie Sie hier sehen, legen wir für Elasticsearch Port 9200 und für Kibana Port 5601 fest. An dieser Stelle können Sie auch vom Lizenztyp „basic“ zum Lizenztyp „trial“ wechseln, um zusätzliche Features testen zu können.

Wir verwenden hier für die Übergabe an die einzelnen Services (Container) in unserer Datei docker-compose.yml die Umgebungsvariable STACK_VERSION. Bei Verwendung von Docker bietet sich eine harte Codierung der Versionsnummer an, um eine positive Kontrolle über die Umgebung zu behalten. Das wäre bei Verwendung von so etwas wie dem Tag :latest nicht gegeben, denn das Tag :latest wird von Komponenten des Elastic Stack nicht unterstützt und wir benötigen zum Abrufen der Images Versionsnummern.

Einrichtung und Elasticsearch-Knoten

Zu den ersten neuralgischen Punkten, auf die man beim Einstieg stößt, gehört die Security-Konfiguration. Ab Version 8.0 ist Security standardmäßig aktiviert. Daher müssen wir die Zertifikats-CA korrekt eingerichtet und dabei zum Einrichten der Zertifikate einen „Setup“-Knoten verwendet haben. Es wird empfohlen, mit aktivierter Security zu arbeiten – selbst in POC-Umgebungen.

docker-compose.yml (Container ‚setup‘)

version: "3.8"


volumes:
 certs:
   driver: local
 esdata01:
   driver: local
 kibanadata:
   driver: local
 metricbeatdata01:
   driver: local
 filebeatdata01:
   driver: local
 logstashdata01:
   driver: local


networks:
 default:
   name: elastic
   external: false


services:
 setup:
   image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
   volumes:
     - certs:/usr/share/elasticsearch/config/certs
   user: "0"
   command: >
     bash -c '
       if [ x${ELASTIC_PASSWORD} == x ]; then
         echo "Set the ELASTIC_PASSWORD environment variable in the .env file";
         exit 1;
       elif [ x${KIBANA_PASSWORD} == x ]; then
         echo "Set the KIBANA_PASSWORD environment variable in the .env file";
         exit 1;
       fi;
       if [ ! -f config/certs/ca.zip ]; then
         echo "Creating CA";
         bin/elasticsearch-certutil ca --silent --pem -out config/certs/ca.zip;
         unzip config/certs/ca.zip -d config/certs;
       fi;
       if [ ! -f config/certs/certs.zip ]; then
         echo "Creating certs";
         echo -ne \
         "instances:\n"\
         "  - name: es01\n"\
         "    dns:\n"\
         "      - es01\n"\
         "      - localhost\n"\
         "    ip:\n"\
         "      - 127.0.0.1\n"\
         "  - name: kibana\n"\
         "    dns:\n"\
         "      - kibana\n"\
         "      - localhost\n"\
         "    ip:\n"\
         "      - 127.0.0.1\n"\
         > config/certs/instances.yml;
         bin/elasticsearch-certutil cert --silent --pem -out config/certs/certs.zip --in config/certs/instances.yml --ca-cert config/certs/ca/ca.crt --ca-key config/certs/ca/ca.key;
         unzip config/certs/certs.zip -d config/certs;
       fi;
       echo "Setting file permissions"
       chown -R root:root config/certs;
       find . -type d -exec chmod 750 \{\} \;;
       find . -type f -exec chmod 640 \{\} \;;
       echo "Waiting for Elasticsearch availability";
       until curl -s --cacert config/certs/ca/ca.crt https://es01:9200 | grep -q "missing authentication credentials"; do sleep 30; done;
       echo "Setting kibana_system password";
       until curl -s -X POST --cacert config/certs/ca/ca.crt -u "elastic:${ELASTIC_PASSWORD}" -H "Content-Type: application/json" https://es01:9200/_security/user/kibana_system/_password -d "{\"password\":\"${KIBANA_PASSWORD}\"}" | grep -q "^{}"; do sleep 10; done;
       echo "All done!";
     '
   healthcheck:
     test: ["CMD-SHELL", "[ -f config/certs/es01/es01.crt ]"]
     interval: 1s
     timeout: 5s
     retries: 120

Zu Beginn der Datei docker-compose.yml legen wir die Compose-Version fest, gefolgt von den Volumes und der Standardnetzwerkkonfiguration, die in unseren verschiedenen Containern verwendet werden soll.

Wie Sie sehen, haben wir mit ein bisschen Bash-Zauberei einen Container namens „setup“ eingerichtet, um unsere Cluster-Knoten anzugeben. Auf diese Weise können wir elasticsearch-certutil aufrufen und die Servernamen im yml-Format übergeben, um das CA-Zertifikat und die Knotenzertifikate zu erstellen. Wenn Sie in Ihrem Stack mehrere Elasticsearch-Knoten haben möchten, müssten Sie hier den Servernamen hinzufügen, um die Zertifikaterstellung zu erlauben.

Hinweis: In einem zukünftigen Blogpost werden wir die empfohlene Methode der Verwendung eines Schlüsselspeichers zur Wahrung von Secrets anwenden, aber für den Moment reicht uns das so und wir können den Cluster zum Laufen bringen.

Dieser Container ‚setup‘ startet zuerst, wartet dann darauf, dass der Container ‚es01‘ online geht, und nutzt anschließend unsere Umgebungsvariablen, um die Passwörter einzurichten, die wir in unserem Cluster haben wollen. Wir speichern auch alle Zertifikate im Volume „certs“, damit alle anderen Container auf sie zugreifen können.

Da der Container ‚setup‘ vom Container ‚es01‘ abhängig ist, sehen wir uns kurz die nächste Konfiguration an, damit wir beide starten können:

docker-compose.yml (Container ‚es01‘)

 es01:
   depends_on:
     setup:
       condition: service_healthy
   image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
   labels:
     co.elastic.logs/module: elasticsearch
   volumes:
     - certs:/usr/share/elasticsearch/config/certs
     - esdata01:/usr/share/elasticsearch/data
   ports:
     - ${ES_PORT}:9200
   environment:
     - node.name=es01
     - cluster.name=${CLUSTER_NAME}
     - discovery.type=single-node
     - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
     - bootstrap.memory_lock=true
     - xpack.security.enabled=true
     - xpack.security.http.ssl.enabled=true
     - xpack.security.http.ssl.key=certs/es01/es01.key
     - xpack.security.http.ssl.certificate=certs/es01/es01.crt
     - xpack.security.http.ssl.certificate_authorities=certs/ca/ca.crt
     - xpack.security.transport.ssl.enabled=true
     - xpack.security.transport.ssl.key=certs/es01/es01.key
     - xpack.security.transport.ssl.certificate=certs/es01/es01.crt
     - xpack.security.transport.ssl.certificate_authorities=certs/ca/ca.crt
     - xpack.security.transport.ssl.verification_mode=certificate
     - xpack.license.self_generated.type=${LICENSE}
   mem_limit: ${ES_MEM_LIMIT}
   ulimits:
     memlock:
       soft: -1
       hard: -1
   healthcheck:
     test:
       [
         "CMD-SHELL",
         "curl -s --cacert config/certs/ca/ca.crt https://localhost:9200 | grep -q 'missing authentication credentials'",
       ]
     interval: 10s
     timeout: 10s
     retries: 120

Dies ist der aus einem einzigen Knoten bestehende Cluster von Elasticsearch, den wir zum Testen verwenden werden.

Zu beachten ist, dass wir das CA-Zertifikat und die Knotenzertifikate verwenden, die generiert wurden. 

Sie werden außerdem bemerken, dass wir die Elasticsearch-Daten in einem Volume außerhalb des Containers speichern, indem wir - esdata01:/usr/share/elasticsearch/data festlegen. Die zwei Hauptgründe dafür sind die Performance und die Datenpersistenz. Wenn wir das Datenverzeichnis im Container belassen würden, würde sich die Performance unseres Elasticsearch-Knotens deutlich verschlechtern, und wir würden Daten verlieren, sobald wir die Konfiguration des Containers in unserer docker-compose-Datei ändern müssten.

Jetzt sind beide Konfigurationen einsatzbereit und wir können unseren ersten ‚docker-compose up‘-Befehl ausführen.

Tipps für Docker Compose

Für alle, für die Docker Compose neu ist oder die den einen oder anderen Docker Compose-Befehl schon wieder vergessen haben, werfen wir im Folgenden einen kurzen Blick auf die wichtigsten Befehle, die Sie für unsere Zwecke hier kennen sollten.

Alle diese Befehle sollten in einem Terminal ausgeführt werden und Sie sollten sich dabei im selben Ordner befinden, in dem sich auch Ihre Datei docker-compose.yml befindet. Mein Beispielordner sieht wie folgt aus:

Gehen wir diese Befehle gemeinsam durch.

Jetzt führen wir ‚docker-compose up‘ aus.

Wenn die Syntax korrekt ist, beginnt Docker an dieser Stelle damit, alle Images herunterzuladen und die Umgebung zu erstellen, die in der Datei docker-compose.yml beschrieben ist. Je nachdem, wie schnell das Internet bei Ihnen ist, kann das ein paar Minuten dauern. Wenn Sie sich die Images außerhalb von Docker Desktop ansehen möchten, finden Sie sie zu jedem Zeitpunkt im offiziellen Elastic Docker Hub.

Fehlerbehebung bei Fehlkonfigurationen des virtuellen Arbeitsspeichers

Wenn sie den Elasticsearch-Knoten zum ersten Mal starten, bleiben viele Nutzer:innen bei der Konfiguration des virtuellen Arbeitsspeichers stecken und erhalten eine Fehlermeldung wie die folgende:

{"@timestamp":"2023-04-14T13:16:22.148Z", "log.level":"ERROR", "message":"node validation exception\n[1] bootstrap checks failed. You must address the points described in the following [1] lines before starting Elasticsearch.\nbootstrap check failure [1] of [1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]", "ecs.version": "1.2.0","service.name":"ES_ECS","event.dataset":"elasticsearch.server","process.thread.name":"main","log.logger":"org.elasticsearch.bootstrap.Elasticsearch","elasticsearch.node.name":"es01","elasticsearch.cluster.name":"docker-cluster"}

Der wichtigste Teil dieser Fehlermeldung ist folgender: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144].

Letztendlich muss dort, wo die Container gehostet werden, der Befehl sysctl -w vm.max_map_count=262144 ausgeführt werden.

Eine Anleitung für Docker for Mac (für macOS) finden Sie hier. Wie bei Docker Desktop vorzugehen ist, können Sie hier nachlesen. Linux-Nutzer:innen finden entsprechende Informationen hier. Windows-Nutzer:innen, die Docker Desktop nutzen können, werden hier fündig. Und wenn Sie WSLv2 mit Docker Desktop verwenden, schlagen Sie hier nach.

Wenn alle Probleme beseitigt sind, können Sie Docker Desktop neu starten und es erneut mit dem Befehl docker-compose up versuchen.

Zur Erinnerung: Der Container ‚setup‘ wird nach dem Generieren der Zertifikate und Passwörter absichtlich beendet.

So weit so gut. Jetzt geht es ans Testen. 

Wir können zum Kopieren von ca.crt aus dem Container ‚es01-1‘ einen Befehl verwenden. Zur Erinnerung: Der Name des Container-Sets richtet sich nach dem Ordner, in dem die Datei docker-compose.yml ausgeführt wird. Bei mir heißt das Verzeichnis „elasticstack_docker“, sodass im Falle des Screenshots oben mein Befehl wie folgt aussieht:

docker cp

elasticstack_docker-es01-1:/usr/share/elasticsearch/config/certs/ca/ca.crt /de/tmp/.

Nach dem Herunterladen des Zertifikats führen wir einen curl-Befehl aus, um den Elasticsearch-Knoten abzufragen:

curl --cacert /de/tmp/ca.crt -u elastic:changeme https://localhost:9200

Es hat geklappt!

Beachten Sie, dass der Zugriff auf Elasticsearch über localhost:9200 erfolgt. Das liegt an dem Port, der im Abschnitt ports der Datei docker-compose.yml angegeben wurde. Diese Einstellung ordnet die Ports des Containers den Ports des Hosts zu und ermöglicht es dem Datenverkehr, durch Ihre Maschine in den Docker-Container zu gelangen, dem der angegebene Port zugeordnet ist.

Kibana

Für die Konfiguration von Kibana nutzen wir die Zertifikatausgabe von vorhin. Außerdem legen wir fest, dass dieser Knoten erst startet, wenn er sieht, dass der Elasticsearch-Knoten oben aktiv ist und korrekt ausgeführt wird.

docker-compose.yml (Container ‚kibana‘)

kibana:
   depends_on:
     es01:
       condition: service_healthy
   image: docker.elastic.co/kibana/kibana:${STACK_VERSION}
   labels:
     co.elastic.logs/module: kibana
   volumes:
     - certs:/usr/share/kibana/config/certs
     - kibanadata:/usr/share/kibana/data
   ports:
     - ${KIBANA_PORT}:5601
   environment:
     - SERVERNAME=kibana
     - ELASTICSEARCH_HOSTS=https://es01:9200
     - ELASTICSEARCH_USERNAME=kibana_system
     - ELASTICSEARCH_PASSWORD=${KIBANA_PASSWORD}
     - ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=config/certs/ca/ca.crt
     - XPACK_SECURITY_ENCRYPTIONKEY=${ENCRYPTION_KEY}
     - XPACK_ENCRYPTEDSAVEDOBJECTS_ENCRYPTIONKEY=${ENCRYPTION_KEY}
     - XPACK_REPORTING_ENCRYPTIONKEY=${ENCRYPTION_KEY}
   mem_limit: ${KB_MEM_LIMIT}
   healthcheck:
     test:
       [
         "CMD-SHELL",
         "curl -s -I http://localhost:5601 | grep -q 'HTTP/1.1 302 Found'",
       ]
     interval: 10s
     timeout: 10s
     retries: 120

Im Abschnitt ‚environment‘ legen wir ELASTICSEARCH_HOSTS=https://es01:9200 fest. Wir können hier den Containernamen für unseren Elasticsearch-Container ‚es01‘ angeben, weil wir die standardmäßige Docker-Netzwerkkonfiguration verwenden. Alle Container, die das Netzwerk „elastic“ verwenden, das am Anfang unserer Datei docker-compose.yml angegeben wurde, sind in der Lage, andere Containernamen korrekt aufzulösen und miteinander zu kommunizieren.

Wir laden jetzt einfach Kibana hoch und probieren, ob wir darauf zugreifen können.

Die Container sind grün. Wir sollten also jetzt auf http://localhost:5601 zugreifen können.

Ein kurzer Login mit dem festgelegten Nutzernamen und Passwort sollte uns direkt in eine nagelneue Instanz von Kibana bringen. Hervorragend!

Metricbeat

Wir haben Kibana und Elasticsearch zum Laufen und zum Kommunizieren gebracht. Jetzt ist es Zeit, Metricbeat zu konfigurieren, um im Auge zu behalten, was sich so abspielt. Dazu müssen wir die Datei docker-compose.yml und auch eine separate Datei mit dem Namen metricbeat.yml konfigurieren.

Hinweis: Für Logstash, Filebeat und Metricbeat verwenden die Konfigurationsdateien sogenannte Bind-Mounts. Bind-Mounts für Dateien behalten innerhalb des Containers dieselben Berechtigungen und denselben Eigentümer wie auf dem Host-System. Achten Sie darauf, die Berechtigungen so festzulegen, dass die Dateien lesbar sind und, im Idealfall, durch die Nutzer:innen des Containers nicht verändert werden können. Andernfalls erhalten Sie eine Fehlermeldung im Container. Es könnte reichen, einfach die Schreibberechtigungen auf Ihrem Host zu entfernen.

docker-compose.yml (Container ‚metricbeat01‘)

 metricbeat01:
   depends_on:
     es01:
       condition: service_healthy
     kibana:
       condition: service_healthy
   image: docker.elastic.co/beats/metricbeat:${STACK_VERSION}
   user: root
   volumes:
     - certs:/usr/share/metricbeat/certs
     - metricbeatdata01:/usr/share/metricbeat/data
     - "./metricbeat.yml:/usr/share/metricbeat/metricbeat.yml:ro"
     - "/var/run/docker.sock:/var/run/docker.sock:ro"
     - "/sys/fs/cgroup:/hostfs/sys/fs/cgroup:ro"
     - "/proc:/hostfs/proc:ro"
     - "/:/hostfs:ro"
   environment:
     - ELASTIC_USER=elastic
     - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
     - ELASTIC_HOSTS=https://es01:9200
     - KIBANA_HOSTS=http://kibana:5601
     - LOGSTASH_HOSTS=http://logstash01:9600

Hier stellen wir dem Metricbeat-Container schreibgeschützte Host-Informationen über Prozesse, das Dateisystem und den Docker-Daemon zur Verfügung. Dadurch ist Metricbeat in der Lage, die Daten zu sammeln, die an Elasticsearch gesendet werden sollen.

metricbeat.yml

metricbeat.config.modules:
 path: ${path.config}/modules.d/*.yml
 reload.enabled: false


metricbeat.modules:
- module: elasticsearch
 xpack.enabled: true
 period: 10s
 hosts: ${ELASTIC_HOSTS}
 ssl.certificate_authorities: "certs/ca/ca.crt"
 ssl.certificate: "certs/es01/es01.crt"
 ssl.key: "certs/es01/es01.key"
 username: ${ELASTIC_USER}
 password: ${ELASTIC_PASSWORD}
 ssl.enabled: true


- module: logstash
 xpack.enabled: true
 period: 10s
 hosts: ${LOGSTASH_HOSTS}


- module: kibana
 metricsets:
   - stats
 period: 10s
 hosts: ${KIBANA_HOSTS}
 username: ${ELASTIC_USER}
 password: ${ELASTIC_PASSWORD}
 xpack.enabled: true


- module: docker
 metricsets:
   - "container"
   - "cpu"
   - "diskio"
   - "healthcheck"
   - "info"
   #- "image"
   - "memory"
   - "network"
 hosts: ["unix:///var/run/docker.sock"]
 period: 10s
 enabled: true


processors:
 - add_host_metadata: ~
 - add_docker_metadata: ~


output.elasticsearch:
 hosts: ${ELASTIC_HOSTS}
 username: ${ELASTIC_USER}
 password: ${ELASTIC_PASSWORD}
 ssl:
   certificate: "certs/es01/es01.crt"
   certificate_authorities: "certs/ca/ca.crt"
   key: "certs/es01/es01.key"

Voraussetzung für unser Metricbeat ist, dass der Knoten ‚es01‘ und der Kibana-Knoten vor dem Starten ordnungsgemäß funktionieren. Die wichtigsten Konfigurationen hier erfolgen in der Datei metricbeat.yml. Wir haben für das Sammeln von Metriken vier Module aktiviert: Elasticsearch, Kibana, Logstash und Docker. Sobald wir uns davon überzeugt haben, dass Metricbeat läuft, können wir somit zu Kibana gehen und uns dort unter „Stack Monitoring“ ansehen, ob alles in Ordnung ist.

Vergessen Sie nicht, Ihre Out-of-the-Box-Regeln einzurichten!

Metricbeat ist über /var/run/docker.sock auch für das Monitoring des Container-Hosts konfiguriert. In Elastic Observability können Sie sehen, wie die Metriken von Ihrem Host hereinkommen.

Filebeat

Das Cluster ist jetzt stabil und wird mit Metricbeat überwacht. Daher können wir uns jetzt für das Ingestieren von Logs Filebeat zuwenden. Unser Filebeat wird hier auf zwei unterschiedliche Arten eingesetzt:

docker-compose.yml (Container ‚filebeat01‘)

 filebeat01:
   depends_on:
     es01:
       condition: service_healthy
   image: docker.elastic.co/beats/filebeat:${STACK_VERSION}
   user: root
   volumes:
     - certs:/usr/share/filebeat/certs
     - filebeatdata01:/usr/share/filebeat/data
     - "./filebeat_ingest_data/:/usr/share/filebeat/ingest_data/"
     - "./filebeat.yml:/usr/share/filebeat/filebeat.yml:ro"
     - "/var/lib/docker/containers:/var/lib/docker/containers:ro"
     - "/var/run/docker.sock:/var/run/docker.sock:ro"
   environment:
     - ELASTIC_USER=elastic
     - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
     - ELASTIC_HOSTS=https://es01:9200
     - KIBANA_HOSTS=http://kibana:5601
     - LOGSTASH_HOSTS=http://logstash01:9600

filebeat.yml

filebeat.inputs:
- type: filestream
 id: default-filestream
 paths:
   - ingest_data/*.log


filebeat.autodiscover:
 providers:
   - type: docker
     hints.enabled: true


processors:
- add_docker_metadata: ~


setup.kibana:
 host: ${KIBANA_HOSTS}
 username: ${ELASTIC_USER}
 password: ${ELASTIC_PASSWORD}


output.elasticsearch:
 hosts: ${ELASTIC_HOSTS}
 username: ${ELASTIC_USER}
 password: ${ELASTIC_PASSWORD}
 ssl.enabled: true
 ssl.certificate_authorities: "certs/ca/ca.crt"

Als Erstes legen wir ein Bind-Mount fest, um den Ordner „filebeat_ingest_data“ dem Container zuzuordnen. Wenn dieser Ordner auf Ihrem Host nicht vorhanden ist, wird er beim Starten des Containers erstellt. Wenn Sie für Ihre benutzerdefinierten Logs den Logs Stream-Viewer von Elastic Observability testen möchten, können Sie einfach eine beliebige Datei mit der Erweiterung .log in /filebeat_ingest_data/ ablegen. Die Logs werden dann in den Standard-Filebeat-Datastream eingelesen.

Zusätzlich ordnen wir auch /var/lib/docker/containers und /var/run/docker.sock zu, was es Filebeat – in Kombination mit dem Abschnitt filebeat.autodiscover und hinweisbasiertem Autodiscover – ermöglicht, die Logdaten für alle Container abzurufen. Diese Logdaten sind auch im oben erwähnten Logs Stream-Viewer zu finden.

Logstash

Der letzte Container, den wir zum Laufen bringen wollen, ist der Logstash-Container.

docker-compose.yml (Container ‚logstash01‘)

 logstash01:
   depends_on:
     es01:
       condition: service_healthy
     kibana:
       condition: service_healthy
   image: docker.elastic.co/logstash/logstash:${STACK_VERSION}
   labels:
     co.elastic.logs/module: logstash
   user: root
   volumes:
     - certs:/usr/share/logstash/certs
     - logstashdata01:/usr/share/logstash/data
     - "./logstash_ingest_data/:/usr/share/logstash/ingest_data/"
     - "./logstash.conf:/usr/share/logstash/pipeline/logstash.conf:ro"
   environment:
     - xpack.monitoring.enabled=false
     - ELASTIC_USER=elastic
     - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
     - ELASTIC_HOSTS=https://es01:9200

logstash.conf

input {
 file {
   #https://www.elastic.co/guide/en/logstash/current/plugins-inputs-file.html
   #default is TAIL which assumes more data will come into the file.
   #change to mode => "read" if the file is a compelte file.  by default, the file will be removed once reading is complete -- backup your files if you need them.
   mode => "tail"
   path => "/usr/share/logstash/ingest_data/*"
 }
}


filter {
}


output {
 elasticsearch {
   index => "logstash-%{+YYYY.MM.dd}"
   hosts=> "${ELASTIC_HOSTS}"
   user=> "${ELASTIC_USER}"
   password=> "${ELASTIC_PASSWORD}"
   cacert=> "certs/ca/ca.crt"
 }
}

Die Logstash-Konfiguration ist der Filebeat-Konfiguration sehr ähnlich. Wir verwenden erneut ein Bind-Mount und ordnen dem Logstash-Container einen Ordner namens /logstash_ingest_data/ vom Host zu. Hier können Sie durch Bearbeiten der Datei logstash.yml einige der vielen Input-Plugins und Filter-Plugins ausprobieren. Legen Sie anschließend Ihre Daten im Ordner /logstash_ingest_data/ ab. Nach dem Bearbeiten der Datei logstash.yml kann es erforderlich sein, den Logstash-Container neu zu starten.

Der Logstash-Ausgabeindex hat den Namen „logstash-%{+YYYY.MM.dd}“. Um die Daten zu sehen, müssen Sie, wie unten zu sehen, für das „logstash-*“-Muster eine Datenansicht erstellen.

Filebeat und Logstash sind jetzt beide eingerichtet und werden ausgeführt. Wenn Sie zu Cluster Monitoring zurückgehen, werden Sie feststellen, dass Logstash überwacht wird, und Sie werden einige Metriken und Links zu Elasticsearch-Logs sehen.

Fazit

In Teil 1 dieser Serie haben wir uns damit beschäftigt, als Basiskonfiguration für unseren Stack einen aktiven Cluster mit Monitoring und Ingestion einzurichten. Dieser Cluster wird uns dazu dienen, einige der Features des Elastic-Ökosystems auszuprobieren.

Sie möchten mehr erfahren? Dann sehen Sie sich Teil 2 an! Darin beschäftigen wir uns damit, wie wir diese Basiskonfiguration optimieren und zusätzliche Features einrichten können, wie APM Server, Elastic Agents, Elastic Integrations und Elastic Search. Außerdem werden wir eine Anwendung bereitstellen und testen, die Sie mit einigen dieser Komponenten instrumentieren können.

Alle Dateien, die hier erwähnt wurden, stehen auf GitHub zur Verfügung. Dort finden Sie auch ein paar Beispieldaten zum Ingestieren für Filebeat und Logstash.

Einführung in Elastic Stack ansehen