В Deckhouse предусмотрен сбор и доставка логов из узлов и подов кластера во внутреннюю или внешние системы хранения.

DVP позволяет:

  • собирать логи из всех или отдельных подов и пространств имён;
  • фильтровать логи по лейблам, содержимому сообщений и другим признакам;
  • направлять логи одновременно в несколько хранилищ (например, Loki и Elasticsearch);
  • обогащать логи метаданными Kubernetes;
  • использовать буферизацию логов для повышения производительности.

Общий механизм сбора, доставки и фильтрации логов подробно описан в разделе «Архитектура».

Администраторам DVP доступна настройка сбора и отправки логов с помощью трёх кастомных ресурсов:

  • ClusterLoggingConfig — описывает источник логов на уровне кластера, включая правила сбора, фильтрации и парсинга;
  • PodLoggingConfig — описывает источник логов в рамках заданного пространства имён, включая правила сбора, фильтрации и парсинга;
  • ClusterLogDestination — задаёт параметры хранилища логов.

На основе этих ресурсов формируется pipeline, который используется в DVP для чтения логов и дальнейшей работы с ними c помощью модуля log-shipper. Полный перечень настроек модуля log-shipper доступен в отдельном разделе документации.

Настройка сбора и доставки логов

Ниже приведён вариант базовой конфигурации Deckhouse, при котором логи со всех подов кластера отправляются в хранилище на базе Elasticsearch.

Для настройки выполните следующие шаги:

  1. Включите модуль log-shipper с помощью следующей команды:

    d8 platform module enable log-shipper
    
  2. Создайте ресурс ClusterLoggingConfig, который задаёт правила сбора логов. Данный ресурс позволяет вам настроить сбор логов с подов в определенном пространстве имён и с определенным лейблом, гибко настраивать парсинг многострочных логов и задавать другие правила.

    В этом примере указывается, что нужно собирать логи со всех подов и отправлять их в Elasticsearch:

    apiVersion: deckhouse.io/v1alpha1
    kind: ClusterLoggingConfig
    metadata:
      name: all-logs
    spec:
      type: KubernetesPods
      destinationRefs:
      - es-storage
    
  3. Создайте ресурс ClusterLogDestination, который описывает параметры отправки логов в хранилище. Данный ресурс позволяет вам указать одно или несколько хранилищ и описать параметры подключения, буферизации и дополнительные лейблы, которые будут применяться к логам перед отправкой.

    В этом примере в качестве принимающего хранилища указан Elasticsearch:

    apiVersion: deckhouse.io/v1alpha1
    kind: ClusterLogDestination
    metadata:
      name: es-storage
    spec:
      type: Elasticsearch
      elasticsearch:
        endpoint: http://192.168.1.1:9200
        index: logs-%F
        auth:
          strategy: Basic
          user: elastic
          password: c2VjcmV0IC1uCg==
    

Интеграция с внешними системами

Вы можете настроить Deckhouse на работу с внешними системами хранения и анализа логов, такими как Elasticsearch, Splunk, Logstash и другими, используя параметр type ресурса ClusterLogDestination.

Elasticsearch

Чтобы отправлять логи в Elasticsearch, создайте ресурс ClusterLogDestination, следуя этому примеру:

apiVersion: deckhouse.io/v1alpha1
kind: ClusterLogDestination
metadata:
  name: es-storage
spec:
  type: Elasticsearch
  elasticsearch:
    endpoint: http://192.168.1.1:9200
    index: logs-%F
    auth:
      strategy: Basic
      user: elastic
      password: c2VjcmV0IC1uCg==

Использование шаблона индексов

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

apiVersion: deckhouse.io/v1alpha1
kind: ClusterLogDestination
metadata:
  name: es-storage
spec:
  type: Elasticsearch
  elasticsearch:
    endpoint: http://192.168.1.1:9200
    index: "k8s--%F"

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

Эта функция удобна в комбинации с параметром extraLabels:

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

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

Для работы с версиями Elasticsearch ранее 6.0 включите поддержку индексов docType с помощью ресурса ClusterLogDestination:

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

Splunk

Чтобы настроить отправку событий в Splunk, выполните следующие шаги:

  1. Настройте Splunk:
    • Определите endpoint. Он должен совпадать с именем вашего экземпляра Splunk с портом 8088, но без указания пути, например, https://prd-p-xxxxxx.splunkcloud.com:8088.
    • Создайте токен для доступа. Для этого в Splunk откройте раздел Setting -> Data inputs, добавьте новый HTTP Event Collector и скопируйте сгенерированный токен.
    • Укажите индекс Splunk для хранения логов, например, logs.
  2. Настройте Deckhouse, добавив ресурс ClusterLogDestination для отправки логов в Splunk:
apiVersion: deckhouse.io/v1alpha1
kind: ClusterLogDestination
metadata:
  name: splunk
spec:
  type: Splunk
  splunk:
    endpoint: https://prd-p-xxxxxx.splunkcloud.com:8088
    token: xxxx-xxxx-xxxx
    index: logs
    tls:
      verifyCertificate: false
      verifyHostname: false

destination не поддерживает метки пода для индексирования. Чтобы добавить нужные метки, используйте опцию extraLabels:

extraLabels:
  pod_label_app: ''

Logstash

Чтобы настроить отправку логов в Logstash, выполните следующее:

  1. Настройте входящий поток tcp с кодеком json на стороне Logstash.

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

    input {
      tcp {
        port => 12345
        codec => json
      }
    }
    output {
      stdout { codec => json }
    }
    
  2. Добавьте ресурс ClusterLogDestination:

    apiVersion: deckhouse.io/v1alpha1
    kind: ClusterLogDestination
    metadata:
      name: logstash
    spec:
      type: Logstash
      logstash:
        endpoint: logstash.default:12345
    

Graylog

Чтобы настроить отправку логов в Graylog, выполните следующее:

  1. Убедитесь, что в Graylog настроен входящий поток для приема сообщений по протоколу TCP на указанном порте.
  2. Создайте ресурс ClusterLogDestination, следуя примеру:

    apiVersion: deckhouse.io/v1alpha1
    kind: ClusterLogDestination
    metadata:
      name: test-socket2-dest
    spec:
      type: Socket
      socket:
        address: graylog.svc.cluster.local:9200
        mode: TCP
        encoding:
          codec: GELF
    

Формат сообщений

Вы можете выбрать формат отправляемых сообщений, используя параметр .encoding.codec ресурса ClusterLogDestination:

  • CEF
  • GELF
  • JSON
  • Syslog
  • Text

Ниже примеры конфигурации для некоторых из них.

Syslog

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

apiVersion: deckhouse.io/v1alpha1
kind: ClusterLogDestination
metadata:
  name: rsyslog
spec:
  type: Socket
  socket:
    mode: TCP
    address: 192.168.0.1:3000
    encoding: 
      codec: Syslog
  extraLabels:
    syslog.severity: "alert"
    # Поле request_id должно присутствовать в сообщении.
    syslog.message_id: ""

CEF

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

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

apiVersion: deckhouse.io/v1alpha1
kind: ClusterLogDestination
metadata:
  name: siem-kafka
spec:
  extraLabels:
    cef.name: ''
    cef.severity: ''
  type: Kafka
  kafka:
    bootstrapServers:
      - my-cluster-kafka-brokers.kafka:9092
    encoding:
      codec: CEF
    tls:
      verifyCertificate: false
      verifyHostname: true
    topic: logs

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

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

Преобразование логов

Вы можете настроить один или несколько видов трансформаций, которые будут применяться к логам перед отправкой в хранилище.

Преобразование записи в структурированный объект

Трансформация ParseMessage позволяет преобразовать строку в поле message в структурированный JSON-объект на основе одного или нескольких заданных форматов (String, Klog, SysLog и другие).

При использовании нескольких трансформаций ParseMessage преобразование строки (sourceFormat: String) должно выполняться в последнюю очередь.

Пример настройки преобразования записей смешанных форматов:

apiVersion: deckhouse.io/v1alpha2
kind: ClusterLoggingDestination
metadata:
  name: parse-json
spec:
  ...
  transformations:
  - action: ParseMessage
    parseMessage:
      sourceFormat: JSON
  - action: ParseMessage
    parseMessage:
      sourceFormat: Klog
  - action: ParseMessage
    parseMessage:
      sourceFormat: String
      string:
        targetField: "text"

Пример изначальной записи в логе:

/docker-entrypoint.sh: Configuration complete; ready for start up
{"level" : { "severity": "info" },"msg" : "fetching.module.release"}
I0505 17:59:40.692994   28133 klog.go:70] hello from klog

Результат преобразования:

{... "message": {
  "text": "/docker-entrypoint.sh: Configuration complete; ready for start up"
  }
}
{... "message": {
  "level" : "{ "severity": "info" }",
  "msg" : "fetching.module.release"
  }
}
{... "message": {
  "file":"klog.go",
  "id":28133,
  "level":"info",
  "line":70,
  "message":"hello from klog",
  "timestamp":"2025-05-05T17:59:40.692994Z"
  }
}

Замена лейблов

Трансформация ReplaceKeys позволяет рекурсивно заменить все совпадения шаблона source на значение target в указанных ключах лейблов.

