Home » Настройка стека логирования Elasticsearch, Fluentd и Kibana (EFK) в Kubernetes
Настройка стека логирования Elasticsearch, Fluentd и Kibana (EFK) в Kubernetes

Настройка стека логирования Elasticsearch, Fluentd и Kibana (EFK) в Kubernetes

Логирование в Kubernetes – это боль многих девопсов. Приложения пишут логи, но где их искать? Как централизовать? Как мониторить? Сегодня разберем стек EFK – Elasticsearch, Fluentd и Kibana, который решает эти проблемы изящно и эффективно.

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

Как работает стек EFK?

Архитектура EFK состоит из трех основных компонентов:

  • Fluentd – агент сбора логов, работающий как DaemonSet на каждой ноде
  • Elasticsearch – поисковый движок для индексации и хранения логов
  • Kibana – веб-интерфейс для визуализации и поиска по логам

Fluentd читает логи из стандартных путей Kubernetes (/var/log/containers/), парсит их, добавляет метаданные (namespace, pod name, labels) и отправляет в Elasticsearch. Kibana подключается к Elasticsearch и предоставляет интерфейс для поиска и анализа.

Подготовка инфраструктуры

Для установки EFK нужен Kubernetes кластер с достаточными ресурсами. Рекомендую минимум 3 ноды по 4GB RAM каждая. Если у вас нет кластера, можно арендовать VPS или выделенный сервер для развертывания.

Создадим namespace для компонентов логирования:

kubectl create namespace logging
kubectl config set-context --current --namespace=logging

Установка Elasticsearch

Начнем с Elasticsearch. Создадим манифест для StatefulSet:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: elasticsearch
  namespace: 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.15.0
        ports:
        - containerPort: 9200
        - containerPort: 9300
        env:
        - name: discovery.type
          value: single-node
        - name: ES_JAVA_OPTS
          value: "-Xms512m -Xmx512m"
        volumeMounts:
        - name: elasticsearch-data
          mountPath: /usr/share/elasticsearch/data
        resources:
          requests:
            memory: "1Gi"
            cpu: "500m"
          limits:
            memory: "2Gi"
            cpu: "1000m"
  volumeClaimTemplates:
  - metadata:
      name: elasticsearch-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 10Gi

Создадим Service для доступа к Elasticsearch:

apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
  namespace: logging
spec:
  selector:
    app: elasticsearch
  ports:
  - port: 9200
    targetPort: 9200
  type: ClusterIP

Применяем манифесты:

kubectl apply -f elasticsearch-statefulset.yaml
kubectl apply -f elasticsearch-service.yaml

Настройка Fluentd

Fluentd будет собирать логи с каждой ноды. Создадим ConfigMap с конфигурацией:

apiVersion: v1
kind: ConfigMap
metadata:
  name: fluentd-config
  namespace: logging
