Как снять метрики со служебных подов кластера Kubernetes

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Мониторинг служебных компонентов Kubernetes в пространстве kube-system часто остается за пределами первоначальной настройки кластера. Однако стабильность таких компонентов как kube-apiserver, kube-scheduler и kube-controller-manager напрямую определяет работоспособность всей системы. Сбор метрик с этих подов требует точной настройки механизма обнаружения и безопасного доступа к их эндпоинтам.

Привет, Хабр! Меня зовут Катя Низовцева, я системный администратор в Selectel. В этой статье я покажу практическую методику развертывания vmagent с помощью Helm и настройки конфигураций для сбора метрик с ключевых системных компонентов. Это обеспечит видимость их состояния без избыточной сложности. Мы увидим в Victoria Metrics Cluster метрики, снимаемые с подов в служебном неймспейсе kube-system. Но обо всем по порядку.

Это продолжение статьи, в рамках которой мы с помощью Kubespray быстро развернули работоспособный Kubernetes-кластер и интегрировали с ним систему мониторинга VictoriaMetrics.

База: что такое Kubernetes, зачем нужен мониторинг и из чего состоит VictoriaMetrics Cluster

Kubernetes (k8s) — это оркестратор контейнеров, упрощающий развертывание, масштабирование и управление приложениями. Мониторинг — процесс сбора и анализа метрик, логов и событий для оценки состояния системы.

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

kube-system — один неймспейсов, предназначенный исключительно для системных компонентов, которые управляют работой самого кластера. Неймспейс (namespace)  — это механизм изоляции группы ресурсов, в частности, в кластере Kubernetes.

В статье рассмотрим мониторинг основных компонентов мастер-нод, таких как API-сервер (kube-apiserver), контроллер-менеджер (kube-controller-manager) и планировщик, который распределяет поды по физическим нодам (kube-scheduler). В данной статье я не затрагиваю etcd (распределённая, согласованная база данных типа «ключ-значение») — ее мониторинг требует отдельного разбора из-за особенностей работы распределенного хранилища.

VictoriaMetrics Cluster — это база данных временных рядов, альтернатива Prometheus, но с оптимизациями для масштабируемости и долгосрочного хранения. В рамках предыдущей статьи мы развернули VictoriaMetrics в режиме single-node, то есть у нас уже была виртуальная машина, готовая снимать (скрейпить) метрики с нашего кластера Kubernetes. Это нам еще пригодится далее.

Managed Kubernetes на выделенных серверах

Снизьте расходы на IT-инфраструктуру и улучшите производительность микросервисов.

Подробнее →

Схема реализации сбора метрик со служебных ресурсов в кластере Kubernetes

У VictoriaMetrics есть разные компоненты, которые стоят в стороне и не входят в состав VictoriaMetrics Cluster. Нас интересует vmagent — сборщик метрик (аналог Prometheus agent mode). Если говорить иными словами, vmagent идет на ресурс (в нашем случае, под или эндпоинт) и снимает с него метрики, которые ресурс сам отдает. Далее, в зависимости от настроек, vmagent либо сохраняет метрики локально, либо отправляет на удаленный VIctoriaMetrics кластер. В нашем случае, метрики будут отправляться на удаленный ресурс.

Вот схема, которую мы реализуем в статье:

Сбор метрик

Подготовка инфраструктуры

Итак, у нас уже есть кластер K8s с системн��ми компонентами, которые мы планируем мониторить. Напомню, что это поды из неймспейса kube-system: kube-apiserver, kube-scheduler, kube-controller-manager. А vmagent развернем внутри K8s-кластера через Helm.

Я не просто так акцентирую внимание на таком компоненте как vmagent, поскольку он несет в себе конфигурацию, благодаря которой мы получим интересующие нас метрики с интересующих нас ресурсов. Например, мы сможем рассмотреть поднят ли под, зависшее/ошибочное состояние пода (Pending, Backoff, Gated, Unschedulable), потребление памяти, CPU, время запросов к apiserver, количество запросов разного типа к API и другое. Что ж, приступим.

