B3 — İlk Kırık Lab#
"Tutorial 'şunu kur' der; kırık lab 'şunu tamir et' der. İkincisi mühendis yetiştirir."
Blok: B — Görebilmek · Süre: ~12 saat · Ön koşul: B1, B2
🎯 Bu modülü bitirdiğinde#
- Ne bozulduğu söylenmeden, yalnızca belirtiden yola çıkıp arızayı sistematik olarak daraltırsın.
- Hipotezini log ve metrikle kanıtlarsın, tahmine dayanmazsın.
- Kök sebebe giden teşhis akışını, başkasının izleyebileceği biçimde yazılı anlatırsın.
🧠 Niye bu, niye şimdi#
Kırık lab, B3'ten itibaren patikanın omurgasıdır. Şimdiye kadar hep kurdun; kurabilmek bir beceri ama asıl mühendislik, senin kurmadığın bir şey bozulduğunda onu geri getirebilmektir. Blok C'ye (karmaşıklık eklemek — container, CI, Terraform) geçmeden önce, kurduğun sistemi görebildiğini (B1/B2) ve bir arızayı kanıtlayabildiğini göstermen gerekir. Bu modül, B → C geçiş sinyalinin sınavıdır: "Bir servisin neden ayağa kalkmadığını, dokümana bakmadan üç komutla daraltabiliyor musun?"
📖 Nasıl çalışılır#
K01 kırık lab'ının README.md'si sana yalnızca belirtiyi söyler ("servis yanıt vermiyor"). Ne bozulduğunu söylemez — söylemesi bütün dersi öldürür. hints/ klasörünü erken açma: önce kendin daralt. Takıldığında sırayla hint-1 (yön) → hint-2 (daralt) → hint-3 (neredeyse cevap). Çözerken bir teshis.md tut; her adımda ne gördüğünü ve ne çıkardığını yaz. O dosya bu modülün asıl çıktısıdır.
📚 Kavram haritası#
| Terim | Bir cümlede |
|---|---|
| Belirti (symptom) | Gözlemlenen yanlış davranış ("502 dönüyor") — sebep değil |
| Kök sebep (root cause) | Belirtiyi üreten asıl neden ("DB parolası yanlış") |
| Hipotez | Sebep hakkında test edilebilir bir tahmin |
| Kanıt | Hipotezi doğrulayan/çürüten somut çıktı (log satırı, metrik) |
| Daraltma (bisection) | Sistemi katmanlara bölüp arızayı yarıya indirme |
| USE method | Utilization / Saturation / Errors — kaynak darboğazı taraması |
1️⃣ Tutorial vs kırık lab: niçin bu fark her şey#
Bir tutorial mutlu yolu gösterir: adımları takip et, çalışır. Ama production'da adımlar seni beklemez; bozuk, yarım, çelişkili bir durumla karşılaşırsın ve sana kimse ne bozulduğunu söylemez. Kırık lab bu gerçeği simüle eder. Öğrettiği şey bir komut değil, bir tavırdır: panik yerine yöntem.
2️⃣ Teşhis disiplini: belirti → hipotez → kanıt → düzelt#
Arızayı çözmek doğaçlama değil, küçük bir bilimsel yöntemdir:
1. Belirtiyi netleştir → "Tam olarak ne yanlış? Ne zaman başladı?"
2. Hipotez kur → "Sanırım DB'ye bağlanamıyor."
3. Kanıt topla → journalctl'de 'connection refused to :5432' var mı?
4. Kanıt hipotezi tutuyor mu?
evet → düzelt, sonra DOĞRULA (belirti gitti mi?)
hayır → yeni hipotez, 2'ye dön
Kritik olan 3. adım: her hipotezi bir çıktıyla kanıtla. "Muhtemelen DB'dir" bir teşhis değil, bir tahmindir; onunla yanlış yeri düzeltip saatler kaybedersin. B1 (log) ve B2 (metrik) tam olarak bu kanıtı sağlamak için vardı.
3️⃣ Daraltma: sistemi katmanlara böl#
A6'da kurduğun mimarîyi hatırla — arıza bu zincirin bir halkasındadır:
Her katmanı tek tek sına, arızayı yarıya indir:
curl -s http://127.0.0.1/health # nginx üzerinden — çalışıyor mu?
curl -s http://127.0.0.1:<APP_PORT>/health # doğrudan uygulama — çalışıyor mu?
psql "postgresql://.../appdb" -c "SELECT 1;" # DB — bağlanıyor mu?
curl 127.0.0.1/health patlıyor ama curl :<APP_PORT>/health çalışıyorsa → sorun nginx ile uygulama arasında (proxy config, port). İkisi de patlıyorsa → uygulamada veya altındadır. Böylece arama alanını her adımda ikiye bölersin — dört komutta kök sebebe inersin.
4️⃣ Üç-komut refleksi (A → B geçiş sinyali)#
Bir servis ayağa kalkmadığında, dokümana bakmadan attığın ilk üç komut:
systemctl status <servis> # 1) çalışıyor mu, failed mı, ne diyor
journalctl -u <servis> -e -p err # 2) neden çıktı — son hatalar (B1)
ss -tlnp | grep <PORT> # 3) port gerçekten dinleniyor mu (A2)
Buna bir de kaynak kontrolü eklenir: df -h (disk dolu mu — çok yaygın kök sebep) ve free -h (bellek). Bu refleks, geçiş sinyalinin kendisidir — düşünmeden, sırayla gelmeli.
5️⃣ Kaynak darboğazı: USE method#
Bir sistem "yavaş" ya da "tökezliyor"sa, tek tek servis yerine kaynaklara bak. USE method her kaynak için üç soru sorar:
| Soru | Komut | |
|---|---|---|
| Utilization | Ne kadar meşgul? | top, mpstat |
| Saturation | Kuyruk/bekleme var mı? | uptime (load), vmstat |
| Errors | Hata sayacı artıyor mu? | dmesg, journalctl -p err |
mpstat/vmstat/dmesgyeni olabilir — şimdilik derinliğine girme;top,uptimevejournalctl -k(=dmesg) yeter. Ayrıntı aşağıdaki cheatsheet deep-dive'ında.
Derinlik (Brendan Gregg'in USE method'u, 60-saniye protokolü): 16-Cheatsheets/linux-troubleshooting.md. Bu cheatsheet artık senin için okunabilir — A1–A6 ve B1–B2'yi bitirdin; başlangıçta "duvar" olan bu doküman şimdi araç kutun.
6️⃣ Yaygın kök sebep sınıfları#
Kırık lab'ların bozukluğu gerçekçidir. En sık görülen sınıflar:
| Sınıf | Belirti | İlk kontrol |
|---|---|---|
| İzin (permission denied) | Servis dosyaya/porta erişemiyor | ls -l, journalctl (A1 izin modeli) |
| Port çakışması | Address already in use | ss -tlnp \| grep <PORT> |
| Disk dolu | Yazma hatası, servis çöküyor | df -h, df -i (inode) |
| DNS | "isim çözülemedi", timeout | dig, /etc/resolv.conf (A3) |
| systemd unit | failed, yanlış ExecStart/path | systemctl status, unit dosyası (A6) |
| Saat kayması | TLS/sertifika/kimlik hataları | timedatectl, NTP |
| Yanlış config | Servis başlıyor, yanlış davranıyor | Config diff, nginx -t |
🔒
permission deniedbir güvenlik sınırıdır, sinir bozucu bir engel değil. Onuchmod 777veya servisirootçalıştırarak "çözmek" arızayı kapatmaz, bir açık açar — reponun tüm eleştirdiği hatanın ta kendisi. Doğru düzeltme: hangi kullanıcının, hangi kaynağa, niçin erişmesi gerektiğini anla ve en dar izni ver (A1/A6 least-privilege).
7️⃣ Teşhis akışını yazmak#
Kök sebebi bulmak yarısı; onu yazmak diğer yarısı. İyi bir teşhis notu şunları içerir:
- Belirti — ne gözlemledin (tam çıktıyla).
- Daraltma adımları — hangi hipotezi hangi kanıtla eledin.
- Kök sebep — asıl neden.
- Düzeltme — ne yaptın, ve belirtinin gittiğini nasıl doğruladın.
- Niçin böyle oldu / tekrar nasıl önlenir — bir sonraki kişi için.
Bu yapı bir tesadüf değil; E3'teki blameless postmortem'in çekirdeğidir. Burada tek kişilik bir lab için yazdığın şey, orada bir ekip için yazacağın belgenin taslağıdır.
8️⃣ Hint disiplini: kendini erken kurtarma#
Hint'ler bir başarısızlık değil, ayarlı bir güvenlik ağıdır. Ama erken açmak dersi çalar. Kural: bir hipotezi kanıtla test etmeden hint açma. Sıra:
hint-1→ yön ("hangi katmana bak").hint-2→ daralt ("şu komutun çıktısına dikkat et").hint-3→ neredeyse cevap.
hint-3'ü açtıysan sorun değil — ama sonra solution.md'yi oku ve teşhis akışını (cevabı değil, oraya nasıl gidildiğini) ayrıca çalış. Asıl öğretilen o akıştır.
9️⃣ Baştan sona bir teşhis: yöntem iş başında#
Yöntemi soyut bırakma — bir kez uçtan uca izle. (Bu örnek kasıtlı olarak K01'in gizli sebebiyle örtüşmez; amaç cevabı vermek değil, akışı göstermek.) Belirti şu: "Uygulama açılıyor ama ödeme adımında name resolution failed logluyor ve istek düşüyor."
1) Belirtiyi netleştir. Ne zaman başladı, hep mi, ara ara mı?
journalctl -u app --since "30 min ago" -p err # B1
# 11:02:14 app: ERROR calling payments: dial tcp: lookup api.payments.local: name resolution failed
Hata DNS diyor (A3). Hipotez: uygulama api.payments.local adını çözemiyor.
2) Katmanı böl — sorun uygulamada mı, sistemin DNS'inde mi? Uygulamayı ele, adı doğrudan çözmeyi dene:
dig +short api.payments.local # boş dönüyor → sistem de çözemiyor (uygulama masum)
dig +short google.com # bu da boş → DNS tümden kırık, yalnız bu ad değil
İki komut arama alanını yarıya böldü: sorun uygulamada değil, makinenin DNS çözümlemesinde. Uygulamanın loguna daha fazla bakmak zaman kaybı olurdu.
3) Kök sebebe in — DNS neden kırık?
cat /etc/resolv.conf # hangi resolver? (A3) — ör. boş ya da erişilemez bir IP
ss -u -a | grep :53 # DNS trafiği gidiyor mu (A2)
ping -c1 <RESOLVER_IP> # resolver'a ağ var mı
resolv.conf'taki resolver'a ping gitmiyorsa kök sebep ağ/resolver erişimi; resolver doğru ama yanıt vermiyorsa resolver servisi. Her adımda bir hipotezi bir çıktıyla eledin — tahmin yok.
4) Düzelt ve DOĞRULA. Resolver'ı düzelttikten sonra, "düzelttim" deme — belirtinin gittiğini kanıtla, üstelik en dıştan (kullanıcının gördüğü yerden):
dig +short api.payments.local # artık bir IP dönüyor
curl -s http://127.0.0.1/checkout # 200 — kullanıcı yolu çalışıyor
journalctl -u app --since "2 min ago" -p err # boş → yeni hata yok
Bütün akış dört soruya indi: Ne yanlış? Hangi katmanda? Niçin? Gerçekten düzeldi mi? Kırık lab'da yapman gereken tam olarak bu — sadece sebep her seferinde farklı olur.
🔟 Zaman kutusu, yan etki ve ne zaman durulur#
Yöntem kadar önemli olan üç disiplin daha var; bunlar E bloğundaki incident çalışmasının provasıdır:
- Zaman kutusu (time-box). Bir hipoteze saplanma. "15 dakika bu yolu deneyip kanıtlayamazsam geri dönüp katmanı değiştireceğim" de. Kırık lab'da bu, hint açma eşiğindir; gerçek incident'te eskalasyon eşiği.
- Yan etkiye dikkat. Bir düzeltme yeni bir arıza doğurabilir (config değiştirdin, başka bir şey bozuldu). Düzelttikten sonra tek belirtiyi değil, sistemin bütününü doğrula:
systemctl status, birkaç uçtancurl,journalctl -p err. - Ne zaman durup yardım istenir. Takılmak bir başarısızlık değil; sessizce saatlerce takılmak öyle. Kırık lab'da sıra
hint-1 → 2 → 3 → solution.md. Gerçek hayatta sıra: kanıtladığın şeyi (belirti + denediklerin + eledikleri) yazıp eskalasyondur — E2/E3'te göreceğin on-call disiplininin çekirdeği. "Neyi denemedim" değil, "neyi kanıtladım" ile eskale edersin.
🔒 Baskı altında en sık yapılan hata, teşhisi atlayıp "hızlı düzeltme" denemektir:
chmod 777, servisirootçalıştır, güvenlik kontrolünü kapat. Bu, arızayı kapatıp bir açık açar (A1/A6). Zaman kutusu tam da bunu önlemek içindir: acele, güvenliği ilk feda edilen şey yapar.
🚫 Anti-pattern tablosu#
| Anti-pattern | Niye kötü | Doğru |
|---|---|---|
| Belirtiyi kanıtsız bir sebebe bağlamak | Yanlış yeri düzeltir, saat kaybedersin | Her hipotezi log/metrikle kanıtla |
| Rastgele "şunu da deneyeyim" | İzlenemez, tekrar üretilemez, yeni arıza doğurur | Katman katman daralt (bisection) |
permission denied'ı chmod 777 ile geçmek | Arızayı kapatır, güvenlik açar | Doğru kullanıcı + en dar izin (A1/A6) |
| Hint'i ilk takılmada açmak | Teşhis kasını çalıştırmadan geçersin | Önce üç-komut refleksi + bir hipotez dene |
| Düzeltip doğrulamamak | Belirti hâlâ orada olabilir | Düzeltmeden sonra belirtinin gittiğini kanıtla |
| Kök sebep yerine belirtiyi düzeltmek | Servisi yeniden başlatmak arızayı geri getirir | Asıl nedeni bul; restart erteleme değil çözüm değil |
| Teşhisi yazmamak | Bir dahaki sefere sıfırdan; ekip öğrenmez | teshis.md tut (E3 postmortem tohumu) |
| Sadece tahminle çalışmak | "Muhtemelen DB" ≠ teşhis | Kanıt = B → C geçişinin ta kendisi |
| Tek hipoteze saatlerce saplanmak | Zaman kaybı, tünel görüşü | Zaman kutusu koy; süre dolunca katman değiştir |
| Düzeltince yalnız tek belirtiyi bakmak | Yan etki yeni arıza doğurmuş olabilir | Bütünü doğrula (status, çok uçtan curl, -p err) |
| "Neyi denemedim" diye eskale etmek | Karşı taraf sıfırdan başlar | "Neyi kanıtladım" ile eskale et (E2/E3) |
📖 Önce oku#
| Kaynak | Ne için | Süre |
|---|---|---|
16-Cheatsheets/linux-troubleshooting.md | USE method + 60-saniye protokolü — teşhis çerçevesi | ~25 dk |
💥 Kırık lab#
👉 labs/broken/K01-kirik-vm/ — Belirti: "Servis ayağa kalkmıyor / yanıt vermiyor." Gerçekçi sebep gizli (yanlış izin / port çakışması / disk dolu / systemd unit hatası). README.md asla ne bozulduğunu söylemez — yalnız belirtiyi verir.
✅ Kabul kriterleri#
Hepsi doğrulanmadan sonraki modüle geçme: - [ ] K01'i çözdün: bash labs/broken/K01-kirik-vm/verify.sh sıfır hatayla geçiyor. - [ ] Kök sebebi log/metrik kanıtıyla gösteren bir teshis.md yazdın (belirti → daraltma → kök sebep → düzeltme → doğrulama). - [ ] "Dokümana bakmadan hangi üç komutla daralttın" sorusunu, komutları ve niçinlerini vererek yazdın (A → B sinyali). - [ ] Düzeltmeden sonra belirtinin gittiğini ayrı bir komutla kanıtladın (sadece "düzelttim" demedin).
🧪 Kendini test et#
- "Belirti" ile "kök sebep" arasındaki fark nedir? "502 dönüyor" hangisidir?
- Senaryo:
curl 127.0.0.1/health→ 502. Sistemi ikiye bölerek kök sebebe inmek için ilk hangi komutu çalıştırırsın ve iki olası sonucu ne anlama gelir? - Tasarım: Bir arızayı çözdün ama neden olduğunu tam anlamadın; servisi yeniden başlatınca düzeldi. İşin bitti mi? Niçin?
Cevaplar
1. Belirti = gözlemlenen yanlış davranış; kök sebep = onu üreten asıl neden. "502 dönüyor" bir **belirti**dir — nginx arkadaki uygulamaya ulaşamıyor demek, ama *niçin* ulaşamadığı (uygulama ölü mü, port yanlış mı, DB mi düşürdü) kök sebeptir ve ayrıca bulunmalıdır. 2. `curl -s http://127.0.0.1:🆘 Takıldıysan#
| Belirti | Muhtemel sebep | Ne yap |
|---|---|---|
| Nereden başlayacağımı bilmiyorum | Belirti netleşmemiş | "Tam olarak ne yanlış?" yaz; üç-komut refleksini uygula |
| Her şey normal görünüyor | Yanlış katmana bakıyorsun | Katmanı değiştir (nginx→app→DB→OS); df -h/free -h |
| Hipotezim tutmadı | Doğal — eleme sürecinin parçası | Yeni hipotez kur, 2. adıma dön; kanıtla test et |
| Çözdüm ama geri geldi | Belirti düzeltildi, kök sebep değil | Asıl nedeni bul; restart erteleme değildir |
| Tıkandım, ilerleyemiyorum | Teşhis kası henüz gelişiyor | hints/ sırayla: hint-1 → 2 → 3; sonra solution.md'de akışı çalış |
💼 Portfolyo çıktısı#
Yazdığın teshis.md — bir "arıza günlüğü"nün ilk sayfası. E3'te blameless postmortem'e evrilir; bu tür belgeler, "gerçek bir arızayı yöntemle çözdüm" diyebildiğin somut kanıtlardır.
⏭️ Sırada#
"Bir arızayı yardımsız daraltabilmek, bu patikanın öğrettiği asıl beceridir."