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

blog-thumb-virtual-stack.png

Willkommen bei Teil 2 von „Erste Schritte mit dem Elastic® Stack und Docker Compose“. Im ersten Teil der Blogpost-Serie haben wir uns mit den Grundlagen von Docker Compose und damit beschäftigt, wie wir einen Einzelknoten-Cluster mit Elasticsearch®, Kibana®, Logstash®, Metricbeat und Filebeat einrichten, um ihn als lokale Spielwiese zu nutzen. Wenn Sie diesen ersten Teil noch nicht gelesen haben, empfiehlt es sich, dies jetzt nachzuholen, bevor Sie fortfahren.

In diesem Blogpost werden wir unseren in Teil 1 erstellten Cluster verwenden und ihm zusätzliche Features wie Fleet, Agent, APM sowie eine Demo-Anwendung für Ihr POC hinzufügen. Zur Erinnerung: Docker Compose wird nicht für den Produktionseinsatz empfohlen, auch nicht bei größeren Clustern.

Wenn Sie sich mit dem Thema schon auskennen und nur den Code schreiben möchten, können Sie natürlich gern diesen Teil einfach überspringen und direkt zum GitHub-Repo gehen, um sich die Dateien dort zu holen.

Lassen Sie uns anfangen.

Agent, Fleet, APM … was ist denn das nun schon wieder?!

Keine Sorge, wenn Sie mit diesen Begriffen und Produkten noch nicht vertraut sind! Wir nehmen uns zunächst kurz die Zeit, um uns damit zu beschäftigen, was diese Features sind und warum sie Ihnen helfen könnten. 

In unserer ursprünglichen Architektur für diesen Cluster lag der Schwerpunkt auf den Grundlagen, ergänzt um ein bisschen Monitoring und Dateningestion. Das Ganze sah wie folgt aus:

Elastic Agent: ein Kurzüberblick

Beginnen wir mit Elastic Agent und einigen Begriffen, die in diesem Zusammenhang zusätzlich relevant sind.

Elastic Agent bietet die Möglichkeit, per Host-Monitoring verschiedene Datentypen wie Logdaten, Metriken und andere zentral zu überwachen. Außerdem bietet es Schutz vor Sicherheitsbedrohungen, dem Abfragen von Betriebssystemdaten, der Weiterleitung von Remote-Service- oder Hardware-Daten und vielem mehr. Elastic Agent rationalisiert und beschleunigt Monitoring-Deployments in Ihrer Infrastruktur. Jeder Agent ist mit Richtlinien verknüpft, die aktualisiert werden können, um Integrationen für neue Datenquellen, Sicherheitsmaßnahmen und zusätzliche Funktionalitäten einzubauen.

Elastic Integrations sollen Ihnen dabei helfen, schnell und einfach Daten aus externen Quellen zu erfassen und in Erkenntnisse umzuwandeln. Diese Integrationen verwenden oft vordefinierte Einstellungen, Dashboards, Visualisierungen und Pipelines, die bei der Nutzbarmachung von Logdaten, Metriken und Ereignisdaten helfen. Die Seite „Integrations“ finden Sie in Ihrer lokalen Kibana-Instanz – so können Sie ganz einfach Integrationen in Zusammenhang mit Elastic Agent und dessen Richtlinien durchsuchen, installieren und konfigurieren. Eine Liste der verfügbaren Integrationen finden Sie auch auf der Elastic-Website.

Richtlinien (auch „Policies“ genannt) sind Zusammenstellungen von Einstellungen und Integrationen, die festlegen, wie Elastic Agent arbeitet. Einer Agent-Richtlinie können mehrere Integrationen zugewiesen sein; das macht es möglich, flexibel festzulegen, welche Daten Agents erfassen sollen. Wenn Sie eine Elastic Agent-Richtlinie mehreren Agents zuweisen, können Sie Fleet nutzen, um eine größere Anzahl von Agents zu verwalten und zu konfigurieren.

