Мониторинг Kubernetes

Материал из Документация Ключ-АСТРОМ

Collector OpenTelemetry обеспечивает расширенную поддержку мониторинга кластера и рабочей нагрузки Kubernetes. Он поддерживает различные приёмники для сбора критически важных метрик о кластере, узлах и объектах Kubernetes.

В этом примере использования объясняется, как настроить коллекторы OpenTelemetry для получения полного обзора кластеров Kubernetes с помощью готовых панелей мониторинга, предоставляемых приложением Ключ-АСТРОМ OpenTelemetry Dashboards.

Ключ-АСТРОМ Operator

Ключ-АСТРОМ рекомендует использовать Operator для мониторинга Kubernetes. Однако этот вариант использования разработан специально для пользователей OpenTelemetry, которые решили не развертывать Operator. Он использует только данные OpenTelemetry, которые не интегрированы в приложение Ключ-АСТРОМ Kubernetes. Несмотря на это, Ключ-АСТРОМ предоставляет готовые панели мониторинга Kubernetes и позволяет пользователям создавать собственные дашборды и блокноты на основе собранных данных телеметрии.

Предпосылки

  • Один из следующих дистрибутивов Collector с приемниками Kubernetes Cluster, Kubernetes Events и Kubelet Stats :
  • Два развертывания Collector
    1. Один в режиме агента для телеметрии на уровне рабочей нагрузки
    2. Один в режиме шлюза для телеметрии на уровне кластера и пересылки в Ключ-АСТРОМ
  • URL-адрес API вашей среды Ключ-АСТРОМ
  • API-токен с соответствующей областью доступа
  • Kubernetes настроен на требуемый контроль доступа на основе ролей

Инструкции по настройке с использованием представленных ниже конфигураций см . в разделах Развертывание и Конфигурация коллектора.

Демонстрационные конфигурации

Конфигурация RBAC

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

apiVersion: v1

kind: ServiceAccount

metadata:

  labels:

    app: otelcol-dt

  name: otelcol-dt

---

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRole

metadata:

  name: otelcol-dt

  labels:

    app: otelcol-dt

rules:

  - apiGroups:

      - ""

    resources:

      - events

      - namespaces

      - namespaces/status

      - nodes

      - nodes/spec

      - nodes/stats

      - nodes/proxy

      - persistentvolumes

      - persistentvolumeclaims

      - pods

      - pods/status

      - replicationcontrollers

      - replicationcontrollers/status

      - resourcequotas

      - services

    verbs:

      - get

      - list

      - watch

  - apiGroups:

      - apps

    resources:

      - daemonsets

      - deployments

      - replicasets

      - statefulsets

    verbs:

      - get

      - list

      - watch

  - apiGroups:

      - batch

    resources:

      - jobs

      - cronjobs

    verbs:

      - get

      - list

      - watch

  - apiGroups:

      - autoscaling

    resources:

      - horizontalpodautoscalers

    verbs:

      - get

      - list

      - watch

  - apiGroups:

      - coordination.k8s.io

    resources:

      - leases

    verbs:

      - get

      - list

      - watch

      - create

      - update

      - patch

      - delete

---

apiVersion: rbac.authorization.k8s.io/v1

kind: ClusterRoleBinding

metadata:

  name: otelcol-dt

  labels:

    app: otelcol-dt

roleRef:

  apiGroup: rbac.authorization.k8s.io

  kind: ClusterRole

  name: otelcol-dt

subjects:

  - kind: ServiceAccount

    name: otelcol-dt

    namespace: default

Конфигурация Collector

Учетная запись службы

Помимо конфигурации Collector, обязательно обновите конфигурацию Kubernetes, чтобы она соответствовала имени учетной записи службы, используемому в файле RBAC (см. записи для Helm и Operator).

Развертывание агента

extensions:

  health_check:

    endpoint: 0.0.0.0:13133

