Пошаговая настройка Kube-Prometheus-Stack для мониторинга Kubernetes

Пошаговая настройка Kube-Prometheus-Stack для мониторинга Kubernetes

Здравствуйте. Меня зовут Николай. И у меня паранойя в лёгкой форме, которая не мешает, а наоборот, помогает мне быть хорошим devops-инженером в компании INOSTUDIO. В мои обязанности входит настройка инфраструктур для разработчиков и продукции для клиентов, настройка CI/CD и поддержка, мониторинг оного, бэкапы. В этой статье я хотел бы поделиться частью личного опыта взаимодействия с Kubernetes и рассказать о том, как я к нему пришел.

Как я пришел к Kubernetes

Начинал с виртуализации на различных платформах, потом познал docker, затем облачные сервисы. Во всём этом можно было применить zabbix-agent, с написанным bash, python-скриптом, или собрать отдельный модуль zabbix-agent для настройки discovery-обнаружения контейнеров на хосте и передачи информации о контейнере в zabbix-server. Но при плотном изучении Kubernetes у меня сработала защитная реакция — как все это мониторить? Долго искать ответ на вопрос не пришлось, благо люди уже задавались таким вопросом ранее. Стек, в составе которого Prometheus + Alertmanager + Grafana. Из-за недостаточного опыта возникла проблема с простой и понятной инструкцией как запускать эту связку в кластере.

Какие задачи мониторинга решаем в Kubernetes

Мониторинг Kubernetes решает вопрос оповещения выхода из строя нод, под и прочего. Также анализ потребления ресурсов каждого deployment, statefulset т.д. Например, можно наглядно увидеть изменение потребления ресурсов после последнего деплоя.

Существуют некоторые готовые решения такие как:

1. kube-prometheus
2. kube-Prometheus-Stack
3. bitnami Prometheus Operator

Мне показался наиболее подходящим kube-Prometheus-Stack с плагином devopsprodigy-kubegraf-app.

Dashboards плагина выглядят так:

kube-Prometheus-Stack
Dashboards плагина
devopsprodigy-kubegraf-app

Это малая часть dashboards. Графиков достаточно для любого анализа.

Архитектура Prometheus

Разница между prometheus и prometheus-operator в том, что в prometheus-operator дополнительно включена Grafana с готовыми дашбордами и ServiceMonitors для сбора метрик из сервисов кластера таких как: CoreDNS, API Server, Scheduler и другие.

Архитектура Prometheus1

Prometheus — главная составляющая всей конструкции. Система мониторинга, которая собирает показатели из ваших служб и сохраняет их в базе данных временных рядов. Если кратко, то она собирает метрики, на которые можно посмотреть при помощи Prometheus Web.

Grafana — веб-приложение для аналитики и интерактивной визуализации

Для построения графиков Grafana может брать данные не только из Prometheus, но и из таких систем как: Graphite, Elasticsearch, OpenTSDB, InfluxDB.

Alertmanager — инструмент для обработки оповещений. Он устраняет дубликаты, группирует и отправляет нотификации.

Экспортёры (агенты) — их задача собирать метрики из сервисов и переводить их в понятный вид для Prometheus. Видов экспортёров существует огромное количество например: mysql_exporter, memcached_exporter, jms_exporter и так далее.

В стеке используются экспортёры:

Node-exporter — собирает метрики о вычислительных ресурсах Node в Kubernetes.

Kube-state-metrics — собирает метрики со всех узлов Kubernetes, обслуживаемых Kubelet через Summary API. Создатели экспортёра были вдохновлены проектом Heapster.

Подключение к кластеру

Тестовый проект я буду запускать в Google Cloud Platform. Но так же решение применяется в Azure, AWS. Уверен, оно будет работать и на других платформах.

Для запуска тестового kubernetes cluster в GCP нужно зайти в Kubernetes Engine, нажать Create cluster. Далее выбрать нужные настройки типа: локации, самой локации, описать конфигурацию машин, которые будут выступать в роли нод кластера, и настройку сети кластера. Этого достаточно для демонстрации. Примерно через 10 минут кластер готов к работе.

Подключение к кластеру может быть как через встроенную веб-консоль аккаунта GCP, так и через локальный компьютер. Для работы с GCP из локального компьютера нужно установить пакеты из google-cloud-sdk. Информация по скачиванию и установке пакетов для всех OS

gcloud auth login

gcloud auth login

В консоли будет показан url link, по которому нужно перейти в браузер. Затем скопируйте код проверки из браузера в консоль.

Вводим ID проекта, в котором запустили кластер:

gcloud config set project Project-ID

Затем строку подключения к кластеру, которую можно скопировать в окне, открывшемся после нажатия Сonnect на кластере в веб-интерфейсе:

Сonnect
Command-line

Установка HELM на Linux