Fleet ist die Kibana-Benutzeroberfläche für die zentralisierte Verwaltung des Elastic Agent und der mit ihm verbundenen Richtlinien. Über diese Benutzeroberfläche können Sie den Zustand jedes einzelnen Agents, die installierte Version, den letzten Check-in oder die letzte Aktivitätszeit sowie Richtlinieninformationen einsehen. Die Kommunikation mit den einzelnen Elastic Agents erfolgt durch Fleet über Fleet Server. Auf diese Weise können per Remote-Push beim Check-in neue Richtlinien-Updates sowie Upgrades von Agent-Binärdateien oder Integrationen bereitgestellt werden.

Fleet Server ist eine Elastic Agent-Instanz, die als Koordinator der Kommunikation zwischen Fleet und allen bereitgestellten Elastic Agents dient.

*Puh!*

Wenn Sie mehr zu all diesen Themen im Zusammenhang mit Agent und Fleet erfahren möchten, sehen Sie sich in der Dokumentation von Elastic um.

Wir werden jetzt Elastic Agent und Fleet integrieren, um zu zeigen, wie Verwaltungsrichtlinien genutzt werden können, um Logdaten und Metriken zu erfassen. Wir bauen sie beide in unser Architekturdiagramm ein – mal sehen, wie das Ganze dann aussieht.

Elastic APM und eine individuelle Webanwendung

Elastic APM ist ein System zum Monitoring der Anwendungs-Performance, das auf dem Elastic Stack basiert. Wenn Sie zum Instrumentieren Ihres Codes Elastic APM Agents verwenden, kann dass die Fehlersuche sowie Fragen zur Performance vereinfachen, indem Metriken, Traces, Logdaten, Fehler und Ausnahmen gesammelt und an Elasticsearch übertragen werden, um sie in der APM-Benutzeroberfläche sichtbar zu machen.

Elastic APM kann in der Cloud eingerichtet oder lokal verwaltet werden. Wenn Sie eine lokale Instanz von APM verwalten, können Sie entscheiden, ob Sie eine Standalone-APM-Server-Binärdatei verwalten oder APM als Integration über Elastic Agent nutzen möchten.

Für unseren lokalen POC implementieren wir Elastic APM und lassen es durch Elastic Agent und Fleet-Dienste verwalten.

Die Fähigkeit, die Anwendungs-Performance zu überwachen, bringt reichlich wenig, wenn es gar keine zu überwachende Anwendung gibt. Im Idealfall haben Sie bereits Code, den Sie mit einem unserer APM Agents instrumentieren möchten. Wenn das nicht der Fall ist, finden Sie im GitHub-Repository eine kleine Python-Anwendung, die wir für ein paar grundlegende Tests verwenden können.

Neue Architektur

Sehen wir uns unser Architekturdiagramm noch einmal an, um herauszufinden, wie das alles passt.

Hier können wir erkennen, dass der neue Fleet-Server-Container, auf dem der Elastic Agent ausgeführt wird, als zentraler Kommunikationspunkt für die gesamte Agent-Kommunikation mit dem Elastic-Cluster fungiert. Der Elastic Agent führt die Elastic APM-Integration aus, um Telemetriedaten sowohl aus unserer benutzerdefinierten Webanwendung als auch aus Kibana zu erfassen.

Kommunikation und Zugriff

Eine der häufigsten Herausforderungen beim Einstieg in die Arbeit mit Docker besteht darin zu verstehen, wie die Kommunikation funktioniert. Angesichts all der Container, Ports, Zertifikate und URLs, die hier erwähnt wurden, ist es am besten, kurz einen Schritt zurückzutreten und sich anzusehen, wie diese neue Architektur aussieht, wenn die verschiedenen Teile miteinander kommunizieren müssen.

Wie Sie gesehen haben, enthält unsere Datei docker-compose.yml Code, den wir zum Generieren von Zertifikaten für die verschiedenen Container verwenden. Dieser sieht ungefähr so aus:

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"\
"  - name: fleet-server\n"\
"    dns:\n"\
"      - fleet-server\n"\
"      - localhost\n"\
"    ip:\n"\
"      - 127.0.0.1\n"\
> config/certs/instances.yml;

