Наш эксперт Михаил Сергеев подготовил подробный материал (в двух форматах: статья и видеоурок), из которого вы узнаете:
- Что такое Grafana / Loki / Promtail;
- Об аналоге на базе ELK / EFK;
- Как установить эти компоненты в кластер Kubernetes;
- Как получить логи из различных подов;
- О настройте хранения логов в объектном хранилище S3.
Что такое Grafana / Loki / Promtail
Grafana Loki — это система для сбора, хранения и анализа логов, которая использует методы индексации на основе меток и предоставляет возможности запросов и визуализации логов облачных серверов через веб-интерфейс Grafana.
Стек Grafana Loki состоит из 3 компонентов: Promtail, Loki и Grafana.
Promtail — это агент, ответственный за сбор логов и отправку их в Loki.
Loki — это основной сервис, ответственный за хранение логов и обработку запросов.
Grafana — веб-приложение для запросов и отображения логов.
Аналог на базе ELK /EFK
EFK стек или Elastic Stack - это комбинация трёх открытых инструментов: Elasticsearch, Fluentd и Kibana, которые используются для анализа и визуализации больших объёмов данных.
Elasticsearch - это движок поиска и аналитики, который используется для индексирования и обработки данных.
Logstash - это инструмент для обработки журналов, который используется для сбора, парсинга и преобразования журналов в другой формат.
Kibana - это инструмент для визуализации данных, который используется для анализа и отображения данных, индексированных в Elasticsearch.
Вместе они позволяют обрабатывать, индексировать и визуализировать большие объемы данных журналов для поиска, анализа и отчетности.
Установим эти компоненты в кластер Kubernetes
Kubernetes алиасы
echo "alias k='kubectl'" >> ~/.bashrc echo "alias kg='kubectl get'" >> ~/.bashrc echo "alias kgp='kubectl get po'" >> ~/.bashrc echo "alias kd='kubectl delete -f'" >> ~/.bashrc echo "alias ka='kubectl apply -f'" >> ~/.bashrc echo "alias ke='kubectl exec -it'" >> ~/.bashrc echo "alias k1='kubectl describe'" >> ~/.bashrc echo "alias kl='kubectl logs'" >> ~/.bashrc echo "alias kgs='kubectl get svc -A'" >> ~/.bashrc echo "alias kr='kubectl rollout restart deployment'" >> ~/.bashrc echo "alias krs='kubectl rollout restart sts'" >> ~/.bashrc echo "alias kpa='kubectl get po -A'" >> ~/.bashrc source ~/.bashrc
Наш Kubernetes-кластер состоит из 7 нод: из одной воркер ноды (с которого всё будет запускаться), 3 мастер ноды и 3 ceph нод (для создания хранилища persistent volume). Container runtime - containerd. Также нам понадобиться storage class (sc) для persistent volume. Он как раз на ceph нодах построен и называется rook-cephfs.
Для установки Loki посетим официальный сайт Grafana.
Есть два варианта установки: Install Loki и Install Single Binary Loki. Второй способ — это установка в файловую систему. А первый способ как раз предлагает хранить данные в S3.
Поэтому первым шагом мы добавляет репозиторий и обновляем его.
helm repo add grafana https://grafana.github.io/helm-charts helm repo update helm search repo grafana ## loki-stack - не наш выбор helm pull grafana/loki-stack tar zxf loki-stack-2.8.9.tgz rm loki-stack-2.8.9.tgz -f vi loki-stack/values.yaml rm -rf loki-stack
Очень важный момент — кластер домен. Если вы меняли дефолтное (данное по умолчанию) название кластера, то вам нужно его здесь поменять. И днс-сервис также изменить (kube-dns на coredns).
Установка:
#### LOKI helm pull grafana/loki tar zxf loki-4.4.2.tgz rm loki-4.4.2.tgz -f cp loki/values.yaml loki-values.yaml # получить название днс-сервиса: kubectl get svc --namespace=kube-system -l k8s-app=kube-dns vi loki-values.yaml заменить: dnsService: "kube-dns" на dnsService: "coredns" kubectl get cm coredns -n kube-system -o jsonpath="{.data.Corefile}" | grep ".local " | awk -F ' ' '{print $2}' cluster.local
Будем хранить логи в бакетах s3
Для этого создаем ключи и бакеты в админке нашей S3:
https://s3adm.194.126.161.151.sslip.io/ MINIO_ROOT_USER: cs24 MINIO_ROOT_PASSWORD: 3nDPUk1GpfrWHn7kw1p9 s3adm.194.126.161.151.sslip.io s3.194.126.161.151.sslip.io # для этого редактируем: type: s3 s3: s3: null endpoint: s3.194.126.161.151.sslip.io region: null secretAccessKey: BDRCsg1cnqM8aUkqF2hZtCP2vRyPcRYu accessKeyId: q1MQqDKU8eux280X s3ForcePathStyle: true insecure: false
Указываем s3ForcePathStyle: true, чтобы он не добавлял название бакета в урл, а то будет использовать домен bucket.s3.194.126.161.151.sslip.io вместо s3.194.126.161.151.sslip.io
#отключаем аутентификацию, чтобы promtail не получал 401 auth_enabled: false #Устанавливаем Loki в неймспейс loki: helm upgrade --install --create-namespace --values loki-values.yaml loki -n loki grafana/loki #Смотрим какие создались поды: kg po -n loki NAME READY STATUS RESTARTS AGE loki-backend-0 0/1 Running 0 13s loki-backend-1 0/1 Running 0 13s loki-backend-2 0/1 Running 0 13s loki-canary-877f7 0/1 Running 0 13s loki-canary-fm9vk 0/1 Running 0 13s loki-canary-gqgzf 0/1 Running 0 13s loki-canary-v2zqx 0/1 Running 0 13s loki-gateway-747cc46d5b-9zlxr 0/1 Running 0 13s loki-grafana-agent-operator-79867d6656-j4hfh 1/1 Running 0 13s loki-logs-6nfhn 2/2 Running 0 10s loki-logs-7d94f 2/2 Running 0 10s loki-logs-dhpl7 2/2 Running 0 10s loki-logs-wdpwx 2/2 Running 0 10s loki-read-7f988bb5bd-5rxkf 0/1 Running 0 13s loki-read-7f988bb5bd-b5lhw 0/1 Running 0 13s loki-read-7f988bb5bd-c6rf9 0/1 Running 0 13s loki-write-0 0/1 ContainerCreating 0 13s loki-write-1 0/1 Running 0 13s loki-write-2 0/1 Running 0 13s #сервисы: kg svc -n loki NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE loki-backend ClusterIP 10.233.18.27 3100/TCP,9095/TCP 46s loki-backend-headless ClusterIP None 3100/TCP,9095/TCP 46s loki-canary ClusterIP 10.233.20.25 3500/TCP 46s loki-gateway ClusterIP 10.233.63.216 80/TCP 46s loki-memberlist ClusterIP None 7946/TCP 46s loki-read ClusterIP 10.233.59.191 3100/TCP,9095/TCP 46s loki-read-headless ClusterIP None 3100/TCP,9095/TCP 46s loki-write ClusterIP 10.233.31.117 3100/TCP,9095/TCP 46s loki-write-headless ClusterIP None 3100/TCP,9095/TCP 46s #persistent volume claim: kg pvc -n loki NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE data-loki-backend-0 Bound pvc-6186ece7-0e2b-4d06-b936-a50e1c2c416d 10Gi RWO rook-cephfs 73s data-loki-backend-1 Bound pvc-ef69b3dc-c622-452b-9bf4-601af05c3d85 10Gi RWO rook-cephfs 73s data-loki-backend-2 Bound pvc-656431f4-68db-4ef1-b307-cf0f80ef905c 10Gi RWO rook-cephfs 73s data-loki-write-0 Bound pvc-80856a2b-9266-4322-9a9e-2271d9bce0d3 10Gi RWO rook-cephfs 73s data-loki-write-1 Bound pvc-7f925129-494d-49c3-8902-0c2095205549 10Gi RWO rook-cephfs 73s data-loki-write-2 Bound pvc-fdf188cc-d966-49ee-9c2d-e33cbd98b49e 10Gi RWO rook-cephfs 73
На прошлом уроке мы с вами устанавливали хранилище на базе Minio через Docker, давайте использовать его. Есть 2 адреса – это админка и API. В админке необходимо создать бакеты (bucket) и ключ. А через API обращаться к S3. Прежде чем создавать бакеты, посмотрим, что нам необходимо. Раздел storage: bucketNames:, в котором нужно создать 3 бакета, которым можно дать произвольные имена. Регион можно не указывать. У них снизу будет ID, а сверху — пароль. Не перепутайте! Давайте создадим 3 бакета и акцесс кей (access key) и секрет кей (secret key). Вот наша админка S3. У нас стоит защита по IP-адресу – означает, что в админку нельзя зайти с другого IP-адреса. Поэтому пароль и логин можно спокойно использовать в открытую.
Давайте установим helm upgrade install create namespace. Запускаем и устанавливаем. Также давайте посмотрим, какие pvc он создал. Он для бэкенда и вейда создал 3 persistent volume по 10 Гб, они указаны в конфигурации. Скачиваем бинарник и устанавливаем.
Далее устанавливаем компонент promtai
### PROMTAIL helm pull grafana/promtail tar zxf promtail-6.8.1.tgz rm promtail-6.8.1.tgz -f cp promtail/values.yaml promtail-values.yaml vi promtail-values.yaml # Устанавливаем promtail helm upgrade --install --create-namespace --values promtail-values.yaml promtail -n loki grafana/promtail #поды promtail: kg po -n loki NAME READY STATUS RESTARTS AGE loki-backend-0 1/1 Running 0 8m3s loki-backend-1 1/1 Running 0 8m3s loki-backend-2 1/1 Running 0 8m3s loki-canary-7p79j 1/1 Running 0 8m3s loki-canary-d2lph 1/1 Running 0 8m4s loki-canary-dpvxr 1/1 Running 0 8m4s loki-canary-fsm52 1/1 Running 0 8m4s loki-gateway-747cc46d5b-xs4qm 1/1 Running 0 8m3s loki-grafana-agent-operator-79867d6656-sn9fz 1/1 Running 0 8m3s loki-logs-8c9zc 2/2 Running 0 8m loki-logs-gtv8s 2/2 Running 0 8m loki-logs-rx9tz 2/2 Running 0 8m loki-logs-v4c2m 2/2 Running 0 8m loki-read-7d4c5c5686-4q4cg 1/1 Running 0 8m3s loki-read-7d4c5c5686-bnhw5 1/1 Running 0 8m3s loki-read-7d4c5c5686-dg8x8 1/1 Running 0 8m3s loki-write-0 1/1 Running 0 8m3s loki-write-1 1/1 Running 0 8m3s loki-write-2 1/1 Running 0 8m3s promtail-2xcxg 0/1 ContainerCreating 0 7s promtail-6ftz2 0/1 ContainerCreating 0 7s promtail-7x6tn 0/1 ContainerCreating 0 7s promtail-hwc2v 0/1 ContainerCreating 0 7s promtail-prgm9 0/1 ContainerCreating 0 7s promtail-rq8jb 0/1 ContainerCreating 0 7s promtail-s8lf7 0/1 ContainerCreating 0 7s #т.к это daemonset, то устанавливается по 1 штуке на ноду
Далее устанавливаем новые поды.
Теперь установим Grafana.
#Далее устанавливаем компонент grafana #### GRAFANA helm pull grafana/grafana tar zxf grafana-6.50.5.tgz rm grafana-6.50.5.tgz -f cp grafana/values.yaml grafaa-values.yaml vi grafana-values.yaml persistence необходимо поставить в положение true иначе после смерти пода все настройки сбросятся persistence: type: pvc enabled: true # установка grafana helm upgrade --install --create-namespace --values grafana-values.yaml grafana -n loki grafana/grafana #Добавляем ингресс для внешнего доступа: cat << \EOF > grafana-ingress.yaml --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/whitelist-source-range: 95.217.236.3/32,192.248.191.109/32,94.143.44.29/32 cert-manager.io/issuer: gitlab-issuer kubernetes.io/ingress.class: nginx kubernetes.io/tls-acme: "true" name: grafana namespace: loki spec: rules: - host: loki.195-208-185-64.sslip.io http: paths: - backend: service: name: grafana port: number: 80 path: / pathType: Prefix tls: - hosts: - loki.195-208-185-64.sslip.io secretName: grafana-tls ... EOF ka grafana-ingress.yaml
#Получить пароль админа от Grafana: kubectl get secret --namespace loki loki-grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
Для защиты Grafana зададим доступ только с разрешённых IP-адресов. Создастся SSL-сертификат, и можно будет извне заходить на этот домен.
Получим логи из различных подов
Давайте зайдём в админку Loki по адресу https://loki.195-208-185-64.sslip.io/login
Пароль мы берём из сикрета, извлекаем и декодируем. Защита тут стоит двойная - (логин с паролем и проверка IP-адреса) и в админку всё равно не зайти с постороннего IP-адреса.
Во вкладке Explore (Исследовать) пока нет Loki нашего источника данных, поэтому добавляем источник данных. Для этого заходим в Configuration (Конфигурация или Настройки) во вкладку Data Source (Источник данных) и нажимаем на Add Data Source (Добавить источник данных). И увидим список различных источников, включая облачные и энтерпрайс плагины. Но нас интересует Loki. Название источника оставляем рандомным. В разделе HTTP вводим https://loki.gateway:80 (шлюз на 80 порту). Мы попадаем в локи гейтвей. Он дальше уже сам раскидывает данные в нужные сервисы.
Затем нажимаем Save and Test (Сохранить и протестировать). На этом мы успешно подключили данный источник к нашей Grafana. Далее мы можем создавать различные запросы для анализа Loki. Здесь имеется удобный браузер, позволяющий выбрать метку или нужный под. Тут же мы можем посмотреть все логи за последний час, которые произошли в текущем наймспейсе. Данные можно фильтровать и делать различные запросы. Если к нам кто-то ломится, то в логах это отобразится. При необходимости логи можно компоновать и на их основе блокировать доступ к ресурсу.
Далее создаём новый дашборд, в котором отображаются логи под определённый запрос. Ему можно задать имя и сохранить в определённую папку. Также можно сделать визуализацию с наглядными графиками, чтобы увидеть, например, пики ошибок или попытку взлома сайта.
Dashboard (дашборд) — это форма визуализации данных. В дашборде информация может быть представлена в виде таблиц, инфографики, статистики, отчетов. Панель индикаторов можно изменять на лету, меняя анализируемые данные или подгружая их в реальном времени.
На сайте Grafana есть уже готовые шаблоны дашбордов. Импорт дашборда происходит после введения его ID. Указываем название дашборда, в какую папку его класть и источник. Некоторые дашборды требуют наличия Prometheus.
ID (ай-ди) — это часть английского слова Identifier, которое переводится как идентификатор. Это информация, которая может идентифицировать субъект (номер, имя, число или строка символов).
Prometheus (прометеус) — это бесплатное программное приложение, используемое для мониторинга и оповещения о событиях. Он записывает метрики в реальном времени в базу данных временных рядов, созданную с использованием модели извлечения HTTP с гибкими запросами и оповещениями в реальном времени.
Настроим хранение логов в объектное хранилище S3
Теперь посмотрим, что с нашим объектным хранилищем S3. Обновляем страницу и проверяем список объектов. У Minio есть проблема, для создания одного объекта он занимает сразу 2 иноды. Вторая его проблема – в файловой системе ext4 есть ограничение на 65 тысяч папок, которое мы можем через некоторое получить. Поэтому для Minio рекомендуется использовать XFS файловую систему. Архитектура Miniо позволяет создавать до миллиарда папок.
Ext4 — журналируемая файловая система, используемая преимущественно в операционных системах с ядром Linux, созданная на базе ext3 в 2006 году. Основные изменения в ext4 по сравнению с ext3: увеличен максимальный объём одного раздела диска до 1 эксбибайта при размере блока 4 кибибайт. При этом 1 эксбибайт (ЭиБ) = 260 байт = 1 152 921 504 606 846 976 байт, а 1 кибибайт (КиБ) = 210 байт = 1024 байт.
XFS — высокопроизводительная 64-битная журналируемая файловая система, созданная компанией Silicon Graphics для собственной операционной системы IRIX. 1 мая 2001 года Silicon Graphics выпустила XFS под GNU General Public License. XFS отличается от других файловых систем, поскольку она изначально была рассчитана для использования на дисках большого объёма (более 2 терабайт, например, для RAID-массивов).
Если возникла необходимость удалить Loki, то используем соответствующую команду. Эта команда удалит все поды и деплойменты, даймонт сеты и всё остальное, кроме pvc.
#Удаление LOKI helm uninstall loki grafana promtail -n loki Для удаления pvc: k delete pvc data-loki-backend-0 data-loki-backend-1 data-loki-backend-2 data-loki-write-0 data-loki-write-1 data-loki-write-2 -n loki kd grafana-ingress.yaml