Исторически в монолитных архитектурах журналы были сохранены непосредственно на голых металлических или виртуальных машинах. Они никогда не покидали машину, а операционная команда проверит каждый для журналов по мере необходимости.
Это работало на долгоживущих машинах, но машины в облаке являются эфемерными. По мере того, как все больше компаний управляют своими услугами по контейнерам и развертыванию оружия с помощью Kubernetes, журналы больше не могут храниться на машинах и реализация стратегии управления журналом имеет первостепенное значение.
Журналы являются эффективным способом отладки и мониторинга ваших приложений, и они должны храниться на отдельной бэкэнде, где они могут быть запрошены и проанализированы в случае сбоев POD или узла. Эти отдельные брюки включают в себя такие системы, как Elasticsearch, Stackdriver GCP и CloudWatch AWS.
Хранение журналов выключения кластера в бэкэнде хранения называется журналом уровня кластера. В этой статье мы обсудим, как реализовать этот подход в ваших собственных кластере Kubernetes.
Регистрация архитектур
В кластере Kubernetes есть два основных источника журнала, ваше приложение и компоненты системы.
Ваше приложение запускается как контейнер в кластере Kubernetes, и время выполнения контейнера позаботится о том, чтобы выбрать журналы вашего приложения, когда Docker перенаправляет эти журналы к потокам Stdout и STDERR. В кластере Kubernetes оба этих потока записываются в файл JSON на узле кластера.
Эти журналы контейнеров могут быть извлечены в любое время со следующей командой:
kubectl logs podname
Другой источник журналов — это компоненты системы. Некоторые из компонентов системы (а именно Kube-планировщик
и Kube-Proxy
) Запустите в качестве контейнеров и следуйте тому же принципам регистрации в качестве приложения.
Другие компоненты системы ( kublet
и Контейнерное время выполнения
сам) беги как родной сервис. Если Systemd
Доступен на машине, компоненты пишут журналы в журнал
иначе они пишут .Log
Файл в /var/log
каталог.
Теперь, когда мы понимаем, какие компоненты вашего приложения и кластера генерируют журналы и где они хранятся, давайте посмотрим на некоторые общие шаблоны для разгрузки этих журналов в отдельные системы хранения.
Шаблоны регистрации
Два самых выдающихся шаблонов для сбора журналов сбора являются шаблон для колеса и рисунок Daemonset.
1. Daemonset Pattern
В рисунке Daemonset ведется ведение ведения лесозаготовительных агентов, в качестве стручков через ресурс Daemonset в Куберане. Развертывание DAEMONSET гарантирует, что каждый узел в кластере имеет один POD с помощью вегетационного агента. Этот регистрационный агент настроен для чтения журналов из /var/logs
каталог и отправьте их на хранилище. Вы можете увидеть диаграмму этой конфигурации на рисунке 1.
Рисунок 1: Регистрационный агент работает на узел через DAEMONSET
2. Узор для колеса
В качестве альтернативы, в шаблоне Sidecar выделенный контейнер проходит вдоль каждого контейнера прикладного в том же POD. Этот кодарь может быть двух типов, потоковых сторонника или ведения журнала агента.
Потоковое Sidecar используется, когда вы используете приложение, которое записывает журналы в файл вместо потоков STDOUT/STDERR, или тот, который записывает журналы нестандартным форматом. В этом случае вы можете использовать трансляционный контейнер Sidecar для публикации журналов из файла в свой собственный поток STDOUT/STDERR, который затем может быть подхвачен самим Kubernetes.
Потоковая кодарь может также принести четность к структуре журнала, преобразовав сообщения журнала в стандартный формат журнала. Вы можете увидеть этот шаблон на рисунке 2.
Фигура 2: Потоковое тебовое узор
Другой подход — это ведение журнала агента, где сама Sidecar отправляет журналы на бэкэнд хранения. Каждый POD содержит ведущий журнал, такой как FluentD или FileBeat, который захватывает журналы из контейнера приложения и отправляет их непосредственно на бэкэнд хранения, как показано на рисунке 3.
Рисунок 3: Регистрационный агент для колеса
Плюсы и минусы
Теперь, когда мы отправились как по подходам Daemonset, так и на стороне, давайте познакомимся с плюсами и минусами каждого.
1. Daemonset (уровень узла)
Плюс
Регистрация уровня узла легче реализовать, поскольку он подключается к существующему журналу на основе файлов и является менее ресурсом интенсивным, чем подход для Sidecar, так как находятся меньше контейнеров.
Журналы доступны через команду kubectl для отладки, поскольку файлы журнала доступны для Kubelet, который возвращает содержимое файла журнала.
Господин
Менее гибкость в поддержке различных структур журнала или приложений, которые записывают файлы журнала вместо потоков. Вам нужно будет изменить структуру журнала приложений для достижения четности или обрабатывать разницу в вашем бэкене хранения.
Поскольку они хранятся как файлы JSON на узле-диске, журналы не могут быть проведены навсегда. Вы должны иметь механизм вращения журнала на месте для переработки старых журналов. Если вы используете интерфейс выполнения контейнера, Kubelet позаботится о вращении журналов, и не нужно реализовать явный раствор.
2. Сидячий
Плюс
У вас есть гибкость для настройки боковых кредитов на контейнер приложений. Например, приложение не может иметь возможность писать на
Stdout/Stderr
или у него может быть какой-то другой формат ведения журнала. В этих случаях контейнер Sidecar может принести четность к системе.Если вы используете боковочный агент Sidecar без потоковой передачи, вам не нужно поворачивать журналы, потому что на узле диска не нужно вращать журналы.
Господин
Запуск SideCar для каждого контейнера прикладного прикладного является вполне ресурсоемким, по сравнению с стручками уровня узла.
Добавление коляска на каждое развертывание создает дополнительный слой сложности.
Если вы используете потоковую Sidecar для приложения, который пишет свои журналы к файлам, вы будете использовать двойное хранилище для тех же журналов, потому что вы будете дублировать записи.
Если вы используете боковочный агент Sidecar без потоковой передачи, вы потеряете возможность доступа к журналам через
kubectl
Отказ Это потому, чтоКублет
больше не имеет доступа к журналам JSON.С помощью боковочного агента Sidecar вам также нужен агент на уровне узла, в противном случае вы не сможете собрать журналы компонентов системы.
Положить теорию на практику
Теперь, когда мы смотрели на возможные шаблоны для входа в кластер Kubernetes, давайте привели их в действие. Мы развертываем гаммы-контейнеры, генерирующие журналы и создайте ресурсы Kubernetes для реализации шаблонов регистрации, которые мы обсуждали выше.
Для этого примера мы будем использовать Fluentd в качестве ведомого агента, и мы устанавливаем Elasticsearch для регистрации Backend и Kibana для целей визуализации. Мы устанавливаем Elasticsearch и Kibana, используя Helm Charts в тот же кластер. Обратите внимание, однако, что ваш бэкэнд хранения не должен быть в том же кластере, и мы делаем это только для демонстрационных целей. Благодаря подключаемой архитектуре Fluentd она поддерживает различные разные раковины. Вот почему бэкэнда Elasticsearch может быть заменена любым облачным нативным решением, включая StackDriver или CloudWatch.
1. Установка Elasticsearch и Kibana
Мы развертываем Elasticsearch и Kibana, используя официальные хелмы, которые можно найти здесь ( Elasticsearch , Kibana ). Для установки через HELM вам понадобится бинарный шлем на вашем пути, но установка HELM находится за пределами объема этого поста.
Давайте начнем с добавления Helm Repos.
helm repo add elastic https://helm.elastic.co
Далее мы устанавливаем Elasticsearch и Cibana Charts в наш кластер.
helm install elasticsearch elastic/elasticsearch helm install kibana elastic/kibana
Это установит последнюю версию Elasticsearch и Kibana в вашем кластере, который затем можно использовать в качестве хранилища для ваших журналов.
Мы использовали значения по умолчанию на наших графиках, но вы можете изменить любой параметр на основе ваших потребностей, когда вы устанавливаете это в производстве.
2. Daemonset.
Мы будем развертывать свободные в качестве DAEMONSET. Держать слабость низкого, мы не будем создавать отдельный сервоприятный и кластерроль. Но в производственной среде FLUENTD PODS должен работать с отдельной учетной записью услуг с ограниченным доступом.
Вы можете развернуть FluentD в качестве DAEMONESE, используя после ресурса Kubernetes:
apiVersion: extensions/v1beta1 kind: DaemonSet metadata: name: fluentd namespace: kube-system labels: k8s-app: fluentd-logger spec: template: metadata: labels: k8s-app: fluentd-logger spec: containers: - name: fluentd image: fluent/fluentd-kubernetes-daemonset:elasticsearch env: - name: FLUENT\_ELASTICSEARCH\_HOST value: "elasticsearch-master" - name: FLUENT\_ELASTICSEARCH\_PORT value: "9200" volumeMounts: - name: varlog mountPath: /var/log - name: dockerlogs mountPath: /var/lib/docker/containers readOnly: true volumes: - name: varlog hostPath: path: /var/log - name: dockerlogs hostPath: path: /var/lib/docker/containers
В этом примере мы устанавливаем два тома: один в /var/log
И другой в /var/log/docker/контейнеры
, где компоненты системы и Docker Runtime помещают журналы соответственно.
Изображение, которое мы используем, уже настроено с помощью смартфонов, которые будут использоваться с Daemonset, но Вы можете изменить конфигурацию Отказ
Сохраните вышеуказанные ресурсы YAML в файле с именем Fluentdd-ds.yaml
и применить ресурс через следующую команду:
kubectl apply -f fluentd-ds.yaml
Это начнет FluentD POD на каждом узле в кластере Kubernetes.
Теперь мы увидим, как реализовать потоковую и регистрацию боковых моделей агента.
3. Сидячий
Во-первых, давайте посмотрим на потоковый шаблон Sidecar, когда ваше приложение записывает журналы в файл вместо потока. Мы управляем SideCar, чтобы прочитать эти журналы и записывать его обратно в поток STDOUT/STDERR.
apiVersion: v1 kind: Pod metadata: name: my-app spec: containers: - name: legacy-app image: busybox args: - /bin/sh - -c - > i=0; while true; do echo "$i: $(date)" >> /var/log/output.log; i=$((i+1)); sleep 1; done volumeMounts: - name: varlog mountPath: /var/log - name: streaming-sidecar image: busybox args: \[/bin/sh, -c, 'tail -n+1 -f /var/log/output.log'\] volumeMounts: - name: varlog mountPath: /var/log volumes: - name: varlog emptyDir: {}
В этом примере у нас есть фиктивные журналы записи контейнера для файлов в /var/log
каталог контейнера. Теперь эти журналы не могут быть извлечены в течение времени выполнения контейнера, поэтому мы реализовали потоковую коляску для хвоста в журналы из /var/log
Расположение и перенаправить его к stdout
ручей.
Этот поток журнала будет поднят временем выполнения контейнера и сохранен в виде файла JSON в /var/log
Справочник на узле, который в свою очередь будет подхвачен средством ведения журнала узла.
Теперь давайте посмотрим на ведение журнала агента. В этом шаблоне мы развертываем Fleentd в качестве Sidecar, который будет напрямую писать на нашу elasticsearch Storage Backend.
К сожалению, нет предварительного произвольного изображения с установленным плагином Elasticsearch, а создание пользовательского образа докера выходит из объема этой статьи. Вместо этого мы будем использовать одно и то же Fluentd Image, которое мы использовали в примере Daemonset.
apiVersion: v1 kind: Pod metadata: name: my-app spec: containers: - name: count image: busybox args: - /bin/sh - -c - > i=0; while true; do echo "$i: $(date)" >> /var/log/output.log; i=$((i+1)); sleep 1; done volumeMounts: - name: varlog mountPath: /var/log - name: logging-agent image: fluent/fluentd-kubernetes-daemonset:elasticsearch env: - name: FLUENT\_ELASTICSEARCH\_HOST value: "elastisearch-master" - name: FLUENT\_ELASTICSEARCH\_PORT value: "9200" volumeMounts: - name: varlog mountPath: /var/log volumes: - name: varlog emptyDir: {}
Вывод
Учитывая эфемерную природу стручков и узлов, очень важно хранить журналы из ваших кластеров Kubernetes в отдельном хранилище. Есть несколько шаблонов, которые вы можете использовать для настройки архитектуры регистрации, которую мы обсуждали в этой статье.
Обратите внимание, что мы предлагаем смесь обоих моделей Sidecar, так и узел узел для ваших производственных систем. Это включает в себя создание кластеров, шириной узла, используя шаблон на уровне DAEMONSE, и реализация потокового контейнера Sidecar для приложений, которые не поддерживают журналы записи для потока ( stdout/STDERR
) Или что не пишут в Стандартный формат журнала. Этот потоковый контейнер автоматически наследует журналы для поднятия агентов по узел.
Для выбора бэкэнда хранилища вы можете выбрать самих размещенных, таких решений с открытым исходным кодом, таким как elasticsearch, или вы можете пойти на управляемый сервис, или вы можете пойти на управляемый сервис с вариантами, такими как облачный Elasticsearch, StackDriver или CloudWatch. Выбор бэкэнда, который подходит для вас, будет зависеть от требований к анализу затрат, запросов и журналов, которые вы хотите реализовать с вашей архитектурой.
Для наших последних идей и обновлений Следуйте за нами на LinkedIn
Оригинал: «https://dev.to/coder_society/kubernetes-logging-in-production-1ld3»