Чтение логов из всех подов кластера и направление их в Loki

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLoggingConfig
3metadata:
4  name: all-logs
5spec:
6  type: KubernetesPods
7  destinationRefs:
8  - loki-storage
9---
10apiVersion: deckhouse.io/v1alpha1
11kind: ClusterLogDestination
12metadata:
13  name: loki-storage
14spec:
15  type: Loki
16  loki:
17    endpoint: http://loki.loki:3100

Чтение логов подов из указанного namespace с указанным label и перенаправление одновременно в Loki и Elasticsearch

Чтение логов подов из namespace whispers только с label app=booking и перенаправление одновременно в Loki и Elasticsearch:

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLoggingConfig
3metadata:
4  name: whispers-booking-logs
5spec:
6  type: KubernetesPods
7  kubernetesPods:
8    namespaceSelector:
9      matchNames:
10        - whispers
11    labelSelector:
12      matchLabels:
13        app: booking
14  destinationRefs:
15  - loki-storage
16  - es-storage
17---
18apiVersion: deckhouse.io/v1alpha1
19kind: ClusterLogDestination
20metadata:
21  name: loki-storage
22spec:
23  type: Loki
24  loki:
25    endpoint: http://loki.loki:3100
26---
27apiVersion: deckhouse.io/v1alpha1
28kind: ClusterLogDestination
29metadata:
30  name: es-storage
31spec:
32  type: Elasticsearch
33  elasticsearch:
34    endpoint: http://192.168.1.1:9200
35    index: logs-%F
36    auth:
37      strategy: Basic
38      user: elastic
39      password: c2VjcmV0IC1uCg==

Создание source в namespace и чтение логов всех подов в этом NS с направлением их в Loki

Следующий pipeline создает source в namespace test-whispers, читает логи всех подов в этом NS и пишет их в Loki:

1apiVersion: deckhouse.io/v1alpha1
2kind: PodLoggingConfig
3metadata:
4  name: whispers-logs
5  namespace: tests-whispers
6spec:
7  clusterDestinationRefs:
8    - loki-storage
9---
10apiVersion: deckhouse.io/v1alpha1
11kind: ClusterLogDestination
12metadata:
13  name: loki-storage
14spec:
15  type: Loki
16  loki:
17    endpoint: http://loki.loki:3100

Чтение только подов в указанном namespace и с определенным label

Пример чтения только подов, имеющих label app=booking, в namespace test-whispers:

1apiVersion: deckhouse.io/v1alpha1
2kind: PodLoggingConfig
3metadata:
4  name: whispers-logs
5  namespace: tests-whispers
6spec:
7  labelSelector:
8    matchLabels:
9      app: booking
10  clusterDestinationRefs:
11    - loki-storage
12---
13apiVersion: deckhouse.io/v1alpha1
14kind: ClusterLogDestination
15metadata:
16  name: loki-storage
17spec:
18  type: Loki
19  loki:
20    endpoint: http://loki.loki:3100

Переход с Promtail на Log-Shipper

В ранее используемом URL Loki требуется убрать путь /loki/api/v1/push.

Vector сам добавит этот путь при работе с Loki.

Работа с Grafana Cloud

Данная документация подразумевает, что у вас уже создан ключ API.

Для начала вам потребуется закодировать в base64 ваш токен доступа к Grafana Cloud.

Grafana cloud API key

1echo -n "<YOUR-GRAFANACLOUD-TOKEN>" | base64 -w0

Затем нужно создать ClusterLogDestination

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLogDestination
3metadata:
4  name: loki-storage
5spec:
6  loki:
7    auth:
8      password: PFlPVVItR1JBRkFOQUNMT1VELVRPS0VOPg==
9      strategy: Basic
10      user: "<YOUR-GRAFANACLOUD-USER>"
11    endpoint: <YOUR-GRAFANACLOUD-URL> # Например https://logs-prod-us-central1.grafana.net или https://logs-prod-eu-west-0.grafana.net
12  type: Loki

Теперь можно создать PodLogginConfig или ClusterPodLoggingConfig и отправлять логи в Grafana Cloud.

Добавление Loki в Deckhouse Grafana

Вы можете работать с Loki из встроенной в Deckhouse Grafana. Достаточно добавить GrafanaAdditionalDatasource.

1apiVersion: deckhouse.io/v1
2kind: GrafanaAdditionalDatasource
3metadata:
4  name: loki
5spec:
6  access: Proxy
7  basicAuth: false
8  jsonData:
9    maxLines: 5000
10    timeInterval: 30s
11  type: loki
12  url: http://loki.loki:3100

Поддержка Elasticsearch < 6.X

