Einführung
Wenn Sie mehrere Dienste und Anwendungen auf einem Kubernetes-Cluster ausführen, können Sie mithilfe eines zentralen Protokollstapels auf Cluster-Ebene schnell das große Volumen der von Ihren Pods erzeugten Protokolldaten sortieren und analysieren. Eine beliebte zentralisierte Protokollierungslösung ist der StapelElasticsearch,Fluentd undKibana (EFK).
Elasticsearch ist eine verteilte und skalierbare Echtzeit-Suchmaschine, die Volltext- und strukturierte Suche sowie Analysen ermöglicht. Es wird häufig zum Indizieren und Durchsuchen großer Mengen von Protokolldaten verwendet, kann jedoch auch zum Durchsuchen vieler verschiedener Arten von Dokumenten verwendet werden.
Elasticsearch wird üblicherweise zusammen mitKibana bereitgestellt, einem leistungsstarken Datenvisualisierungs-Frontend und Dashboard für Elasticsearch. Mit Kibana können Sie Ihre Elasticsearch-Protokolldaten über eine Webschnittstelle durchsuchen und Dashboards und Abfragen erstellen, um Fragen schnell zu beantworten und einen Einblick in Ihre Kubernetes-Anwendungen zu erhalten.
In diesem Tutorial verwenden wirFluentd, um Protokolldaten zu sammeln, zu transformieren und an das Elasticsearch-Backend zu senden. Fluentd ist ein beliebter Open-Source-Datenkollektor, den wir auf unseren Kubernetes-Knoten einrichten, um Container-Protokolldateien auszudehnen, die Protokolldaten zu filtern und zu transformieren und sie an den Elasticsearch-Cluster weiterzuleiten, wo sie indiziert und gespeichert werden.
Zunächst konfigurieren und starten wir einen skalierbaren Elasticsearch-Cluster und erstellen dann den Kibana Kubernetes Service and Deployment. Abschließend richten wir Fluentd als DaemonSet ein, damit es auf jedem Kubernetes-Worker-Knoten ausgeführt werden kann.
Voraussetzungen
Bevor Sie mit diesem Handbuch beginnen, stellen Sie sicher, dass Ihnen Folgendes zur Verfügung steht:
-
Ein Kubernetes 1.10+ -Cluster mit aktivierter rollenbasierter Zugriffssteuerung (RBAC)
-
Stellen Sie sicher, dass Ihr Cluster über genügend Ressourcen verfügt, um den EFK-Stapel bereitzustellen, und skalieren Sie den Cluster, wenn dies nicht der Fall ist, indem Sie Arbeitsknoten hinzufügen. Wir werden einen 3-Pod-Elasticsearch-Cluster sowie einen einzelnen Kibana-Pod bereitstellen (Sie können ihn bei Bedarf auf 1 verkleinern). Auf jedem Arbeitsknoten wird auch ein Fluentd Pod ausgeführt. Der Cluster in diesem Handbuch besteht aus 3 Arbeitsknoten und einer verwalteten Steuerebene.
-
-
Das auf Ihrem lokalen Computer installierte Befehlszeilentool
kubectl
, das für die Verbindung mit Ihrem Cluster konfiguriert ist. Weitere Informationen zum Installieren vonkubectl
in the official documentation finden Sie hier.
Sobald Sie diese Komponenten eingerichtet haben, können Sie mit diesem Handbuch beginnen.
[[Schritt-1 - Erstellen eines Namespace]] == Schritt 1 - Erstellen eines Namespace
Bevor wir einen Elasticsearch-Cluster einführen, erstellen wir zunächst einen Namespace, in dem wir alle unsere Protokollierungsinstrumente installieren. Mit Kubernetes können Sie Objekte, die in Ihrem Cluster ausgeführt werden, mithilfe einer "virtuellen Cluster" -Abstraktion namens Namespaces trennen. In diesem Handbuch erstellen wir einenkube-logging
-Namensraum, in den wir die EFK-Stack-Komponenten installieren. Mit diesem Namespace können wir auch den Protokollierungsstapel schnell bereinigen und entfernen, ohne die Funktion des Kubernetes-Clusters zu beeinträchtigen.
Untersuchen Sie zunächst die vorhandenen Namespaces in Ihrem Cluster mitkubectl
:
kubectl get namespaces
Sie sollten die folgenden drei anfänglichen Namespaces sehen, die mit Ihrem Kubernetes-Cluster vorinstalliert werden:
OutputNAME STATUS AGE
default Active 5m
kube-system Active 5m
kube-public Active 5m
Derdefault
-Namespace enthält Objekte, die ohne Angabe eines Namespace erstellt wurden. Der Namespacekube-system
enthält Objekte, die vom Kubernetes-System erstellt und verwendet werden, z. B.kube-dns
,kube-proxy
undkubernetes-dashboard
. Es wird empfohlen, diesen Namespace sauber zu halten und ihn nicht mit Ihren Anwendungs- und Instrumentierungs-Workloads zu verunreinigen.
Derkube-public
-Namespace ist ein weiterer automatisch erstellter Namespace, in dem Objekte gespeichert werden können, die im gesamten Cluster lesbar und zugänglich sein sollen, auch für nicht authentifizierte Benutzer.
Um den Namespacekube-logging
zu erstellen, öffnen und bearbeiten Sie zunächst eine Datei mit dem Namenkube-logging.yaml
mit Ihrem bevorzugten Editor, z. B. nano:
nano kube-logging.yaml
Fügen Sie in Ihrem Editor das folgende Namespace-Objekt YAML ein:
kube-logging.yaml
kind: Namespace
apiVersion: v1
metadata:
name: kube-logging
Speichern und schließen Sie dann die Datei.
Hier geben wir diekind
des Kubernetes-Objekts alsNamespace
-Objekt an. Weitere Informationen zuNamespace
-Objekten finden Sie inNamespaces Walkthrough in der offiziellen Kubernetes-Dokumentation. Wir geben auch die Kubernetes-API-Version an, die zum Erstellen des Objekts verwendet wird (v1
), und geben ihmname
,kube-logging
.
Nachdem Sie die Namespace-Objektdateikube-logging.yaml
erstellt haben, erstellen Sie den Namespace mitkubectl create
mit dem Dateinamen-Flag-f
:
kubectl create -f kube-logging.yaml
Sie sollten die folgende Ausgabe sehen:
Outputnamespace/kube-logging created
Sie können dann bestätigen, dass der Namespace erfolgreich erstellt wurde:
kubectl get namespaces
Zu diesem Zeitpunkt sollte der neue Namespace vonkube-logging
angezeigt werden:
OutputNAME STATUS AGE
default Active 23m
kube-logging Active 1m
kube-public Active 23m
kube-system Active 23m
Wir können jetzt einen Elasticsearch-Cluster in diesem isolierten Protokollierungs-Namespace bereitstellen.
[[Schritt 2 - Erstellen des Elasticsearch-StatefulSets]] == Schritt 2 - Erstellen des Elasticsearch StatefulSet
Nachdem wir einen Namespace für unseren Protokollstapel erstellt haben, können wir mit der Bereitstellung der verschiedenen Komponenten beginnen. Zunächst wird ein Elasticsearch-Cluster mit drei Knoten bereitgestellt.
In diesem Handbuch werden 3 Elasticsearch-Pods verwendet, um das Problem der Aufteilung des Gehirns zu vermeiden, das bei hochverfügbaren Clustern mit mehreren Knoten auftritt. Auf hoher Ebene entsteht "Split-Brain", wenn ein oder mehrere Knoten nicht mit den anderen kommunizieren können und mehrere "Split" -Master gewählt werden. Wenn einer der drei Knoten vorübergehend vom Cluster getrennt wird, können die beiden anderen Knoten einen neuen Master wählen und der Cluster kann weiterarbeiten, während der letzte Knoten versucht, sich erneut anzumelden. Weitere Informationen finden Sie unterA new era for cluster coordination in Elasticsearch undVoting configurations.
Erstellen des Headless-Dienstes
Zu Beginn erstellen wir einen kopflosen Kubernetes-Dienst namenselasticsearch
, der eine DNS-Domäne für die 3 Pods definiert. Ein kopfloser Dienst führt keinen Lastausgleich durch oder hat keine statische IP. Um mehr über kopflose Dienste zu erfahren, konsultieren Sie die offiziellenKubernetes documentation.
Öffnen Sie eine Datei mit dem Namenelasticsearch_svc.yaml
mit Ihrem bevorzugten Editor:
nano elasticsearch_svc.yaml
Fügen Sie den folgenden Kubernetes-Dienst YAML ein:
elasticsearch_svc.yaml
kind: Service
apiVersion: v1
metadata:
name: elasticsearch
namespace: kube-logging
labels:
app: elasticsearch
spec:
selector:
app: elasticsearch
clusterIP: None
ports:
- port: 9200
name: rest
- port: 9300
name: inter-node
Speichern und schließen Sie dann die Datei.
Wir definieren einService
namenselasticsearch
imkube-logging
Namespace und geben ihm die Bezeichnungapp: elasticsearch
. Wir setzen dann.spec.selector
aufapp: elasticsearch
, damit der Dienst Pods mit der Bezeichnungapp: elasticsearch
auswählt. Wenn wir unser Elasticsearch StatefulSet diesem Service zuordnen, gibt der Service DNS A-Einträge zurück, die auf Elasticsearch Pods mit der Bezeichnungapp: elasticsearch
verweisen.
Wir setzen dannclusterIP: None
, wodurch der Dienst kopflos wird. Schließlich definieren wir die Ports9200
und9300
, die zur Interaktion mit der REST-API bzw. für die Kommunikation zwischen Knoten verwendet werden.
Erstellen Sie den Service mitkubectl
:
kubectl create -f elasticsearch_svc.yaml
Sie sollten die folgende Ausgabe sehen:
Outputservice/elasticsearch created
Überprüfen Sie abschließend, ob der Dienst mitkubectl get
erfolgreich erstellt wurde:
kubectl get services --namespace=kube-logging
Sie sollten Folgendes sehen:
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
elasticsearch ClusterIP None 9200/TCP,9300/TCP 26s
Nachdem wir unseren Headless-Service und eine stabile.elasticsearch.kube-logging.svc.cluster.local
-Domäne für unsere Pods eingerichtet haben, können wir das StatefulSet erstellen.
StatefulSet erstellen
Mit einem Kubernetes StatefulSet können Sie Pods eine stabile Identität zuweisen und ihnen einen stabilen, dauerhaften Speicherplatz gewähren. Für Elasticsearch ist ein stabiler Speicher erforderlich, damit die Daten über die Pod-Neuplanung und den Neustart hinweg erhalten bleiben. Weitere Informationen zur StatefulSet-Arbeitslast finden Sie auf der SeiteStatefulsetsin den Kubernetes-Dokumenten.
Öffnen Sie eine Datei mit dem Namenelasticsearch_statefulset.yaml
in Ihrem bevorzugten Editor:
nano elasticsearch_statefulset.yaml
Wir gehen die StatefulSet-Objektdefinition abschnittsweise durch und fügen Blöcke in diese Datei ein.
Beginnen Sie mit dem Einfügen im folgenden Block:
elasticsearch_statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: es-cluster
namespace: kube-logging
spec:
serviceName: elasticsearch
replicas: 3
selector:
matchLabels:
app: elasticsearch
template:
metadata:
labels:
app: elasticsearch
In diesem Block definieren wir ein StatefulSet mit dem Namenes-cluster
im Namespacekube-logging
. Wir verknüpfen es dann mit unserem zuvor erstelltenelasticsearch
-Service über das FeldserviceName
. Dadurch wird sichergestellt, dass auf jeden Pod im StatefulSet über die folgende DNS-Adresse zugegriffen werden kann:es-cluster-[0,1,2].elasticsearch.kube-logging.svc.cluster.local
, wobei[0,1,2]
der vom Pod zugewiesenen Ganzzahl-Ordnungszahl entspricht.
Wir geben 3replicas
(Pods) an und setzen den SelektormatchLabels
aufapp: elasticseach
, den wir dann im Abschnitt.spec.template.metadata
spiegeln. Die Felder.spec.selector.matchLabels
und.spec.template.metadata.labels
müssen übereinstimmen.
Wir können nun mit der Objektspezifikation fortfahren. Fügen Sie den folgenden YAML-Block direkt unter dem vorhergehenden Block ein:
elasticsearch_statefulset.yaml
. . .
spec:
containers:
- name: elasticsearch
image: docker.elastic.co/elasticsearch/elasticsearch:7.2.0
resources:
limits:
cpu: 1000m
requests:
cpu: 100m
ports:
- containerPort: 9200
name: rest
protocol: TCP
- containerPort: 9300
name: inter-node
protocol: TCP
volumeMounts:
- name: data
mountPath: /usr/share/elasticsearch/data
env:
- name: cluster.name
value: k8s-logs
- name: node.name
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: discovery.seed_hosts
value: "es-cluster-0.elasticsearch,es-cluster-1.elasticsearch,es-cluster-2.elasticsearch"
- name: cluster.initial_master_nodes
value: "es-cluster-0,es-cluster-1,es-cluster-2"
- name: ES_JAVA_OPTS
value: "-Xms512m -Xmx512m"
Hier definieren wir die Pods im StatefulSet. Wir benennen die Containerelasticsearch
und wählen das Docker-Imagedocker.elastic.co/elasticsearch/elasticsearch:7.2.0
. An dieser Stelle können Sie dieses Image-Tag so ändern, dass es Ihrem internen Elasticsearch-Image oder einer anderen Version entspricht. Beachten Sie, dass für die Zwecke dieses Handbuchs nur Elasticsearch7.2.0
getestet wurde.
Wir verwenden dann das Feldresources
, um anzugeben, dass der Container mindestens 0,1 vCPU garantiert benötigt und bis zu 1 vCPU platzen kann (was die Ressourcennutzung des Pods begrenzt, wenn eine anfängliche große Aufnahme durchgeführt oder eine Lastspitze behandelt wird ). Sie sollten diese Werte in Abhängigkeit von Ihrer voraussichtlichen Auslastung und den verfügbaren Ressourcen ändern. Weitere Informationen zu Ressourcenanforderungen und -beschränkungen finden Sie in den offiziellenKubernetes Documentation.
Anschließend öffnen und benennen wir die Ports9200
und9300
für die REST-API- bzw. die Kommunikation zwischen Knoten. Wir geben einvolumeMount
mit dem Namendata
an, das das PersistentVolume mit dem Namendata
unter dem Pfad/usr/share/elasticsearch/data
in den Container einbindet. Wir werden die VolumeClaims für dieses StatefulSet in einem späteren YAML-Block definieren.
Zuletzt setzen wir einige Umgebungsvariablen in den Container:
-
cluster.name
: Der Name des Elasticsearch-Clusters, in diesem Handbuchk8s-logs
. -
node.name
: Der Name des Knotens, den wir mitvalueFrom
auf das Feld.metadata.name
setzen. Dies wird abhängig von der zugewiesenen Ordnungszahl des Knotens ines-cluster-[0,1,2]
aufgelöst. -
discovery.seed_hosts
: In diesem Feld wird eine Liste der Master-fähigen Knoten im Cluster festgelegt, die den Knotenerkennungsprozess auslösen. In diesem Handbuch haben unsere Pods dank des zuvor konfigurierten Headless-Dienstes Domänen der Formes-cluster-[0,1,2].elasticsearch.kube-logging.svc.cluster.local
, sodass wir diese Variable entsprechend festlegen. Mit der DNS-Auflösung des lokalen Namespace Kubernetes können wir diese aufes-cluster-[0,1,2].elasticsearch
verkürzen. Weitere Informationen zur Elasticsearch-Erkennung finden Sie in den offiziellenElasticsearch documentation. -
cluster.initial_master_nodes
: Dieses Feld gibt auch eine Liste der Master-fähigen Knoten an, die am Master-Wahlprozess teilnehmen werden. Beachten Sie, dass Sie für dieses Feld Knoten anhand ihrernode.name
und nicht anhand ihrer Hostnamen identifizieren sollten. -
ES_JAVA_OPTS
: Hier setzen wir dies auf-Xms512m -Xmx512m
, wodurch die JVM angewiesen wird, eine minimale und maximale Heap-Größe von 512 MB zu verwenden. Sie sollten diese Parameter in Abhängigkeit von der Ressourcenverfügbarkeit und den Anforderungen Ihres Clusters anpassen. Weitere Informationen finden Sie inSetting the heap size.
Der nächste Block, den wir einfügen, sieht folgendermaßen aus:
elasticsearch_statefulset.yaml
. . .
initContainers:
- name: fix-permissions
image: busybox
command: ["sh", "-c", "chown -R 1000:1000 /usr/share/elasticsearch/data"]
securityContext:
privileged: true
volumeMounts:
- name: data
mountPath: /usr/share/elasticsearch/data
- name: increase-vm-max-map
image: busybox
command: ["sysctl", "-w", "vm.max_map_count=262144"]
securityContext:
privileged: true
- name: increase-fd-ulimit
image: busybox
command: ["sh", "-c", "ulimit -n 65536"]
securityContext:
privileged: true
In diesem Block definieren wir mehrere Init-Container, die vor dem App-Container des Hauptelasticsearch
ausgeführt werden. Diese Init-Container werden jeweils in der Reihenfolge ausgeführt, in der sie definiert wurden. Um mehr über Init Containers zu erfahren, konsultieren Sie die offiziellenKubernetes Documentation.
Der erste Befehl mit dem Namenfix-permissions
führt einen Befehlchown
aus, um den Eigentümer und die Gruppe des Elasticsearch-Datenverzeichnisses in1000:1000
, die UID des Elasticsearch-Benutzers, zu ändern. Standardmäßig stellt Kubernetes das Datenverzeichnis alsroot
bereit, wodurch es für Elasticsearch unzugänglich wird. Weitere Informationen zu diesem Schritt finden Sie unter "https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#_notes_for_production_use_and_defaults[Notes for production use and defaults" von Elasticsearch.
Der zweite Befehl mit dem Namenincrease-vm-max-map
führt einen Befehl aus, um die Grenzwerte des Betriebssystems für mmap-Zählungen zu erhöhen, die standardmäßig zu niedrig sind und zu Speicherfehlern führen. Um mehr über diesen Schritt zu erfahren, konsultieren Sie die offiziellenElasticsearch documentation.
Der nächste auszuführende Init-Container istincrease-fd-ulimit
, der den Befehlulimit
ausführt, um die maximale Anzahl geöffneter Dateideskriptoren zu erhöhen. Weitere Informationen zu diesem Schritt finden Sie in der offiziellen Elasticsearch-Dokumentation unter „https://www.elastic.co/guide/en/elasticsearch/reference/current/docker.html#_notes_for_production_use_and_defaults[Notes for Production Use and Defaults]“.
[.note] #Note: In ElasticsearchNotes for Production Use wird auch erwähnt, dass das Austauschen aus Leistungsgründen deaktiviert wird. Abhängig von Ihrer Kubernetes-Installation oder Ihrem Anbieter ist das Austauschen möglicherweise bereits deaktiviert. Um dies zu überprüfen, geben Sieexec
in einen laufenden Container ein und führen Siecat /proc/swaps
aus, um aktive Swap-Geräte aufzulisten. Wenn Sie dort nichts sehen, ist der Swap deaktiviert.
#
Nachdem wir unseren Haupt-App-Container und die Init-Container definiert haben, die zuvor ausgeführt werden, um das Container-Betriebssystem zu optimieren, können wir das letzte Stück zu unserer StatefulSet-Objektdefinitionsdatei hinzufügen:volumeClaimTemplates
.
Fügen Sie den folgendenvolumeClaimTemplate
-Block ein:
elasticsearch_statefulset.yaml
. . .
volumeClaimTemplates:
- metadata:
name: data
labels:
app: elasticsearch
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: do-block-storage
resources:
requests:
storage: 100Gi
In diesem Block definieren wir dievolumeClaimTemplates
des StatefulSet. Kubernetes verwendet dies, um PersistentVolumes für die Pods zu erstellen. Im obigen Block nennen wir esdata
(dies sind diename
, auf die wir in der BezeichnungvolumeMount+`s defined previously), and give it the same `+app: elasticsearch
als StatefulSet verweisen.
Wir geben dann den Zugriffsmodus alsReadWriteOnce
an, was bedeutet, dass er nur von einem einzelnen Knoten als Lese- / Schreibzugriff bereitgestellt werden kann. In diesem Handbuch definieren wir die Speicherklasse alsdo-block-storage
, da wir zu Demonstrationszwecken einen DigitalOcean Kubernetes-Cluster verwenden. Sie sollten diesen Wert ändern, je nachdem, wo Sie Ihren Kubernetes-Cluster ausführen. Weitere Informationen finden Sie in der Dokumentation zuPersistent Volume.
Schließlich geben wir an, dass jedes PersistentVolume 100 GB groß sein soll. Sie sollten diesen Wert an Ihre Produktionsanforderungen anpassen.
Die vollständige StatefulSet-Spezifikation sollte ungefähr so aussehen:
elasticsearch_statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: es-cluster
namespace: kube-logging
spec:
serviceName: elasticsearch
replicas: 3
selector:
matchLabels:
app: elasticsearch
template:
metadata:
labels:
app: elasticsearch
spec:
containers:
- name: elasticsearch
image: docker.elastic.co/elasticsearch/elasticsearch:7.2.0
resources:
limits:
cpu: 1000m
requests:
cpu: 100m
ports:
- containerPort: 9200
name: rest
protocol: TCP
- containerPort: 9300
name: inter-node
protocol: TCP
volumeMounts:
- name: data
mountPath: /usr/share/elasticsearch/data
env:
- name: cluster.name
value: k8s-logs
- name: node.name
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: discovery.seed_hosts
value: "es-cluster-0.elasticsearch,es-cluster-1.elasticsearch,es-cluster-2.elasticsearch"
- name: cluster.initial_master_nodes
value: "es-cluster-0,es-cluster-1,es-cluster-2"
- name: ES_JAVA_OPTS
value: "-Xms512m -Xmx512m"
initContainers:
- name: fix-permissions
image: busybox
command: ["sh", "-c", "chown -R 1000:1000 /usr/share/elasticsearch/data"]
securityContext:
privileged: true
volumeMounts:
- name: data
mountPath: /usr/share/elasticsearch/data
- name: increase-vm-max-map
image: busybox
command: ["sysctl", "-w", "vm.max_map_count=262144"]
securityContext:
privileged: true
- name: increase-fd-ulimit
image: busybox
command: ["sh", "-c", "ulimit -n 65536"]
securityContext:
privileged: true
volumeClaimTemplates:
- metadata:
name: data
labels:
app: elasticsearch
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: do-block-storage
resources:
requests:
storage: 100Gi
Wenn Sie mit Ihrer Elasticsearch-Konfiguration zufrieden sind, speichern und schließen Sie die Datei.
Stellen Sie nun das StatefulSet mitkubectl
bereit:
kubectl create -f elasticsearch_statefulset.yaml
Sie sollten die folgende Ausgabe sehen:
Outputstatefulset.apps/es-cluster created
Sie können das StatefulSet beim Rollout mitkubectl rollout status
überwachen:
kubectl rollout status sts/es-cluster --namespace=kube-logging
Sie sollten die folgende Ausgabe sehen, wenn der Cluster bereitgestellt wird:
OutputWaiting for 3 pods to be ready...
Waiting for 2 pods to be ready...
Waiting for 1 pods to be ready...
partitioned roll out complete: 3 new pods have been updated...
Sobald alle Pods bereitgestellt wurden, können Sie überprüfen, ob Ihr Elasticsearch-Cluster ordnungsgemäß funktioniert, indem Sie eine Anforderung für die REST-API ausführen.
Leiten Sie dazu zuerst den lokalen Port9200
an den Port9200
auf einem der Elasticsearch-Knoten (es-cluster-0
) mitkubectl port-forward
weiter:
kubectl port-forward es-cluster-0 9200:9200 --namespace=kube-logging
Führen Sie dann in einem separaten Terminalfenster einecurl
-Anforderung für die REST-API aus:
curl http://localhost:9200/_cluster/state?pretty
Sie sollten die folgende Ausgabe sehen:
Output{
"cluster_name" : "k8s-logs",
"compressed_size_in_bytes" : 348,
"cluster_uuid" : "QD06dK7CQgids-GQZooNVw",
"version" : 3,
"state_uuid" : "mjNIWXAzQVuxNNOQ7xR-qg",
"master_node" : "IdM5B7cUQWqFgIHXBp0JDg",
"blocks" : { },
"nodes" : {
"u7DoTpMmSCixOoictzHItA" : {
"name" : "es-cluster-1",
"ephemeral_id" : "ZlBflnXKRMC4RvEACHIVdg",
"transport_address" : "10.244.8.2:9300",
"attributes" : { }
},
"IdM5B7cUQWqFgIHXBp0JDg" : {
"name" : "es-cluster-0",
"ephemeral_id" : "JTk1FDdFQuWbSFAtBxdxAQ",
"transport_address" : "10.244.44.3:9300",
"attributes" : { }
},
"R8E7xcSUSbGbgrhAdyAKmQ" : {
"name" : "es-cluster-2",
"ephemeral_id" : "9wv6ke71Qqy9vk2LgJTqaA",
"transport_address" : "10.244.40.4:9300",
"attributes" : { }
}
},
...
Dies zeigt an, dass unser Elasticsearch-Clusterk8s-logs
erfolgreich mit 3 Knoten erstellt wurde:es-cluster-0
,es-cluster-1
undes-cluster-2
. Der aktuelle Hauptknoten istes-cluster-0
.
Nachdem Ihr Elasticsearch-Cluster nun ausgeführt wird, können Sie ein Kibana-Frontend dafür einrichten.
[[Schritt 3 - Erstellen der Kibana-Bereitstellung und -Dienst]] == Schritt 3 - Erstellen der Kibana-Bereitstellung und des Kibana-Dienstes
Um Kibana auf Kubernetes zu starten, erstellen wir einen Dienst namenskibana
und eine Bereitstellung, die aus einem Pod-Replikat besteht. Sie können die Anzahl der Replikate abhängig von Ihren Produktionsanforderungen skalieren und optional einenLoadBalancer
-Typ angeben, damit der Service Anforderungen für den Lastausgleich in den Bereitstellungs-Pods ausgleichen kann.
Dieses Mal erstellen wir den Service und die Bereitstellung in derselben Datei. Öffnen Sie eine Datei mit dem Namenkibana.yaml
in Ihrem bevorzugten Editor:
nano kibana.yaml
Fügen Sie folgende Leistungsbeschreibung ein:
kibana.yaml
apiVersion: v1
kind: Service
metadata:
name: kibana
namespace: kube-logging
labels:
app: kibana
spec:
ports:
- port: 5601
selector:
app: kibana
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: kibana
namespace: kube-logging
labels:
app: kibana
spec:
replicas: 1
selector:
matchLabels:
app: kibana
template:
metadata:
labels:
app: kibana
spec:
containers:
- name: kibana
image: docker.elastic.co/kibana/kibana:7.2.0
resources:
limits:
cpu: 1000m
requests:
cpu: 100m
env:
- name: ELASTICSEARCH_URL
value: http://elasticsearch:9200
ports:
- containerPort: 5601
Speichern und schließen Sie dann die Datei.
In dieser Spezifikation haben wir einen Service namenskibana
im Namespacekube-logging
definiert und ihm die Bezeichnungapp: kibana
gegeben.
Wir haben außerdem festgelegt, dass auf Port5601
zugegriffen werden soll, und verwenden Sie das Labelapp: kibana
, um die Ziel-Pods des Dienstes auszuwählen.
In der SpezifikationDeployment
definieren wir eine Bereitstellung mit dem Namenkibana
und geben an, dass wir 1 Pod-Replikat möchten.
Wir verwenden das Bild vondocker.elastic.co/kibana/kibana:7.2.0
. An dieser Stelle können Sie Ihr eigenes privates oder öffentliches Kibana-Bild zur Verwendung einsetzen.
Wir geben an, dass mindestens 0,1 vCPU für den Pod garantiert werden sollen, wobei ein Limit von 1 vCPU überschritten wird. Sie können diese Parameter in Abhängigkeit von Ihrer voraussichtlichen Auslastung und den verfügbaren Ressourcen ändern.
Als Nächstes verwenden wir die UmgebungsvariableELASTICSEARCH_URL
, um den Endpunkt und den Port für den Elasticsearch-Cluster festzulegen. Bei Verwendung von Kubernetes DNS entspricht dieser Endpunkt seinem Dienstnamenelasticsearch
. Diese Domain wird in eine Liste mit IP-Adressen für die 3 Elasticsearch-Pods aufgelöst. Weitere Informationen zu Kubernetes DNS finden Sie unterDNS for Services and Pods.
Schließlich setzen wir den Container-Port von Kibana auf5601
, an den der Service vonkibana
Anfragen weiterleitet.
Sobald Sie mit Ihrer Kibana-Konfiguration zufrieden sind, können Sie den Service und die Bereitstellung mitkubectl
bereitstellen:
kubectl create -f kibana.yaml
Sie sollten die folgende Ausgabe sehen:
Outputservice/kibana created
deployment.apps/kibana created
Sie können überprüfen, ob der Rollout erfolgreich war, indem Sie den folgenden Befehl ausführen:
kubectl rollout status deployment/kibana --namespace=kube-logging
Sie sollten die folgende Ausgabe sehen:
Outputdeployment "kibana" successfully rolled out
Um auf die Kibana-Schnittstelle zuzugreifen, leiten wir erneut einen lokalen Port an den Kubernetes-Knoten weiter, auf dem Kibana ausgeführt wird. Holen Sie sich die Kibana Pod-Details mitkubectl get
:
kubectl get pods --namespace=kube-logging
OutputNAME READY STATUS RESTARTS AGE
es-cluster-0 1/1 Running 0 55m
es-cluster-1 1/1 Running 0 54m
es-cluster-2 1/1 Running 0 54m
kibana-6c9fb4b5b7-plbg2 1/1 Running 0 4m27s
Hier beobachten wir, dass unser Kibana Podkibana-6c9fb4b5b7-plbg2
heißt.
Leiten Sie den lokalen Port5601
an Port5601
auf diesem Pod weiter:
kubectl port-forward kibana-6c9fb4b5b7-plbg2 5601:5601 --namespace=kube-logging
Sie sollten die folgende Ausgabe sehen:
OutputForwarding from 127.0.0.1:5601 -> 5601
Forwarding from [::1]:5601 -> 5601
Besuchen Sie jetzt in Ihrem Webbrowser die folgende URL:
http://localhost:5601
Wenn die folgende Kibana-Begrüßungsseite angezeigt wird, haben Sie Kibana erfolgreich in Ihrem Kubernetes-Cluster bereitgestellt:
Sie können nun mit der endgültigen Komponente des EFK-Stacks fortfahren: dem Protokollsammler Fluentd.
[[Schritt-4 - Erstellen des fließenden Dämonensatzes]] == Schritt 4 - Erstellen des fließenden Dämonensatzes
In diesem Handbuch richten wir Fluentd als DaemonSet ein, einen Kubernetes-Workload-Typ, der eine Kopie eines bestimmten Pods auf jedem Knoten im Kubernetes-Cluster ausführt. Mit diesem DaemonSet-Controller wird auf jedem Knoten in unserem Cluster ein Fluentd-Protokollierungs-Agent-Pod bereitgestellt. Weitere Informationen zu dieser Protokollierungsarchitektur finden Sie unter "https://kubernetes.io/docs/concepts/cluster-administration/logging/#using-a-node-logging-agent[Using a node logging agent]" in den offiziellen Kubernetes docs.
In Kubernetes werden bei Containeranwendungen, die sich beistdout
undstderr
anmelden, die Protokolldatenströme erfasst und in JSON-Dateien auf den Knoten umgeleitet. Der Fluentd Pod überwacht diese Protokolldateien, filtert Protokollereignisse, transformiert die Protokolldaten und sendet sie an das Elasticsearch-Protokollierungs-Backend, das wir inStep 2 bereitgestellt haben.
Zusätzlich zu den Container-Protokollen werden vom Fluentd-Agenten die Protokolle der Kubernetes-Systemkomponenten wie Kubelet-, Kube- Proxy- und Docker-Protokolle nachverfolgt. Eine vollständige Liste der vom Fluentd-Protokollierungsagenten bereitgestellten Quellen finden Sie in der Dateikubernetes.conf
, die zum Konfigurieren des Protokollierungsagenten verwendet wird. Weitere Informationen zur Protokollierung in Kubernetes-Clustern finden Sie auf der offiziellen Website unter "https://kubernetes.io/docs/concepts/cluster-administration/logging/#logging-at-the-node-level[Logging at the node level]" Kubernetes Dokumentation.
Öffnen Sie zunächst eine Datei mit dem Namenfluentd.yaml
in Ihrem bevorzugten Texteditor:
nano fluentd.yaml
Wieder werden wir die Kubernetes-Objektdefinitionen Block für Block einfügen und dabei den Kontext angeben. In diesem Handbuch verwenden wir dieFluentd DaemonSet spec, die von den Fluentd-Betreuern bereitgestellt werden. Eine weitere hilfreiche Ressource, die von den Fluentd-Betreuern bereitgestellt wird, istKuberentes Fluentd.
Fügen Sie zunächst die folgende ServiceAccount-Definition ein:
fluentd.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: fluentd
namespace: kube-logging
labels:
app: fluentd
Hier erstellen wir ein Dienstkonto mit dem Namenfluentd
, mit dem die Fluentd Pods auf die Kubernetes-API zugreifen. Wir erstellen es im Namespacekube-logging
und geben ihm erneut die Bezeichnungapp: fluentd
. Weitere Informationen zu Dienstkonten in Kubernetes finden Sie inConfigure Service Accounts for Pods in den offiziellen Kubernetes-Dokumenten.
Fügen Sie als Nächstes den folgendenClusterRole
-Block ein:
fluentd.yaml
. . .
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fluentd
labels:
app: fluentd
rules:
- apiGroups:
- ""
resources:
- pods
- namespaces
verbs:
- get
- list
- watch
Hier definieren wir eine ClusterRole namensfluentd
, der wir die Berechtigungenget
,list
undwatch
für die Objektepods
undnamespaces
erteilen. Mit ClusterRoles können Sie Zugriff auf Cluster-Kubernetes-Ressourcen wie Nodes gewähren. Weitere Informationen zu rollenbasierter Zugriffssteuerung und Clusterrollen finden Sie inUsing RBAC Authorization in der offiziellen Kubernetes-Dokumentation.
Fügen Sie nun den folgendenClusterRoleBinding
-Block ein:
fluentd.yaml
. . .
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: fluentd
roleRef:
kind: ClusterRole
name: fluentd
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: fluentd
namespace: kube-logging
In diesem Block definieren wir einClusterRoleBinding
namensfluentd
, das die ClusterRole vonfluentd
an das Dienstkonto vonfluentd
bindet. Dadurch wird dem ServiceAccount vonfluentd
die in der Clusterrolle vonfluentd
aufgeführten Berechtigungen gewährt.
An dieser Stelle können wir mit dem Einfügen der aktuellen DaemonSet-Spezifikation beginnen:
fluentd.yaml
. . .
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
namespace: kube-logging
labels:
app: fluentd
Hier definieren wir ein DaemonSet mit dem Namenfluentd
im Namespacekube-logging
und geben ihm die Bezeichnungapp: fluentd
.
Fügen Sie als Nächstes den folgenden Abschnitt ein:
fluentd.yaml
. . .
spec:
selector:
matchLabels:
app: fluentd
template:
metadata:
labels:
app: fluentd
spec:
serviceAccount: fluentd
serviceAccountName: fluentd
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1
env:
- name: FLUENT_ELASTICSEARCH_HOST
value: "elasticsearch.kube-logging.svc.cluster.local"
- name: FLUENT_ELASTICSEARCH_PORT
value: "9200"
- name: FLUENT_ELASTICSEARCH_SCHEME
value: "http"
- name: FLUENTD_SYSTEMD_CONF
value: disable
Hier stimmen wir mit der in.metadata.labels
definierten Bezeichnungapp: fluentd
überein und weisen dem DaemonSet das Dienstkontofluentd
zu. Wir wählen auch dieapp: fluentd
als die von diesem DaemonSet verwalteten Pods aus.
Als nächstes definieren wir eineNoSchedule
-Toleranz, um dem äquivalenten Taint auf Kubernetes-Masterknoten zu entsprechen. Dadurch wird sichergestellt, dass das DaemonSet auch an die Kubernetes-Master verteilt wird. Wenn Sie auf Ihren Masterknoten keinen Fluentd Pod ausführen möchten, entfernen Sie diese Toleranz. Weitere Informationen zu Kubernetes-Fehlern und -Toleranzen finden Sie in den offiziellen Kubernetes-Dokumenten unter „https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/[Taints and Tolerations]“.
Als nächstes definieren wir den Pod-Container, den wirfluentd
nennen.
Wir verwenden dieofficial v1.4.2 Debian image, die von den Fluentd-Betreuern bereitgestellt werden. Wenn Sie Ihr eigenes privates oder öffentliches Fluentd-Image oder eine andere Image-Version verwenden möchten, ändern Sie dasimage
-Tag in der Containerspezifikation. Die Docker-Datei und der Inhalt dieses Bildes sind influentd-kubernetes-daemonset Github repovon Fluentd verfügbar.
Als Nächstes konfigurieren wir Fluentd mithilfe einiger Umgebungsvariablen:
-
FLUENT_ELASTICSEARCH_HOST
: Wir setzen dies auf die zuvor definierte Headless Service-Adresse von Elasticsearch:elasticsearch.kube-logging.svc.cluster.local
. Dadurch wird eine Liste mit IP-Adressen für die 3 Elasticsearch-Pods erstellt. Der tatsächliche Elasticsearch-Host ist höchstwahrscheinlich die erste in dieser Liste zurückgegebene IP-Adresse. Um Protokolle über den Cluster zu verteilen, müssen Sie die Konfiguration für Fluentds Elasticsearch-Ausgabe-Plugin ändern. Um mehr über dieses Plugin zu erfahren, konsultieren SieElasticsearch Output Plugin. -
FLUENT_ELASTICSEARCH_PORT
: Wir setzen dies auf den zuvor konfigurierten Elasticsearch-Port9200
. -
FLUENT_ELASTICSEARCH_SCHEME
: Wir setzen dies aufhttp
. -
FLUENTD_SYSTEMD_CONF
: Wir setzen dies aufdisable
, um die Ausgabe zu unterdrücken, die sich aufsystemd
bezieht, die nicht im Container eingerichtet sind.
Fügen Sie abschließend den folgenden Abschnitt ein:
fluentd.yaml
. . .
resources:
limits:
memory: 512Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
Hier legen wir eine Speicherkapazität von 512 MiB für den FluentD Pod fest und garantieren 0,1 vCPU und 200 MB Speicher. Sie können diese Ressourcenbeschränkungen und -anforderungen in Abhängigkeit von Ihrem erwarteten Protokollvolumen und den verfügbaren Ressourcen optimieren.
Als nächstes hängen wir die Hostpfade/var/log
und/var/lib/docker/containers
in den Container ein, indem wirvarlog
undvarlibdockercontainers
volumeMounts
verwenden. Diesevolumes
werden am Ende des Blocks definiert.
Der letzte Parameter, den wir in diesem Block definieren, istterminationGracePeriodSeconds
, was Fluentd 30 Sekunden Zeit gibt, um beim Empfang einesSIGTERM
-Signals ordnungsgemäß herunterzufahren. Nach 30 Sekunden erhalten die Container einSIGKILL
-Signal. Der Standardwert fürterminationGracePeriodSeconds
ist 30s, daher kann dieser Parameter in den meisten Fällen weggelassen werden. Weitere Informationen zum ordnungsgemäßen Beenden von Kubernetes-Workloads finden Sie unter "https://cloud.google.com/blog/products/gcp/kubernetes-best-practices-terminating-with-grace[Kubernetes-Best Practices: Beenden mit Vorbehalt".
Die gesamte Fluentd-Spezifikation sollte ungefähr so aussehen:
fluentd.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: fluentd
namespace: kube-logging
labels:
app: fluentd
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: fluentd
labels:
app: fluentd
rules:
- apiGroups:
- ""
resources:
- pods
- namespaces
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: fluentd
roleRef:
kind: ClusterRole
name: fluentd
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: fluentd
namespace: kube-logging
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
namespace: kube-logging
labels:
app: fluentd
spec:
selector:
matchLabels:
app: fluentd
template:
metadata:
labels:
app: fluentd
spec:
serviceAccount: fluentd
serviceAccountName: fluentd
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd
image: fluent/fluentd-kubernetes-daemonset:v1.4.2-debian-elasticsearch-1.1
env:
- name: FLUENT_ELASTICSEARCH_HOST
value: "elasticsearch.kube-logging.svc.cluster.local"
- name: FLUENT_ELASTICSEARCH_PORT
value: "9200"
- name: FLUENT_ELASTICSEARCH_SCHEME
value: "http"
- name: FLUENTD_SYSTEMD_CONF
value: disable
resources:
limits:
memory: 512Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
Speichern und schließen Sie die Datei, nachdem Sie das Fluentd DaemonSet konfiguriert haben.
Rollen Sie nun das DaemonSet mitkubectl
aus:
kubectl create -f fluentd.yaml
Sie sollten die folgende Ausgabe sehen:
Outputserviceaccount/fluentd created
clusterrole.rbac.authorization.k8s.io/fluentd created
clusterrolebinding.rbac.authorization.k8s.io/fluentd created
daemonset.extensions/fluentd created
Stellen Sie sicher, dass Ihr DaemonSet mitkubectl
erfolgreich eingeführt wurde:
kubectl get ds --namespace=kube-logging
Sie sollten die folgende Statusausgabe sehen:
OutputNAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
fluentd 3 3 3 3 3 58s
Dies zeigt an, dass 3fluentd
Pods ausgeführt werden, was der Anzahl der Knoten in unserem Kubernetes-Cluster entspricht.
Wir können jetzt Kibana überprüfen, um sicherzustellen, dass die Protokolldaten ordnungsgemäß erfasst und an Elasticsearch gesendet werden.
Navigieren Sie bei noch geöffnetenkubectl port-forward
zuhttp://localhost:5601
.
Klicken Sie im linken Navigationsmenü aufDiscover:
Sie sollten das folgende Konfigurationsfenster sehen:
Auf diese Weise können Sie die Elasticsearch-Indizes definieren, die Sie in Kibana erkunden möchten. Weitere Informationen finden Sie inDefining your index patterns in den offiziellen Kibana-Dokumenten. Im Moment verwenden wir nur das Platzhaltermusterlogstash-*
, um alle Protokolldaten in unserem Elasticsearch-Cluster zu erfassen. Geben Sielogstash-*
in das Textfeld ein und klicken Sie aufNext step.
Sie werden dann auf die folgende Seite weitergeleitet:
Auf diese Weise können Sie konfigurieren, in welchem Feld Kibana die Protokolldaten nach der Zeit filtert. Wählen Sie in der Dropdown-Liste das Feld@timestamp aus und drücken SieCreate index pattern.
Drücken Sie nun im linken NavigationsmenüDiscover.
Sie sollten ein Histogrammdiagramm und einige aktuelle Protokolleinträge sehen:
Zu diesem Zeitpunkt haben Sie den EFK-Stack auf Ihrem Kubernetes-Cluster erfolgreich konfiguriert und bereitgestellt. Informationen zur Verwendung von Kibana zur Analyse Ihrer Protokolldaten finden Sie inKibana User Guide.
Im nächsten optionalen Abschnitt werden wir einen einfachen Zähler-Pod bereitstellen, der Zahlen auf stdout druckt und seine Protokolle in Kibana findet.
[[Schritt-5-optional -—- Testen der Container-Protokollierung]] == Schritt 5 (Optional) - Testen der Container-Protokollierung
Um einen grundlegenden Kibana-Anwendungsfall für das Durchsuchen der neuesten Protokolle für einen bestimmten Pod zu demonstrieren, stellen wir einen minimalen Zähler-Pod bereit, der fortlaufende Nummern nach Standard ausgibt.
Beginnen wir mit der Erstellung des Pods. Öffnen Sie eine Datei mit dem Namencounter.yaml
in Ihrem bevorzugten Editor:
nano counter.yaml
Fügen Sie dann die folgenden Pod-Spezifikationen ein:
counter.yaml
apiVersion: v1
kind: Pod
metadata:
name: counter
spec:
containers:
- name: count
image: busybox
args: [/bin/sh, -c,
'i=0; while true; do echo "$i: $(date)"; i=$((i+1)); sleep 1; done']
Speichern und schließen Sie die Datei.
Dies ist ein minimaler Pod namenscounter
, der einewhile
-Schleife ausführt und Zahlen nacheinander druckt.
Stellen Sie dencounter
Pod mitkubectl
bereit:
kubectl create -f counter.yaml
Sobald der Pod erstellt wurde und ausgeführt wird, navigieren Sie zurück zu Ihrem Kibana-Dashboard.
Geben Sie auf der SeiteDiscover in der Suchleistekubernetes.pod_name:counter
ein. Dadurch werden die Protokolldaten für Pods mit dem Namencounter
gefiltert.
Sie sollten dann eine Liste der Protokolleinträge für den Pod voncounter
ehen:
Sie können in jeden der Protokolleinträge klicken, um zusätzliche Metadaten wie den Containernamen, den Kubernetes-Knoten, den Namespace usw. anzuzeigen.
Fazit
In diesem Handbuch wird gezeigt, wie Elasticsearch, Fluentd und Kibana in einem Kubernetes-Cluster eingerichtet und konfiguriert werden. Wir haben eine minimale Protokollierungsarchitektur verwendet, die aus einem einzelnen Protokollierungsagenten-Pod besteht, der auf jedem Kubernetes-Arbeitsknoten ausgeführt wird.
Bevor Sie diesen Protokollstapel in Ihrem Produktions-Kubernetes-Cluster bereitstellen, sollten Sie die Ressourcenanforderungen und -beschränkungen wie in diesem Handbuch angegeben anpassen. Möglicherweise möchten Sie auchX-Pack einrichten, um integrierte Überwachungs- und Sicherheitsfunktionen zu aktivieren.
Die hier verwendete Protokollierungsarchitektur besteht aus 3 Elasticsearch-Pods, einem einzelnen Kibana-Pod (nicht lastausgeglichen) und einer Reihe von Fluentd-Pods, die als DaemonSet bereitgestellt werden. Möglicherweise möchten Sie diese Konfiguration in Abhängigkeit von Ihrem Produktionsanwendungsfall skalieren. Weitere Informationen zum Skalieren Ihres Elasticsearch- und Kibana-Stacks finden Sie unterScaling Elasticsearch.
Kubernetes ermöglicht auch komplexere Architekturen für Protokollierungsagenten, die möglicherweise besser zu Ihrem Anwendungsfall passen. Weitere Informationen finden Sie inLogging Architecture in den Kubernetes-Dokumenten.