Dieser Codeblock erstellt eine Datei namens instances.yml, die im „setup“-Container gespeichert ist. Dabei handelt es sich um eine Liste aller Namen des Containers und der entsprechenden DNS-Einträge, aus der hervorgeht, wie sie sich innerhalb der Docker-Engine zueinander verhalten. Wir erstellen mit dieser Datei und dem Dienstprogramm elasticsearch-certutil für jeden Container ein Zertifikat, um dafür zu sorgen, dass die Container sowohl untereinander als auch mit Ihnen sicher kommunizieren können.
 

Alle unsere Container nutzen für die Kommunikation untereinander das Standardnetzwerk, das wir in docker-compose.yml wie folgt eingerichtet haben:

networks:
  default:
    name: elastic

Dieses Netzwerk ist ein internes Netzwerk in Docker Engine, das es allen Containern ermöglicht, sich untereinander zu unterhalten und die Namen anderer Container aufzulösen. Damit Traffic von Ihrem Browser den Container erreichen kann, geben wir in jedem Dienst die erforderlichen Ports frei. Dazu ein Beispiel:

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
  ...

Dabei sehen wir uns insbesondere den Abschnitt ports: an. Dieser weist Docker Compose an, die mit dem Format „host:container“ angegebenen Ports zuzuweisen. In diesem Beispiel würde „${ES_PORT}“ durch 9200 aus unserer .env-Datei ersetzt werden und dieser Port würde auf Ihrem Computer (Host) geöffnet werden. Die zweite 9200 steht für den Port am Container, dem wir unseren Host zuordnen. Damit wird festgelegt, dass Traffic, der von Ihrem Browser ausgeht, beim Zugriff auf https://localhost:9200 an den Container „es01“ gesendet wird.

Für die Kommunikation zwischen den Knoten öffnet Elasticsearch standardmäßig auch Port 9300. Die anderen Container in Ihrer Docker-Engine haben zwar bei Bedarf Zugriff auf diesen Port, aber da wir ihn nicht freigegeben haben, können Sie von Ihrem Host aus nicht auf ihn zugreifen.

Wenn wir versuchen, diese Konzepte mithilfe unserer neuen Architektur zu visualisieren, könnte das wie folgt aussehen:

In dieser Grafik ist der Container „metricbeat01“ in der Lage, die Namen aufzulösen, die wir „es01“ und „logstash01“ gegeben haben, und sogar auf den nicht freigegebenen Monitoring-Port 9600 auf „logstash01“ zuzugreifen, da diese sich im selben Docker-Netzwerk befinden.

Wir können jedoch sehen, dass Sie für die Kommunikation mit Elasticsearch über den Port 9200 und mit Kibana über den Port 5601 auf „localhost“ zugreifen müssen, damit Ihr Computer den Traffic in das Docker-Netzwerk und zu den richtigen Containern leiten kann.

Schließlich kann es schwierig sein zu entscheiden, welche Adresse zum Verweisen auf einen dieser Dienste zu verwenden ist. Ein ganz wichtiger Punkt dabei ist: Wenn einer Ihrer Container auf einen anderen Container zugreift, der mit dem Elastic-Netzwerk konfiguriert wurde, müssen Sie den richtigen Dienst-/Containernamen verwenden. Wenn jedoch von Ihrem Host-Computer ausgehender Traffic auf einen der Container zugreift, müssen Sie sicherstellen, dass in der Datei docker-compose.yml der richtige Port freigegeben ist, und für den Zugriff auf diesen Port „localhost“ nutzen.

Bitte beachten Sie auch, dass diese Konfigurationen zwar den Einstieg in die lokale Entwicklung vereinfachen, nicht aber für den Einsatz in Produktionsumgebungen empfohlen werden.

Implementierung

Wie implementieren wir nun all das?

