Как стать автором
Обновить
VK
Технологии, которые объединяют

Как настроить хранение логов кластера Kubernetes в бакете S3 и зачем это нужно

Время на прочтение13 мин
Количество просмотров5.4K

Стандартный способ хранения логов Kubernetes на ноде неудобен: память ограничена, данные разбросаны, а многие аналитические инструменты просто не получится применять. Чтобы сделать хранение и работу с логами удобнее для разработки аналитических инструментов, логи можно перенести в бакет объектного хранилища S3.

Меня зовут Илья Нырков, я программист компании VK Cloud Solutions и разработчик облачных решений. На примере нашего облака я расскажу, почему вообще стоит обратить внимание на S3, как перенести и хранить логи кластера Kubernetes в бакет S3 и в чем преимущество этого решения.

Зачем в K8s нужно централизованное хранение логов 

По умолчанию в Kubernetes логи хранятся на отдельных нодах. Для небольших проектов с низкой нагрузкой и редким обновлением этот вариант оптимален. Но из-за базовых ограничений памяти ноды он не подходит для больших систем с огромным количеством логом. Кроме того:

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

  • Ротация логов в контейнере — дополнительный процесс. Чтобы запустить в контейнере больше одного процесса, нужен «костыль» в виде Supervisor. Но такое решение нарушает философию Docker: «1 контейнер — 1 процесс».

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

Почему именно S3

S3 — распространенный стандарт хранилищ. Он подходит для больших объемов информации, может работать с любыми ее типами. То есть в S3 можно структурированно хранить практически неограниченное количество логов.

Еще одно его преимущество в совместимости с большинством приложений для аналитики больших данных, например со Spark, ClickHouse и Greenplum. Также в объектном хранилище можно организовать доступ к логам через сервис на базе EFK (Elasticsearch, Fluentd, Kibana) для просмотра информации в виде дашбордов и графиков. Это упрощает работу с большими данными и нахождение зависимостей.

Дополнительное достоинство S3 заключается в гибкости конфигурирования: можно взять любую из многочисленных готовых конфигураций S3 и легко адаптировать под свою «железную» или облачную инфраструктуру. Это позволяет быстро собирать нужные конфигурации без сложной перенастройки.

А еще после переноса логов в бакет S3 они начинают храниться отдельно от ноды. Это повышает надежность: даже если нода упадет, логи сохранятся. Но важно исключить риски отключения ноды от сети — в таком случае логи в S3 не запишутся.

Как настроить отправку логов кластера Kubernetes в бакет S3: пошаговая инструкция

Подробно рассмотрим все действия на примере S3 VK Cloud Solutions (Cloud Storage). Для справки: все описанные команды выполняются в консоли Linux (bash).

  1. Регистрируемся на платформе VK Cloud Solutions. После входа в «Личный кабинет» нужно зайти в «Личный проект» или получить приглашение и перейти в проект другого пользователя.

  2. Создаем виртуальную машину (ВМ) в облаке VK Cloud Solutions. Сделать это можно через соответствующий раздел интерфейса облака. При создании ВМ выбираем нужные параметры, в том числе подходящую под задачи операционную систему (ОС). При этом важно, чтобы на образ ОС можно было установить kubectl и Helm. Для примера берем Ubuntu 20.04.1.

    Примечание: пункт необязательный — эти действия можно выполнить с обычной машиной на Linux.
    Примечание: пункт необязательный — эти действия можно выполнить с обычной машиной на Linux.
  3. Настраиваем сеть виртуальной машины. Главное на этом этапе — указать настройки Firewall. Default стоит по умолчанию, дополнительно прописываем правило «ssh + www»: оно позволяет получать доступ к SSH, а также открывает порты ВМ для получения по протоколам HTTP и HTTPS.

Настройки резервного копирования не изменяем, для примера они не имеют значения.

Примечание: пункт необязательный — эти действия можно выполнить с обычной машиной на Linux.

  1. Создаем простой кластер Kubernetes. Используем соответствующий раздел облака. При создании выбираем нужную конфигурацию и набор предустановленных сервисов.