Шаг 1. Разворачиваем vmagent в существующем Kubernetes-кластере

Приложение vmagent в кластере развернем через Helm. Это менеджер пакетов для Kubernetes, который позволяет установить сложное приложение одной командой, а не десятками ручных настроек. Он уже содержит все нужные базовые настройки «из коробки», что экономит достаточное количество времени и избавляет от ошибок. Нам остается только дополнить правила снятия метрик.

Чтобы развернуть приложение в кластере через Helm, у нас должен быть файл с нужной информацией (values). Соберем его по кусочкам.

Шаг 2. Собираем основу файла values.yaml

Обозначаем chart, как и всегда при развертывании любого приложения через Helm в кластере K8s. Здесь указывается информация об источнике пакета, его версии и namespace, в которое это приложение будет установлено в кластере K8s.

chart:
  repo: https://victoriametrics.github.io/helm-charts/
  version: "0.18.2"
  namespace: "victoria-metrics-agent"

Актуальную версию можно найти в репозитории.

Далее разворачиваем под в единственном экземпляре. Для небольших кластеров этого достаточно. Кластер Kubernetes сам позаботится о бесшовном перезапуске пода, если будет нужно обновить конфигурацию vmagent, так как под управляется такой сущностью K8s как Deployment. Это инструкция, которая описывает, какой образ приложения запустить, сколько его копий создать и как обновлять их без простоя. Проще говоря, это автопилот для вашего приложения, который следит, чтобы оно всегда было запущено и работало в нужном состоянии.

replicaCount: 1

Указываем, из какого образа разворачиваем контейнер в поде, и скачиваем образ в том случае, если он не существует локально.

image:
  repository: docker.io/victoriametrics/vmagent
  tag: ""
  pullPolicy: IfNotPresent

Указываем, в какое хранилище будем отправлять метрики. Тут указывается внешний IP-адрес того сервера (или доменное имя, если есть), на котором поднимался VictoriaMetrics Cluster в рамках предыдущей статьи.

remoteWrite:
  - url: http://*IP-адрес*:8428/api/v1/write

Указываем данные для подключения к этому удаленному хранилищу (по умолчанию, они отсутствуют):

env:
  - name: VM_remoteWrite_basicAuth_username
    value: "vmetrics_user"
  - name: VM_remoteWrite_basicAuth_password
    value: "vmetrics_password"

Указываем максимальное количество данных, которые можно получить за один скрейпинг метрик, чтобы не перегружать как локально ноду, так и удаленное хранилище.

extraArgs:
  promscrape.maxScrapeSize: 33554432

Указываем ресурсы для пода vmagent:

resources:
  limits:
    cpu: 400m
    memory: 256Mi
  requests:
    cpu: 200m
    memory: 128Mi

Шаг 3. Пишем джобу для снятия метрик для файла values.yaml

Пишем саму конфигурацию скрейпа метрик с подов kube-apiserver. В ней обозначается, какие именно метрики и для чего vmagent будет собирать.

По умолчанию в K8s-кластере есть сущность service с именем kubernetes. У нее есть эндпоинт — поды kube-apiserve, поэтому в качестве role указываются эндпоинты. 

 - job_name: "kube-apiserver"
      kubernetes_sd_configs:
        - role: endpoints

Сбор метрик происходит через https со всех подов, поэтому часть ниже будет в каждой джобе:

      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token

И, наконец, самое важное — конфигурация того, с чего мы хотим снимать метрики:

      relabel_configs:
        - source_labels:
            [
              __meta_kubernetes_namespace,
              __meta_kubernetes_service_name,
              __meta_kubernetes_endpoint_port_name,
            ]
          action: keep
          regex: default;kubernetes;https