Als Erstes sehen wir uns kurz unseren Basis-Stack an und gehen auf einige Änderungen ein. Wir beginnen dabei mit unserer Dateistruktur, der .env-Datei und der Datei docker-compose.yml

Dateistruktur

Unserer Dateistruktur haben wir den Ordner „app“ hinzugefügt, der neben kibana.yml den gesamten Code und die Konfiguration für unsere benutzerdefinierte Webanwendung enthalten soll, da wir sowohl für Elastic Agent als auch APM genauere Einstellungen hinzufügen werden.

.env

Unsere .env-Datei (GitHub-Link) bleibt im Wesentlichen unverändert, aber ihr werden neue Ports für Fleet, APM Server und ein geheimes APM-Token hinzugefügt (siehe unten).

Das geheime Token kommt später in unserer Implementierung zum Autorisieren von Anfragen an den APM-Server zum Einsatz. Mehr zu diesem Thema finden Sie in der Dokumentation.

# Port to expose Fleet to the host
FLEET_PORT=8220


# Port to expose APM to the host
APMSERVER_PORT=8200


# APM Secret Token for POC environments only
ELASTIC_APM_SECRET_TOKEN=supersecrettoken

Zur Erinnerung: Alle Passwörter oder Schlüssel, die in diesem Blogpost verwendet werden, dienen einzig und allein der Demonstration und sollten in Ihren Umgebungen sofort geändert werden.

docker-compose.yml

Für unsere Datei docker-compose.yml haben wir dem Basis-Stack Container für „Fleet Server“ und „webapp“ sowie zusätzliche Volumes hinzugefügt und wir haben Fleet Server auf unsere Serverliste für die Zertifikatgenerierung gesetzt, wie oben erwähnt.

Sie finden die vollständige Datei auf GitHub, im Rahmen dieses Blogposts gehen wir aber nur auf einige wenige Bearbeitungen ein.

Hinweis zu Umgebungsvariablen

Es gibt eine Reihe von Umgebungsvariablen in bestehenden Diensten, in denen Zertifikate angegeben und an den Container oder die entsprechende Konfigurationsdatei weitergegeben wurden.

Ähnlich wie in unserer .env-Datei erlauben uns Umgebungsvariablen in docker-compose.yml, Variablen an unsere Container zu übergeben. In diesem Sinne setzen wir die Variable „CA_CERT“ einmalig auf unserem Container gleich dem Zertifikatspfad. Dann können wir in der Datei metricbeat.yml diese Variable überall verwenden. Wenn wir „CA_CERT“ beispielsweise aktualisieren müssten, müssten wir lediglich einmal den Pfad in docker-compose.yml aktualisieren und dann den Metricbeat-Container neu bereitstellen.

Der Container metricbeat01 und die Datei metricbeat.yml sind gute Beispiele für die Übergabe der Umgebungsvariable „CA_CERT“ und deren mehrmaliger Verwendung in der yml-Datei. 

Weitere Informationen zum Festlegen und Verwenden von Umgebungsvariablen

docker-compose.yml (Container „fleet-server“)

Durch Hinzufügen eines „fleet-server“-Containers zur Datei docker-compose.yml (GitHub-Link) wird ein zusätzlicher Container erstellt, der sich das Elastic Agent-Image holt. Das Agent-Image wird für das Erfassen von Edge-Daten und als Basis-Image für das Konfigurieren des Fleet-Management-Servers verwendet.

Bitte beachten Sie, dass wir einige zusätzliche Flags verwenden, um die Strenge der Zertifikatsprüfungen zu verringern, da es sich um einen lokalen POC handelt. In einer Produktionsumgebung sollten aber alle Zertifikate ordnungsgemäß ausgestellt und verifiziert werden.

Wie bereits erwähnt geben wir für die Kommunikation zwei Ports frei. 

ports:
  - ${FLEET_PORT}:8220
  - ${APMSERVER_PORT}:8200
  • Über den Port 8220 läuft der gesamte Traffic für die Kommunikation zwischen Agent und Fleet.
  • Über den Port 8200 läuft der gesamte Traffic, der vom APM-Server verwendet wird, da unser Agent die APM-Integration beherbergt.

