Постепенно эволюционируя, каждая организация переходит от ручного grep логов к более современным инструментам для сбора, анализа логов. Если вы работаете с kubernetes, где приложение может масштабироваться горизонтально и вертикально, вас просто вынуждают отказаться от старой парадигмы сбора логов. В текущее время существует большое количество вариантов систем централизованного логирования, причем каждый выбирает наиболее приемлемый вариант для себя. В данной статье пойдет речь о наиболее популярном и зарекомендовавшем себя стэке Elasticsearch + Kibana + Fluentd в связке с плагином OpenDistro Security. Данный стэк полностью open source, что придает ему особую популярность.
Нам необходимо было наладить сборку логов с кластера kubernetes. Из требований:
Использовать только открытые решения.
Сделать очистку логов.
Необходимо прикрутить LDAP, для разграничения прав.
Пререквизиты
Данный материал предполагает:
Имеется установленный kuberenetes 1.18 или выше (ниже версию не проверяли)
Установленный пакетный менеджер helm 3
Наиболее популярным способом установки приложения в kubernetes является helm. Helm это пакетный менеджер, с помощью которого можно подготовить набор компонентов для установки и связать их вместe, дополнив необходимыми метриками и конфигурацией.
В своей практике мы используем helm chart от компании bitnami(подразделение vmware)
собраны open source продукты на все случаи жизни.
корпоративные стандарты по разработке чатов и докер образов
красивая документация
проект живой и активно поддерживается сообществом
Во многом выбор стека технологий определило время. С большой долей вероятностью два года назад мы бы деплоили ELK стек вместо EFK и не использовали helm chart.
Fluentd часто упоминается в документации, широко распространен, имеет большое количество плагинов, на все случаи жизни. К тому же у нас есть человек, который после обучение в rebrain и очень хотел внедрить fluentd.
Elasticsearch и kibana поставляются с открытой лицензией, однако плагины для security и других вкусностей идут под иной лицензией. Однако компания Amazon выпустила плагины Open Distro, которые покрывают оставшийся функционал под открытой лицензией.
Схема выглядит примерно так
Хорошим тоном является вынесение инфраструктурных компонентов в отдельный кластер, поэтому зеленым прямоугольником выделена та часть, которая должна быть установлена на все кластера в которых должны собираться логи.
Сборка EFK стека была произведена по статье Collect and Analyze Log Data for a Kubernetes Cluster with Bitnami’s Elasticsearch, Fluentd and Kibana Charts. Компоменты упакованы в отдельный чат. Исходники можно взять здесь и произвести командой
helm dependency update
helm upgrade --install efk . -f values-minimal.yaml
Из исходников values-minimal.yaml
elasticsearch:
volumePermissions:
enabled: true
kibana:
volumePermissions:
enabled: true
elasticsearch:
hosts:
- "efk-elasticsearch-coordinating-only"
port: 9200
# Пропишите свой хост, если используете ингресс
ingress:
enabled: true
hostname: kibana.local
# Либо
service:
type: NodePort
port: 30010
fluentd:
aggregator:
enabled: true
configMap: elasticsearch-output
extraEnv:
- name: ELASTICSEARCH_HOST
value: "efk-elasticsearch-coordinating-only"
- name: ELASTICSEARCH_PORT
value: "9200"
forwarder:
# Чтение логов с диска /var/log/containers/* отключено
enabled: false
configMap: apache-log-parser
extraEnv:
- name: FLUENTD_DAEMON_USER
value: root
- name: FLUENTD_DAEMON_GROUP
value: root
Кибана будет доступна по адресу http://minikube_host:30010/, либо http://kibana.local.
Как видим компонент fluentd forwarder не включен. Перед включением парсинга, я рекомендовал бы настроить на определенные логи, иначе еластику может быть послано слишком большое количество логов. Правила для парсинга описаны в файле apache-log-parser.yaml.
Существует много способов, для начала предлагаем либо включить fluentd forwarder, либо воспользоваться простейшим приложением на python. Ниже пример для bare metal. Исправьте FLUENT_HOST FLUENT_PORT на ваши значения.
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld
labels:
app: helloworld
spec:
replicas: 1
template:
metadata:
name: helloworld
labels:
app: helloworld
spec:
containers:
- name: helloworld
image: sergbs/django-hello-world:1
imagePullPolicy: Always
ports:
- containerPort: 8000
env:
- name: FLUENT_HOST
value: "efk-fluentd-headless"
- name: FLUENT_PORT
value: "24224"
selector:
matchLabels:
app: helloworld
---
apiVersion: v1
kind: Service
metadata:
name: helloworld
spec:
selector:
app: helloworld
ports:
- port: 8000
nodePort: 30011
type: NodePort
EOF
По ссылке http://minikube_host:30011/ Будет выведено “Hello, world!” И лог уйдет в elastic
Пример
Включить fluentd forwarder, он создаст daemon set, т.е. запустится на каждой ноде вашего кубернетеса и будет читать логи docker container-ов.
Добавить в ваш докер контейнер драйвер fluentd, тем более можно добавлять более одного драйвера
Добавить в ваше приложение библиотеку, которая будет напрямую логировать. Пример приложения на python. Используйте его, как отладочное средство при установке EFK.
И как показывает практика, логировать напрямую эффективный, но далеко не самый надежный способ. Даже если вы логируете сразу в fluentd и в консоль. В случае потери конекта, во fluentd часть логов просто не смогут попасть и будут потеряны для него навсегда. Поэтому наиболее надежный способ, это считывать логи с диска для отправки в EFK.
Для очистки логов используется curator. Его можно включить, добавив в yaml файл:
elasticsearch:
curator:
enabled: true
По умолчанию его конфигурация уже предусматривает удаление через индекса старше 90 дней это можно увидеть внутри подчата efk/charts/elasticsearch-12.6.1.tgz!/elasticsearch/values.yaml
configMaps:
# Delete indices older than 90 days
action_file_yml: |-
...
unit: days
unit_count: 90
Как обычно security доставляет основную боль при настройке и использовании. Но если ваша организация чуть подросла, это необходимый шаг. Стандартом де факто при настройке безопасности является интеграция с LDAP. Официальные плагины от еластика выходят не под открытой лицензией, поэтому приходится использовать плагин Open Distro. Далее продемонстрируем, как его можно запустить.
Сборка elasticsearch c плагином opendistro
Вот проект в котором собирали docker images.
Для установки плагина, необходимо, чтобы версия elasticsearch соответствовала версии плагина.
В quickstart плагина рекомендуется установить install_demo_configuration.sh с демо сертификатами.
FROM bitnami/elasticsearch:7.10.0
RUN elasticsearch-plugin install -b https://d3g5vo6xdbdb9a.cloudfront.net/downloads/elasticsearch-plugins/opendistro-security/opendistro_security-1.12.0.0.zip
RUN touch /opt/bitnami/elasticsearch/config/elasticsearch.yml
USER root
RUN /bin/bash /opt/bitnami/elasticsearch/plugins/opendistro_security/tools/install_demo_configuration.sh -y -i
RUN mv /opt/bitnami/elasticsearch/config/elasticsearch.yml /opt/bitnami/elasticsearch/config/my_elasticsearch.yml
COPY my_elasticsearch.yml /opt/bitnami/elasticsearch/config/my_elasticsearch.yml
USER 1001
Есть небольшая магия, ввиду, того что плагин дополняет elasticsearch.yml, а контейнеры bitnami только при старте генерируют этот файл. Дополнительные же настройки они просят передавать через my_elasticsearch.yml
В my_elasticsearch.yml мы изменили настройку, это позволит нам обращаться к рестам elasticsearch по http.
# turn off REST layer
tlsopendistro_security.ssl.http.enabled: false
Сделано это в демонстрационных целях, для облегчения запуска плагина. Если вы захотите включить Rest Layer tls придется добавлять соответствующие настройки во все компоненты, которые общаются с elasticsearch.
Запуск docker-compose с LDAP интеграцией
Запустим проект с помощью docker-compose up
, и залогинимся на http://0:5601 под admin/admin
Теперь у нас есть вкладка Security
Можно посмотреть настройку LDAP через интерфейс кибаны
Настройки должны совпадать с файлами конфигурации. Стоит обратить внимание, что плагин хранит свои данные в индексе еластика, и файлы конфигурации применяет при инициализации, т.е. если индекс не создан. Если вы измените файлы позже то вам придется воспользоваться утилитой securityadmin.sh
docker exec -it elasticsearch /bin/bash
I have no name!@68ac2255bb85:/$ ./securityadmin_demo.sh
Open Distro Security Admin v7
Will connect to localhost:9300 ... done
Connected as CN=kirk,OU=client,O=client,L=test,C=de
Elasticsearch Version: 7.10.0
Open Distro Security Version: 1.12.0.0
Contacting elasticsearch cluster 'elasticsearch' and wait for YELLOW clusterstate ...
Clustername: elasticsearch
Clusterstate: YELLOW
Number of nodes: 1
Number of data nodes: 1
.opendistro_security index already exists, so we do not need to create one.
Populate config from /opt/bitnami/elasticsearch/plugins/opendistro_security/securityconfig/
Will update '_doc/config' with /opt/bitnami/elasticsearch/plugins/opendistro_security/securityconfig/config.yml
SUCC: Configuration for 'config' created or updated
Will update '_doc/roles' with /opt/bitnami/elasticsearch/plugins/opendistro_security/securityconfig/roles.yml
SUCC: Configuration for 'roles' created or updated
Will update '_doc/rolesmapping' with /opt/bitnami/elasticsearch/plugins/opendistro_security/securityconfig/roles_mapping.yml
SUCC: Configuration for 'rolesmapping' created or updated
Will update '_doc/internalusers' with /opt/bitnami/elasticsearch/plugins/opendistro_security/securityconfig/internal_users.yml
SUCC: Configuration for 'internalusers' created or updated
Will update '_doc/actiongroups' with /opt/bitnami/elasticsearch/plugins/opendistro_security/securityconfig/action_groups.yml
SUCC: Configuration for 'actiongroups' created or updated
Will update '_doc/tenants' with /opt/bitnami/elasticsearch/plugins/opendistro_security/securityconfig/tenants.yml
SUCC: Configuration for 'tenants' created or updated
Will update '_doc/nodesdn' with /opt/bitnami/elasticsearch/plugins/opendistro_security/securityconfig/nodes_dn.yml
SUCC: Configuration for 'nodesdn' created or updated
Will update '_doc/whitelist' with /opt/bitnami/elasticsearch/plugins/opendistro_security/securityconfig/whitelist.yml
SUCC: Configuration for 'whitelist' created or updated
Will update '_doc/audit' with /opt/bitnami/elasticsearch/plugins/opendistro_security/securityconfig/audit.yml
SUCC: Configuration for 'audit' created or updated
Done with success
I have no name!@68ac2255bb85:/$
настройка Ldap
Для настройки интеграции с LDAP необходимо заполнить соответствующие секции в elastisearch-opendistro-sec/config.yml, ссылка на официальную документацию по authentication
config:
dynamic:
authc:
# тут можно настроить авторизацию
authz:
# а здесь аутентификацию
В случае с Active Directory, необходимо будет изменить конфигурационный файл примерно так:
# тут можно настроить авторизацию
ldap:
...
hosts:
- ldaphost:389
bind_dn: cn=LDAP,ou=Example,dc=example,dc=ru
password: CHANGEME
userbase: 'DC=example,DC=ru'
usersearch: '(sAMAccountName={0})'
username_attribute: sAMAccountName
Не забудьте воспользоваться securityadmin.sh после изменения конфигурации. Процедура была описана в предыдущем параграфе.
Вернемся к проекту с kubernetes, установим проект командой
helm upgrade --install efk . -f values.yaml
Нам необходимо будет
Для настройка OpenDistro Security plugin мы скопировали файл конфигурации, которые поместим в секреты kubernetes.
extraVolumes:
- name: config
secret:
secretName: opendistro-config
items:
- key: config.yml
path: config.yml
- name: roles-mapping
secret:
secretName: opendistro-config
items:
- key: roles_mapping.yml
path: roles_mapping.yml
extraVolumeMounts:
- mountPath: /opt/bitnami/elasticsearch/plugins/opendistro_security/securityconfig/config.yml
subPath: config.yml
name: config
- mountPath: /opt/bitnami/elasticsearch/plugins/opendistro_security/securityconfig/roles_mapping.yml
subPath: roles_mapping.yml
name: roles-mapping
Чтобы настройки применялись при команде helm upgrade, мы сделали job, который будет запускаться при каждой команде helm upgrade
apiVersion: batch/v1
kind: Job
metadata:
name: opendistro-config-reload
labels:
app.kubernetes.io/managed-by: {{.Release.Service | quote }}
app.kubernetes.io/instance: {{.Release.Name | quote }}
annotations:
"helm.sh/hook": post-upgrade
"helm.sh/hook-delete-policy": hook-succeeded
spec:
template:
metadata:
name: config-reload
labels:
app.kubernetes.io/managed-by: {{.Release.Service | quote }}
app.kubernetes.io/instance: {{.Release.Name | quote }}
spec:
initContainers:
- name: "wait-for-db"
image: "alpine:3.6"
command:
- 'sh'
- '-c'
- >
until nc -z -w 2 efk-elasticsearch-coordinating-only 9300 && echo elastic is ok; do
sleep 2;
done;
containers:
- name: opendistro-config-reload
image: "{{ .Values.elasticsearch.image.registry }}/{{ .Values.elasticsearch.image.repository}}:{{ .Values.elasticsearch.image.tag }}"
imagePullPolicy: {{ .Values.elasticsearch.image.pullPolicy | quote }}
{{- if .Values.elasticsearch.master.securityContext.enabled }}
securityContext:
runAsUser: {{ .Values.elasticsearch.master.securityContext.runAsUser }}
{{- end }}
command:
- 'bash'
- '-c'
- >
"/opt/bitnami/elasticsearch/plugins/opendistro_security/tools/securityadmin.sh" -h efk-elasticsearch-coordinating-only -cd "/opt/bitnami/elasticsearch/plugins/opendistro_security/securityconfig" -icl -key "/opt/bitnami/elasticsearch/config/kirk-key.pem" -cert "/opt/bitnami/elasticsearch/config/kirk.pem" -cacert "/opt/bitnami/elasticsearch/config/root-ca.pem" -nhnv
restartPolicy: Never
backoffLimit: 1
Если вы собираетесь организовать централизованную сборку логов для приложений под управление kubernetes, данный вариант мог бы стать вполне обоснованным решением. Все продукты поставляются под открытыми лицензиями. В статье приведена заготовка из которой можно создать production ready решение. Спасибо за внимание!
Центр управления связью общего пользования (ЦМУ ССОП) Роскомнадзора рекомендовал компаниям из реестра провайдеров ограничить доступ поисковых ботов к информации на российских сайтах.…
Apple возобновила переговоры с OpenAI о возможности внедрения ИИ-технологий в iOS 18, на основе данной операционной системы будут работать новые…
Конкурсный управляющий российской «дочки» Google подготовил 23 иска к участникам рекламного рынка. Общая сумма исков составляет 16 млрд рублей –…
Google завершил обновление основного алгоритма March 2024 Core Update. Раскатка обновлений была завершена 19 апреля, но сообщил об этом поисковик…
У частных продавцов на Авито появилась возможность составлять текст объявлений с помощью нейросети. Новый функционал доступен в категории «Обувь, одежда,…
24 апреля 2024 года в Москве состоялась церемония вручения наград международного конкурса Workspace Digital Awards. В этом году участниками стали…