Benutzer-Werkzeuge

Webseiten-Werkzeuge


it-wiki:kubernetes:cluster_logging_loki

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
it-wiki:kubernetes:cluster_logging_loki [2025/09/04 09:33] – [Warum Loki] markoit-wiki:kubernetes:cluster_logging_loki [2025/09/05 07:36] (aktuell) – [Installation von Loki] marko
Zeile 40: Zeile 40:
   * **Datenvisualisierung:** Graylog oder Kibana   * **Datenvisualisierung:** Graylog oder Kibana
  
-Neben dieser etablierten Architektur hat sich mit der Kombination aus Loki und Grafana Alloy ein alternativer, ressourcenschonenderer OpenTelemetry Collector etabliert.+Neben dieser etablierten Architektur hat sich mit der Kombination aus Loki und Grafana Alloy ein alternativer, ressourcenschonenderer Logging-Stack etabliert.
  
 Loki bietet im Vergleich zu traditionellen Log-Aggregationssystemen eine Reihe spezifischer Vorteile: Loki bietet im Vergleich zu traditionellen Log-Aggregationssystemen eine Reihe spezifischer Vorteile:
Zeile 57: Zeile 57:
  
 Obwohl Kibana und Graylog ein umfangreicheres Funktionsspektrum bereitstellen, zeichnet sich Loki durch seine geringere Komplexität und den reduzierten Ressourcenbedarf aus, was ihn insbesondere für Entwicklungs- und Testumgebungen prädestiniert. Obwohl Kibana und Graylog ein umfangreicheres Funktionsspektrum bereitstellen, zeichnet sich Loki durch seine geringere Komplexität und den reduzierten Ressourcenbedarf aus, was ihn insbesondere für Entwicklungs- und Testumgebungen prädestiniert.
 +
 +==== Komponenten des Logging-Stack Loki und Grafana Alloy =====
 +Ein auf Loki basierender Logging-Stack besteht aus drei Kernkomponenten:
 +  - **Loki**\\ Loki bildet die zentrale Komponente des Stacks und verwaltet den Log-Index. Es fungiert als Hauptserver, der eingehende Protokolldaten aggregiert und in das konfigurierte Storage-Backend schreibt. Neben der Speicherung übernimmt Loki die Verarbeitung eingehender Abfragen und dient als Datenquelle für Visualisierungstools wie Grafana. Die Log-Daten werden dabei von vorgelagerten Agenten wie Promtail empfangen.
 +  - **Grafana Alloy**\\ Grafana Alloy übernimmt die Erfassung und Weiterleitung von Log-Daten an Loki. Seine Hauptaufgabe ist es, die Logs aus den verschiedenen Pods und Containern im Cluster zu sammeln, sie zu verarbeiten (z.B. filtern oder Labels hinzufügen) und sie anschließend im richtigen Format an Loki zu senden.
 +  - **Grafana**\\ Grafana ist ein Open-Source-Tool zur Überwachung und Visualisierung von Daten. Es ermöglicht die Erstellung und Verwaltung von Dashboards, welche Daten aus einer Vielzahl von Quellen – darunter InfluxDB, MySQL, PostgreSQL, Prometheus und Graphite – aggregieren können. Durch ein flexibles Plug-in-System lassen sich sowohl die Datenquellen als auch die Darstellungsoptionen erweitern. Im Kontext des Loki-Stacks dient Grafana als Visualisierungskomponente für die Abfrage und Darstellung der erfassten Logs.
 +
 +===== Installation von Loki =====
 +Das **Loki Helm-Chart** unterstützt drei verschiedene Bereitstellungsmethoden:
 +  * **Monolithic**
 +  * **Simple Scalable**
 +  * **Microservice**
 +(vgl. [[https://grafana.com/docs/loki/latest/setup/install/helm/
 +concepts/|Grafana Labs Documentation]])
 +\\
 +
 +Standardmäßig wird das Chart im **Simple-Scalable-Modus** installiert, welcher für die meisten Anwendungsfälle die empfohlene Betriebsart darstellt.
 +
 +<note>Storage für Loki\\ Idealerweise nutzt Loki einen Object Storage wie Ceph, S3 oder GCS. In einfachen (Test-
 +)Umgebungen kann lokaler Storage genutzt werden – mit einigen Einschränkungen
 +u. a. bezüglich Geschwindigkeit und Sicherheit.</note>
 +
 +Für das Deployment im Rahmen des Trainings-Labs oder in einer Test- oder Entwicklungsumgebungen steht meistens kein Objektspeicher eines externen Storage-Providers zur Verfügung. Stattdessen wird lokaler Speicher in Kombination mit der Methode ''deploymentMode: SingleBinary'' verwendet.
 +
 +Das Loki Helm-Chart umfasst standardmäßig **kein integriertes Monitoring**. Für eine übergreifende Überwachung des Loki-Clusters hinsichtlich Logs, Metriken und Traces empfiehlt sich der Einsatz des sogenannten //Meta-Monitoring-Stacks//.
 +Installation des Loki-Stacks auf Kubernetes
 +
 +Die Bereitstellung von Loki erfolgt üblicherweise mittels Helm, einem Package-Manager für Kubernetes. Das offizielle Helm-Chart beinhaltet die erforderlichen Komponenten für das Trainingsszenario: Loki, Grafana Alloy und Grafana.
 +
 +Die Installation erfolgt in folgenden Schritten:
 +  - **Hinzufügen des Helm-Repositories:**\\ <code bash>helm repo add grafana https://grafana.github.io/helm-charts</code>
 +  - **Installation von Loki in einem separaten Namespace (z.B. ''loki''):**\\ <code bash>helm install loki grafana/loki --values loki-values.yaml --create-namespace -n loki</code>
 +  - **Überprüfung der laufenden Pods und Services:**\\ <code bash>kubectl get pods,svc -n loki</code>
 +
 +==== Konfiguration ====
 +Zur Anpassung der Loki-Konfiguration kann die aktuelle Standardkonfiguration des Charts mit folgendem Befehl angezeigt und in eine Vorlage exportiert werden:
 +<code bash>
 +helm show values grafana/loki > config-loki.yaml
 +</code>
 +
 +Auf Basis dieser Datei können die erforderlichen Anpassungen für die eigene Umgebung vorgenommen werden.\\
 +''loki-values.yaml''
 +<code yaml>
 +loki:
 +  commonConfig:
 +    replication_factor: 1
 +  storage:
 +    type: 'filesystem'
 +    bucketNames:
 +      chunks: chunks
 +      ruler: ruler
 +      admin: admin
 +  schemaConfig:
 +    configs:
 +      - from: "2024-04-01"
 +        store: tsdb
 +        object_store: filesystem
 +        schema: v13
 +        index:
 +          prefix: loki_index_
 +          period: 24h
 +  storage_config:
 +    filesystem:
 +      directory: /tmp/loki/chunks
 +  pattern_ingester:
 +    enabled: true
 +  limits_config:
 +    allow_structured_metadata: true
 +    volume_enabled: true
 +  ruler:
 +    enable_api: true
 +  auth_enabled: false
 +
 +minio:
 +  enabled: false
 +      
 +deploymentMode: SingleBinary
 +
 +singleBinary:
 +  replicas: 1
 +  persistence:
 +    storageClass: nfs-delete
 +    accessModes:
 +      - ReadWriteOnce
 +    size: 20Gi
 +
 +  resources:
 +    requests:
 +      cpu: "1"
 +      memory: "2Gi"
 +    limits:
 +      cpu: "2"
 +      memory: "4Gi"
 +
 +sidecar:
 +  image:
 +    repository: kiwigrid/k8s-sidecar
 +    tag: 1.30.0
 +  resources:
 +    requests:
 +      cpu: 50m
 +      memory: 50Mi
 +    limits:
 +      cpu: 100m
 +      memory: 100Mi
 +
 +backend:
 +  replicas: 0
 +read:
 +  replicas: 0
 +write:
 +  replicas: 0
 +
 +chunksCache:
 +  allocatedMemory: 500
 +</code>
 +
 +Weitere Konfigurationsbeispiele sind in der offiziellen Dokumentation verfügbar:
 +[[https://grafana.com/docs/loki/latest/configure/examples/
 +configuration-examples/|Configuration Examples]]
 +
 +===== Einspeisen von Logs in Loki mittels Alloy =====
 +Grafana Alloy ist ein vielseitiger Observability-Collector, der in der Lage ist, Protokolldaten in unterschiedlichen Formaten zu erfassen und an Loki weiterzuleiten. Alloy wird als bevorzugte Methode zur Log-Ingestion empfohlen, da es eine robuste und funktionsreiche Grundlage für den Aufbau hochskalierbarer und zuverlässiger Observability-Pipelines bietet.
 +
 +{{ :it-wiki:kubernetes:flow-diagram-small-alloy.png?nolink |}}
 +
 +==== Komponenten von Alloy für die Log-Verarbeitung ====
 +Alloy-Pipelines bestehen aus einzelnen Komponenten, die jeweils spezifische Funktionen erfüllen. Für die Verarbeitung von Log-Daten lassen sich diese in drei Hauptkategorien unterteilen:
 +  * **Collector:**\\ Diese Komponenten sind verantwortlich für die Erfassung bzw. den Empfang von Logs aus unterschiedlichen Quellen. Dies kann beispielsweise durch das Auslesen von Log-Dateien, den Empfang von Logs über HTTP oder gRPC oder das Einlesen aus einer Message Queue erfolgen.
 +
 +  * **Transformer:**\\ Transformationskomponenten dienen der Manipulation von Logs vor deren Weiterleitung an eine Zielkomponente. Typische Anwendungsfälle sind das Anreichern mit zusätzlichen Metadaten, das Filtern unerwünschter Logs oder das Bündeln (Batching) von Logs zur Optimierung des Transports.
 +
 +  * **Writer:**\\ Diese Komponenten sind für die Weiterleitung der verarbeiteten Logs an ein definiertes Zielsystem verantwortlich. Im Rahmen dieser Dokumentation liegt der Fokus auf der Anbindung an Loki, jedoch unterstützt Alloy prinzipiell auch andere Zielsysteme.
 +
 +==== Log-Komponenten in Alloy ====
 +
 +Nachfolgend findet sich eine nicht abschließende Übersicht von Komponenten, die für den Aufbau einer Log-Pipeline in Alloy verwendet werden können. Für eine vollständige Auflistung aller verfügbaren Komponenten wird auf die [[https://grafana.com/docs/alloy/latest/reference/components/|offizielle Komponentenübersicht]] verwiesen.
 +
 +^Type ^Component |
 +| Collector | loki.source.api |
 +| Collector | loki.source.awsfirehose |
 +| Collector | loki.source.azure_event_hubs |
 +| Collector | loki.source.cloudflare |
 +| Collector | loki.source.docker |
 +| Collector | loki.source.file |
 +| Collector | loki.source.gcplog |
 +| Collector | loki.source.gelf |
 +| Collector | loki.source.heroku |
 +| Collector | loki.source.journal |
 +| Collector | loki.source.kafka |
 +| Collector | loki.source.kubernetes |
 +| Collector | loki.source.kubernetes_events |
 +| Collector | loki.source.podlogs |
 +| Collector | loki.source.syslog |
 +| Collector | loki.source.windowsevent |
 +| Collector | otelcol.receiver.loki |
 +| Transformer | loki.relabel |
 +| Transformer | loki.process |
 +| Writer | loki.write |
 +| Writer | otelcol.exporter.loki |
 +
 +==== Installation von Grafana Alloy ====
 +Der Alloy lässt sich über Helm Chart installieren. Diesen finden wir im selben Helm-Repository wie unseren Loki Chart. Daher ist kein weiteres Helm Repository hinzufügen nötig.
 +
 +Die Installation erfolgt in folgenden Schritten:
 +  - **Installation von Alloy im selben Namespace wie loki:**\\ <code bash>helm install grafana-alloy grafana/alloy --values alloy-values.yaml -n loki</code>
 +  - **Überprüfung der laufenden Pods und Services:**\\ <code bash>kubectl get pods,svc -n loki</code>
 +
 +Für die Installation und Konfiguration von Alloy kann eine Values-Datei verwendet werden, in der sämtliche Parameter des Helm-Charts angepasst werden. Die verfügbaren Standardoptionen lassen sich mit folgendem Befehl anzeigen und gleichzeitig in eine Vorlage exportieren:
 +<code bash>
 +helm show values grafana/loki > config-loki.yaml
 +</code>
 +
 +Auf Basis dieser Konfigurationsvorlage können spezifische Anpassungen vorgenommen werden, um den Betrieb in der eigenen Umgebung sicherzustellen. Ein Beispiel für eine entsprechende Konfiguration wird nachfolgend dargestellt.
 +''alloy-values.yaml''
 +<code yaml>
 +alloy:
 +  configMap:
 +    content: |-
 +      logging {
 +        level = "debug"
 +        format = "logfmt"
 +      }
 +      discovery.kubernetes "pods" {
 +        role = "pod"
 +      }
 +      discovery.relabel "pods" {
 +        targets = discovery.kubernetes.pods.targets
 +
 +        rule {
 +          source_labels = ["__meta_kubernetes_namespace"]
 +          target_label = "namespace"
 +          action = "replace"
 +        }
 +
 +        rule {
 +          source_labels = ["__meta_kubernetes_pod_label_app_kubernetes_io_name"]
 +          target_label = "app"
 +          action = "replace"
 +        }
 +
 +        rule {
 +          source_labels = ["__meta_kubernetes_pod_container_name"]
 +          target_label = "container"
 +          action = "replace"
 +        }
 +
 +        rule {
 +          source_labels = ["__meta_kubernetes_pod_name"]
 +          target_label = "pod"
 +          action = "replace"
 +        }
 +      }
 +      loki.source.kubernetes "pods" {
 +        targets    = discovery.relabel.pods.output
 +        forward_to = [loki.process.process.receiver]
 +      }
 +      loki.process "process" {
 +        forward_to = [loki.write.loki.receiver]
 +
 +        stage.drop {
 +          older_than          = "1h"
 +          drop_counter_reason = "too old"
 +        }
 +        stage.match { 
 +          selector = "{instance=~\".*\"}"
 +          stage.json {
 +            expressions = {
 +              level = "\"level\"",
 +            }
 +          }
 +          stage.labels {
 +            values = { 
 +              level = "level",
 +            }
 +          }
 +        }
 +        stage.label_drop {
 +          values = [ "service_name" ]
 +        }
 +      }
 +      loki.write "loki" {
 +        endpoint {
 +          url = "http://loki-gateway/loki/api/v1/push"
 +        }
 +      }
 +  mounts:
 +    varlog: true
 +    dockercontainers: true
 +
 +  resources:
 +    limits:
 +      cpu: 200m
 +      memory: 128Mi
 +    requests:
 +      cpu: 100m
 +      memory: 128Mi
 +</code>
 +
 +===== Installation von Grafana mittels Helm-Chart =====
 +Die Bereitstellung von Grafana erfolgt analog zu Loki über ein offizielles Helm-Chart. Auch hier kann wieder das selbe Repository von Grafana verwendet werden.
 +
 +<code bash>
 +helm install grafana grafana/grafana -f grafana-values.yaml --create-namespace -n grafana
 +</code>
 +
 +Für die Installation empfiehlt sich die Verwendung einer vorbereiteten Konfigurationsdatei, welche die notwendigen Parameter für eine einfache Grafana-Instanz enthält. Diese kann unter folgender Adresse abgerufen werden:
 +[[https://grafana.com/docs/loki/latest/setup/install/helm/monitor-and-alert/with-grafana-cloud/?utm_source=chatgpt.com|Grafana Cloud Helm-Konfiguration]]
 +
 +Für unsere kleine Übung verwenden wir am besten folgende Konfiguration. Diese beinhaltet bereits ein vorkonfiguriertes Dashboard.
 +''grafana-values.yaml''
 +<code yaml>
 +# grafana-values.yaml - Erweiterte Version mit Dashboards
 +replicas: 1
 +
 +resources:
 +  limits:
 +    cpu: 300m
 +    memory: 512Mi
 +  requests:
 +    cpu: 100m
 +    memory: 256Mi
 +
 +persistence:
 +  enabled: true
 +  size: 5Gi
 +  storageClassName: null
 +
 +adminUser: admin
 +adminPassword: admin123
 +
 +# Service configuration
 +service:
 +  type: ClusterIP
 +  port: 80
 +
 +# Datasources
 +datasources:
 +  datasources.yaml:
 +    apiVersion: 1
 +    datasources:
 +    - name: Loki
 +      type: loki
 +      url: http://loki-gateway.loki.svc.cluster.local
 +      access: proxy
 +      isDefault: true
 +      jsonData:
 +        maxLines: 1000
 +        derivedFields:
 +          - datasourceUid: loki
 +            matcherRegex: "traceID=(\\w+)"
 +            name: TraceID
 +            url: "$${__value.raw}"
 +
 +# Dashboard providers
 +dashboardProviders:
 +  dashboardproviders.yaml:
 +    apiVersion: 1
 +    providers:
 +    - name: 'kubernetes'
 +      orgId: 1
 +      folder: 'Kubernetes'
 +      type: file
 +      disableDeletion: false
 +      editable: true
 +      updateIntervalSeconds: 10
 +      allowUiUpdates: true
 +      options:
 +        path: /var/lib/grafana/dashboards/kubernetes
 +    - name: 'loki'
 +      orgId: 1
 +      folder: 'Loki'
 +      type: file
 +      disableDeletion: false
 +      editable: true
 +      updateIntervalSeconds: 10
 +      allowUiUpdates: true
 +      options:
 +        path: /var/lib/grafana/dashboards/loki
 +
 +# Custom Dashboards
 +dashboards:
 +  kubernetes:
 +    kubernetes-cluster-overview:
 +      json: |
 +        {
 +          "annotations": {
 +            "list": [
 +              {
 +                "builtIn": 1,
 +                "datasource": "-- Grafana --",
 +                "enable": true,
 +                "hide": true,
 +                "iconColor": "rgba(0, 211, 255, 1)",
 +                "name": "Annotations & Alerts",
 +                "type": "dashboard"
 +              }
 +            ]
 +          },
 +          "description": "Kubernetes Cluster Overview with Loki Logs",
 +          "editable": true,
 +          "gnetId": null,
 +          "graphTooltip": 0,
 +          "id": null,
 +          "links": [],
 +          "panels": [
 +            {
 +              "datasource": "Loki",
 +              "fieldConfig": {
 +                "defaults": {},
 +                "overrides": []
 +              },
 +              "gridPos": {
 +                "h": 8,
 +                "w": 24,
 +                "x": 0,
 +                "y": 0
 +              },
 +              "id": 1,
 +              "options": {
 +                "showLabels": false,
 +                "showTime": false,
 +                "sortOrder": "Descending",
 +                "wrapLogMessage": false,
 +                "prettifyLogMessage": false,
 +                "enableLogDetails": true,
 +                "dedupStrategy": "none"
 +              },
 +              "targets": [
 +                {
 +                  "expr": "{namespace=~\".+\"} |= \"\"",
 +                  "refId": "A"
 +                }
 +              ],
 +              "title": "All Kubernetes Logs",
 +              "type": "logs"
 +            },
 +            {
 +              "datasource": "Loki",
 +              "fieldConfig": {
 +                "defaults": {
 +                  "color": {
 +                    "mode": "palette-classic"
 +                  },
 +                  "custom": {
 +                    "axisLabel": "",
 +                    "axisPlacement": "auto",
 +                    "barAlignment": 0,
 +                    "drawStyle": "line",
 +                    "fillOpacity": 10,
 +                    "gradientMode": "none",
 +                    "hideFrom": {
 +                      "legend": false,
 +                      "tooltip": false,
 +                      "vis": false
 +                    },
 +                    "lineInterpolation": "linear",
 +                    "lineWidth": 1,
 +                    "pointSize": 5,
 +                    "scaleDistribution": {
 +                      "type": "linear"
 +                    },
 +                    "showPoints": "never",
 +                    "spanNulls": false,
 +                    "stacking": {
 +                      "group": "A",
 +                      "mode": "none"
 +                    },
 +                    "thresholdsStyle": {
 +                      "mode": "off"
 +                    }
 +                  },
 +                  "mappings": [],
 +                  "thresholds": {
 +                    "mode": "absolute",
 +                    "steps": [
 +                      {
 +                        "color": "green",
 +                        "value": null
 +                      },
 +                      {
 +                        "color": "red",
 +                        "value": 80
 +                      }
 +                    ]
 +                  },
 +                  "unit": "short"
 +                },
 +                "overrides": []
 +              },
 +              "gridPos": {
 +                "h": 8,
 +                "w": 12,
 +                "x": 0,
 +                "y": 8
 +              },
 +              "id": 2,
 +              "options": {
 +                "legend": {
 +                  "calcs": [],
 +                  "displayMode": "list",
 +                  "placement": "bottom"
 +                },
 +                "tooltip": {
 +                  "mode": "single"
 +                }
 +              },
 +              "targets": [
 +                {
 +                  "expr": "sum(rate({namespace=~\".+\"}[5m])) by (namespace)",
 +                  "refId": "A"
 +                }
 +              ],
 +              "title": "Log Rate by Namespace",
 +              "type": "timeseries"
 +            },
 +            {
 +              "datasource": "Loki",
 +              "fieldConfig": {
 +                "defaults": {
 +                  "color": {
 +                    "mode": "thresholds"
 +                  },
 +                  "custom": {
 +                    "align": "auto",
 +                    "displayMode": "auto"
 +                  },
 +                  "mappings": [],
 +                  "thresholds": {
 +                    "mode": "absolute",
 +                    "steps": [
 +                      {
 +                        "color": "green",
 +                        "value": null
 +                      },
 +                      {
 +                        "color": "red",
 +                        "value": 80
 +                      }
 +                    ]
 +                  }
 +                },
 +                "overrides": []
 +              },
 +              "gridPos": {
 +                "h": 8,
 +                "w": 12,
 +                "x": 12,
 +                "y": 8
 +              },
 +              "id": 3,
 +              "options": {
 +                "showHeader": true
 +              },
 +              "targets": [
 +                {
 +                  "expr": "topk(10, sum(count_over_time({namespace=~\".+\"}[5m])) by (namespace, pod_name))",
 +                  "refId": "A"
 +                }
 +              ],
 +              "title": "Top 10 Pods by Log Volume",
 +              "type": "table"
 +            }
 +          ],
 +          "refresh": "30s",
 +          "schemaVersion": 30,
 +          "style": "dark",
 +          "tags": ["kubernetes", "logs"],
 +          "templating": {
 +            "list": []
 +          },
 +          "time": {
 +            "from": "now-1h",
 +            "to": "now"
 +          },
 +          "timepicker": {},
 +          "timezone": "",
 +          "title": "Kubernetes Cluster Overview",
 +          "uid": "kubernetes-cluster-overview",
 +          "version": 1
 +        }
 +
 +    kubernetes-namespace-logs:
 +      json: |
 +        {
 +          "annotations": {
 +            "list": []
 +          },
 +          "description": "Kubernetes Namespace Specific Logs",
 +          "editable": true,
 +          "
 +</code>
 +
 +===== Testen des Cluster Loggings =====
 +Um sich nun das Gesamtergebnis schnell anschauen zu können richtet man am besten ein Port-Forwarding zum Grafana WebUI auf Port 3000 ein.
 +<code bash>
 +kubectl port-forward service/grafana 3000:80 -n grafana
 +</code>
 +
 +==== Zugriff auf das Grafana-Webinterface ====
 +
 +Nach erfolgreicher Installation und korrekter Konfiguration kann auf das Grafana-Webinterface zugegriffen werden.
 +
 +Nach Eingabe der entsprechenden Zugangsdaten erfolgt die Anmeldung am System. Anschließend steht die vollständige Benutzeroberfläche von Grafana zur Verfügung, über die beispielsweise ein Dashboard für Loki genutzt oder eingerichtet werden kann.
it-wiki/kubernetes/cluster_logging_loki.1756978394.txt.gz · Zuletzt geändert: von marko