data:
  fluent.conf: |
    
      @type tail
      path /var/log/containers/*.log
      pos_file /var/log/fluentd-containers.log.pos
      tag kubernetes.*
      format json
      time_format %Y-%m-%dT%H:%M:%S.%NZ
    
    
    
      @type kubernetes_metadata
    
    
    
      @type elasticsearch
      host elasticsearch.logging.svc.cluster.local
      port 9200
      logstash_format true
      logstash_prefix kubernetes
      buffer_chunk_limit 2M
      buffer_queue_limit 8
      flush_interval 5s
      max_retry_wait 30
      disable_retry_limit
      num_threads 2
    

Создадим DaemonSet для Fluentd:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
  namespace: logging
spec:
  selector:
    matchLabels:
      app: fluentd
  template:
    metadata:
      labels:
        app: fluentd
    spec:
      serviceAccountName: fluentd
      containers:
      - name: fluentd
        image: fluent/fluentd-kubernetes-daemonset:v1.14-debian-elasticsearch7-1
        env:
        - name: FLUENT_ELASTICSEARCH_HOST
          value: "elasticsearch.logging.svc.cluster.local"
        - name: FLUENT_ELASTICSEARCH_PORT
          value: "9200"
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
        - name: config
          mountPath: /fluentd/etc/fluent.conf
          subPath: fluent.conf
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers
      - name: config
        configMap:
          name: fluentd-config

Создадим ServiceAccount и RBAC для Fluentd:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: fluentd
  namespace: logging
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: fluentd
rules:
- apiGroups: [""]
  resources: ["pods", "namespaces"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: fluentd
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: fluentd
subjects:
- kind: ServiceAccount
  name: fluentd
  namespace: logging

Развертывание Kibana

Kibana предоставит веб-интерфейс для работы с логами. Создадим Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kibana
  namespace: logging
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kibana
  template:
    metadata:
      labels:
        app: kibana
    spec:
      containers:
      - name: kibana
        image: docker.elastic.co/kibana/kibana:7.15.0
        ports:
        - containerPort: 5601
        env:
        - name: ELASTICSEARCH_HOSTS
          value: "http://elasticsearch.logging.svc.cluster.local:9200"
        resources:
          requests:
            memory: "512Mi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "1000m"

Создадим Service для Kibana:

apiVersion: v1
kind: Service
metadata:
  name: kibana
  namespace: logging
spec:
  selector:
    app: kibana
  ports:
  - port: 5601
    targetPort: 5601
  type: LoadBalancer

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

Применим все манифесты:

kubectl apply -f fluentd-config.yaml
kubectl apply -f fluentd-rbac.yaml
kubectl apply -f fluentd-daemonset.yaml
kubectl apply -f kibana-deployment.yaml
kubectl apply -f kibana-service.yaml

Проверим статус подов:

kubectl get pods -n logging
kubectl logs -f deployment/kibana -n logging

Настройка Kibana

Получим IP адрес Kibana:

kubectl get svc kibana -n logging

Откроем браузер и перейдем по адресу. При первом запуске нужно создать index pattern:

  • Идем в Management → Index Patterns
  • Создаем паттерн: kubernetes-*
  • Выбираем поле времени: @timestamp
  • Переходим в Discover для просмотра логов

Практические примеры использования

Теперь можно эффективно искать логи по различным критериям:

Задача Запрос в Kibana Описание
Логи конкретного пода kubernetes.pod_name:”my-app-*” Все логи подов начинающихся с my-app
Ошибки в namespace kubernetes.namespace_name:”production” AND level:”ERROR” Ошибки в продакшене
Логи за последний час @timestamp:[now-1h TO now] Временной фильтр

Оптимизация производительности

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

  • Elasticsearch heap: не более 50% RAM ноды
  • Retention policy: автоматическое удаление старых индексов
  • Шардинг: оптимальное количество шардов для индексов
  • Репликация: минимум 1 реплика для отказоустойчивости

Настройка ротации индексов:

PUT _template/kubernetes-logs
{
  "index_patterns": ["kubernetes-*"],
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1,
    "index.lifecycle.name": "kubernetes-logs-policy"
  }
}

Альтернативные решения

Кроме EFK существуют другие популярные стеки:

  • ELK (Elasticsearch + Logstash + Kibana) – более тяжелый, но мощный
  • Grafana Loki – легковесная альтернатива от Grafana Labs
  • Fluentd + Grafana + Loki – современный стек для метрик и логов
  • Prometheus + Grafana + Alertmanager – больше для метрик

Сравнение ресурсопотребления:

Стек RAM (минимум) CPU Диск Сложность
EFK 3-4 GB 2-3 cores SSD рекомендуется Средняя
Loki 1-2 GB 1-2 cores Любой Низкая
ELK 4-6 GB 3-4 cores SSD обязательно Высокая

Мониторинг и алертинг

Для мониторинга самого стека логирования можно использовать Prometheus метрики:

apiVersion: v1
kind: ServiceMonitor
metadata:
  name: elasticsearch-metrics
spec:
  selector:
    matchLabels:
      app: elasticsearch
  endpoints:
  - port: metrics
    interval: 30s

Полезные метрики для мониторинга:

  • elasticsearch_cluster_health_status – статус кластера
  • elasticsearch_indices_docs_count – количество документов
  • fluentd_output_status_buffer_queue_length – длина очереди Fluentd

Интеграция с другими инструментами

EFK хорошо интегрируется с экосистемой Kubernetes:

  • Prometheus – для сбора метрик производительности
  • Jaeger – для distributed tracing
  • Helm – для упрощения развертывания
  • Istio – для логирования service mesh

Пример Helm команды для быстрой установки:

helm repo add elastic https://helm.elastic.co
helm install elasticsearch elastic/elasticsearch
helm install kibana elastic/kibana

Безопасность

Для продакшена обязательно настройте:

  • Authentication – базовая авторизация или OAuth
  • TLS – шифрование трафика между компонентами
  • Network policies – ограничение сетевого доступа
  • Role-based access – разграничение прав пользователей

Troubleshooting

Частые проблемы и их решения:

  • Fluentd не отправляет логи: проверьте доступность Elasticsearch
  • Высокое потребление памяти: уменьшите buffer_chunk_limit
  • Медленный поиск: добавьте индексы и оптимизируйте запросы
  • Потеря логов: увеличьте размер буфера и количество реплик

Полезные команды для диагностики:

kubectl logs -f daemonset/fluentd -n logging
kubectl exec -it elasticsearch-0 -n logging -- curl localhost:9200/_cluster/health
kubectl port-forward svc/kibana 5601:5601 -n logging

Заключение

Стек EFK – это мощное решение для централизованного логирования в Kubernetes. Хотя настройка может показаться сложной, результат того стоит. Вы получаете единую точку для поиска по логам всего кластера, возможность быстро находить проблемы и анализировать поведение приложений.

Для небольших проектов можно рассмотреть более легкие альтернативы типа Loki, но для энтерпрайза EFK остается золотым стандартом. Главное – правильно рассчитать ресурсы и настроить retention policy, чтобы не утонуть в терабайтах логов.

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


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

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

Leave a reply

Your email address will not be published. Required fields are marked