Остальные шаги создания кластера можем пропустить.

  1. Скачиваем конфигурационный файл кластера. Для этого через меню «Личного кабинета» переходим во вкладку «Контейнеры» и раздел «Кластеры Kubernetes».

Выбираем созданный кластер и в разделе «Общие данные» скачиваем файл.

  1. Через консоль Linux (bash) отправляем скачанный файл в ранее созданную ВМ.

  1. Устанавливаем kubectl на ВМ (если не установлен ранее). Используем команды:

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

После этого проверяем, установился ли kubectl:

kubectl version --client

  1. Устанавливаем на виртуальную машину Helm (если не установлен ранее):

curl -L https://git.io/get_helm.sh | bash

  1. Подключаемся к кластеру Kubernetes через ВМ:

export KUBECONFIG=<название файла конфигурации кластера>

Проверяем подключение:

kubectl config current-context

  1. Устанавливаем Tiller (если не установлен ранее). Сначала создаем Kubernetes Account для Tiller:

kubectl --namespace kube-system create serviceaccount tiller

kubectl --namespace kube-system create clusterrolebinding tiller-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:tiller

Устанавливаем Tiller:

helm init

kubectl --namespace kube-system patch deploy tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'

Проверяем правильность установки: 

helm list

Если ошибок нет, Tiller установлен корректно.

  1. Создаем бакет S3. Делаем это через интерфейс облака в «Личном кабинете». В классе хранения выбираем тип — горячее или холодное. Icebox — трафик дороже, но хранение дешевле. Подходит для ситуаций, когда записывается много логов, но обращаются к ним редко. Hotbox — дешевый трафик, хранение дороже. Оптимален, когда к логам обращаются часто.

Следом создаем ключ для доступа к бакету.

  1. Запускаем под с fluent-bit. В консоли Linux создаем файл с названием fluent-bit-fd-values-2.8.11.yaml со следующим содержимым: 

Код

# если запускаем на minikube

on_minikube: false

image:

  fluent_bit:

    repository: fluent/fluent-bit

    tag: 1.3.7

  pullPolicy: Always

testFramework:

  image: "dduportal/bats"

  tag: "0.4.0"

nameOverride: ""

fullnameOverride: ""

metrics:

  enabled: false

  service:

    annotations: {}

    port: 2020

    type: ClusterIP

  serviceMonitor:

    enabled: false

    additionalLabels: {}

    

trackOffsets: false

priorityClassName: ""

backend:

  type: forward 

  forward:

    host: fluentd-es-s3 # имя пода с fluentd, можно получить командой: kubectl get svc

    port: 24224 # порт пода с fluentd

    tls: "off"

    tls_verify: "on"

    tls_debug: 1

    shared_key:

  es:

    host: elasticsearch

    port: 9200

    # Elastic Index Name

    index: kubernetes_cluster

    type: flb_type

    logstash_prefix: kubernetes_cluster

    replace_dots: "On"

    logstash_format: "On"

    retry_limit: "False"

    time_key: "@timestamp"

    http_user:

    http_passwd:

    tls: "off"

    tls_verify: "on"

    tls_ca: ""

    tls_debug: 1

  splunk:

    host: 127.0.0.1

    port: 8088

    token: ""

    send_raw: "on"

    tls: "on"

    tls_verify: "off"

    tls_debug: 1

    message_key: "kubernetes"

  stackdriver: {}

  http:

    host: 127.0.0.1

    port: 80

    uri: "/"

    http_user:

    http_passwd:

    tls: "off"

    tls_verify: "on"

    tls_debug: 1

    format: msgpack

    headers: []

parsers:

  enabled: false

  regex: []

  logfmt: []

  json: []

env: []

podAnnotations: {}

fullConfigMap: false

existingConfigMap: ""

rawConfig: |-

  @INCLUDE fluent-bit-service.conf

  @INCLUDE fluent-bit-input.conf

  @INCLUDE fluent-bit-filter.conf

  @INCLUDE fluent-bit-output.conf

extraEntries:

  input: |-

  audit: |-

  filter: |-

  output: |-

extraPorts: []

extraVolumes: []

extraVolumeMounts: []

resources: {}

hostNetwork: false

dnsPolicy: ClusterFirst

tolerations: []