Данной конфигурацией мы выбираем, с каких ресурсов будем собирать все метрики, которые отдает непосредственно сам ресурс. По конфигурации выше выбираются все ресурсы endpoints в кластере по лейблам __meta_kubernetes_namespace, __meta_kubernetes_service_name и __meta_kubernetes_endpoint_port_name. Их значения описаны в строке “regex”, где:

  • __meta_kubernetes_namespace =  default,

  • __meta_kubernetes_service_name = kubernetes,

  • __meta_kubernetes_endpoint_port_name = https.

В данном случае они отфильтрованы таким образом, чтобы мы получили только те эндпоинты, которыми являются поды kube-apiserver.

Далее скрейп конфиг для подов kube-scheduler выглядит так: 

- job_name: "kube-scheduler"
      kubernetes_sd_configs:
        - role: pod
          namespaces:
            names: ['kube-system']

Забираем все поды с неймспейса kube-system:

     relabel_configs:
        - source_labels: [__meta_kubernetes_pod_label_component]
          action: keep
          regex: kube-scheduler
        - source_labels: [__address__, __meta_kubernetes_pod_container_port_number]
          separator: ':'
          target_label: __address__
          regex: (.+?)(:\d+)?
          replacement: ${1}10259

Отфильтровываем поды так, чтобы в имени содержалось «kube-scheduler» и переделываем адрес для сбора метрик. В данной конфигурации vmagent будет идти на https://<IP-адрес пода kube-scheduler>:10259/metrics.

Точно такой же конфиг создаем для подов kube-controller-manager. Единственное изменение — заменить порт 10259 на 10257.

Итого файл values.yaml для vmagent будет выглядеть следующим образом:
chart:
  repo: https://victoriametrics.github.io/helm-charts/
  version: "0.18.2"
  namespace: "victoria-metrics-agent"

replicaCount: 1

image:
  repository: docker.io/victoriametrics/vmagent
  tag: ""
  pullPolicy: IfNotPresent

remoteWrite:
  - url: http://*IP-адрес*:8428/api/v1/write

env:
  - name: VM_remoteWrite_basicAuth_username
    value: "vmetrics_user"
  - name: VM_remoteWrite_basicAuth_password
    value: "vmetrics_password"

extraArgs:
  promscrape.maxScrapeSize: 33554432

resources:
  limits:
    cpu: 400m
    memory: 256Mi
  requests:
    cpu: 200m
    memory: 128Mi

config:
  global:
    scrape_interval: 10s
    external_labels:
      cluster: name-of-mine-cluster
      env: prod

  scrape_configs:
    - job_name: vmagent
      static_configs:
        - targets: ["localhost:8429"]

    - job_name: "kube-apiserver"
      kubernetes_sd_configs:
        - role: endpoints
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
        - source_labels:
            [
              __meta_kubernetes_namespace,
              __meta_kubernetes_service_name,
              __meta_kubernetes_endpoint_port_name,
            ]
          action: keep
          regex: default;kubernetes;https

    - job_name: "kube-scheduler"
      kubernetes_sd_configs:
        - role: pod
          namespaces:
            names: ['kube-system']
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      authorization:
        credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token 
      relabel_configs:
        - source_labels: [__meta_kubernetes_pod_label_component]
          action: keep
          regex: kube-scheduler
        - source_labels: [__address__, __meta_kubernetes_pod_container_port_number]
          separator: ':'
          target_label: __address__
          regex: (.+?)(:\d+)?
          replacement: ${1}10259

    - job_name: "kube-controller-manager"
      kubernetes_sd_configs:
        - role: pod
          namespaces:
            names: ['kube-system']
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
        insecure_skip_verify: true
      authorization:
        credentials_file: /var/run/secrets/kubernetes.io/serviceaccount/token 
      relabel_configs:
        - source_labels: [__meta_kubernetes_pod_label_component]
          action: keep
          regex: kube-controller-manager
        - source_labels: [__address__, __meta_kubernetes_pod_container_port_number]
          separator: ':'
          target_label: __address__
          regex: (.+?)(:\d+)?
          replacement: ${1}10257

