Kubernetes prometheus stack (Grafana, Prometheus & scrape config, Alertmanager) Kubernetes 1.25.2

Bu hafta gerçekleştirdiğimiz makaleleri göz önünde bulundurduğumuzda, temiz kurulum bir kubernetes cluster, portworx, external load balance (metallb), ingress’e sahibiz. Şimdi kubernetes clusterı monitor edip, istenmeyen durumlarda alarm üretmek için çalışmalar gerçekleştireceğiz.

Şimdi prometheus ve Grafana için pvc tanımı olduğunu gözlemleyeceğiz (storageclass: px-db-high) storageclass eklemek için; https://www.ibm.com/docs/en/cloud-paks/cp-data/3.5.0?topic=storage-creating-portworx-classes

Aynı zamanda Grafana erişimi için ingress kullanacağız,

Ek olarak prometheus üzerinde exporterların konfigürasyonu için scrape ayarlarını (mysql, Nginx, ingress, Redis, mongo, rabbitmq, elasticsearch, portworx )

Son olarakta alertmanager ile slack üzerinden bildirim yapmayı hedeflemekteyiz,

Aşağıda belirttiğim tüm komutlar tek bir values dosyasında olabilir, erişmek için https://github.com/mertyakan/pretest-prometheus-stack/blob/main/pretest.yaml

#https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack
# for grafana -- from dependency chart
grafana:
  persistence:
    enabled: true
    storageClassName: px-db-high
  service:
    type: ClusterIP
  defaultDashboardsTimezone: "Europe/Istanbul"

  ingress:
    annotations:
      kubernetes.io/ingress.class: nginx
    enabled: true
    path: /
    hosts:
      -  burayaistediginizurl.com #degistiriniz
    tls:
      - secretName: tls-secret
        hosts:
        - "*.istediginizurl-secret.com" #degistiriniz, sonradan sertifikayı yerlestirebilirsiniz. İleriki makalelerde certmanager olacak, sertifika otomatik oluşturulacak.

# for prometheus
prometheus:
  prometheusSpec:
    ##### data retention configs
    retention: 10d
    retentionSize: ""

    ###### pvc-config
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: px-db-high
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 50Gi

# scrape configs
    additionalScrapeConfigs:
    - job_name: mysqld-exporter
      scrape_interval: 5s
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - action: keep
        source_labels:
        - __meta_kubernetes_service_label_app_kubernetes_io_name
        regex: (mariadb|mysql)
      - action: keep
        source_labels:
        - __meta_kubernetes_pod_container_port_number
        regex: 9104
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: instance

    - job_name: nginx-exporter
      scrape_interval: 5s
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - action: keep
        source_labels:
        - __meta_kubernetes_service_label_app_kubernetes_io_name
        regex: nginx
      - action: keep
        source_labels:
        - __meta_kubernetes_pod_container_port_number
        regex: 9113
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: instance

    - job_name: ingress-nginx-exporter
      scrape_interval: 5s
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - action: keep
        source_labels:
        - __meta_kubernetes_service_label_app_kubernetes_io_name
        regex: ingress-nginx
      - action: keep
        source_labels:
        - __meta_kubernetes_pod_container_port_number
        regex: 10254
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: instance

    - job_name: redis-exporter
      scrape_interval: 5s
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - action: keep
        source_labels:
        - __meta_kubernetes_service_label_app_kubernetes_io_name
        regex: redis
      - action: keep
        source_labels:
        - __meta_kubernetes_pod_container_port_number
        regex: 9121
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: instance

    - job_name: mongo-exporter
      scrape_interval: 5s
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - action: keep
        source_labels:
        - __meta_kubernetes_service_label_app_kubernetes_io_name
        regex: mongodb
      - action: keep
        source_labels:
        - __meta_kubernetes_pod_container_port_number
        regex: 9216
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: instance

    - job_name: rabbitmq-exporter
      scrape_interval: 5s
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - action: keep
        source_labels:
        - __meta_kubernetes_service_label_app_kubernetes_io_name
        regex: rabbitmq
      - action: keep
        source_labels:
        - __meta_kubernetes_pod_container_port_number
        regex: 9419
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: instance

    - job_name: elasticsearch-exporter
      scrape_interval: 5s
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - action: keep
        source_labels:
        - __meta_kubernetes_service_label_release
        regex: .*-elasticsearch-exporter
      - action: keep
        source_labels:
        - __meta_kubernetes_pod_container_port_number
        regex: 9108
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: instance

    - job_name: portworx-exporter
      scrape_interval: 5s
      static_configs:
        - targets: ['localhost:9090','10.10.10.111:9001','10.10.10.112:9001','10.10.10.113:9001','10.10.10.114:9001','10.10.10.115:9001']

# for alertmanager
alertmanager:
  enabled: true
  config:
    global:
      resolve_timeout: 1h

    route:
      group_by: ['alertname']
      receiver: 'prometheus-pretest-slack'
      routes:
      - match:
          severity: critical|warning
        receiver: 'prometheus-pretest-slack'
      - match:
          alertname: 'InfoInhibitor'
        receiver: null

    receivers:
    - name: 'null'

    - name: 'prometheus-pretest-slack'
      slack_configs:
      - api_url: 'https://hooks.slack.com/services/BURAYAAPIURL' #degistiriniz,
        channel: 'prometheus-pretest'
        username: '{{ template "slack.default.username" . }}'
        color: '{{ if eq .Status "firing" }}danger{{ else }}good{{ end }}'
        title: '{{ template "slack.default.title" . }}'
        title_link: '{{ template "slack.default.titlelink" . }}'
        pretext: '{{ .CommonAnnotations.summary }}'
        text: |-
          {{ range .Alerts }}
             *Alert:* {{ .Annotations.summary }} - `{{ .Labels.severity }}`
            *Description:* {{ .Annotations.description }}
            *Details:*
            {{ range .Labels.SortedPairs }} • *{{ .Name }}:* `{{ .Value }}`
            {{ end }}
          {{ end }}
        fallback: '{{ template "slack.default.fallback" . }}'
        icon_emoji: '{{ template "slack.default.iconemoji" . }}'
        icon_url: '{{ template "slack.default.iconurl" . }}'

