kertenkerem_
· Spor ve Sağlık · 4 dk okuma

Mühendis Yakılmasına Son: Sağlıklı ve Sürdürülebilir Bir On-Call Kültürü Nasıl Kurulur?

Gece saat 03:00. Slack ya da PagerDuty’den gelen o tanıdık sesle uyanıyorsunuz. Modern bir devops kültürü yerine “kim ayaktaysa baksın” kaosunu yaşıyorsanız, ekibinizde tükenmişlik (burnout) çanları çoktan çalmaya başlamış demektir. Doğru yapılandırılmamış bir on-call yönetimi yalnızca sistemlerin değil, en yetenekli mühendislerinizin de sessizce istifa etmesine (ya da daha kötüsü, ortada çökmesine) neden olur. Bu yazıda incident response süreçlerini nasıl insani, sürdürülebilir ve otomatize hale getirebileceğimizi inceliyoruz. Teoriyi bir kenara bırakıp doğrudan production ortamında işe yarayacak pratiklere odaklanıyoruz.

Alert fatigue ile savaş: yalnızca “aksiyon alınabilir” alarmlar

Alert fatigue (alarm yorgunluğu), on-call mühendislerinin en büyük düşmanıdır. CPU kullanımının %85’e çıkması tek başına bir alarm sebebi olmamalıdır. Alarm çaldığında mühendisin yapabileceği net, manuel bir aksiyon yoksa (örneğin sistem kendi kendine auto-scale oluyorsa) o alarm çöp gürültüdür. Pager seviyesinde yalnızca kullanıcı deneyimini doğrudan etkileyen (SLO/SLI ihlalleri) ya da sistemin tamamen durma noktasına geldiğini gösteren durumlar olmalıdır.

Gürültüyü azaltmak için Prometheus Alertmanager üzerinde akıllı gruplama (grouping) ve engelleme (inhibition) kuralları uygulamalısınız. Örneğin tüm veri merkezi down olmuşken her bir pod için ayrı ayrı 500 tane “PodDown” alarmı almak yerine tek bir “DatacenterDown” alarmı tetiklenmeli, alt alarmlar susturulmalıdır.

Aşağıdaki Alertmanager konfigürasyon bloğu, benzer alarmları nasıl gruplayıp birbirini ezmesini (inhibit) sağlayabileceğinizi gösterir:

# alertmanager.yml
route:
  group_by: ['alertname', 'cluster', 'service']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: 'pagerduty-high-priority'
  routes:
    - match:
        severity: warning
      receiver: 'slack-low-priority'

inhibit_rules:
  - source_match:
      alertname: 'NodeNetworkDown'
    target_match_re:
      alertname: 'InstanceDown|TargetDown'
    equal: ['node', 'instance']

Bu kuralı neden böyle yazıyoruz? NodeNetworkDown olduğunda o node üzerindeki tüm container’ların erişilemez olması kaçınılmazdır. Engelleme kuralı sayesinde gece yarısı telefonunuza 50 farklı push bildirimi gelmez; sorunun kök nedenine odaklanan tek bir kritik alarm alırsınız.

Rotasyon ve eskalasyon politikalarında matematiksel adalet

Adil bir on-call rotasyonu oluşturmak excel tablolarından fazlasını gerektirir. Tek bir birincil (Primary) nöbetçi koyup tüm yükü ona yıkmak tek hata noktası (SPOF) yaratmaktır. Sürdürülebilir bir sistemde Primary ve Secondary (Shadow/Backup) rolleri her zaman tanımlı olmalıdır.

Global bir ekipseniz “Follow-the-Sun” modelini uygulamak hayat kurtarır. Bu modelde nöbetler, coğrafi olarak gündüz vaktinde olan bölgeye devredilir. Lokal bir ekipseniz haftalık rotasyonları cuma günü saat 17:00’de değil, salı günü öğleden sonra devretmek daha sağlıklıdır. Böylece yeni nöbetçi haftalık iş yoğunluğunun ortasında sisteme ısınır ve olası devir-teslim sorunlarını mesai saatleri içinde çözer.

Bu yapıyı kod olarak yönetmek (Infrastructure as Code) esnekliği artırır. Aşağıdaki Terraform konfigürasyonu, PagerDuty üzerinde adil bir eskalasyon politikasını tanımlar:

# pagerduty.tf
resource "pagerduty_escalation_policy" "production_policy" {
  name      = "Production Escalation Policy"
  num_loops = 2

  rule {
    escalation_delay_in_minutes = 10
    target {
      id   = pagerduty_schedule.primary_schedule.id
      type = "schedule_reference"
    }
  }

  rule {
    escalation_delay_in_minutes = 15
    target {
      id   = pagerduty_schedule.secondary_schedule.id
      type = "schedule_reference"
    }
  }

  rule {
    escalation_delay_in_minutes = 20
    target {
      id   = pagerduty_user.engineering_lead.id
      type = "user_reference"
    }
  }
}