Helm — это установщик пакетов для Kubernetes. Обычно его устанавливают локально на ОС, с которой управляется Kubernetes. Helm нам нужен для быстрой установки пакетов Kube-Prometheus-Stack в Kubernetes. Чтобы оставалась возможность обновлять helm, рекомендую сделать установку через apt:

curl https://baltocdn.com/helm/signing.asc | sudo apt-key add –

sudo apt-get install apt-transport-https –yes

echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list

sudo apt-get update

sudo apt-get install helm

Источник

Подготовка к установке Kube-Prometheus-Stack

Перед запуском Kube-Prometheus-Stack нужно описать файлы конфигурации Grafana и Alertmanager.

1. Добавление плагинов в Grafana

В самой Grafana нам понадобится плагин devopsprodigy-kubegraf-app из списка плагинов Grafana Labs. У него достаточно обширные dashboards.

Для добавления плагина мы создадим .yml-файл, который будем использовать при запуске установки Kube-Prometheus-Stack.

mkdir /opt/Kube-Prometheus-Stack

nano /opt/Kube-Prometheus-Stack/grafana.yml

В файле прописываем параметр:
grafana:
  plugins:
    - devopsprodigy-kubegraf-app

2. Добавление параметров в Alertmanager 

Кроме визуальной информации нужно настроить оповещение о проблемах. Для этого и существует  Alertmanager. Нам нужно, чтобы нотификации приходили в slack, канал #grafana. Потому мы заранее, в нужном нам workspace slack, генерируем webhook URL и создаем канал #grafana. Для изменения стандартных параметров Alertmanager, по аналогии с Grafana, — создаем файл alertmanager.yml, в котором будут указаны координаты отправки оповещений и шаблон самого сообщения — Prometheus Event Notification.

Заменяем содержимое переменных:

slack_api_url:

channel:

username:

nano  /opt/Kube-Prometheus-Stack/alertmanager.yml

Содержимое файла:

alertmanager:
  config:
    global:
      resolve_timeout: 5m
      slack_api_url: 'https://hooks.slack.com/services/……’ # Ваш webhook URL
    route:
      group_by: ['alertname', 'cluster', 'service']
      group_wait: 30s
      group_interval: 5m
      repeat_interval: 1h
      receiver: 'default-receiver'
      routes:
      - match:
          alertname: DeadMansSwitch
        receiver: 'null'
    inhibit_rules:
    - source_match:
        severity: 'critical'
      target_match:
        severity: 'warning'
      equal: ['alertname', 'cluster', 'service']
    receivers:
    - name: 'default-receiver'
      slack_configs:
      - channel: '#grafana' # Ваш канал Slack для оповещений
        username: 'Grafana-Kube'  # Имя, отображаемое в оповещении
        color: '{{ if eq .Status "firing" }}danger{{ else }}good{{ end }}'
        title: '[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] Prometheus Event Notification'
        title_link: '{{ template "slack.default.titlelink" . }}'
        pretext: '{{ .CommonAnnotations.summary }}'
        text: |-
          {{ range .Alerts }}
            {{- if .Annotations.summary }}*Alert:* {{ .Annotations.summary }} - `{{ .Labels.severity }}`{{- end }}
            *Description:* {{ .Annotations.description }}{{ .Annotations.message }}
            *Graph:* <{{ .GeneratorURL }}|:chart_with_upwards_trend:>{{ if or .Annotations.runbook .Annotations.runbook_url }} *Runbook:* <{{ .Annotations.runbook }}{{ .Annotations.runbook_u
rl }}|:spiral_note_pad:>{{ end }}
            *Details:*
            {{ range .Labels.SortedPairs }} • *{{ .Name }}:* `{{ .Value }}`
            {{ end }}
          {{ end }}
        fallback: '{{ template "slack.default.fallback" . }}'
        icon_emoji: '{{ template "slack.default.iconemoji" . }}'
        icon_url: '{{ template "slack.default.iconurl" . }}'
        send_resolved: true
    - name: 'null'

Установка Kube-Prometheus-Stack

Наконец, мы подошли к установке того, ради чего все затевалось.

Для установки нужно добавить репозитории в helm:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts

helm repo update

Теперь запускаем непосредственно установку Kube-Prometheus-Stack

helm install --set name=grafana my-test prometheus-community/kube-prometheus-stack -f /opt/Kube-Prometheus-Stack/grafana.yml -f /opt/Kube-Prometheus-Stack/alertmanager.yml

Спустя некоторое время можно проверить запущенные pods

kubectl get po
kubectl get po

Проверяем, что настройки Аlertmanager применились. Для этого проксируем pod alertmanager на локальный порт:

kubectl port-forward alertmanager-my-test-prometheus-operato-alertmanager-0 9093

В браузере на странице alertmanager переходим во вкладку Status, где можно удостовериться, что текущие настройки соответствуют конфигу alertmanager.yml.

Генерация token для доступа к кластеру

