Введение
Наблюдаемость имеет первостепенное значение для каждой распределенной системы, и она становится все более сложной в мире облачных технологий, где мы можем развернуть несколько эфемерных кластеров и хотим сохранить их метрики после окончания их жизненного цикла.
Эта статья предназначена для инженеров, работающих в облаке, которые сталкиваются с проблемой наблюдения за несколькими кластерами 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, которые затем можно отображать в одной панели, выбирая соответствующий источник для каждого графика и запроса).