Нестационарный, бессекретный многокластерный мониторинг в Azure Kubernetes Service с помощью Thanos, Prometheus и Azure Managed Grafana


Введение

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

Эта статья предназначена для инженеров, работающих в облаке, которые сталкиваются с проблемой наблюдения за несколькими кластерами Azure Kubernetes Clusters (AKS) и нуждаются в гибком, безэталонном решении, использующем доступное и экономически эффективное блочное хранилище для долгосрочного хранения метрик, которое не требует введения статических секретов для доступа к хранилищу (поскольку оно использует собственные управляемые идентификаторы Azure, связанные с кластером).

Это решение опирается на хорошо зарекомендовавшие себя проекты с открытым исходным кодом Cloud Native Computing Foundation (CNCF), такие как Thanos и Prometheus, а также на новую управляемую службу Azure Managed Grafana, недавно выпущенную в публичный предварительный просмотр. Это позволяет эфемерным кластерам иметь обновляемые метрики без необходимости хранить метрики в локальном хранилище в течение 2 часов при классическом развертывании Thanos sidecar для Prometheus.

Эта статья была написана под влиянием нескольких источников, наиболее важными из которых являются эти две статьи: Использование Azure Kubernetes Service с Grafana и Prometheus и Хранение метрик Prometheus с помощью Thanos, Azure Storage и Azure Kubernetes Service в блоге Microsoft Techcommunity.

Необходимые условия

  • Кластер AKS версии 1.23 или 1.24 с идентификатором пользователя, назначенным на идентификатор кубелета, или идентификатором, назначенным системой.
  • Возможность назначать роли на ресурсах Azure (роль администратора пользовательского доступа)
  • Учетная запись хранилища
  • (рекомендуется) Публичная зона DNS в Azure
  • Azure CLI
  • Helm CLI

Архитектура

Мы развернем все компоненты Thanos и Prometheus в одном кластере, но поскольку они соединяются только через вход, им не нужно располагаться вместе.

Общекластерные сервисы

Чтобы компоненты получения и запроса Thanos были доступны за пределами кластера и защищены TLS, нам понадобятся ingress-nginx и cert-manager. Для ingress разверните схему Helm с помощью следующей команды, чтобы учесть эту проблему в кластерах AKS >1.23:

helm upgrade --install ingress-nginx ingress-nginx 
  --repo https://kubernetes.github.io/ingress-nginx 
  --set controller.service.annotations."service.beta.kubernetes.io/azure-load-balancer-health-probe-request-path"=/healthz 
  --set controller.service.externalTrafficPolicy=Local 
  --namespace ingress-nginx --create-namespace
Войдите в полноэкранный режим Выход из полноэкранного режима

Обратите внимание на дополнительные аннотации и externalTrafficPolicy, установленный на Local.

Далее нам понадобится cert-manager для автоматического предоставления SSL-сертификатов от Let’s Encrypt; нам просто понадобится действительный адрес электронной почты для ClusterIssuer:

helm upgrade -i cert-manager 
  --namespace cert-manager --create-namespace 
  --set installCRDs=true 
  --set ingressShim.defaultIssuerName=letsencrypt-prod 
  --set ingressShim.defaultIssuerKind=ClusterIssuer 
  --repo https://charts.jetstack.io cert-manager

kubectl apply -f - <<EOF
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    email: email@email.com
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: nginx
EOF
Войдите в полноэкранный режим Выход из полноэкранного режима

И последнее, но не менее важное: мы добавим запись DNS для IP нашего входящего Loadbalancer, чтобы можно было легко получить публичные FQDN для наших конечных точек для Thanos receive и Thanos Query.