Die wichtigsten Umgebungskonfigurationen sehen so aus:

Hinweis: Wenn Sie auch Tests im Rahmen des synthetischen Monitorings konfigurieren und durchführen möchten, müssen Sie stattdessen das Docker-Image von „docker.elastic.co/beats/elastic-agent-complete:${STACK_VERSION}“ verwenden. Auf diesen Teil gehen wir hier nicht ein, Sie finden aber weitere Informationen dazu in unserer Dokumentation.

docker-compose.yml (Container „kibana“)

Am Container „kibana“ müssen zwei Änderungen vorgenommen werden (GitHub-Link). Bei der ersten geht es um die sehr wichtige Verbindung zwischen der Datei docker-compose.yml und der Datei kibana.yml im Abschnitt „volumes“. Diese Zeile weist Docker an, die lokale Datei kibana.yml per „Bind-Mount“ in den zu verwendenden Container einzubinden.

- ./kibana.yml:/usr/share/kibana/config/kibana.yml:ro

Als Nächstes wurde eine einfache Änderung am unteren Ende der Umgebungsvariablen vorgenommen, die es uns ermöglicht, das geheime APM-Token zu übergeben, das wir ursprünglich in der .env-Datei festgelegt haben.

- ELASTIC_APM_SECRET_TOKEN=${ELASTIC_APM_SECRET_TOKEN}

kibana.yml

Wir fügen eine neue yml-Datei zum Konfigurieren von Kibana hinzu, um Fleet und Agent zu integrieren (GitHub-Link).

Mit xpack.fleet.packages können wir festlegen, dass Pakete sich ihre Assets automatisch holen:

xpack.fleet.packages:
  - name: fleet_server
    version: latest
  - name: system
...

xpack.fleet.agentPolicies wiederum ermöglicht das Definieren der Basisrichtlinien, die intern in Fleet und Agent verwendet werden sollen:

xpack.fleet.agentPolicies:
  - name: Fleet-Server-Policy
    id: fleet-server-policy
    namespace: default
    monitoring_enabled: 
      - logs
      - metrics
...

Weitere Informationen zum Konfigurieren von Richtlinien ohne Verwendung der Benutzeroberfläche finden Sie in unserer Dokumentation.

Wir fügen außerdem eine Richtlinie zur Unterstützung von Elastic APM und die zugehörigen APM-Paket-Assets hinzu:

- name: apm-1
        package:
          name: apm
        inputs:
        - type: apm
          enabled: true
          vars:
          - name: host
            value: 0.0.0.0:8200
          - name: secret_token
            value: ${ELASTIC_APM_SECRET_TOKEN}

Wir legen die Server-URL und das geheime Token (secret_token) fest, um sicherzustellen, dass unsere Anwendungen ordnungsgemäß kommunizieren können. 

Als Bonus legen wir telemetry.enabled: "true" fest, sodass wir Elastic APM gegen unsere eigene Kibana-Instanz laufen lassen und so zusätzliche Informationen dazu erhalten können, wie APM funktioniert.

docker-compose.yml (Container „webapp“)

 webapp:
    build:
      context: app
    volumes:
      - "/var/lib/docker/containers:/var/lib/docker/containers:ro"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "/sys/fs/cgroup:/hostfs/sys/fs/cgroup:ro"
      - "/proc:/hostfs/proc:ro"
      - "/:/hostfs:ro"
    ports:
      - 8000:8000

Für unsere Webbeispielanwendung verwenden wir ein Dockerfile. Das hilft uns, unsere Anwendung zu erstellen und in Docker bereitzustellen.

Diese Containerkonfiguration stützt sich in hohem Maße auf den Build-Befehl „context: app“. Docker geht davon aus, dass „app“ ein Ordner ist, in dem sich unser Dockerfile befindet. Diese Attribute können spezifischer sein, für unsere Zwecke sind die Standardausnahmen aber völlig ausreichend.