Шаг 4. Деплоим vmagent в кластер

Приступим к разворачиванию vmagent с конфигурацией выше в кластере K8s. Дальнейшие команды можно выполнять на хосте, с которого выполнялась установка кластера (это хост с Ansible, вне кластера). 

Установим Helm. 

curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

Добавим репозиторий.

helm repo add victoria-metrics-agent https://victoriametrics.github.io/helm-charts/

Обновим список репозиториев.

helm repo update

Так как мы хотим установить приложение в кластер Kubernetes с хоста, который не является частью этого кластера, нам необходимо найти kubeconfig для подключения к конкретному кластеру. Так как кластер мы разворачивали через Kubespray по первой статье, то этот файл будет под названием super-admin.conf на мастере по пути /etc/kubernetes/super-admin.conf.

Затем на локальном хосте выполняем экспорт:

export KUBECONFIG=~/*папка сохранения*/super-admin.conf

Проверка, что удалось подключиться к кластеру:

kubectl get node

NAME     STATUS   ROLES           AGE   VERSION
master   Ready    control-plane   82d   v1.31.9
node1    Ready    <none>          82d   v1.31.9

Сервисы мониторинга рекомендуется разворачивать в отдельном неймспейсе, поэтому одной командой мы и создадим неймспейс с именем «victoria-metrics-agent», и развернем там vmagent. Файл values.yaml сгенерирован выше, его необходимо сохранить на хосте, с которого будете выполнять команду:

helm install victoria-metrics-agent victoria-metrics-agent/victoria-metrics-agent --namespace victoria-metrics-agent --create-namespace --values values.yaml

Смотрим, что получилось:

kubectl get pod -n victoria-metrics-agent

NAME                                      READY   STATUS    RESTARTS   AGE
victoria-metrics-agent-58dbdd74cc-7468w   1/1     Running   0          45s

Идем в VMCluster по адресу IP-адрес:8428, заходим в vmui (веб-интерфейс) → Explore → Explore Prometheus Metrics и тут видим наши джобы по их имени, для которых мы писали конфигурацию по снятию метрик:

Посмотрим, например, метрики, по поду kube-apiserver:

Например, результат за последние 15 минут по метрике на количество запросов к api серверу.

Линий несколько — это на разные типы запросов к серверу (GET, POST, PATCH и т. д.).

Итог

Мы разобрали, как построить эффективный мониторинг Kubernetes с помощью vmagent и VictoriaMetrics Cluster, сосредоточившись на ключевых компонентах kube-system. Но собранные метрики — лишь сырые данные. В следующей статье я покажу, как выделить самые важные метрики для подов (CPU, память, сеть, готовность пода к работе) и превратить их в наглядные Grafana-дашборды.

Источник: https://habr.com/ru/companies/selectel/articles/949354/


Интересные статьи

Интересные статьи

В современном мире невозможно быть энциклопедистом. Со времён Вольтера и Дидро человечество накопило слишком много знаний, и они не поместятся в одну голову. Однако это не значит, что не стоит даже пы...
Кинематограф стал неотъемлемой частью нашей жизни. Сопереживая героям, мы слово проживаем вторую жизнь, смотрим на мир глазами героев, начинаем смотреть на некоторые вещи иначе. Иногд...
Предыстория Когда-то у меня возникла необходимость проверять наличие неотправленных сообщений в «1С-Битрикс: Управление сайтом» (далее Битрикс) и получать уведомления об этом. Пробле...
Ваш сайт работает на 1С-Битрикс? Каждому клиенту вы даёте собственную скидку или назначаете персональную цену на товар? Со временем в вашей 1С сложилась непростая логика ценообразования и формирования...
Устраивать конкурсы в инстаграме сейчас модно. И удобно. Инстаграм предоставляет достаточно обширный API, который позволяет делать практически всё, что может сделать обычный пользователь ручками.