Table of Contents

Задача

Нужно настроить:

Настройки в кластере k8s с опубликованными приложениями

Я предполагаю, что работы идут в уже настроенном кластере, в котором есть Ingress Controller и из которого можно публиковать сервисы (prometheus) наружу.
В кластере в котором работают приложения нужно:

Установка оператора prometheus

https://grafana.com/docs/grafana-cloud/kubernetes/prometheus/prometheus_operator/
Создаем CRD's и устанавливаем оператора:

NS=monitoring
kubectl create ns $NS
wget https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/master/bundle.yaml
sed -i "s/  namespace: default/  namespace: $NS/g" ./bundle.yaml
kubectl create -f ./bundle.yaml

Создаем сервис-аккаунт, роль и даем права:

kubectl apply -n $NS -f -<<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
  name: prometheus
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus
rules:
- apiGroups: [""]
  resources:
  - nodes
  - nodes/metrics
  - services
  - endpoints
  - pods
  verbs: ["get", "list", "watch"]
- apiGroups: [""]
  resources:
  - configmaps
  verbs: ["get"]
- apiGroups:
  - networking.k8s.io
  resources:
  - ingresses
  verbs: ["get", "list", "watch"]
- nonResourceURLs: ["/metrics"]
  verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: prometheus
subjects:
- kind: ServiceAccount
  name: prometheus
  namespace: $NS
EOF

Создаем Prometheus:
https://github.com/prometheus-operator/prometheus-operator/issues/2382

kubectl apply -n monitoring -f - <<EOF
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  name: prometheus
  labels:
    app: prometheus
spec:
  externalUrl: https://ingress.domain.com/prometheus/
  routePrefix: /prometheus
  image: quay.io/prometheus/prometheus:v2.22.1
  nodeSelector:
    kubernetes.io/os: linux
  replicas: 2
  resources:
    requests:
      memory: 400Mi
  securityContext:
    fsGroup: 2000
    runAsNonRoot: true
    runAsUser: 1000
  serviceAccountName: prometheus
  version: v2.22.1
  ruleNamespaceSelector:
    matchLabels:
      monitoring: prometheus
  serviceMonitorNamespaceSelector:
    matchLabels:
      monitoring: prometheus
  serviceMonitorSelector: {}
---
apiVersion: v1
kind: Service
metadata:
  name: prometheus-web
  labels:
    prometheus: prometheus
spec:
  ports:
  - name: web
    port: 9090
    targetPort: web
  selector:
    prometheus: prometheus
  sessionAffinity: ClientIP
  type: ClusterIP
EOF

Тут важно обратить внимание на параметры externalUrl и routePrefix. Они должны соответветствовать тому, что будет прописано в Ingress. Они же параметры командной строки prometheus - –web.external-url и –web.route-prefix соответственно.

Пометим неймспйесы, которые должны мониториться этим прометиусом

kubectl label ns monitoring monitoring=prometheus

Публикация prometheus через Ingress

Prometheus будет опубликован наружу через Ingress и защищен basic-аутентификацией.

Создадим секрет для basic-аутентификации:

kubectl create -n monitoring secret generic prometheus-basic-auth --from-literal=auth=username:$(openssl passwd -5 superpassword)

И теперь можем создать ингресс:
https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/user-guides/exposing-prometheus-and-alertmanager.md#ingress

kubectl apply -n monitoring -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: prometheus-metrics
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: prometheus-basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required'
spec:
  rules:
  - host: ingress.domain.com
    http:
      paths:
      - backend:
          service:
            name: prometheus-web
            port:
              number: 9090
        path: /prometheus
        pathType: Prefix
  tls:
  - hosts:
    - ingress.domain.com
    secretName: ingress-domain-com-tls
EOF

Тут важно - path должен быть таким же как и в настройках prometheus, имя секрета в аннотации - соответствовать имени созданного серкрета с учеткой basic-auth. Можно проверить:

curl -u 'username:superpassword' https://ingress.domain.com/prometheus/metrics

Или какие-то более осмысленные метрики:

curl -u 'username:superpassword' -g 'https://ai-eu-1.voximplant.com/prometheus/federate?match[]={container="gateway-container"}'

Настройка ServiceMonitors

https://docs.openshift.com/container-platform/4.9/rest_api/monitoring_apis/servicemonitor-monitoring-coreos-com-v1.html

kubectl apply -n monitoring -f -<<EOF
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: gateway
spec:
  selector:
    matchLabels:
      app: gateway
  namespaceSelector:
    matchNames:
    - nlu-prod
  endpoints:
  - targetPort: 8080
    path: /metrics
    scheme: http
    interval: 10s
EOF

Траблшутинг проблем с сервис-мониторами: https://github.com/prometheus-operator/prometheus-operator/blob/main/Documentation/troubleshooting.md#troubleshooting-servicemonitor-changes Что тут важно:

Настройки на основном сервере логирования

На основоном сервере логирования но настроить federation
Примерно так: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config

# https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config
- job_name: 'kubernetes-pods-aws'
  scrape_interval: 15s

  honor_labels: true
  metrics_path: '/prometheus/federate'

  basic_auth:
    username: username
    password: superpassword

  scheme: https

  params:
    match[]:
      - '{job=~".+"}'

  static_configs:
    - targets:
      - 'remote.prometheus.domain.com:443'
      labels:
        cluster: remote_prometheus_domain_com

И на основном сервере логирования можно выполнить запрос какого-либо значения, указав в качестве параметра фильтрации - метку для данного таргета:

curl -g 'http://127.0.0.1:9090/api/v1/query?query=system_cpu_usage{container="container_name",cluster="remote_prometheus_domain_com"}'