Для Elasticsearch < 6.0 нужно включить поддержку doc_type индексов. Сделать это можно следующим образом:

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLogDestination
3metadata:
4  name: es-storage
5spec:
6  type: Elasticsearch
7  elasticsearch:
8    endpoint: http://192.168.1.1:9200
9    docType: "myDocType" # Укажите значение здесь. Оно не должно начинаться с '_'.
10    auth:
11      strategy: Basic
12      user: elastic
13      password: c2VjcmV0IC1uCg==

Шаблон индекса для Elasticsearch

Существует возможность отправлять сообщения в определенные индексы на основе метаданных с помощью шаблонов индексов:

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLogDestination
3metadata:
4  name: es-storage
5spec:
6  type: Elasticsearch
7  elasticsearch:
8    endpoint: http://192.168.1.1:9200
9    index: "k8s-{{ namespace }}-%F"

В приведенном выше примере для каждого пространства имен Kubernetes будет создан свой индекс в Elasticsearch.

Эта функция также хорошо работает в комбинации с extraLabels:

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLogDestination
3metadata:
4  name: es-storage
5spec:
6  type: Elasticsearch
7  elasticsearch:
8    endpoint: http://192.168.1.1:9200
9    index: "k8s-{{ service }}-{{ namespace }}-%F"
10  extraLabels:
11    service: "{{ service_name }}"
  1. Если сообщение имеет формат JSON, поле service_name этого документа JSON перемещается на уровень метаданных.
  2. Новое поле метаданных service используется в шаблоне индекса.

Пример интеграции со Splunk

Существует возможность отсылать события из Deckhouse в Splunk.

  1. Endpoint должен быть таким же, как имя вашего экземпляра Splunk с портом 8088 и без указания пути, например https://prd-p-xxxxxx.splunkcloud.com:8088.
  2. Чтобы добавить token для доступа, откройте пункт меню Setting -> Data inputs, добавьте новый HTTP Event Collector и скопируйте token.
  3. Укажите индекс Splunk для хранения логов, например logs.
1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLogDestination
3metadata:
4  name: splunk
5spec:
6  type: Splunk
7  splunk:
8    endpoint: https://prd-p-xxxxxx.splunkcloud.com:8088
9    token: xxxx-xxxx-xxxx
10    index: logs
11    tls:
12      verifyCertificate: false
13      verifyHostname: false

destination не поддерживает метки пода для индексирования. Рассмотрите возможность добавления нужных меток с помощью опции extraLabels.

1extraLabels:
2  pod_label_app: '{{ pod_labels.app }}'

Простой пример Logstash

Чтобы отправлять логи в Logstash, на стороне Logstash должен быть настроен входящий поток tcp и его кодек должен быть json.

Пример минимальной конфигурации Logstash:

1input {
2  tcp {
3    port => 12345
4    codec => json
5  }
6}
7output {
8  stdout { codec => json }
9}

Пример манифеста ClusterLogDestination:

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLogDestination
3metadata:
4  name: logstash
5spec:
6  type: Logstash
7  logstash:
8    endpoint: logstash.default:12345

Syslog

Следующий пример показывает, как отправлять сообщения через сокет по протоколу TCP в формате syslog:

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLogDestination
3metadata:
4  name: rsyslog
5spec:
6  type: Socket
7  socket:
8    mode: TCP
9    address: 192.168.0.1:3000
10    encoding: 
11      codec: Syslog
12  extraLabels:
13    syslog.severity: "alert"
14    # поле request_id должно присутствовать в сообщении
15    syslog.message_id: "{{ request_id }}"

Логи в CEF формате

Существует способ формировать логи в формате CEF, используя codec: CEF, с переопределением cef.name и cef.severity по значениям из поля message (лога приложения) в формате JSON.

В примере ниже app и log_level это ключи содержащие значения для переопределения:

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLogDestination
3metadata:
4  name: siem-kafka
5spec:
6  extraLabels:
7    cef.name: '{{ app }}'
8    cef.severity: '{{ log_level }}'
9  type: Kafka
10  kafka:
11    bootstrapServers:
12      - my-cluster-kafka-brokers.kafka:9092
13    encoding:
14      codec: CEF
15    tls:
16      verifyCertificate: false
17      verifyHostname: true
18    topic: logs

Так же можно вручную задать свои значения:

1extraLabels:
2  cef.name: 'TestName'
3  cef.severity: '1'

Сбор событий Kubernetes

События Kubernetes могут быть собраны log-shipper’ом, если events-exporter включен в настройках модуля extended-monitoring.

Включите events-exporter, изменив параметры модуля extended-monitoring:

1apiVersion: deckhouse.io/v1alpha1
2kind: ModuleConfig
3metadata:
4  name: extended-monitoring
5spec:
6  version: 1
7  settings:
8    events:
9      exporterEnabled: true

Выложите в кластер следующий ClusterLoggingConfig, чтобы собирать сообщения с пода events-exporter:

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLoggingConfig
3metadata:
4  name: kubernetes-events
5spec:
6  type: KubernetesPods
7  kubernetesPods:
8    labelSelector:
9      matchLabels:
10        app: events-exporter
11    namespaceSelector:
12      matchNames:
13      - d8-monitoring
14  destinationRefs:
15  - loki-storage