nodeSelector: {}

affinity: {}

service:

  flush: 1

  logLevel: info

input:

  tail:

    memBufLimit: 5MB

    parser: docker

    path: /var/log/containers/*.log

    ignore_older: ""

  systemd:

    enabled: false

    filters:

      systemdUnit:

        - docker.service

        - kubelet.service

        - node-problem-detector.service

    maxEntries: 1000

    readFromTail: true

    stripUnderscores: false

    tag: host.*

audit:

  enable: false

  input:

    memBufLimit: 35MB

    parser: docker

    tag: audit.*

    path: /var/log/kube-apiserver-audit.log

    bufferChunkSize: 2MB

    bufferMaxSize: 10MB

    skipLongLines: On

    key: kubernetes-audit

filter:

  kubeURL: https://kubernetes.default.svc:443

  kubeCAFile: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

  kubeTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token

  kubeTag: kube

  kubeTagPrefix: kube.var.log.containers.

  mergeJSONLog: true

  mergeLogKey: ""

  enableParser: true

  enableExclude: true

  useJournal: false

rbac:

  create: true

  pspEnabled: false

taildb:

  directory: /var/lib/fluent-bit

serviceAccount:

  create: true

  annotations: {}

  name:

securityContext: {}

podSecurityContext: {}

После создания файла выполняем команду:

helm install --name fluent-bit stable/fluent-bit --version 2.8.11 -f fluent-bit-fd-values-2.8.11.yaml

  1. Запускаем под с fluentd. Создаем файл fluentd-es-s3-values-2.3.2.yaml со следующим содержимым:

Код

replicaCount: 1

image:

  repository: gcr.io/google-containers/fluentd-elasticsearch

  tag: v2.4.0

  pullPolicy: IfNotPresent

host: elasticsearch-client.logging

  port: 9200

  scheme: http

  sslVersion: TLSv1

  buffer_chunk_limit: 2M

  buffer_queue_limit: 8

env: {}

extraEnvVars:

plugins:

  enabled: true

  pluginsList: 

    - fluent-plugin-s3

    - fluent-plugin-rewrite-tag-filter

service:

  annotations: {}

  type: ClusterIP

  ports:

    - name: "monitor-agent"

      protocol: TCP

      containerPort: 24220

    - name: "forward"  

      protocol: TCP

      containerPort: 24224

metrics:

  enabled: false

  service:

    port: 24231

  serviceMonitor:

    enabled: false

    additionalLabels: {}

annotations: {}

ingress:

  enabled: false

  annotations:

    kubernetes.io/ingress.class: nginx

  labels: []

  hosts:

  tls: {}

configMaps:

  general.conf: |

    <match fluentd.**>

      @type null

    </match>

    # Used for health checking

    <source>

      @type http

      port 9880

      bind 0.0.0.0

    </source>

    <source>

      @type monitor_agent

      bind 0.0.0.0

      port 24220

      tag fluentd.monitor.metrics

    </source>

  system.conf: |-

    <system>

      root_dir /tmp/fluentd-buffers/

    </system>

  forward-input.conf: |

    <source>

      @type forward

      port 24224

      bind 0.0.0.0

    </source>

  output.conf: |

    <filter kube.**>

       @type record_transformer

       enable_ruby

       <record>

         kubernetes_tag ${"%s" % [record["kubernetes"]["labels"]["app"] || record["kubernetes"]["labels"]["k8s-app"] || record["kubernetes"]["labels"]["name"] || "unspecified-app-label"]}

       </record>

    </filter>

    <match kube.**>

       @type rewrite_tag_filter

       <rule>

         key     kubernetes_tag

         pattern ^(.+)$

         tag     $1

       </rule>

    </match>

    <match **>

       @type s3

       aws_key_id # Access Key ID из ключа к бакету который мы создали ранее

       aws_sec_key # Secret Key ID из ключа к бакету который мы создали ранее

       s3_bucket fluentd-instruction-test # название созданного бакета

       s3_endpoint https://hb.bizmrg.com # url s3 облака vkcs

       s3_object_key_format "${tag}/%{time_slice}-events_%{index}.%{file_extension}"

       time_slice_format %Y/%m/%d/%H

       time_slice_wait 10m

       path test-logs

      

       <buffer tag,time>

         @type file

         flush_mode interval

         flush_interval 30s

         path /var/log/fluent/s3

         timekey 300 # 1 hour partition

         timekey_wait 1m

         timekey_use_utc true # use utc

         chunk_limit_size 100m

       </buffer>

       <format>

         @type json

       </format>

    </match>

    

resources: 

  limits:

    cpu: 500m

    memory: 512Mi

  requests:

    cpu: 500m

    memory: 512Mi  

rbac:

  create: false

serviceAccount:

  create: true

  name:

persistence:

  enabled: false

  accessMode: ReadWriteOnce

  size: 10Gi

nodeSelector: {}

tolerations: []

affinity: {}

autoscaling:

  enabled: false

  minReplicas: 2

  maxReplicas: 5

  metrics:

    - type: Resource

      resource:

        name: cpu

        target:

          type: Utilization

          averageUtilization: 90

    - type: Resource

      resource:

        name: memory

        target:

          type: Utilization

          averageUtilization: 80

terminationGracePeriodSeconds: 30

В полях aws_key_id, aws_sec_key, s3_bucket подставляем свои значения. После создания файла выполняем команду:

helm install --name fluentd-es-s3 stable/fluentd --version 2.3.2 -f fluentd-es-s3-values-2.3.2.yaml

После этого все новые логи будут появляться в S3.

На этом настройка завершена.

Что дает хранение логов в S3-хранилище 

Повышается безопасность хранения. В облаке VK Cloud Solutions объектное хранилище S3 выделено в отдельный сервис с собственной технической поддержкой и механизмами бэкапов. Уровень доступности данных — 99,95 %. Надежность хранения данных — 99,99999 %. Логи не потеряются и всегда будут доступны.

Масштабируемость. Перенос в бакет S3 позволяет не ограничиваться объемом памяти на ноде, где запущено приложение. В Cloud Storage объем архитектурно практически не ограничен, хранилище масштабируется вместе с данными.

Появляется возможность комбинированного хранения. S3 от VK Cloud Solutions позволяет организовать как горячее, так и холодное хранение данных. Холодное хранение подойдет, когда логов пишется много, а запросы к ним редкие. Горячее — когда к логам обращаются часто. Кроме того, часть логов можно хранить в сжатом виде: это позволяет экономить, поскольку тарификация в S3 идет по объему хранимых файлов. 

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

Таким образом, S3 можно комбинировать с другими типами хранилищ — например, хранить логи за последний месяц в Elasticsearch, а в S3 — за последние 6 месяцев.  

Создается единое хранилище логов. По умолчанию логи разбросаны по разным нодам, их сложно собирать и обрабатывать. При переносе в S3 все логи «складываются» в один бакет, поэтому работать с единым хранилищем удобнее.

Что в итоге

  1. Стандартный способ хранения логов на ноде неудобен: память ограничена, данные разбросаны, а многие инструменты для аналитики несовместимы. 

  2. S3-объектные хранилища отлично подходят для хранения логов: в них можно хранить практически неограниченный объем данных и работать с любыми типами информации. Кроме того, S3 совместимы с большинством приложений для аналитики больших данных и позволяют организовать доступ к логам через сервис на основе EFK.

  3. Можно быстро настроить отправку логов кластера Kubernetes в бакет. Задача упрощена тем, что, например, через пользовательский интерфейс S3 VK Cloud Solutions (Cloud Storage) весь процесс можно выполнить без сложного программирования и конфигурирования.

  4. Перенос логов в бакет S3 VK Cloud Solutions (Cloud Storage) позволяет создать безопасное единое хранилище с неограниченным объемом и возможностью комбинирования способов хранения.

Вы можете попробовать наше объектное хранилище Cloud Storage. Для тестирования мы начисляем пользователям при регистрации 3000 бонусных рублей.

Что еще почитать:

Теги:
Хабы:
+23
Комментарии7

Публикации

Информация

Сайт
team.vk.company
Дата регистрации
Дата основания
Численность
свыше 10 000 человек
Местоположение
Россия
Представитель
Руслан Дзасохов