Мониторинг служебных компонентов 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 (веб-интерфейс) → ExploreExplore Prometheus Metrics и тут видим наши джобы по их имени, для которых мы писали конфигурацию по снятию метрик:

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

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

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

Итог

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

Комментарии (0)