Фильтрация логов

Пользователи могут фильтровать логи, используя следующие фильтры:

  • labelFilter — применяется к метаданным, например имени контейнера (container), пространству имен (namespace) или имени пода (pod_name);
  • logFilter — применяется к полям самого сообщения, если оно в JSON-формате.

Сборка логов только для контейнера nginx

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLoggingConfig
3metadata:
4  name: nginx-logs
5spec:
6  type: KubernetesPods
7  labelFilter:
8  - field: container
9    operator: In
10    values: [nginx]
11  destinationRefs:
12  - loki-storage

Сборка логов без строки, содержащей GET /status" 200

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLoggingConfig
3metadata:
4  name: all-logs
5spec:
6  type: KubernetesPods
7  destinationRefs:
8  - loki-storage
9  labelFilter:
10  - field: message
11    operator: NotRegex
12    values:
13    - .*GET /status" 200$

Аудит событий kubelet’а

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLoggingConfig
3metadata:
4  name: kubelet-audit-logs
5spec:
6  type: File
7  file:
8    include:
9    - /var/log/kube-audit/audit.log
10  logFilter:
11  - field: userAgent  
12    operator: Regex
13    values: ["kubelet.*"]
14  destinationRefs:
15  - loki-storage

Системные логи Deckhouse

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLoggingConfig
3metadata:
4  name: system-logs
5spec:
6  type: File
7  file:
8    include:
9    - /var/log/syslog
10  labelFilter:
11  - field: message
12    operator: Regex
13    values:
14    - .*d8-kubelet-forker.*
15    - .*containerd.*
16    - .*bashible.*
17    - .*kernel.*
18  destinationRefs:
19  - loki-storage

Если вам нужны только логи одного пода или малой группы подов, постарайтесь использовать настройки kubernetesPods, чтобы сузить количество читаемых файлов. Фильтры необходимы только для высокогранулярной настройки.

Настройка сборки логов с продуктовых namespace’ов, используя опцию namespace label selector

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLoggingConfig
3metadata:
4  name: production-logs
5spec:
6  type: KubernetesPods
7  kubernetesPods:
8    namespaceSelector:
9      labelSelector:
10        matchLabels:
11          environment: production
12  destinationRefs:
13  - loki-storage

Исключение подов и пространств имён, используя label

Существует преднастроенный label для исключения определенных подов и пространств имён: log-shipper.deckhouse.io/exclude=true. Он помогает остановить сбор логов с подов и пространств имён без изменения глобальной конфигурации.

1---
2apiVersion: v1
3kind: Namespace
4metadata:
5  name: test-namespace
6  labels:
7    log-shipper.deckhouse.io/exclude: "true"
8---
9apiVersion: apps/v1
10kind: Deployment
11metadata:
12  name: test-deployment
13spec:
14  ...
15  template:
16    metadata:
17      labels:
18        log-shipper.deckhouse.io/exclude: "true"

Включение буферизации

Настройка буферизации логов необходима для улучшения надежности и производительности системы сбора логов. Буферизация может быть полезна в следующих случаях:

  1. Временные перебои с подключением. Если есть временные перебои или нестабильность соединения с системой хранения логов (например, с Elasticsearch), буфер позволяет временно сохранять логи и отправить их, когда соединение восстановится.

  2. Сглаживание пиков нагрузки. При внезапных всплесках объема логов буфер позволяет сгладить пиковую нагрузку на систему хранения логов, предотвращая её перегрузку и потенциальную потерю данных.

  3. Оптимизация производительности. Буферизация помогает оптимизировать производительность системы сбора логов за счёт накопления логов и отправки их группами, что снижает количество сетевых запросов и улучшает общую пропускную способность.

Пример включения буферизации в оперативной памяти

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLogDestination
3metadata:
4  name: loki-storage
5spec:
6  buffer:
7    memory:
8      maxEvents: 4096
9    type: Memory
10  type: Loki
11  loki:
12    endpoint: http://loki.loki:3100

Пример включения буферизации на диске

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLogDestination
3metadata:
4  name: loki-storage
5spec:
6  buffer:
7    disk:
8      maxSize: 1Gi
9    type: Disk
10  type: Loki
11  loki:
12    endpoint: http://loki.loki:3100

Пример определения поведения при переполнении буфера

1apiVersion: deckhouse.io/v1alpha1
2kind: ClusterLogDestination
3metadata:
4  name: loki-storage
5spec:
6  buffer:
7    disk:
8      maxSize: 1Gi
9    type: Disk
10    whenFull: DropNewest
11  type: Loki
12  loki:
13    endpoint: http://loki.loki:3100

Более подробное описание параметров доступно в ресурсе ClusterLogDestination.