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
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.