Wenn Docker Compose diesen Container erstellt, liest es den Ordner „app” und holt sich das Dockerfile, um zu erfahren, wie das Image für den Container zu erstellen ist.

Wir geben außerdem an, dass wir Port 8000 freigeben wollen, und übergeben einige „Volumes“, ähnlich denen, die Metricbeat zur Verfügung hat, um Ressourcen zu überwachen.

app/dockerfile

# syntax=docker/dockerfile:1


FROM python:3.9-slim-buster


WORKDIR /app


COPY requirements.txt requirements.txt


RUN pip3 install -r requirements.txt


COPY main.py main.py


CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--log-level", "info", "--workers", "1"]

Unser Dockerfile verwendet jetzt als Pull-Grundlage das Image „python:3.9-slim-buster“. Anschließend erstellt es den Ordner „/app“, kopiert die Datei requirements.txt von unserem Speicherort und installiert dann die Anforderungen über pip3.

Danach kopiert das Dockerfile unsere Anwendung main.py und versucht dann, die in main.py integrierte Uvicorn-Anwendung auszuführen.

Hinweis: Für das Caching ist die Reihenfolge der Operationen in einem Dockerfile wichtig. Wenn Sie eine der Dateien ändern, die im Dockerfile aufgeführt sind, wird der Cache verworfen und die Datei wird erneut „gepullt“. Normalerweise sollten Sie die Dateien, die sich am häufigsten ändern, an einer späteren Stelle im Dockerfile platzieren, damit langsamere oder sich nicht ändernde Dateien für den Erstellungsprozess im Cache bleiben können.

app/main.py

Die Anwendung main.py (GitHub) ist eine sehr einfache Anwendung, die FastAPI und NiceGUI miteinander kombiniert. Die Hauptanwendung wurde mit dem Starlette-Elastic APM Agent instrumentiert und es gibt ein paar Schaltflächen, die Aufrufe ermöglichen, die gezielt Fehler und Meldungen in unserer APM-Umgebung verursachen.

Python:

from elasticapm.contrib.starlette import ElasticAPM, make_apm_client

apm = make_apm_client({
      'SERVICE_NAME': 'my_python_service',
      'SECRET_TOKEN': 'supersecrettoken',
      'SERVER_URL': 'http://fleet-server:8200',
      'ENVIRONMENT': 'development'
  })

app = FastAPI()
app.add_middleware(ElasticAPM, client=apm)

apm.capture_message(f"Custom Message: {message}")

@app.get("/error")
async def throw_error():
    try:
        1 / 0
    except Exception as e:
        apm.capture_exception()
    return {"message": "Failed Successfully :)"}

Oben sind Ausschnitte aus dem Code zu sehen, denen entnommen werden kann, dass wir die APM-Bibliothek importieren, den APM-Client erstellen und unserer FastAPI-Anwendung die Middleware hinzufügen.

Mit dieser Anwendung möchten wir lediglich zeigen, wie Sie mit Elastic APM interagieren können.

Befehl „docker compose up“

Jetzt ist alles konfiguriert und wir können den Cluster an den Start bringen.

Mit dem Befehl „docker compose up“ werden alle Container gestartet und Sie können sich unter https://localhost:5601 bei Kibana anmelden. Da wir jetzt Zertifikate für Kibana haben, müssen wir HTTPS verwenden. Daher kann es sein, dass Sie in Ihrem Browser Zertifikatswarnungen wegklicken müssen.
Nach dem Anmelden können Sie über das Hamburger-Menü -> Management -> Fleet zu Fleet gehen.

Dort sehen Sie im Menü „Agents“ genau einen Host. Auf dieser Fleet-Seite finden Sie Informationen zu allen Agents, die Sie in Ihrem Cluster registriert haben. Sie können auch Richtlinien erstellen oder ändern, neue Agents registrieren und globale Fleet-Konfigurationen aktualisieren.