Buradaki mantık şu: Primary nöbetçi 10 dakika içinde alarmı ack’lemezse (onaylamazsa) alarm otomatik olarak Secondary nöbetçiye geçer. O da 15 dakika içinde yanıt vermezse eskalasyon engineering lead seviyesine çıkar. Bu hiyerarşi nöbetteki mühendisin üzerindeki psikolojik baskıyı azaltır, çünkü arkasında her zaman bir güvence olduğunu bilir.

Incident response otomasyonu: self-healing ve ChatOps

Bir alarm çaldığında mühendisin ilk işi genellikle terminali açıp df -h yazmak ya da ilgili servisi restart etmekse, ciddi bir otomasyon eksiği var demektir. Tekrarlanan runbook adımları, insan müdahalesine gerek kalmadan otomatik olarak çalışmalıdır.

Örneğin disk doluluk alarmı tetiklendiğinde geçici cache dosyalarını temizleyen ya da log rotasyonunu başlatan bir Kubernetes DaemonSet veya serverless fonksiyon yazabilirsiniz. İnsanı yalnızca “otomasyonun çözemediği” durumlarda devreye sokmalıyız.

Manuel müdahale şartsa bunu Slack/MS Teams üzerinden ChatOps ile yapmak hızı katlar. Aşağıdaki basit bash script’i, Alertmanager webhook’undan gelen disk alarmını yakalayıp AWS API’si üzerinden EBS hacmini otomatik olarak genişleten bir self-healing mekanizmasının mantığını gösteriyor:

#!/usr/bin/env bash
# auto_expand_disk.sh
set -euo pipefail

ALERT_PAYLOAD=$(cat)
VOLUME_ID=$(echo "$ALERT_PAYLOAD" | jq -r '.alerts[0].labels.volume_id')
REGION=$(echo "$ALERT_PAYLOAD" | jq -r '.alerts[0].labels.region')

echo "Kritik disk alarmı alındı: $VOLUME_ID. Disk boyutu %10 artırılıyor..."

# Mevcut boyutu al
CURRENT_SIZE=$(aws ec2 describe-volumes \
  --volume-ids "$VOLUME_ID" \
  --region "$REGION" \
  --query "Volumes[0].Size" --output text)

NEW_SIZE=$(( CURRENT_SIZE + (CURRENT_SIZE * 10 / 100) ))

# AWS üzerinde diski genişlet
aws ec2 modify-volume \
  --volume-id "$VOLUME_ID" \
  --region "$REGION" \
  --size "$NEW_SIZE"

echo "Disk başarıyla $NEW_SIZE GB değerine genişletildi."

Böyle bir otomasyonu neden kuruyoruz? Gece 04:00’te bir mühendisi yalnızca disk genişletmek için uyandırmak, operasyonel verimliliği baltalamaktan başka bir işe yaramaz. Bırakın otomasyon diski genişletsin, mühendis sabah kahvesini içerken slack kanalındaki log’lardan olayı takip etsin.

Suçsuz (blameless) post-mortem kültürü

Sürdürülebilir on-call kültürünün teknik olmayan en kritik ayağı olay sonrası analizlerdir. Bir incident bittiğinde her şey bitmiş sayılmaz. Amaç “Hatayı kim yaptı?” sorusunu sormak değil, “Sistemimiz bu hatanın yapılmasına nasıl izin verdi?” sorusuna yanıt aramaktır.

Blameless post-mortem süreçlerinde şu üç kuralı asla esnetmeyin:

  • İnsanlar hata yapabilir: Süreçleriniz ve tool’larınız bu hataları tolere edebilecek şekilde tasarlanmalıdır.
  • Zaman çizelgesi çıkarın: Alarmın çaldığı andan ilk müdahaleye ve nihai çözüme (mitigation) kadar geçen süreci kronolojik olarak dökün.
  • Aksiyon maddeleri (action items) üretin: Her post-mortem belgesinden, benzer hatanın gelecekte tekrarlanmasını önleyecek en az 2 adet Jira task’i çıkmalı ve bunlar sonraki sprint’e dahil edilmelidir.

Sonuç: mühendisleri yakmadan sistemleri ayakta tutmak

Sağlıklı bir on-call sistemi kurmak, teknik bir zorunluluk olduğu kadar etik bir sorumluluktur. Ekibinizi sürekli yangın söndüren itfaiyecilere dönüştürmek yerine, yangının hiç çıkmamasını sağlayan sistem mimarlarına dönüştürün. Alarmlarınızı sadeleştirin, rotasyonlarınızı adilleştirin, otomasyona yatırım yapın ve her hatayı sisteminizi güçlendirmek için bir fırsat olarak görün. İyi bir SRE, uykusunu en iyi almış SRE’dir.