receivers:

  kubeletstats:

    auth_type: "serviceAccount"

    collection_interval: 10s

    node: '${env:K8S_NODE_NAME}'

    extra_metadata_labels:

      - k8s.volume.type

    k8s_api_config:

      auth_type: "serviceAccount"

    endpoint: "https://${env:K8S_NODE_NAME}:10250"

    insecure_skip_verify: true

    metric_groups:

      - node

      - pod

      - container

      - volume

processors:

  filter:

    error_mode: ignore

    metrics:

      metric:

          - 'IsMatch(name, "k8s.volume.*") and resource.attributes["k8s.volume.type"] == nil'

          - 'resource.attributes["k8s.volume.type"] == "configMap"'

          - 'resource.attributes["k8s.volume.type"] == "emptyDir"'

          - 'resource.attributes["k8s.volume.type"] == "secret"'

  k8sattributes:

    filter:

      node_from_env_var: K8S_NODE_NAME

    extract:

      metadata:

        - k8s.pod.name

        - k8s.pod.uid

        - k8s.pod.ip

        - k8s.deployment.name

        - k8s.replicaset.name

        - k8s.statefulset.name

        - k8s.daemonset.name

        - k8s.job.name

        - k8s.cronjob.name

        - k8s.namespace.name

        - k8s.node.name

        - k8s.cluster.uid

        - k8s.container.name

      annotations:

        - from: pod

          key_regex: metadata.astromkey.com/(.*)

          tag_name: $$1

        - from: pod

          key: metadata.astromkey.com

          tag_name: metadata.astromkey.com

    pod_association:

      - sources:

          - from: resource_attribute

            name: k8s.pod.name

          - from: resource_attribute

            name: k8s.namespace.name

      - sources:

          - from: resource_attribute

            name: k8s.pod.ip

      - sources:

          - from: resource_attribute

            name: k8s.pod.uid

      - sources:

          - from: connection

exporters:

  otlp:

    endpoint: otelcolsvc:4317

    tls:

      insecure: true

service:

  extensions:

    - health_check

  pipelines:

    metrics:

      receivers:

        - kubeletstats

      processors:

        - filter

        - k8sattributes

      exporters:

        - otlp

Развертывание шлюза

extensions:

  health_check:

    endpoint: 0.0.0.0:13133

receivers:

  otlp:

    protocols:

      grpc:

        endpoint: 0.0.0.0:4317

  k8s_events:

    auth_type: "serviceAccount"

  k8s_cluster:

    auth_type: "serviceAccount"

    collection_interval: 10s

    allocatable_types_to_report:

      - cpu

      - memory

      - pods

    node_conditions_to_report:

      - Ready

      - MemoryPressure

      - PIDPressure

      - DiskPressure

      - NetworkUnavailable

    metrics:

      k8s.node.condition:

        enabled: true

      k8s.pod.status_reason:

        enabled: true