Sie werden aber möglicherweise bemerken, dass die Felder „CPU“ und „Memory“ nicht aktualisiert werden. Und wenn Sie auf den Host-Link klicken, sieht es so aus, dass auch die Logs nicht befüllt werden. Bei näherer Betrachtung sehen wir in den Container-Logs unseres Fleet-Servers Fehlermeldungen wie die folgende:

{"log.level":"info","message":"Attempting to reconnect to backoff(elasticsearch(http://localhost:9200)) with 17 reconnect attempt(s)","component":{"binary":"metricbeat","dataset":"elastic_agent.metricbeat","id":"http/metrics-monitoring","type":"http/metrics"},"log":{"source":"http/metrics-monitoring"},"log.origin":{"file.line":139,"file.name":"pipeline/client_worker.go"},"service.name":"metricbeat","ecs.version":"1.6.0","log.logger":"publisher_pipeline_output","ecs.version":"1.6.0"}
{"log.level":"error","message":"Error dialing dial tcp 127.0.0.1:9200: connect: connection refused","component":{"binary":"metricbeat","dataset":"elastic_agent.metricbeat","id":"http/metrics-monitoring","type":"http/metrics"},"log":{"source":"http/metrics-monitoring"},"service.name":"metricbeat","ecs.version":"1.6.0","log.logger":"esclientleg","log.origin":{"file.line":38,"file.name":"transport/logging.go"},"network":"tcp","address":"localhost:9200","ecs.version":"1.6.0"}

Das liegt daran, dass unser Elastic Agent standardmäßig versucht, Daten in einer lokalen Elasticsearch-Instanz zu protokollieren, was für unsere Docker-Umgebung nicht richtig ist.

Um dieses Problem zu lösen, müssen wir in Fleet unter „Settings“ ein paar Änderungen vornehmen. 

Wie das geht, sehen wir uns im nächsten Abschnitt an.

Ausgabe neu konfigurieren, Zertifikat hinzufügen

Wenn wir in Fleet „Settings“ geöffnet haben, gehen wir zum Bereich „Outputs“ und klicken in der Spalte „Actions“ auf die Schaltfläche Edit:

Dadurch wird auf der rechten Seite der Benutzeroberfläche ein Slide-out eingeblendet, in dem wir die Standardausgabe ändern können.

Wir möchten die Werte in den Feldern „Hosts“ und „Elasticsearch CA trusted fingerprint (optional)“ und den Bereich „Advanced YAML configuration“ ändern.

Uns fehlen aber noch ein paar Informationen. Gehen wir also zu einem Terminal und besorgen uns, was noch fehlt.

Als Erstes müssen wir das CA-Zertifikat aus dem Cluster abrufen. Das geht mit demselben Befehl, den wir auch in Teil 1 verwendet haben:

docker cp es-cluster-es01-1:/usr/share/elasticsearch/config/certs/ca/ca.crt /tmp/.

Hinweis: Wie der Befehl genau aussieht, hängt davon ab, von welchem Verzeichnis aus Sie die Datei docker-compose.yml ausführen, bzw. davon, welche COMPOSE_PROJECT_NAME-Variable in der .env-Datei angegeben ist.

Als Nächstes benötigen wir den Fingerprint des Zertifikats. Dafür können wir einen OpenSSL-Befehl verwenden:

openssl x509 -fingerprint -sha256 -noout -in /tmp/ca.crt | awk -F"=" {' print $2 '} | sed s/://g

Der Wert, den wir erhalten, sieht in etwa so aus: 

5A7464CEABC54FA60CAD3BDF16395E69243B827898F5CCC93E5A38B8F78D5E72

Zum Schluss müssen wir das ganze Zertifikat in ein yml-Format bekommen. Dazu können wir entweder einen „cat“-Befehl verwenden oder einfach das Zertifikat in einem Texteditor öffnen:

cat /tmp/ca.crt

Wenn wir den Zertifikatstext haben, fügen wir ihn in ein yml-Format ein und geben all diese Informationen in den Fleet-Bildschirm „Settings“ von vorhin ein.