Перед применением трансформации ReplaceKeys к полю message или его вложенным полям преобразуйте запись лога в структурированный объект с помощью трансформации ParseMessage.

Пример настройки замены точек на нижние подчеркивания в лейблах:

apiVersion: deckhouse.io/v1alpha2
kind: ClusterLoggingDestination
metadata:
  name: replace-dot
spec:
  ...
  transformations:
    - action: ReplaceKeys
      replaceKeys:
        source: "."
        target: "_"
        labels:
          - .pod_labels

Пример изначальной записи в логе:

{"msg" : "fetching.module.release"} # Лейбл пода pod.app=test

Результат преобразования:

{... "message": {
  "msg" : "fetching.module.release"
  },
  "pod_labels": {
    "pod_app": "test"
  }
}

Удаление лейблов

Трансформация DropLabels позволяет удалить указанные лейблы из структурированного JSON-сообщения.

Перед применением трансформации DropLabels к полю message или его вложенным полям преобразуйте запись лога в структурированный объект с помощью трансформации ParseMessage.

Пример конфигурации с удалением лейбла и предварительной трансформацией ParseMessage:

apiVersion: deckhouse.io/v1alpha2
kind: ClusterLoggingDestination
metadata:
  name: drop-label
spec:
  ...
  transformations:
    - action: ParseMessage
      parseMessage:
        sourceFormat: JSON
    - action: DropLabels
      dropLabels:
        labels:
          - .message.example

Пример изначальной записи в логе:

{"msg" : "fetching.module.release", "example": "test"}

Результат преобразования:

{... "message": {
  "msg" : "fetching.module.release"
  }
}

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

В Deckhouse предусмотрены фильтры, позволяющие исключить лишние сообщения для оптимизации процесса сбора логов:

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

Сборка логов из определенного контейнера

Чтобы настроить фильтрацию с помощью labelFilter, создайте ресурс ClusterLoggingConfig, используя конфигурацию ниже в качестве примера.

В этом случае фильтр отбирает логи из контейнеров с именем nginx, а затем отправляет их во внутреннее хранилище на базе Loki.

apiVersion: deckhouse.io/v1alpha1
kind: ClusterLoggingConfig
metadata:
  name: nginx-logs
spec:
  type: KubernetesPods
  labelFilter:
  - field: container
    operator: In
    values: [nginx]
  destinationRefs:
  - loki-storage

Сборка логов без заданной строки

Пример конфигурации для сбора логов с фильтрацией через labelFilter, где оператор NotRegex исключает строки, соответствующие заданному регулярному выражению.

apiVersion: deckhouse.io/v1alpha1
kind: ClusterLoggingConfig
metadata:
  name: all-logs
spec:
  type: KubernetesPods
  destinationRefs:
  - loki-storage
  labelFilter:
  - field: message
    operator: NotRegex
    values:
    - .*GET /status" 200$

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

Пример конфигурации для сбора и фильтрации событий аудита, связанных с работой kubelet, хранящихся в файле /var/log/kube-audit/audit.log. Фильтрация выполняется с помощью logFilter, который ищет в поле userAgent записи, соответствующие регулярному выражению "kubelet.*".

apiVersion: deckhouse.io/v1alpha1
kind: ClusterLoggingConfig
metadata:
  name: kubelet-audit-logs
spec:
  type: File
  file:
    include:
    - /var/log/kube-audit/audit.log
  logFilter:
  - field: userAgent  
    operator: Regex
    values: ["kubelet.*"]
  destinationRefs:
  - loki-storage

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

Пример конфигурации для сбора системных логов Deckhouse, находящихся в файле /var/log/syslog. Фильтрация сообщений с помощью labelFilter позволяет выделить только те записи, которые относятся к следующим компонентам: d8-kubelet-forker, containerd, bashible и kernel.

apiVersion: deckhouse.io/v1alpha1
kind: ClusterLoggingConfig
metadata:
  name: system-logs
spec:
  type: File
  file:
    include:
    - /var/log/syslog
  labelFilter:
  - field: message
    operator: Regex
    values:
    - .*d8-kubelet-forker.*
    - .*containerd.*
    - .*bashible.*
    - .*kernel.*
  destinationRefs:
  - loki-storage

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

Буферизация логов

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

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

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

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

За настройку буферизации отвечает параметр buffer ресурса ClusterLogDestination.

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

apiVersion: deckhouse.io/v1alpha1
kind: ClusterLogDestination
metadata:
  name: loki-storage
spec:
  buffer:
    memory:
      maxEvents: 4096
    type: Memory
  type: Loki
  loki:
    endpoint: http://loki.loki:3100

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