processors:

  k8sattributes:

    filter:

      node_from_env_var: K8S_NODE_NAME

    extract:

      metadata:

        - k8s.pod.name

        - k8s.pod.uid

        - k8s.pod.ip

        - k8s.deployment.name

        - k8s.replicaset.name

        - k8s.statefulset.name

        - k8s.daemonset.name

        - k8s.job.name

        - k8s.cronjob.name

        - k8s.namespace.name

        - k8s.node.name

        - k8s.cluster.uid

        - k8s.container.name

      annotations:

        - from: pod

          key_regex: metadata.astromkey.com/(.*)

          tag_name: $$1

        - from: pod

          key: metadata.astromkey.com

          tag_name: metadata.astromkey.com

    pod_association:

      - sources:

          - from: resource_attribute

            name: k8s.pod.name

          - from: resource_attribute

            name: k8s.namespace.name

      - sources:

          - from: resource_attribute

            name: k8s.pod.ip

      - sources:

          - from: resource_attribute

            name: k8s.pod.uid

      - sources:

          - from: connection

  transform:

    error_mode: ignore

    trace_statements: &astromkey_transformations

      # Set attributes taken from k8s metadata.

      - context: resource

        statements:

          - set(attributes["k8s.cluster.name"], "${env:CLUSTER_NAME}")

          - set(attributes["k8s.workload.kind"], "job") where IsString(attributes["k8s.job.name"])

          - set(attributes["k8s.workload.name"], attributes["k8s.job.name"]) where IsString(attributes["k8s.job.name"])

          - set(attributes["k8s.workload.kind"], "cronjob") where IsString(attributes["k8s.cronjob.name"])

          - set(attributes["k8s.workload.name"], attributes["k8s.cronjob.name"]) where IsString(attributes["k8s.cronjob.name"])

          - set(attributes["k8s.workload.kind"], "daemonset") where IsString(attributes["k8s.daemonset.name"])

          - set(attributes["k8s.workload.name"], attributes["k8s.daemonset.name"]) where IsString(attributes["k8s.daemonset.name"])

          - set(attributes["k8s.workload.kind"], "statefulset") where IsString(attributes["k8s.statefulset.name"])

          - set(attributes["k8s.workload.name"], attributes["k8s.statefulset.name"]) where IsString(attributes["k8s.statefulset.name"])

          - set(attributes["k8s.workload.kind"], "replicaset") where IsString(attributes["k8s.replicaset.name"])

          - set(attributes["k8s.workload.name"], attributes["k8s.replicaset.name"]) where IsString(attributes["k8s.replicaset.name"])

          - set(attributes["k8s.workload.kind"], "deployment") where IsString(attributes["k8s.deployment.name"])

          - set(attributes["k8s.workload.name"], attributes["k8s.deployment.name"]) where IsString(attributes["k8s.deployment.name"])

          # remove the delete statements if you want to preserve these attributes

          - delete_key(attributes, "k8s.deployment.name")

          - delete_key(attributes, "k8s.replicaset.name")

          - delete_key(attributes, "k8s.statefulset.name")

          - delete_key(attributes, "k8s.daemonset.name")

          - delete_key(attributes, "k8s.cronjob.name")

          - delete_key(attributes, "k8s.job.name")

      # Set attributes from metadata specified in astromkey and set through the astromkey Operator.

      # For more info: https://docs.astromkey.com/docs/shortlink/k8s-metadata-telemetry-enrichment

      - context: resource

        statements:

          - merge_maps(attributes, ParseJSON(attributes["metadata.astromkey.com"]), "upsert") where IsMatch(attributes["metadata.astromkey.com"], "^\\{")

          - delete_key(attributes, "metadata.astromkey.com")

    metric_statements: *astromkey_transformations

    log_statements:

      - context: resource

        statements:

          - set(attributes["k8s.cluster.name"], "${env:CLUSTER_NAME}")

  cumulativetodelta:

exporters:

  otlphttp:

    endpoint: ${env:DT_ENDPOINT}

    headers:

      Authorization: "Api-Token ${env:DT_API_TOKEN}"

service:

  extensions:

    - health_check

  pipelines:

    traces:

      receivers:

        - otlp

      processors:

        - k8sattributes

        - transform

      exporters:

        - otlphttp

    metrics/forward:

      receivers:

        - otlp

      processors:

        - transform

        - cumulativetodelta

      exporters:

        - otlphttp

    metrics:

      receivers:

        - k8s_cluster

      processors:

        - k8sattributes

        - transform

        - cumulativetodelta

      exporters:

        - otlphttp

    logs:

      receivers:

        - k8s_events

      processors:

        - transform

      exporters:

        - otlphttp

Компоненты

Для нашей конфигурации мы настроили следующие компоненты:

Развертывание агента

Приемники

В разделе receivers мы указываем получателя kubeletstats.

Для этого приемника требуется, чтобы переменная среды K8S_NODE_NAME была настроена на использование Kubernetes Downward API (см. пример spec.nodeName).

Процессоры

Под processors

  • filter: Для фильтрации атрибутов Kubernetes.
  • k8sattributes: Для извлечения и предоставления данных модуля.

