Top.Mail.Ru
поддержка 24/7
поддержка 24/7

Сбор логов в кластере Kubernetes с помощью Grafana, Loki и Promtail

Наш эксперт Михаил Сергеев подготовил подробный материал (в двух форматах: статья и видеоурок), из которого вы узнаете:

  • Что такое 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.

Рис.1 Kubernetes-кластер состоит из 7 нод. Рис.1 Kubernetes-кластер состоит из 7 нод.

Для установки Loki посетим официальный сайт Grafana.

Рис.2 Официальный сайт Grafana, информация по установке. Рис.2 Официальный сайт 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
Рис.3 Скачиваем Loki-стек и разархивируем его. Рис.3 Скачиваем Loki-стек и разархивируем его.

Очень важный момент — кластер домен. Если вы меняли дефолтное (данное по умолчанию) название кластера, то вам нужно его здесь поменять. И днс-сервис также изменить (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-адреса. Поэтому пароль и логин можно спокойно использовать в открытую.

Рис.4 Задаём логин и пароль в админке S3. Рис.4 Задаём логин и пароль в админке S3.

Давайте установим helm upgrade install create namespace. Запускаем и устанавливаем. Также давайте посмотрим, какие pvc он создал. Он для бэкенда и вейда создал 3 persistent volume по 10 Гб, они указаны в конфигурации. Скачиваем бинарник и устанавливаем.

Рис.5 Установка Grafana / Loki. Рис.5 Установка Grafana / Loki.

Далее устанавливаем компонент 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 штуке на ноду

Далее устанавливаем новые поды.

Рис.6 Добавление 7 новых подов. Рис.6 Добавление 7 новых подов.

Теперь установим 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
Рис.7 Получение пароля от админки Grafana.. Рис.7 Получение пароля от админки Grafana.
#Получить пароль админа от 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 порту). Мы попадаем в локи гейтвей. Он дальше уже сам раскидывает данные в нужные сервисы.

Рис.8 В разделе HTTP вводим https://loki.gateway:80. Рис.8 В разделе HTTP вводим https://loki.gateway:80.

Затем нажимаем Save and Test (Сохранить и протестировать). На этом мы успешно подключили данный источник к нашей Grafana. Далее мы можем создавать различные запросы для анализа Loki. Здесь имеется удобный браузер, позволяющий выбрать метку или нужный под. Тут же мы можем посмотреть все логи за последний час, которые произошли в текущем наймспейсе. Данные можно фильтровать и делать различные запросы. Если к нам кто-то ломится, то в логах это отобразится. При необходимости логи можно компоновать и на их основе блокировать доступ к ресурсу.

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

Рис.9 Классический дашборд: вверху — временная шкала, снизу — логи. Рис.9 Классический дашборд: вверху — временная шкала, снизу — логи.

Dashboard (дашборд) — это форма визуализации данных. В дашборде информация может быть представлена в виде таблиц, инфографики, статистики, отчетов. Панель индикаторов можно изменять на лету, меняя анализируемые данные или подгружая их в реальном времени.

На сайте Grafana есть уже готовые шаблоны дашбордов. Импорт дашборда происходит после введения его ID. Указываем название дашборда, в какую папку его класть и источник. Некоторые дашборды требуют наличия Prometheus.

Рис.10 Дашборд с графиком вверху помогает отображать пики ошибок либо любой активности. Рис.10 Дашборд с графиком вверху помогает отображать пики ошибок либо любой активности.

ID (ай-ди) — это часть английского слова Identifier, которое переводится как идентификатор. Это информация, которая может идентифицировать субъект (номер, имя, число или строка символов).

Prometheus (прометеус) — это бесплатное программное приложение, используемое для мониторинга и оповещения о событиях. Он записывает метрики в реальном времени в базу данных временных рядов, созданную с использованием модели извлечения HTTP с гибкими запросами и оповещениями в реальном времени.

Рис.11 Наиболее информативный дашборд. Рис.11 Наиболее информативный дашборд.

Настроим хранение логов в объектное хранилище 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
Kubernetes в облаке Corpsoft24

Загрузка ...