Bölüm bölüm açıklamak gerekir ise; ilk kısım Grafana ile ilgili.

Hangi storage class kullanılacağını, varsayılan saat ayarlarını ve ingress tanımını gerçekleştiriyoruz,

grafana:
  persistence:
    enabled: true
    storageClassName: px-db-high
  service:
    type: ClusterIP
  defaultDashboardsTimezone: "Europe/Istanbul"

  ingress:
    annotations:
      kubernetes.io/ingress.class: nginx
    enabled: true
    path: /
    hosts:
      -  burayaistediginizurl.com #degistiriniz
    tls:
      - secretName: tls-secret
        hosts:
        - "*.istediginizurl-secret.com" #degistiriniz, sonradan sertifikayı 

Prometheus ile ilgili ayarları 2 bölümde açıklayalım,

Ne kadar data tutulacağını, storageclass’ı ve disk alanını belirliyoruz,

prometheus:
  prometheusSpec:
    ##### data retention configs
    retention: 10d
    retentionSize: ""

    ###### pvc-config
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: px-db-high
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 50Gi

Devamında ise scrape ayarlarını gözlemliyoruz, 1 tanesini incelemek gerekirse, __meta_kubernetes_service_label_app_kubernetes_io_name karşılığı mariadb, mysql ismi geçiren ve container portu 9104 (metric) olan verileri prometheus üzerinde gözlemleyebileceğiz .

# scrape configs
    additionalScrapeConfigs:
    - job_name: mysqld-exporter
      scrape_interval: 5s
      kubernetes_sd_configs:
      - role: endpoints
      relabel_configs:
      - action: keep
        source_labels:
        - __meta_kubernetes_service_label_app_kubernetes_io_name
        regex: (mariadb|mysql)
      - action: keep
        source_labels:
        - __meta_kubernetes_pod_container_port_number
        regex: 9104
      - action: replace
        source_labels:
        - __meta_kubernetes_pod_name
        target_label: instance

Alertmanager ile ilgili konfigürasyon ise şöyle;

alertmanager:
  enabled: true
  config:
    global:
      resolve_timeout: 1h

    route:
      group_by: ['alertname']
      receiver: 'prometheus-pretest-slack'
      routes:
      - match:
          severity: critical|warning
        receiver: 'prometheus-pretest-slack'
      - match:
          alertname: 'InfoInhibitor'
        receiver: null

    receivers:
    - name: 'null'

    - name: 'prometheus-pretest-slack'
      slack_configs:
      - api_url: 'https://hooks.slack.com/services/APIURL' #degistiriniz,
        channel: 'prometheus-pretest'
        username: '{{ template "slack.default.username" . }}'
        color: '{{ if eq .Status "firing" }}danger{{ else }}good{{ end }}'
        title: '{{ template "slack.default.title" . }}'
        title_link: '{{ template "slack.default.titlelink" . }}'
        pretext: '{{ .CommonAnnotations.summary }}'
        text: |-
          {{ range .Alerts }}
             *Alert:* {{ .Annotations.summary }} - `{{ .Labels.severity }}`
            *Description:* {{ .Annotations.description }}
            *Details:*
            {{ range .Labels.SortedPairs }} • *{{ .Name }}:* `{{ .Value }}`
            {{ end }}
          {{ end }}
        fallback: '{{ template "slack.default.fallback" . }}'
        icon_emoji: '{{ template "slack.default.iconemoji" . }}'
        icon_url: '{{ template "slack.default.iconurl" . }}'
helm upgrade --install prometheus prometheus-community/kube-prometheus-stack --create-namespace -n prom -f pretest-cluster.yaml

Eğer aşağıdaki gibi bir uyarı alırsanız validateingwebhook silebilirsiniz.; https://stackoverflow.com/questions/61616203/nginx-ingress-controller-failed-calling-webhook

Error: UPGRADE FAILED: failed to create resource: Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": failed to call webhook: Post "https://ingress-nginx-controller-admission.ingress-nginx.svc:443/networking/v1/ingresses?timeout=10s": dial tcp 10.111.223.226:443: connect: no route to host
Kubectl delete validatingwebhookconfigurations.admissionregistration.k8s.io ingress-nginx-admission

Slack için API nasıl oluşturulur sorusuna da şöyle cevap verelim;

https://api.slack.com/apps adresine erişerek yeni bir app yaratıyoruz,

From scratch işaretliyoruz,

Uygulamanın adını ve hangi workspace’te olacağını belirliyoruz,

Açılan ekrandan Incoming Webhook seçiyoruz

Aktif ediyoruz ve Add New Webhook to Workspace seçiyoruz,

Alertmanager’da belirttiğiniz kanalın ismini seçiyoruz

Son olarak alertmanager’ın kurallarını tanımlayabiliriz, bunun için aşağıdaki kaynağı kullanıyorum, https://awesome-prometheus-alerts.grep.to/rules.html

İhtiyacınız olan uyarıları bir dosyaya kaydedip kubectl ile apply edebilirsiniz.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.