Экспортеры

В разделе exporters мы указываем экспортер otlp и настраиваем его для экспорта данных в наш экземпляр шлюза Collector. Убедитесь, что вы указали правильное имя хоста для endpoint.

Сервисные контейнеры

В разделе service мы собираем объекты приёмника, процессора и экспортёра в контейнеры для трассировок, метрик и логов. Эти контейнеры позволяют нам отправлять сигналы OpenTelemetry через экземпляр Collector и автоматически дополнять их дополнительной информацией, специфичной для Kubernetes.

Развертывание шлюза

Приемники

В разделе receivers мы указываем следующие приемники в качестве активных компонентов приемника для развертывания нашего шлюза:

  • otlp: Для принятия запросов OTLP.
  • k8sevents: Для получения событий Kubernetes с сервера API Kubernetes.
  • k8s_cluster: Для получения метрик уровня кластера и событий сущностей с сервера API Kubernetes.

(*) В настоящее время k8seventsreceiver находится на стадии альфа-тестирования и может претерпеть значительные изменения. Несмотря на раннюю стадию разработки, он был включён в дистрибутив Ключ-АСТРОМ OpenTelemetry Collector для поддержки раннего внедрения и экспериментов. Обратите внимание, что на данном этапе стабильность, производительность и полнота функций не гарантируются.

Процессоры

В разделе processors мы указываем следующие процессоры:

  • k8sattributes: для извлечения и предоставления данных модуля. Для этого необходимо задать переменную окружения с именем узла Kubernetes. Для этого приёмника требуется задать переменную окружения K8S_NODE_NAME с использованием Kubernetes Downward API (см. пример K8S_NODE_NAMEspec.nodeName).
  • transform: для преобразования метрик Kubernetes. Для этого необходимо задать переменную окружения CLUSTER_NAME с именем кластера. Задайте в качестве значения переменной произвольное имя, под которым ваш кластер будет отображаться в Ключ-АСТРОМ.
  • cumulativetodelta: Для включения преобразования кумулятивных показателей.

Экспортеры

В разделе exporters мы указываем экспортер otlphttp и настраиваем его с помощью URL-адреса нашего API Ключ-АСТРОМ и необходимого токена аутентификации.

Для этой цели мы устанавливаем следующие две переменные среды и ссылаемся на них в значениях конфигурации для endpoint и Authorization.

  • DT_ENDPOINT содержит базовый URL-адрес конечной точки API Ключ-АСТРОМ (например, https://{your-environment-id}.live.astromkey.com/api/v2/otlp)
  • DT_API_TOKEN содержит токен API

Сервисные контейнеры

В разделе service мы собираем объекты приёмника, процессора и экспортёра в контейнеры для трассировок, метрик и логов. Эти контейнеры позволяют нам отправлять сигналы OpenTelemetry через экземпляр Collector и автоматически дополнять их дополнительной информацией, специфичной для Kubernetes.

Установка и доступ к готовым панелям управления

Установка дашбордов

Чтобы сделать эти дашборды доступными в вашем клиенте, установите приложение OpenTelemetry Dashboards через Ключ-АСТРОМ.

Image4072.png

Доступ к дашбордам

При доступе к дашбордам у вас есть следующие возможности:

  • Кластер OpenTelemetry K8s : комплексный обзор производительности кластера, включая узлы, модули, контейнеры, события и многое другое.
  • Узел OpenTelemetry K8s — Pods : визуализирует потребление ресурсов на уровне pod по всем узлам Kubernetes.
  • Пространство имен OpenTelemetry K8s — Модули : анализирует использование ресурсов всех модулей в определенном пространстве имен.
  • Пространство имен OpenTelemetry K8s — Рабочие нагрузки : фокусируется на распределении ресурсов и производительности рабочих нагрузок в пространстве имен.
  • Постоянные тома OpenTelemetry K8s : отслеживает использование и емкость заявок на постоянные тома.

Image4073.png