az network dns record-set a add-record  -n "*.thanos" -g dns -z cookingwithazure.com 
--ipv4-address $(kubectl get svc ingress-nginx-controller -n ingress-nginx -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
Вход в полноэкранный режим Выход из полноэкранного режима

Обратите внимание, как мы используем kubectl с типом вывода jsonpath, чтобы получить IP-адрес входящего сервера. Теперь мы можем использовать FQDN *.thanos.cookingwithazure.com в наших ингрессах, и cert-manager сможет без проблем получить относительный сертификат.

Подготовка учетной записи для хранения

Поскольку мы не хотим хранить секреты или служебные принципы в кластере, мы воспользуемся управляемыми идентификаторами, назначенными кластеру, и назначим соответствующие роли Azure Roles учетной записи хранилища.

После создания или определения используемой учетной записи хранения и создания в ней контейнера для хранения метрик Thanos назначьте роли с помощью azure cli; сначала определите clientID управляемой идентификации:

clientid=$(az aks show -g <rg> -n <cluster_name> -o json --query identityProfile.kubeletidentity.clientId)
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь назначьте роль Reader and Data Access учетной записи хранилища (она нужна для того, чтобы облачный контроллер мог генерировать ключи доступа для контейнеров) и роль Storage Blob Data Contributor только для контейнера (не нужно давать это разрешение на уровне учетной записи хранилища, поскольку оно позволит записывать данные в каждый контейнер, что нам не нужно. Всегда помните о применении принципов наименьших привилегий!)

az role assignment create --role "Reader and data access" --assignee $clientid --scope /subscriptions/<subID>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<account_name>

az role assignment create --role "Storage Blob Data Contributor" --assignee $clientid --scope /subscriptions/<subID>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<account_name>/containers/<container_name>
Вход в полноэкранный режим Выход из полноэкранного режима

Создание основных учетных данных аутентификации

Ок, мы немного обманули в заголовке: вам действительно нужен один мандат, по крайней мере, для этой настройки, и это мандат для доступа к API Prometheus, открытому Thanos из Azure Managed Grafana. Мы будем использовать те же учетные данные (но не стесняйтесь генерировать другие) для передачи метрик из Prometheus в Thanos с помощью remote-write через ingress controller. Вам понадобится надежный пароль, хранящийся в файле под названием pass локально:

htpasswd -c  -i auth thanos < pass

#Create the namespaces
kubectl create ns thanos
kubectl create ns prometheus

#for Thanos Query and Receive
kubectl create secret generic -n thanos basic-auth --from-file=auth

#for Prometheus remote write
kubectl create secret generic -n prometheus remotewrite-secret 
--from-literal=user=thanos 
--from-literal=password=$(cat pass)
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь у нас есть секреты для ингрессов и для развертывания Prometheus.

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

Мы будем использовать диаграмму Bitnami для развертывания необходимых нам компонентов Thanos.

helm upgrade -i thanos -n monitoring --create-namespace --values thanos-values.yaml bitnami/thanos
Вход в полноэкранный режим Выход из полноэкранного режима

Давайте пройдемся по соответствующим разделам файла значений:

objstoreConfig: |-
  type: AZURE
  config:
    storage_account: "thanostore"
    container: "thanostore"
    endpoint: "blob.core.windows.net"
    max_retries: 0
    user_assigned_id: "5c424851-e907-4cb0-acb5-3ea42fc56082"
Вход в полноэкранный режим Выход из полноэкранного режима

(замените user_assigned_id на объектный id вашего kubeletIdentity, для получения дополнительной информации об идентификаторах AKS, ознакомьтесь с этой статьей) Этот раздел инструктирует Thanos Store Gateway и Compactor использовать Azure Blob store, и использовать идентификатор kubelet для доступа к нему. Далее мы включим линейку и компоненты запросов:

ruler:
  enabled: true

query:
  enabled: true
...
queryFrontend:
  enabled: true
Войти в полноэкранный режим Выход из полноэкранного режима

Мы также включаем автомасштабирование для компонентов запросов без статических данных (query и query-frontend; последний помогает агрегировать запросы на чтение) и включаем простую аутентификацию для службы Query frontend с помощью аннотаций ingress-nginx:

queryFrontend:
...
  ingress:
    enabled: true
    annotations:
      cert-manager.io/cluster-issuer: letsencrypt-prod
      nginx.ingress.kubernetes.io/auth-type: basic
      nginx.ingress.kubernetes.io/auth-secret: basic-auth
      nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - thanos'
    hostname: query.thanos.cookingwithazure.com
    ingressClassName: nginx
    tls: true
Вход в полноэкранный режим Выйти из полноэкранного режима

Аннотация ссылается на секрет basic-auth, который мы создали ранее из учетных данных htpasswd. Обратите внимание, что те же аннотации находятся в разделе receive, поскольку мы используем точно такой же секрет для отправки метрик в Thanos (хотя и с другим hostname).

Удаленная запись в Prometheus

Пока полная поддержка режима агента не появится в операторе Prometheus (следите за этим выпуском), мы можем использовать функцию удаленной записи для мгновенной отправки всех метрик на удаленную конечную точку, в нашем случае представленную ингрессом Thanos Query Frontend. Давайте начнем с развертывания Prometheus с помощью хелпа kube-prometheus-stack:

helm  upgrade -i -n prometheus promremotewrite -f prom-remotewrite.yaml prometheus-community/kube-prometheus-stack
Войти в полноэкранный режим Выход из полноэкранного режима

Давайте просмотрим файл значений, чтобы объяснить опции, необходимые для включения удаленной записи:

prometheus:
  enabled: true
  prometheusSpec:
    externalLabels:
      datacenter: westeu
      cluster: playground
Войти в полноэкранный режим Выйти из полноэкранного режима

Это включает Prometheus и прикрепляет две дополнительные метки к каждой метрике, так что становится проще фильтровать данные, поступающие из нескольких источников/кластеров, позже в Grafana.

    remoteWrite:
    - url: "https://receive.thanos.cookingwithazure.com/api/v1/receive"
      name: Thanos
      basicAuth:
        username:
          name: remotewrite-secret
          key: user
        password:
          name: remotewrite-secret
          key: password
Войти в полноэкранный режим Выйти из полноэкранного режима

Этот раздел указывает на удаленную конечную точку (защищенную по SSL с помощью сертификатов Let’s Encrypt, которым доверяет хранилище сертификатов на узлах AKS; если вы используете недоверенный сертификат, обратитесь к разделу TLSConfig API PrometheusSpec). Обратите внимание, что учетные данные для доступа к удаленной конечной точке поступают из секрета, созданного заранее и хранящегося в пространстве имен prometheus.

Обратите внимание, что хотя Prometheus для простоты развернут в том же кластере, что и Thanos, он отправляет метрики на входящий FQDN, поэтому можно легко распространить эту настройку на несколько удаленных кластеров и собирать их метрики в единый централизованный коллектор Thanos (и единое хранилище blob), причем все метрики будут правильно помечены и идентифицированы.

Наблюдение за стеком с помощью Azure Managed Grafana

Azure Managed Grafana(AME) — это новое предложение в наборе инструментов наблюдаемости в Azure, и оно основано на популярной системе дашбординга с открытым исходным кодом Grafana. Помимо интеграции с Azure из коробки, AME представляет собой полнофункциональное развертывание Grafana, которое можно использовать для мониторинга и построения графиков различных источников, включая Thanos и Prometheus. Для начала перейдите на портал Azure Portal и разверните AME; затем получите конечную точку на вкладке Overview и подключитесь к вашему экземпляру AME.

Добавьте новый источник типа Prometheus и базовую аутентификацию (ту же самую, которую мы создали ранее):

Поздравляем! Теперь мы можем визуализировать данные, поступающие из Prometheus, нам нужна только приборная панель для правильного отображения данных. Перейдите (на левой навигационной панели) Dashboards-> Browse и нажмите на Import; импортируйте «Kubernetes / Views / Global» (ID: 15757) в Grafana, и вы сможете увидеть метрики кластера:

Импортированная приборная панель не имеет фильтра для кластера или региона, поэтому она будет показывать все метрики кластера в агрегированном виде. В одной из следующих статей мы покажем, как добавить переменную в приборную панель Grafana, чтобы правильно выбирать и фильтровать кластерные представления.

Будущая работа

Эта установка позволяет автомасштабировать приемник и фронтенд запросов, поскольку горизонтальные автоскалеры развернуты и связаны с компонентами Thanos. Для еще большей масштабируемости и изоляции метрик Thanos может быть развернут несколько раз (каждый из которых связан с различными учетными записями хранилища по мере необходимости) с разным входом для разделения метрик на источнике (таким образом, они отображаются как отдельные источники в Grafana, которые затем можно отображать в одной панели, выбирая соответствующий источник для каждого графика и запроса).

Оцените статью
devanswers.ru
Добавить комментарий