Für „Hosts“ möchten wir „https://es01:9200“ verwenden. Damit erfährt der Container, der den Fleet-Server hostet, wie er zum Senden von Daten mit dem Container „es01“ kommunizieren muss.

Geben Sie den für das Feld „Elasticsearch CA trusted fingerprint (optional)“ erzeugten Fingerprint ein.

Fügen Sie zum Schluss im Feld „Advanced YAML configuration“ den Zertifikatstext ein. Da dies eine yml-Konfiguration ist, wird ein Fehler ausgegeben, wenn das Spacing nicht korrekt ist. 

Beginnen Sie damit:

ssl:
certificate_authorities:
- |

Fügen Sie dann den Zertifikatstext ein und achten Sie dabei auf den richtigen Einzug.

Beispiel:

Vergessen Sie nicht, auf „Save and Apply Settings“ -> „Save and Deploy“ zu klicken.

Elastic Agent-Daten prüfen

Gehen Sie nach Abschluss des „Save and Deploy“-Vorgangs zum Tab „Agents“ zurück und klicken Sie auf den Namen Ihres Agents. Jetzt sollten die Angaben unter „CPU“ und „Memory“ korrekt angezeigt werden und unter „Logs“ sollten Informationen zu sehen sein.

Sie können hier auch auf View more agent metrics klicken und zu den Agent-Dashboards gehen, um sich weitere Daten anzusehen.

Weitere Informationen zum Monitoring von Agents finden Sie in unserer Dokumentation.

Elastic APM-Daten prüfen

Wenn Sie nun im Hamburger-Menü zu „Observability“ -> „Overview“ gehen, können Sie sehen, wie nach und nach Elastic APM-Metriken eintreffen.

Navigieren Sie zu „APM“ -> „Services“. Dort sehen Sie sowohl Kibana als auch unsere Demo-Anwendung.

Auf diese Weise können Sie die Dienste genauer unter die Lupe nehmen und sich damit vertraut machen, welche Arten von Informationen Elastic APM erfasst.

Fehlersuche und reibungsloses Skalieren mit dem Elastic Stack

In Teil 2 der Serie „Erste Schritte mit dem Elastic Stack und Docker Compose“ standen zusätzliche Sicherheit und Features wie Elastic Agent, Fleet und Elastic APM im Mittelpunkt. Auch das Hinzufügen einer benutzerdefinierten Anwendung über Dockerfile hilft dabei, die Implementierung von Elastic APM zu veranschaulichen. 

So steht eine tolle lokale Lernplattform für das Entwickeln und Ausprobieren von Features zur Verfügung.

Die Instrumentierung Ihrer Anwendungen mit den Elastic APM Agents versetzt Sie in die Lage, die Anwendungen besser zu überwachen, damit Sie sie weiterentwickeln und etwaige Probleme beseitigen können. Elastic Agent und Fleet unterstützen Sie bei der einfachen Skalierung Ihrer Instrumentierung.

Und noch ein Hinweis: Wir haben uns hier zwar mit dem Elastic-Agent und APM beschäftigt, Sie können mit diesem Setup aber auch OTel-Konfigurationen testen!

Wenn Sie bereit sind, auf einen für Produktionsumgebungen besser geeigneten Cluster umzusteigen, sollten Sie sich Elastic Cloud ansehen, um einen reibungslosen Übergang von dem, was Sie lokal gelernt haben, in eine Produktionsumgebung mit vielen Integrationen zu finden.

Alle Dateien, auf die wir hier eingegangen sind, sind auf GitHub verfügbar. Fragen und Pull-Requests sind uns stets willkommen!

Die Entscheidung über die Veröffentlichung von Features oder Leistungsmerkmalen, die in diesem Blogpost beschrieben werden, oder über den Zeitpunkt ihrer Veröffentlichung liegt allein bei Elastic. Es ist möglich, dass nicht bereits verfügbare Features oder Leistungsmerkmale nicht rechtzeitig oder überhaupt nicht veröffentlicht werden.