Kubernetes üzerinde Helm kullanarak kolayca monitoring uygulamanızı kurgulayabilir, cluster içerisinde yaşanan tüm detayları anlık izleyebilir, uyguladığınız kurallara göre alarm üretebilirsiniz,
Makale ile ilgili dosyalara https://github.com/mertyakan/kubernetes-monitoring adresinden erişim sağlayabilirsiniz,
Günümüzde sıkça kullanıldığından ürünlerin detaylarını açıklamadan deploy aşamasına geçebiliriz,
Kısaca prometheus kubernetes cluster içerisindeki tüm node’lar üzerinde birer Daemonset yaratarak verileri topluyor, Grafana ile görselleştiriyoruz, Alertmanager ise prometheus üzerindeki verileri inceleyerek yaşanan bir felaketi size bildirim olarak iletiyor,
İlgili proje için; https://github.com/prometheus-community/helm-charts/tree/main/charts/kube-prometheus-stack helm chart’ını kullanacağız,
Varsayılan olarak hiç bir özelleştirmede bulunmazsanız, aşağıdaki komut deploy için yeterli olacaktır,
helm install [RELEASE_NAME] prometheus-community/kube-prometheus-stack
Özelleştirme için;
helm show values prometheus-community/kube-prometheus-stack
veya https://github.com/prometheus-community/helm-charts/blob/main/charts/kube-prometheus-stack/values.yaml dosyasını inceleyebilirsiniz,
Bu makalede 3 parça halinde yaml dosyasını açıklamaya çalışacağım;
1.Prometheus
yaml dosyasını incelediğimizde;
Prometheus’un 50GB disk kullanabileceği, 10 gün sonrasındaki verileri sileceği ve kubernetes üzerinde çalışan mysql verilerini (bkn: Dashboard ID: 7362 ) export edebileceğimiz scrape ayarlarını gözlemliyoruz,
# for prometheus prometheus: prometheusSpec: ##### data retention configs retention: 10d retentionSize: "" ###### pvc-config storageSpec: volumeClaimTemplate: spec: storageClassName: storageclass 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
2. Grafana
yaml dosyasını incelediğimizde;
Grafana’nın kullanacağı storageclass’ı belirlenebildiği, defaultta dashboardların Istanbul timezone’u alacağını, ingress olarak expose edildiği ayarlarını gözlemliyoruz,
# for grafana grafana: persistence: enabled: true storageClassName: storageclass service: type: LoadBalancer defaultDashboardsTimezone: "Europe/Istanbul" ingress: annotations: kubernetes.io/ingress.class: nginx enabled: true path: / hosts: - burayaurl.gelecek tls: - secretName: tls-secret hosts: - "*.url.com"
3.Alertmanager
En alengirli kısma geldik 😀 yaml dosyasını inceleyelim;
Bu makalede, alertmanager’ın ürettiği bildirimleri slack ile alıyoruz.
Aslında en alttan başlayarak yorumlayacak olursak;
- Receivers kısmında slack konfigürasyonu gerçekleştiriliyor, slack üzerinde yeni bir kanal açıyorsunuz ve https://api.slack.com üzerinde ilgili kanal’a webhook ekliyorsunuz,
- Title ve dosya sonuna kadar olan tüm satırlar slack’te göreceğimiz bildirimin içerikleridir, bu config yeterli düzeyde bilgi aktarmaktadır, aşağıda örnek bir bildirimi gözlemleyebilirsiniz;
- Alarmlar için hangi severity durumunda bildirim göndereceğini match kısmında düzenlebiliyorsunuz,
- Route kısmında hangi alıcıları bu bildirimlerin gideceği kısmı düzenliyoruz,
- Birden fazla alıcı oluşturabilirsiniz detaylar için Alertmanager sayfasını inceleyebilirsiniz.
# for alertmanager alertmanager: enabled: true config: global: resolve_timeout: 1h route: group_by: ['alertname'] #group_wait: 1s #group_interval: 3m #repeat_interval: 30m receiver: 'prometheus-test-slack' routes: - match: severity: critical|warning receiver: 'prometheus-test-slack' receivers: - name: 'prometheus-test-slack' slack_configs: - api_url: 'https://hooks.slack.com/buraya-api-slack-url' channel: 'prometheus-test' send_resolved: false icon_url: https://avatars3.githubusercontent.com/u/3380462 title: |- [{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }} for {{ .CommonLabels.job }} {{- if gt (len .CommonLabels) (len .GroupLabels) -}} {{" "}}( {{- with .CommonLabels.Remove .GroupLabels.Names }} {{- range $index, $label := .SortedPairs -}} {{ if $index }}, {{ end }} {{- $label.Name }}="{{ $label.Value -}}" {{- end }} {{- end -}} ) {{- end }} text: >- {{ range .Alerts -}} *Alert:* {{ .Annotations.title }}{{ if .Labels.severity }} - `{{ .Labels.severity }}`{{ end }} *Description:* {{ .Annotations.description }} *Details:* {{ range .Labels.SortedPairs }} • *{{ .Name }}:* `{{ .Value }}` {{ end }} {{ end }}
Daha önce Alertmanager ile ilgili bir çalışmanız olmadıysa ilk görüşte karışık gelebilir,
Özetle, öncesinde kuralları belirliyoruz, bu stack içerisinde bazı kurallar otomatik olarak entegre oluyor, ayrıca kural eklemek isterseniz, https://awesome-prometheus-alerts.grep.to/rules#kubernetes sitesini şiddetle tavsiye ederim
Kurallar çok fazla olduğundan ayrı bir yaml dosyasında tuttum
groups: - name: AllRules interval: 5s rules: - alert: PrometheusJobMissing expr: absent(up{job="prometheus"}) for: 0m labels: severity: warning annotations: summary: Prometheus job missing (instance {{ $labels.instance }}) description: "A Prometheus job has disappeared\n VALUE = {{ $value }}\n LABELS = {{ $labels }}" - alert: PrometheusTargetMissing expr: up == 0 for: 0m labels: severity: critical annotations: summary: Prometheus target missing (instance {{ $labels.instance }}) description: "A Prometheus target has disappeared. An exporter might be crashed.\n VALUE = {{ $value }}\n LABELS = {{ $labels }}" #kubernetes - alert: KubernetesMemoryPressure expr: kube_node_status_condition{condition="MemoryPressure",status="true"} == 1 for: 2m labels: severity: critical annotations: summary: Kubernetes memory pressure (instance {{ $labels.instance }}) description: "{{ $labels.node }} has MemoryPressure condition\n VALUE = {{ $value }}\n LABELS = {{ $labels }}"