Для подключения к кластеру Kubernetes ранее установленного в Grafana плагина нужно сгенерировать token.

Для этого применяем манифесты для kubernetes

kubectl apply -f https://raw.githubusercontent.com/devopsprodigy/kubegraf/master/kubernetes/serviceaccount.yaml
kubectl apply -f https://raw.githubusercontent.com/devopsprodigy/kubegraf/master/kubernetes/clusterrole.yaml
kubectl apply -f https://raw.githubusercontent.com/devopsprodigy/kubegraf/master/kubernetes/clusterrolebinding.yaml
kubectl apply -f https://raw.githubusercontent.com/devopsprodigy/kubegraf/master/kubernetes/secret.yaml

Генерируем token

kubectl get secret grafana-kubegraf-secret -o jsonpath={.data.token} | base64 -d

Настройка плагина в Grafana

Проксируем под Grafana

kubectl port-forward my-test-grafana-6d77c7fdc6-bxqh8 3000

Стандартный логин пароль — admin / prom-operator (войдя в веб-интерфейс, рекомендуем сменить пароль), url —  http://localhost:3000

Переходим на вкладку Configuration  →Plugins, выбираем плагин DevOpsProdigy KubeGraf и включаем его. В левой панели появится значок этого плагина — переходим в него — вкладка Clusters. В открывшемся окне добавляем наш кластер kubernetes — Add New Cluster.

Нас интересуют параметры:

Name: любое удобное имя

URL: можно получить введя команду 

Информацию о подключаемом кластере можно получить командой:

kubectl cluster-info

Skip TLS Verify: Enable

Access via token: Enable 

Откроется поле для ввода token, который получили в консоли:

token1

Save & Test

После того как кластер добавится в Grafana можно будет посмотреть его статус приложений, нод и т.д. Будет в распоряжении 5 dashboards:

5 dashboards

Протестируем работу Аlertmanager: зайдем на одну из node кластера и сделаем так, чтобы полностью закончилось место на диске. В процессе dd if=/dev/zero …. Сработал триггер, что перегружен процессор:

Аlertmanager1
И множество других оповещений, которые могут возникнуть, когда заканчивается место на ноде kubernetes cluster
kubernetes cluster

Бонус

Если нужно простое оповещение об изменениях состояния в кластере, отправляемые в slack, то можно использовать Kubewatch. Устанавливается так же просто через helm с файлом описания конфигурации.
helm install my-test-helm stable/kubewatch -f values-file.yaml

Файл конфигурации:

rbac:
  create: true
resourcesToWatch:
  deployment: true
  replicationcontroller: true
  replicaset: true
  daemonset: true
  services: true
  pod: true
  job: true
  node: true
  clusterrole: true
  serviceaccount: true
  persistentvolume: true
  namespace: true
  secret: true
  configmap: true
  ingress: true
slack:
  channel: '#grafana'
  token: 'xoxb-KEhH7LhRHF6wNWnfqnBdsCfwvq8qCwRni3lLLrBwIcjvF/Xxs9wUG2VLrLtn06VU108Xa60IUBSGcqtg6S1UVg==’

Мы можем указать в файле конфигурации информацию о каких изменениях в кластере необходимо оповещать в slack-канал. В отличие от настроек Аlertmanager, в KubeWatch используется не webhook_url_api, а бот для авторизации, с которым нужно указывать token и группу. Как итог, получаем такие сообщения в канал:

slack-канал

Плюсы данного метода — простая настройка, быстрое оповещение. Минус — если выбрать все resourcesToWatch:, то KubeWatch будет слать много сообщений. Как я понял, это происходит по причине того, что, например, некоторые объекты в Kubernetes могут самостоятельно обновиться, а KubeWatch это фиксирует и сразу оповещает.

В итоге мы рассмотрели установку и настройку одного метода мониторинга для визуального отображения информации о кластере Kubernetes и два метода для оповещения о возникших проблемах в кластере. Моей целью было кратко описать рабочую схему установки и настройки мониторинга. Надеюсь, я справился. Мониторинг в данном виде работает и выполняет свое предназначение. Но нет предела совершенству.

Есть мысли по небольшому дополнению/модернизации этого стека. Причина — кластеров Kubernetes становится больше и устанавливать весь стек целиком на каждый кластер стало казаться не очень хорошей идеей, так как заходить на каждый кластер в Grafana для анализа графиков становится все большей рутиной. Есть желание объединять мониторинг в одном Grafana. Рассмотренный плагин для Grafana поддерживает подключение нескольких кластеров, но пока стоит вопрос о правильной настройке со стороны безопасности. Объединять мониторинг кластеров разных сред, да и к тому же разных проектов — не самая лучшая идея.

Так же меня не совсем устраивает форма нотификаций (Prometheus Event Notification). Хочется что-то в ней улучшить, но еще не определился, что именно.

В нашей следующей статье расскажем, как реализовать выкладку приложения CI/CD в Kubernetess.