apiVersion: deckhouse.io/v1alpha1
kind: ClusterLogDestination
metadata:
  name: loki-storage
spec:
  buffer:
    disk:
      maxSize: 1Gi
    type: Disk
  type: Loki
  loki:
    endpoint: http://loki.loki:3100

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

apiVersion: deckhouse.io/v1alpha1
kind: ClusterLogDestination
metadata:
  name: loki-storage
spec:
  buffer:
    disk:
      maxSize: 1Gi
    type: Disk
    whenFull: DropNewest
  type: Loki
  loki:
    endpoint: http://loki.loki:3100

Отладка и расширенные возможности

Включение debug-логов агента log-shipper

Чтобы включить debug-логи агента log-shipper на узлах с информацией об HTTP-запросах, переиспользовании подключения, трассировке и прочими данными, включите параметр debug в конфигурации модуля log-shipper.

Пример конфигурации модуля:

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: log-shipper
spec:
  version: 1
  enabled: true
  settings:
    debug: true

Дополнительная информация о каналах передачи логов

Используя команды для Vector, можно получить дополнительную информацию о каналах передачи данных.

Для начала подключитесь к одному из подов log-shipper:

d8 k -n d8-log-shipper get pods -o wide | grep $node
d8 k -n d8-log-shipper exec $pod -it -c vector -- bash

Выполняйте последующие команды из командной оболочки пода.

Обзор топологии

Чтобы получить схему топологии вашей конфигурации:

  1. Выполните команду vector graph. Будет сформирована схема в формате DOT.
  2. Используйте WebGraphviz или аналогичный сервис для отрисовки схемы на основе содержимого DOT-файла.

Пример схемы для одного канала передачи логов в формате ASCII:

+------------------------------------------------+
|  d8_cluster_source_flant-integration-d8-logs   |
+------------------------------------------------+
  |
  |
  v
+------------------------------------------------+
|       d8_tf_flant-integration-d8-logs_0        |
+------------------------------------------------+
  |
  |
  v
+------------------------------------------------+
|       d8_tf_flant-integration-d8-logs_1        |
+------------------------------------------------+
  |
  |
  v
+------------------------------------------------+
| d8_cluster_sink_flant-integration-loki-storage |
+------------------------------------------------+

Мониторинг нагрузки на каналы

Чтобы посмотреть объем трафика на каждом этапе обработки логов, используйте команду vector top.

Пример вывода команды:

Vector TOP output

Получение необработанных и промежуточных логов

Для просмотра входных данных на разных стадиях обработки логов используйте команду vector tap. Указав в ней ID конкретного этапа обработки, вы сможете увидеть логи которые поступают на этом этапе. Также поддерживаются выборки в формате glob, например, cluster_logging_config/*.

Примеры:

  • Просмотр логов до применения правил трансформаций (cluster_logging_config/* является первой стадией обработки согласно выводу команды vector graph):

    vector tap 'cluster_logging_config/*'
    
  • Изменённые логи, поступающие на вход следующих в цепочке компонентов каналов:

    vector tap 'transform/*'
    

Отладка VRL-правил

Для отладки правил на языке Vector Remap Language (VRL) используйте команду vector vrl.

Пример VRL-программы:

. = {"test1": "lynx", "test2": "fox"}
del(.test2)
.

Добавление поддержки нового source или sink

Модуль log-shipper в Deckhouse собирается на основе Vector с ограниченным набором cargo-функций, чтобы минимизировать размер запускаемого файла и ускорить сборку.

Чтобы посмотреть весь список поддерживаемых функций, выполните команду vector list.

Если нужный source или sink отсутствует, добавьте соответствующую cargo-функцию в Dockerfile.

Особые случаи

Сбор логов с продуктовых пространств имён через опцию labelSelector

Если в вашем кластере пространства имён размечены с помощью лейблов (например, environment=production), вы можете использовать опцию labelSelector для сбора логов из продуктивных пространств имён.

Пример конфигурации:

apiVersion: deckhouse.io/v1alpha1
kind: ClusterLoggingConfig
metadata:
  name: production-logs
spec:
  type: KubernetesPods
  kubernetesPods:
    namespaceSelector:
      labelSelector:
        matchLabels:
          environment: production
  destinationRefs:
  - loki-storage

Лейбл для исключения подов и пространств имён

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

---
apiVersion: v1
kind: Namespace
metadata:
  name: test-namespace
  labels:
    log-shipper.deckhouse.io/exclude: "true"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-deployment
spec:
  ...
  template:
    metadata:
      labels:
        log-shipper.deckhouse.io/exclude: "true"