<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hakan İSMAİL</title>
    <description>The latest articles on DEV Community by Hakan İSMAİL (@hakanbaban53).</description>
    <link>https://dev.to/hakanbaban53</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3593379%2F63770104-9eda-408d-bbe7-f9d3072ffe6e.jpeg</url>
      <title>DEV Community: Hakan İSMAİL</title>
      <link>https://dev.to/hakanbaban53</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hakanbaban53"/>
    <language>en</language>
    <item>
      <title>VMware vSAN ile Başlarken: Depolama Politikası, Kullanılabilirlik ve HOL Notları (Modül 1)</title>
      <dc:creator>Hakan İSMAİL</dc:creator>
      <pubDate>Sat, 13 Jun 2026 17:36:05 +0000</pubDate>
      <link>https://dev.to/hakanbaban53/vmware-vsan-ile-baslarken-depolama-politikasi-kullanilabilirlik-ve-hol-notlari-modul-1-2mbi</link>
      <guid>https://dev.to/hakanbaban53/vmware-vsan-ile-baslarken-depolama-politikasi-kullanilabilirlik-ve-hol-notlari-modul-1-2mbi</guid>
      <description>&lt;p&gt;Birkaç haftadır "VMware vSAN - Getting Started and Advanced Topics" başlıklı HOL (Hands-on Lab) üzerinde çalışıyorum. Bu yazı, o serinin ilk modülünden çıkardığım notların ve gözlemlerin bir dökümü. Baştan söyleyeyim: burada anlatılanlar gerçek bir üretim ortamından değil, tamamen HOL ortamından geliyor. Kendi adıma bu ayrımı net tutmak önemliydi çünkü sahadaki dinamikler ile simüle bir ortam arasında her zaman fark var. Ama bu fark, HOL'u değersiz kılmıyor; tam tersine, kavramları karşılıklı test edip yanılma maliyeti sıfır olarak görmek için iyi bir zemin.&lt;/p&gt;

&lt;p&gt;Şimdi Modül 1'de neyle karşılaştığımı aktarayım.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ortam Hakkında Kısa Bir Not
&lt;/h2&gt;

&lt;p&gt;Lab iki siteden oluşuyor: Site A ve Site B. İlk dört modül tamamen Site A üzerinde ilerliyor. Yönetim cluster'larına dokunulmaksızın sadece workload cluster'larında çalışıyoruz. Bu ayrım, özellikle VCF (VMware Cloud Foundation) bağlamında düşününce mantıklı: yönetim katmanına gereksiz yandan temas, gerçek ortamlarda da kaçınılan bir şey.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frocw518jeeva6xodgoft.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frocw518jeeva6xodgoft.png" alt="Lab topoloji diyagramı: Site A ve Site B genel görünümü" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  vSAN Nedir, Neden Var?
&lt;/h2&gt;

&lt;p&gt;vSAN 2014'te hayatımıza girdi. Temel fikir şu: birden fazla ESXi host'unun yerel disklerini bir araya getirip tek, merkezi olarak yönetilen bir depolama havuzu oluşturmak. Ayrı bir storage donanımına gerek kalmıyor, en azından teoride.&lt;/p&gt;

&lt;p&gt;Bunun anlamı şu: vSAN doğrudan vSphere hypervisor'ına gömülü. Yani bir storage OS yönetmiyorsunuz, ayrı bir SAN fabric kurmuyor değilsiniz. Compute ve storage, vSphere Client üzerinden tek elden yönetiliyor. TCO açısından geleneksel storage'a kıyasla yüzde elliye varan maliyet düşüşü iddiası var. Bunu elbette ortam büyüklüğüne, lisans yapısına ve mevcut altyapıya göre ayrı değerlendirmek gerek, ama kavramsal olarak mantığı oturuyor.&lt;/p&gt;

&lt;p&gt;Data resilience tarafında erasure coding (silme kodlaması) kullanılıyor. RAID-5 ve RAID-6 burada saf disk mirroring'e göre daha verimli kapasite kullanımı sağlıyor.&lt;/p&gt;




&lt;h2&gt;
  
  
  vSAN 9'da Neler Değişti?
&lt;/h2&gt;

&lt;p&gt;Bu HOL, vSAN 9 üzerine kurulu. vSAN 9'da öne çıkan başlıklara bakmak istedim çünkü önceki sürümlerle karşılaştırma yapmadan nelerin "yeni" olduğunu anlamak zor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fss2ut6weww3ah0mmp9nf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fss2ut6weww3ah0mmp9nf.png" alt="vSAN OSA ve vSAN ESA" width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gerçek hayatta şunu sormak gerekir: mevcut donanımınız ESA'yı destekliyor mu? ESA'nın VMware HCL gereksinimleri daha kısıtlayıcı. Bu, HOL'da görmediğiniz ama sahaya geçince sizi ilk duraksatan şeylerden biri olabilir.&lt;/p&gt;

&lt;h3&gt;
  
  
  VMware Live Recovery ile DR
&lt;/h3&gt;

&lt;p&gt;vSAN cluster'ları artık VMware Live Recovery entegrasyonuyla korunabiliyor. RPO 1 dakikaya kadar inebiliyormuş. Bu özellik Modül 7'de işleniyor, burada sadece genel bir bilgi olarak geçiyor.&lt;/p&gt;

&lt;h3&gt;
  
  
  File Services ve Kubernetes
&lt;/h3&gt;

&lt;p&gt;vSAN artık Kubernetes pod'ları için file-based persistent volume destekliyor. Aynı zamanda cluster başına 500 adet file share'e kadar çıkılabiliyor (vSAN 9 ile gelen bir iyileştirme). Bu konu Modül 6'da detaylandırılıyor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dying Disk Handling (DDH)
&lt;/h3&gt;

&lt;p&gt;ESA'da disk latency değerlerini izleyip önceden belirlenen eşik aşılırsa otomatik müdahale edebiliyor. Cache drive arızalarını da proaktif olarak yakalıyor. Bu tür şeyler production ortamında görünmez çalışmasını beklediğiniz mekanizmalar; genelde var olduğunu ancak bir sorun çıktığında fark ediyorsunuz.&lt;/p&gt;

&lt;h3&gt;
  
  
  Global Deduplication (Sınırlı Yayın)
&lt;/h3&gt;

&lt;p&gt;OSA'da deduplikasyon alanı disk grubuyla sınırlıydı. ESA ile bu kapsam tüm cluster'a genişliyor; tekrar eden bloklar cluster genelinde tek depolama ihtiyacına düşüyor. Veri azaltma oranları teorik olarak daha iyi. VCF 9.0 P01 ile TQR programı kapsamında geliyor.&lt;/p&gt;




&lt;h2&gt;
  
  
  Storage Policy Based Management (SPBM)
&lt;/h2&gt;

&lt;p&gt;Bu modülün asıl konusu SPBM. Burada anlatmak istediğim şeyin "politika" kısmına takılmamak lazım; bu bir kurumsal yazılım sloganı değil, gerçekten işe yarayan bir mekanizma.&lt;/p&gt;

&lt;p&gt;Temel mantık şu: VM'e "şu datastore'a yerleştir" demiyorsunuz. Onun yerine bir politika tanımlıyorsunuz, "bu VM en az 1 arıza tolere edebilmeli, RAID-5 ile" gibi. vSAN bu politikaya uyan yerleşimi kendisi buluyor. VM o politikaya uymakta zorlanırsa bunu da raporluyor: "Compliant" ya da "Non-compliant."&lt;/p&gt;

&lt;p&gt;Bu yaklaşım, özellikle büyük ortamlarda her VM için ayrı ayrı storage konfigürasyonu yapmak yerine politika bazlı bir standart getiriyor. Dezavantajı şu olabilir: politika sayısı artınca bunları kim/ne zaman güncelleyecek, eski politikalara kim sahip çıkacak sorularına önceden cevap vermek gerekiyor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1mdddnnqk8ohen3mcab.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs1mdddnnqk8ohen3mcab.png" alt="Policies and Profiles menüsü" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Default Policy ve Optimal Datastore Default Policy
&lt;/h3&gt;

&lt;p&gt;vSAN'ın bir "default storage policy"si var. Bu, herhangi bir politika atanmadan oluşturulan VM'lere otomatik atanıyor. Bunu silemiyorsunuz, ama kopyalayıp üzerine kendi politikanızı kurabiliyorsunuz.&lt;/p&gt;

&lt;p&gt;vSAN 8.0 U1 ile gelen "Auto-Policy Management" özelliği ise bunu bir adım öteye taşıyor. Cluster'daki host sayısına ve konfigürasyonuna bakarak size özel bir "cluster-esa-01a - Optimal Datastore Default Policy - RAID5" gibi bir politika oluşturuyor. Bu otomatik politika RAID seviyesini cluster büyüklüğüne göre belirliyor. HOL'da bu özellik zaten etkin hale getirilmiş.&lt;/p&gt;




&lt;h2&gt;
  
  
  İlk Uygulama: VM Deploy Etmek
&lt;/h2&gt;

&lt;p&gt;Bu bölümde mevcut bir VM'i (core-a) vSAN datastore'a klonluyoruz. Adımlar gayet açık:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;vSphere Client'tan VM'e sağ tık → Clone → Clone to Virtual Machine&lt;/li&gt;
&lt;li&gt;İsim: &lt;code&gt;clone-vm-a&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Cluster: &lt;code&gt;cluster-esa-01a&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Datastore: &lt;code&gt;vsan-esa-01a_Datastore&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Storage Policy: &lt;code&gt;cluster-esa-01a - Optimal Datastore Default Policy - RAID 5&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F143qi6sblbc886fcm2y4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F143qi6sblbc886fcm2y4.png" alt="VM klonlama wizard: Yapılan Ayarlar" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Klon işlemi tamamlanınca VM Summary ekranından politikanın atanmış ve "Compliant" olduğunu doğrulamak mümkün.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frnx2ffh6anxw6je8dign.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frnx2ffh6anxw6je8dign.png" alt="VM Summary: Storage Policies bölümü, Compliant durumu" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  VM vSAN Üzerinde Nasıl Depolanıyor?
&lt;/h2&gt;

&lt;p&gt;Bu kısım bence modülün en ilginç parçası. vSAN ESA'nın log-structured file system mimarisine bakınca şunu görüyorsunuz:&lt;/p&gt;

&lt;p&gt;Yazma işlemi iki aşamada gerçekleşiyor:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance Leg (RAID-1):&lt;/strong&gt; Gelen yazma önce RAID-1 olarak iki host arasında mirroring ile saklanıyor. Hızlı write acknowledgement için. Veri henüz kalıcı konumuna geçmedi.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capacity Leg (RAID-5 veya RAID-6):&lt;/strong&gt; Küçük yazmaların yeterince birikmesiyle vSAN bunları full-stripe write olarak RAID-5/6 formatında kalıcı kapasiteye indiriyor (destage). Bu, IO amplifikasyonunu azaltmak için tasarlanmış.&lt;/p&gt;

&lt;p&gt;HOL'da bunu "Monitor &amp;gt; vSAN &amp;gt; Virtual Objects" üzerinden görebiliyorsunuz. VM'in hard diskini seçip "View Placement Details"e tıklayınca bileşenlerin hangi host üzerinde bulunduğunu görüyorsunuz.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx8z4zjk2xcmah1i3tqg0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx8z4zjk2xcmah1i3tqg0.png" alt="VM Placement Details: Performance Leg (RAID-1) ve Capacity Leg (RAID-5) bileşen dağılımı" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bu dağılımı görmek, "storage siyah bir kutu" algısını kırıyor. Veriyi görünür kılıyor.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cluster'ı Büyütmek: Scale Out
&lt;/h2&gt;

&lt;p&gt;RAID-5 ve RAID-6 için host sayısı gereksinimleri önemli:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mimari&lt;/th&gt;
&lt;th&gt;RAID-5 Minimum&lt;/th&gt;
&lt;th&gt;RAID-6 Minimum&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OSA&lt;/td&gt;
&lt;td&gt;4 host&lt;/td&gt;
&lt;td&gt;6 host&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESA&lt;/td&gt;
&lt;td&gt;3 host (2+1 şeması, 1.5x kapasite)&lt;/td&gt;
&lt;td&gt;6 host&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;ESA'da 6 veya daha fazla host varsa RAID-5 şeması 4+1'e geçiyor ve kapasite verimliliği artıyor (1.25x). Bu geçiş host sayısı değiştikten 24 saat sonra otomatik.&lt;/p&gt;

&lt;h3&gt;
  
  
  Yeni Host Eklemek
&lt;/h3&gt;

&lt;p&gt;HOL'da cluster başlangıçta 4 host ile geliyor. İki ek host (&lt;code&gt;esx-09a&lt;/code&gt; ve &lt;code&gt;esx-10a&lt;/code&gt;) dışarıda bekliyor. Bu host'ları sürükle-bırak ile cluster'a ekliyorsunuz.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkz5fhctnujxdnmz8jq9h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkz5fhctnujxdnmz8jq9h.png" alt="vSphere Client: Host'u cluster'a sürükle-bırak ile ekleme" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ESA'da artık "disk group" kavramı yok. Onun yerine "disk pool" var; host üzerindeki tüm uyumlu sürücüler havuza dahil oluyor. "vSAN Managed Disk Claim" etkinse eklenen host'un uyumlu sürücüleri otomatik olarak algılanıp vSAN datastore'a dahil ediliyor. HOL'da bu özellik etkin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8afwy26ruc59zuruj2n9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8afwy26ruc59zuruj2n9.png" alt="vSAN &gt; Disk Management: eklenen host'un sürücüleri" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Skyline Health ve Otomatik Policy Önerisi
&lt;/h3&gt;

&lt;p&gt;İki host eklendikten sonra Skyline Health'i açtığımızda bir uyarı görüyoruz: cluster 6 host'a çıktığı için Auto Policy Management yeni bir politika öneriyor.&lt;/p&gt;

&lt;p&gt;"TROUBLESHOOT" dediğinizde mevcut politika (RAID-5) ile önerilen politika (RAID-6) yan yana görünüyor. Mantıklı: 6 host ile RAID-6 hem mümkün hem daha resilient.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5m2hg8y610icftevido8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5m2hg8y610icftevido8.png" alt="Skyline Health: Policy değişikliği uyarısı" width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"UPDATE CLUSTER DS POLICY" diyebilirsiniz; bu noktadan sonra oluşturulan VM'ler RAID-6 politikası alıyor. Mevcut VM'leri de Policies and Profiles &amp;gt; REAPPLY ile güncelleyebiliyorsunuz. HOL'da bu adım zaman kazanmak için atlanıyor.&lt;/p&gt;




&lt;h2&gt;
  
  
  İleri Düzey Policy: Compression'ı Kapatmak
&lt;/h2&gt;

&lt;p&gt;ESA'da sıkıştırma (compression) artık storage policy seviyesinde yönetiliyor. Varsayılan olarak açık, çünkü replica trafiği de compressed olarak taşınıyor. Ama bazı durumlarda kapatmak gerekebilir: kendi sıkıştırmasını yapan uygulamalar (veritabanları gibi) için ekstra sıkıştırma hem CPU israfı hem de veri azaltma oranlarını yanıltabilir.&lt;/p&gt;

&lt;p&gt;Bu bölümde şunu yapıyoruz:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Mevcut &lt;code&gt;vSAN ESA Default Policy - RAID5&lt;/code&gt; politikasını klonla.&lt;/li&gt;
&lt;li&gt;Yeni politikaya isim ver: &lt;code&gt;vSAN ESA No Compression - RAID 5&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Storage rules &amp;gt; Storage tier: "No space efficiency" seç (sıkıştırma bu şekilde devre dışı kalıyor)&lt;/li&gt;
&lt;li&gt;Uyumluluk kontrolü: &lt;code&gt;vsan-esa-01a_Datastore&lt;/code&gt; compatible göründüğünü doğrula&lt;/li&gt;
&lt;li&gt;Finish&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwsezbet1kij034vjfspx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwsezbet1kij034vjfspx.png" alt="Storage Policy: Storage Rules sekmesi, No space efficiency" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ardından mevcut &lt;code&gt;clone-vm-a&lt;/code&gt; VM'ine bu yeni politikayı atıyoruz: VM &amp;gt; Configure &amp;gt; Policies &amp;gt; EDIT VM STORAGE POLICIES. Dropdown'dan yeni politikayı seçince bir süre sonra VM "Compliant" statüsüne geçiyor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fljux111ueudue06jpg0r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fljux111ueudue06jpg0r.png" alt="VM politika değiştirme ekranı: yeni policy ataması" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Reserved Capacity
&lt;/h2&gt;

&lt;p&gt;vSAN'ın tüm kapasitesi varsayılan olarak workload'lara açık. Ama cluster'da bir rebuild veya rebalancing operasyonu başladığında o an doluysa ne olacak? İşte "Reserved Capacity" tam buna yönelik.&lt;/p&gt;

&lt;p&gt;İki tür rezervasyon var:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Operations Reserve:&lt;/strong&gt; Cluster içi operasyonlar (policy reconfig, vb.) için ayrılan alan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Host Rebuild Reserve:&lt;/strong&gt; Bir host arızalandığında veri yeniden inşası için ayrılan alan. Bu rezervasyon, cluster'daki en büyük host'un kapasitesine göre belirleniyor. Minimum 4 host gereksinimi var.&lt;/p&gt;

&lt;p&gt;HOL'da bu özelliği etkinleştirme ekranını görüyoruz: uyarı eşikleri %70, hata eşikleri %90 olarak ayarlanmış. Sonra iptal ediliyor çünkü iç içe geçmiş (nested) lab ortamında gerçek anlamda reserve etmek için yeterli kapasite yok.&lt;/p&gt;

&lt;p&gt;Bu noktada şunu düşünmeden geçemedim: gerçek ortamlarda bu rezervasyonu kurmak ne zaman anlam taşıyor? Disk kapasitesi kısıtlıysa reserve etmek kısa vadede sizi zorlar. Ama o buffer olmadan bir host çöktüğünde rebuild yetersiz kapasiteye çarpar, bu daha büyük bir risk. Denge kurmak gerekiyor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2kzkmad32xg7c3myzmw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw2kzkmad32xg7c3myzmw.png" alt="Reservations and Alerts: Operations Reserve ve Host Rebuild Reserve toggle'ları" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bir kısıtlama notu:&lt;/strong&gt; Stretched cluster, fault domain kullanılan cluster'lar, ROBO cluster ve 4'ten az host içeren cluster'larda bu özellik desteklenmiyor.&lt;/p&gt;




&lt;h2&gt;
  
  
  Scale In: Node Çıkarmak
&lt;/h2&gt;

&lt;p&gt;Scale out kadar konuşulmayan ama production'da bir o kadar önemli olan şey: cluster'ı küçültmek. vSAN cluster'ı minimum 3 host ile çalışır. Host çıkarmadan önce şunlara bakmak gerekiyor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kalan compute ve storage kapasitesi yeterli mi?&lt;/li&gt;
&lt;li&gt;Mevcut VM storage policy'leri compliant kalmaya devam edecek mi?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Data Migration Pre-Check
&lt;/h3&gt;

&lt;p&gt;Bu araç, "şu host'u çıkarsam ne etkilenir?" sorusunun cevabını veriyor. HOL'da &lt;code&gt;esx-10a&lt;/code&gt; seçilip "Full data migration" tercih edildiğinde hiçbir nesnenin etkilenmeyeceği görülüyor. Ardından direkt "ENTER MAINTENANCE MODE" adımına geçilebiliyor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9auzrtezecdzqefg88np.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9auzrtezecdzqefg88np.png" alt="Data Migration Pre-Check: etkilenen nesne yok görünümü" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Maintenance Mode ve Host Kaldırma
&lt;/h3&gt;

&lt;p&gt;Maintenance mode'a alınan host sonra drag &amp;amp; drop ile cluster dışına (datacenter seviyesine) taşınıyor. Aynı adımlar &lt;code&gt;esx-09a&lt;/code&gt; için de tekrarlanıyor. Cluster böylece 4'e iniyor.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7osc79nobqp5b5arai8t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7osc79nobqp5b5arai8t.png" alt="Maintenance mode ve çıkarılan hostlar" width="384" height="813"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Genel Değerlendirme
&lt;/h2&gt;

&lt;p&gt;HOL formatı bu konu için iyi çalışıyor. Her adım ekran yönlendirmesiyle geldiği için "nerede tıklamalıyım" sancısı yaşamıyorsunuz; odağınız tamamen mantığı anlamaya kayıyor. Ama şunu da söylemeliyim: HOL sizi hiçbir şeyin bozulmadığı, kapasitesinin üstünde çalışmayan bir ortamda karşılıyor. Gerçek sahada bu adımların her birinin yanına "peki bunu değişken bir ortamda nasıl yapacaksın, işler ters giderse ne olur" soruları ekleniyor.&lt;/p&gt;

&lt;p&gt;Modülün beni en çok düşündüren kısmı RAID şeması geçişleri ve bunların kapasite verimliliğine yansımaları oldu. ESA'nın adaptif RAID-5'i (3-5 host için 1.5x, 6+ host için 1.25x) storage planlaması açısından gerçekten önemli bir ayrıntı. Host ekledikten 24 saat sonra otomatik geçiş yapması şık, ama o 24 saatte neler olabileceğini de takip etmek gerekir.&lt;/p&gt;

&lt;p&gt;Bir sonraki haftada Modül 2'ye; sağlık izleme, kapasite takibi ve performans raporlaması konularına geçeceğim.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Bu seri VMware HOL ortamı (HOL-2634-01-VCF-L) üzerinden yürütülmektedir. Buradaki gözlemler lab bağlamında değerlendirilmeli, production ortamı kararları için mutlaka resmi VMware dokümantasyonu ve deneyimli mühendisler referans alınmalıdır.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>vmware</category>
      <category>vsan</category>
    </item>
    <item>
      <title>Local LLM Ops: Building an Observable, GPU-Accelerated AI Cloud at Home with Docker &amp; Grafana</title>
      <dc:creator>Hakan İSMAİL</dc:creator>
      <pubDate>Fri, 13 Feb 2026 19:50:35 +0000</pubDate>
      <link>https://dev.to/hakanbaban53/local-llm-ops-building-an-observable-gpu-accelerated-ai-cloud-at-home-with-docker-grafana-4hbi</link>
      <guid>https://dev.to/hakanbaban53/local-llm-ops-building-an-observable-gpu-accelerated-ai-cloud-at-home-with-docker-grafana-4hbi</guid>
      <description>&lt;h3&gt;
  
  
  Why I Built My Own Local AI Stack: Prioritizing Privacy &amp;amp; ROI
&lt;/h3&gt;

&lt;p&gt;Integrating AI into a development workflow usually starts with a compromise: you either send your proprietary code to a third-party API (risking &lt;strong&gt;Data Privacy&lt;/strong&gt; and &lt;strong&gt;Compliance&lt;/strong&gt;) or you watch your "pay-per-token" bill spiral out of control (&lt;strong&gt;Operational Overhead&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;As a &lt;strong&gt;Systems Administrator&lt;/strong&gt;, I prefer a third option: &lt;strong&gt;Data Sovereignty.&lt;/strong&gt; I wanted a private, secure, and fully observable AI environment, eliminating data leak risks (&lt;strong&gt;GDPR/KVKK compliance&lt;/strong&gt;) while achieving significant &lt;strong&gt;Long-term ROI&lt;/strong&gt; by running on my own hardware (Arch Linux + NVIDIA RTX 3050 Ti).&lt;/p&gt;

&lt;p&gt;The real challenge wasn't just downloading an LLM; it was engineering a &lt;strong&gt;Scalable AI Infrastructure&lt;/strong&gt; that runs efficiently on consumer hardware. I'm documenting how I orchestrated this &lt;strong&gt;microservices-based stack&lt;/strong&gt; with &lt;strong&gt;Docker Compose&lt;/strong&gt;, optimized &lt;strong&gt;Resource Management&lt;/strong&gt; for limited VRAM, and established &lt;strong&gt;Full-Stack Observability&lt;/strong&gt; with &lt;strong&gt;Grafana and Prometheus&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Scalable Microservices Architecture
&lt;/h3&gt;

&lt;p&gt;I went with a modular, containerized approach to ensure internal &lt;strong&gt;Scalability&lt;/strong&gt; and keep the host system clean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Inference Management:&lt;/strong&gt; &lt;code&gt;Ollama&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure Hardware Integration:&lt;/strong&gt; &lt;code&gt;NVIDIA Container Toolkit&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User Experience (UX):&lt;/strong&gt; &lt;code&gt;OpenWebUI&lt;/code&gt; (for a polished RAG-capable interface).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Observability Layer:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;NVIDIA DCGM Exporter&lt;/code&gt; for real-time hardware telemetry.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Prometheus&lt;/code&gt; &amp;amp; &lt;code&gt;Grafana&lt;/code&gt; for &lt;strong&gt;SLA monitoring&lt;/strong&gt; and data retention.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Infrastructure &amp;amp; GPU Passthrough
&lt;/h3&gt;

&lt;p&gt;Before deploying the containers, we must ensure the host operating system (Arch Linux in my case) allows Docker to access the GPU hardware. This is not enabled by default.&lt;/p&gt;

&lt;h4&gt;
  
  
  1.1 The Prerequisites: NVIDIA Container Toolkit
&lt;/h4&gt;

&lt;p&gt;The bridge between Docker containers and the physical GPU is the &lt;strong&gt;NVIDIA Container Toolkit&lt;/strong&gt;. Without this, the containers would only see the CPU, resulting in painfully slow inference speeds (0.5 tokens/sec).&lt;/p&gt;

&lt;p&gt;Since I am running Arch Linux, the setup was straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install the toolkit&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;pacman &lt;span class="nt"&gt;-S&lt;/span&gt; nvidia-container-toolkit

&lt;span class="c"&gt;# Configure the Docker daemon to use the NVIDIA runtime&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nvidia-ctk runtime configure &lt;span class="nt"&gt;--runtime&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;docker

&lt;span class="c"&gt;# Restart Docker to apply changes&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To verify the passthrough is working, I ran a quick ephemeral container. If &lt;code&gt;nvidia-smi&lt;/code&gt; prints the GPU stats inside Docker, we are green.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;--gpus&lt;/span&gt; all nvidia/cuda:12.4.1-runtime-ubuntu22.04 nvidia-smi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsrrkjcd161yeworup8ri.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsrrkjcd161yeworup8ri.png" alt="GPU Passthrough Verification (NVIDIA 590.48.01 / CUDA 13.1 on Arch Linux)" width="800" height="639"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Container Orchestration
&lt;/h3&gt;

&lt;p&gt;I believe in "defining once, running everywhere." Instead of running disparate &lt;code&gt;docker run&lt;/code&gt; commands, I defined the entire stack in a single &lt;code&gt;docker-compose.yml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;This file handles network isolation (creating a private ai-net), volume persistence (so our chat history isn't lost on reboot), and most importantly, &lt;strong&gt;GPU resource reservation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is the complete configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# 🧠 1. AI ENGINE: Ollama&lt;/span&gt;
  &lt;span class="c1"&gt;# This is the backend that runs the LLM inference.&lt;/span&gt;
  &lt;span class="na"&gt;ollama&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ollama/ollama:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ollama&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;11434:11434"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ollama_storage:/root/.ollama&lt;/span&gt;
    &lt;span class="c1"&gt;# Critical: This section reserves the NVIDIA GPU for this container&lt;/span&gt;
    &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;reservations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;devices&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nvidia&lt;/span&gt;
              &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
              &lt;span class="na"&gt;capabilities&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;gpu&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ai-net&lt;/span&gt;

  &lt;span class="c1"&gt;# 💻 2. INTERFACE: OpenWebUI&lt;/span&gt;
  &lt;span class="c1"&gt;# A user-friendly frontend that connects to Ollama.&lt;/span&gt;
  &lt;span class="na"&gt;open-webui&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ghcr.io/open-webui/open-webui:main&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;open-webui&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:8080"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;OLLAMA_BASE_URL=http://ollama:11434&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;openwebui_storage:/app/backend/data&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ollama&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ai-net&lt;/span&gt;

  &lt;span class="c1"&gt;# 🕵️ 3. METRICS EXPORTER: NVIDIA DCGM&lt;/span&gt;
  &lt;span class="c1"&gt;# This container scrapes GPU metrics (Temp, Power, Utilization).&lt;/span&gt;
  &lt;span class="na"&gt;dcgm-exporter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nvidia/dcgm-exporter:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dcgm-exporter&lt;/span&gt;
    &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;reservations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;devices&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nvidia&lt;/span&gt;
              &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
              &lt;span class="na"&gt;capabilities&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;gpu&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DCGM_EXPORTER_NO_HOSTNAME=1&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;9400:9400"&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ai-net&lt;/span&gt;

  &lt;span class="c1"&gt;# 🗄️ 4. TIME-SERIES DB: Prometheus&lt;/span&gt;
  &lt;span class="c1"&gt;# Collects the metrics exposed by dcgm-exporter.&lt;/span&gt;
  &lt;span class="na"&gt;prometheus&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prom/prometheus:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;prometheus&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;9090:9090"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./prometheus.yml:/etc/prometheus/prometheus.yml&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;prometheus_data:/prometheus&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;--config.file=/etc/prometheus/prometheus.yml"&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ai-net&lt;/span&gt;

  &lt;span class="c1"&gt;# 📊 5. VISUALIZATION: Grafana&lt;/span&gt;
  &lt;span class="c1"&gt;# Displays the metrics in a dashboard.&lt;/span&gt;
  &lt;span class="na"&gt;grafana&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;grafana/grafana:latest&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;grafana&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3001:3000"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;grafana_storage:/var/lib/grafana&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;ai-net&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ollama_storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;openwebui_storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;prometheus_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;grafana_storage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ai-net&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bridge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Prometheus Scraper Configuration
&lt;/h4&gt;

&lt;p&gt;Prometheus needs to know exactly where to pull metrics from. I configured a 5-second &lt;code&gt;scrape_interval&lt;/code&gt;. While 15s-30s is more common for production, a 5s interval is better for a local lab where we want to track immediate power spikes during token generation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;global&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;scrape_interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5s&lt;/span&gt; &lt;span class="c1"&gt;# Scrape often for real-time visibility&lt;/span&gt;

&lt;span class="na"&gt;scrape_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;job_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gpu-metrics"&lt;/span&gt;
    &lt;span class="na"&gt;static_configs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;targets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dcgm-exporter:9400"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the configuration files in place, a single command boots the entire cloud infrastructure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdyux3ha2qpeek4tncp2k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdyux3ha2qpeek4tncp2k.png" alt="Stack Deployment (Ollama, DCGM Exporter, Prometheus, Grafana, OpenWebUI)" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Resource Management: Optimizing for 4GB VRAM
&lt;/h3&gt;

&lt;p&gt;The infrastructure setup is the foundation, but &lt;strong&gt;Cost-Sensitive Resource Allocation&lt;/strong&gt;, selecting a model that runs effectively on limited hardware, is where the real value lies. I optimized this build for an &lt;strong&gt;NVIDIA RTX 3050 Ti with 4GB of VRAM&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  The VRAM Constraint
&lt;/h4&gt;

&lt;p&gt;Popular models like DeepSeek R1 or Llama 3 (8B) usually require 5GB to 6GB of VRAM just to load. Offloading these models to system RAM via PCIe on a 4GB card results in unusable generation speeds, often dropping to 1-2 tokens per second.&lt;/p&gt;

&lt;p&gt;I needed a model that fits entirely within the 4GB ceiling while remaining capable for coding tasks.&lt;/p&gt;

&lt;h4&gt;
  
  
  Choosing the right model: Qwen 2.5 Coder (3B)
&lt;/h4&gt;

&lt;p&gt;I used &lt;strong&gt;Hugging Face&lt;/strong&gt; to cross-reference benchmarks and VRAM requirements for various 1B, 3B, and 7B models. After evaluating the trade-offs between parameter count and inference speed, I settled on &lt;strong&gt;Qwen 2.5 Coder (3B Instruct)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Since it only occupies roughly &lt;strong&gt;2.2 GB of VRAM&lt;/strong&gt;, it leaves enough headroom for the context window without triggering a bottleneck. It's significantly faster than larger models that would force the system to swap to system RAM.&lt;/p&gt;

&lt;p&gt;I specifically used the &lt;strong&gt;Instruct&lt;/strong&gt; version; it's much better at actual code logic than the base model.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frj6xcwm5mwioykt0kdej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frj6xcwm5mwioykt0kdej.png" alt="Qwen Model Card" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can pull it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; ollama ollama run qwen2.5-coder:3b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verifying Telemetry
&lt;/h3&gt;

&lt;p&gt;Once the containers are up, query the DCGM exporter directly to ensure the GPU is communicating correctly with Docker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:9400/metrics
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp6xwjnxnxa31wbqeo05f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp6xwjnxnxa31wbqeo05f.png" alt="Raw DCGM Metrics Exposer (Port 9400)" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll see keys like &lt;code&gt;DCGM_FI_DEV_GPU_TEMP&lt;/code&gt; and &lt;code&gt;DCGM_FI_DEV_POWER_USAGE&lt;/code&gt;. Now we need to visualize these in Grafana.&lt;/p&gt;




&lt;h3&gt;
  
  
  Dashboard Configuration
&lt;/h3&gt;

&lt;p&gt;Since Grafana and Prometheus are on the same Docker network (&lt;code&gt;ai-net&lt;/code&gt;), they communicate via container names.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Log in to Grafana (&lt;code&gt;http://localhost:3001&lt;/code&gt;, default &lt;code&gt;admin&lt;/code&gt;/&lt;code&gt;admin&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt; Add &lt;strong&gt;Prometheus&lt;/strong&gt; as a data source and use the URL: &lt;code&gt;http://prometheus:9090&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbcoequasudm252ymofzv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbcoequasudm252ymofzv.png" alt="Grafana Data Source Connection" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Import Dashboard ID &lt;strong&gt;12239&lt;/strong&gt; (NVIDIA DCGM Exporter).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffowxbzl9bcmxfys8dvi1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffowxbzl9bcmxfys8dvi1.png" alt="NVIDIA Dashboard Import" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The result is a comprehensive command center for your local AI hardware.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkc4hncwchp5xt8ljxdw7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkc4hncwchp5xt8ljxdw7.png" alt="Active GPU Dashboard (Idle State: ~54.1°C / 10.8 W)" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Real-World Business Value &amp;amp; Metrics
&lt;/h3&gt;

&lt;p&gt;I tested the stack with a typical DevOps automation request:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Write a bash script that detects zombie processes and logs the action."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Full-Stack Observability Analysis
&lt;/h4&gt;

&lt;p&gt;Checking the Grafana dashboard during inference gives the ultimate validation of the setup, proving &lt;strong&gt;System Reliability&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsf45d3zh91rqg6ikx1dj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsf45d3zh91rqg6ikx1dj.png" alt="Final Hardware Analysis (Peak Inference: 64°C / 20.0 W / 2.8 GB VRAM)" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;VRAM Efficiency&lt;/strong&gt;: Usage peaked at &lt;strong&gt;2.8 GB&lt;/strong&gt;. This confirms that the 3B model is the sweet spot: fluent generation with &lt;strong&gt;Zero Licensing Overhead&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability Benchmarks&lt;/strong&gt;: &lt;strong&gt;~438 prompt tokens/s&lt;/strong&gt; and &lt;strong&gt;~10 generation tokens/s&lt;/strong&gt;. Proving that high-performance AI is possible without cloud dependency.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuwvbt0z0er6uupjrv7ue.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuwvbt0z0er6uupjrv7ue.png" alt="Scalability Benchmarks" width="218" height="292"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Operational Sustainability&lt;/strong&gt;: The GPU pulled a steady &lt;strong&gt;20W&lt;/strong&gt; and stayed at &lt;strong&gt;64°C&lt;/strong&gt;. This is a &lt;strong&gt;Low-Cost/High-Performance&lt;/strong&gt; local solution.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Summary: Driving Innovation Internally
&lt;/h3&gt;

&lt;p&gt;Building a local AI stack isn't just a technical exercise; it's a strategic move for &lt;strong&gt;Business Continuity&lt;/strong&gt; and &lt;strong&gt;Data Security&lt;/strong&gt;. By combining Docker, NVIDIA's toolkit, and a comprehensive observability layer, I've created a dev environment that's both secure and cost-efficient, proving that significant &lt;strong&gt;AI ROI&lt;/strong&gt; can be achieved on existing on-premise hardware.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>devops</category>
    </item>
    <item>
      <title>Dijital Mahremiyeti Geri Kazanmak: Pi-hole, Unbound ve Tailscale ile Gözetimsiz İnternet</title>
      <dc:creator>Hakan İSMAİL</dc:creator>
      <pubDate>Wed, 28 Jan 2026 15:44:13 +0000</pubDate>
      <link>https://dev.to/hakanbaban53/dijital-mahremiyeti-geri-kazanmak-pi-hole-unbound-ve-tailscale-ile-gozetimsiz-internet-53b2</link>
      <guid>https://dev.to/hakanbaban53/dijital-mahremiyeti-geri-kazanmak-pi-hole-unbound-ve-tailscale-ile-gozetimsiz-internet-53b2</guid>
      <description>&lt;h3&gt;
  
  
  Giriş
&lt;/h3&gt;

&lt;p&gt;Bir Sistem Mühendisi için en büyük israf, atıl duran işlem gücüdür. Çekmecemde uzun süredir "kış uykusunda" olan Raspberry Pi 3'e baktığımda, sadece eski bir devre kartı değil, potansiyel bir ağ savunma hattı görüyordum.&lt;/p&gt;

&lt;p&gt;İnternet Servis Sağlayıcımın (ISS) şeffaf olmayan DNS yönlendirmeleri ve evdeki Akıllı TV’min, ben kullanmasam bile arka planda &lt;strong&gt;Google sunucularına telemetri verisi gönderme çabası&lt;/strong&gt; artık bardağı taşırmıştı.&lt;/p&gt;

&lt;p&gt;Ev ağım, benim kontrolümde olması gereken özel bir alanken, adeta büyük şirketlerin veri madenciliği sahasına dönüşmüştü. Çözüm, o çekmecedeki atıl donanımı &lt;strong&gt;aktif ve tavizsiz bir ağ geçidine&lt;/strong&gt; dönüştürmekte yatıyordu.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Amacım netti:&lt;/strong&gt; Kurumsal ağlarda uyguladığımız "Zero Trust" prensibini ev ölçeğine taşımak. Hiçbir cihazın, benim iznim olmadan "Big Tech" sunucularına veri göndermediğinden emin olmak ve bunu yaparken internet performansından ödün vermemek.&lt;/p&gt;

&lt;p&gt;Bu yazıda, basit bir "reklam engelleyici kur geç" rehberinin ötesine geçeceğiz. Terminali açıp, sistemin derinliklerine inerek şunları nasıl yaptığımı anlatacağım:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google veya Cloudflare'a güvenmek yerine, kendi &lt;strong&gt;Recursive DNS (Unbound)&lt;/strong&gt; sunucumu yapılandırarak aracıları nasıl ortadan kaldırdım?&lt;/li&gt;
&lt;li&gt;İnatçı ISS modeminin elinden &lt;strong&gt;DHCP yetkisini&lt;/strong&gt; alarak ağ yönetimini nasıl tamamen kendi kontrolüme geçirdim?&lt;/li&gt;
&lt;li&gt;Ve en önemlisi: &lt;strong&gt;CGNAT&lt;/strong&gt; arkasında olmama rağmen, bu güvenli kaleye &lt;strong&gt;Tailscale&lt;/strong&gt; ile dünyanın her yerinden nasıl şifreli bir tünel açtım?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eski bir donanımı, modern bir güvenlik cihazına (Network Appliance) dönüştürme hikayesi başlıyor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Araç Çantası (The Stack)
&lt;/h2&gt;

&lt;p&gt;Bu projeyi hayata geçirmek için bir süper bilgisayara veya pahalı firewall cihazlarına ihtiyacınız yok. DNS sorguları ve VPN tünelleme işlemleri şaşırtıcı derecede hafiftir; bu yüzden "atıl donanım" felsefesi burada mükemmel işler.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Donanım (Elimdeki Envanter)
&lt;/h3&gt;

&lt;p&gt;Bu proje için özel bir alışveriş yapmadım. Tamamen "çekmeceden ne çıkarsa" prensibiyle ilerledim.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kart:&lt;/strong&gt; &lt;strong&gt;Raspberry Pi 3 Model B&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Neden Bu?&lt;/em&gt; Çünkü elimde boşta duran kart buydu. Ancak şansıma, &lt;strong&gt;dahili Ethernet portuna&lt;/strong&gt; sahip olması DNS sunucusu için büyük avantaj. Wi-Fi gecikmesini (latency) veya sinyal kopmalarını bir DNS sunucusunda asla istemezsiniz. Kablo kararlılıktır.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Depolama:&lt;/strong&gt; &lt;strong&gt;MicroSD Kart (Class 10)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Alternatifler
&lt;/h4&gt;

&lt;p&gt;Elinizde illaki Raspberry Pi 3 gibi bit kart olmak zorunda değil. İşte diğer güzel alternatifler:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Raspberry Pi Zero W / 2W:&lt;/strong&gt; Çok daha ucuz ve az güç tüketir. (Ancak Micro-USB Ethernet adaptörü kullanmanızı şiddetle öneririm).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Eski Bir Laptop:&lt;/strong&gt; Ekranı kırık, bataryası bitik eski dizüstü bilgisayarınız harika bir sunucu olur. Üstelik dahili bataryası "UPS" (Kesintisiz Güç Kaynağı) görevi görür.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Orange Pi / Banana Pi:&lt;/strong&gt; Piyasadaki Raspberry Pi klonlarının çoğu bu proje için fazlasıyla yeterlidir.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Always-Free Cloud VPS:&lt;/strong&gt; Oracle Cloud veya Google Cloud'un ücretsiz katmanlarında (Free Tier) bir Ubuntu sunucu açıp, ev ağınıza Tailscale "Subnet Router" olarak bağlayabilirsiniz. (Donanım maliyeti: 0₺).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Yazılım (Software)
&lt;/h3&gt;

&lt;p&gt;Burada "bloat"tan (gereksiz şişkinlikten) kaçınan, Unix felsefesine uygun (bir şeyi yap ve iyi yap) araçları seçtim:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;İşletim Sistemi:&lt;/strong&gt; &lt;strong&gt;Raspberry Pi OS Lite (64-bit)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Masaüstü ortamı (GUI) yok, sadece terminal. Bir sunucunun monitöre ihtiyacı yoktur. Headless kurulum yapacağız.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pi-hole:&lt;/strong&gt; Ağ seviyesinde reklam ve takipçi engelleyici (DNS Sinkhole).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Unbound:&lt;/strong&gt; Recursive DNS çözümleyici. Google'a veya diğer DNS sağlayıcılarına güvenmek yerine kendi doğrulamamızı yapacağız.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tailscale:&lt;/strong&gt; WireGuard tabanlı Mesh VPN. CGNAT duvarlarını delmek ve dışarıdan eve güvenli tünel açmak için.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🏗️ Bölüm 1: Temeli Atmak (İşletim Sistemi Kurulumu)
&lt;/h2&gt;

&lt;p&gt;Bir sunucu kuruyorsak, ilk kural şudur: &lt;strong&gt;GUI (Grafik Arayüz) gereksiz yük ve güvenlik açığıdır.&lt;/strong&gt; Sunucunun monitörü olmaz, terminali olur. Bu yüzden "Raspberry Pi OS Lite (64-bit)" sürümünü tercih ettim.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adım 1: İmajı Yazdırmak
&lt;/h3&gt;

&lt;p&gt;Raspberry Pi kullandığım için işim nispeten kolaydı. Resmi &lt;strong&gt;Raspberry Pi Imager&lt;/strong&gt; yazılımı, sadece imajı karta yazmakla kalmıyor, "OS Customization" özelliğiyle SSH ayarlarını daha kartı cihaza takmadan yapmamızı sağlıyor.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Cihaz Seçimi:&lt;/strong&gt; Raspberry Pi 3.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;İşletim Sistemi:&lt;/strong&gt; Raspberry Pi OS (Other) -&amp;gt; &lt;strong&gt;Raspberry Pi OS Lite (64-bit)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Neden 64-bit?&lt;/em&gt; Pi 3, 64-bit mimariyi destekler. MongoDB gibi bazı modern veritabanı ve servisler artık 32-bit desteğini kesiyor. Geleceğe yatırım yapmak iyidir.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  3. Kritik Adım: "Headless" Hazırlık (OS Customization)
&lt;/h3&gt;

&lt;p&gt;Bir sunucu kurarken monitör, klavye ve fare aramakla vakit kaybetmek istemeyiz. Amacımız &lt;strong&gt;"Tak ve Çalıştır" (Plug and Play)&lt;/strong&gt; değil, &lt;strong&gt;"Tak ve Yönet"&lt;/strong&gt; olmalı.&lt;/p&gt;

&lt;p&gt;Raspberry Pi Imager'ın yeni sürümleri, &lt;strong&gt;"OS Customization"&lt;/strong&gt; özelliği sayesinde işletim sistemini daha karta yazmadan konfigüre etmemize olanak tanıyor. Bu sayede Pi ilk açıldığı anda ağa bağlanıyor, SSH kapısını açıyor ve bizim bağlanmamızı bekliyor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;İmajı yazdır ("Write") demeden önce, o sihirli ayar menüsünü açarak şu konfigürasyonları yaptım:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hostname (Cihaz Adı):&lt;/strong&gt; Cihaza ağda tanınacağı kimliği verdim: &lt;code&gt;pi-hole&lt;/code&gt;. (Siz &lt;code&gt;dns-server&lt;/code&gt; veya yaratıcı başka bir isim seçebilirsiniz).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable SSH (SSH'ı Aç):&lt;/strong&gt; Bu adım hayati önem taşıyor. Cihaza monitör bağlamayacağımız için tek iletişim yolumuz bu olacak. "Use password authentication" seçeneğini aktif ettim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Username &amp;amp; Password:&lt;/strong&gt; Buraya kendime özel, kullanıcı adı ve güçlü bir şifre tanımladım.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wireless LAN (Wi-Fi):&lt;/strong&gt; Burayı bilinçli olarak &lt;strong&gt;boş bıraktım&lt;/strong&gt;. Bir DNS sunucusu kablosuz ağın kararsızlığına emanet edilemez. Ethernet kablosu takılı olacağı için Wi-Fi konfigürasyonuna ihtiyacımız yok.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bu ayarları kaydedip &lt;strong&gt;"WRITE"&lt;/strong&gt; butonuna bastığımda, elimde sadece bir işletim sistemi değil, tamamen benim kurallarımla yapılandırılmış, göreve hazır bir sunucu kartı vardı.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstol7m2tcntxn81m4khh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fstol7m2tcntxn81m4khh.png" alt="Raspberry Pi Imager" width="730" height="537"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Laptop veya Mini PC Kullananlar İçin Not
&lt;/h3&gt;

&lt;p&gt;Eğer bu projeyi eski bir laptop veya Intel NUC gibi bir x86 cihazda yapacaksanız süreç biraz daha geleneksel:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hafif bir dağıtımın ISO dosyasını indirin (Örn: &lt;strong&gt;Debian Server&lt;/strong&gt; veya &lt;strong&gt;Ubuntu Server&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rufus&lt;/strong&gt; veya &lt;strong&gt;BalenaEtcher&lt;/strong&gt; kullanarak USB belleğe yazdırın.&lt;/li&gt;
&lt;li&gt;Cihazı USB'den başlatıp kurulumu tamamlayın.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Adım 2: İlk Önyükleme (First Boot) ve Ağ Taraması
&lt;/h3&gt;

&lt;p&gt;SD kartı Pi'ye taktım, Ethernet kablosunu modeme bağladım ve gücü verdim. Işıklar yanıp sönmeye başladı ama kritik bir eksiğimiz var: &lt;strong&gt;Monitörsüz bir cihazın IP adresini nasıl bulacağız?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Bunun için iki yolumuz var.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yöntem 1: Klasik Yol (Modem Arayüzü)&lt;/strong&gt;&lt;br&gt;
En garantili yöntem, ağın patronuna yani modeme sormaktır. &lt;code&gt;192.168.1.1&lt;/code&gt; (veya modeminizin IP'si neyse) adresinden arayüze giriş yapıp &lt;strong&gt;"Bağlı Cihazlar" (Connected Devices)&lt;/strong&gt; listesine baktığınızda, Raspberry Pi'nin sessizce bir IP aldığını göreceksiniz.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hhwif2w18tqics5rrup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4hhwif2w18tqics5rrup.png" alt="Modem Web Arayüzü" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yöntem 2: Terminal Yolu (Nmap Taraması)&lt;/strong&gt;&lt;br&gt;
Eğer modem şifresini hatırlamıyorsanız veya tarayıcıyla uğraşmak istemiyorsanız, terminalden ağı taramak çok daha hızlı bir yöntemdir.&lt;/p&gt;

&lt;p&gt;Ağdaki cihazları ve üreticilerini listelemek için şu komutu kullandım:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# -sn: Port taraması yapma, sadece ping at (Ping Scan)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nmap &lt;span class="nt"&gt;-sn&lt;/span&gt; 192.168.1.0/24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ve işte aradığım cevap karşımda:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Nmap scan report for PC192.168.1.4.station (192.168.1.4)
Host is up (0.0040s latency).
MAC Address: B8:27:EB:4B:79:A8 (Raspberry Pi Foundation)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftf33oxb0j56og77ofkkm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftf33oxb0j56og77ofkkm.png" alt="Nmap Tarama Sonucu" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Terminal, üreticisi "Raspberry Pi Foundation" olan cihazın &lt;strong&gt;192.168.1.4&lt;/strong&gt; adresinde olduğunu raporladı.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bağlantı Anı
&lt;/h3&gt;

&lt;p&gt;Hedef belli olduğuna göre, o büyülü an geldi. SSH ile sisteme giriş yapıyoruz:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh hakan@192.168.1.4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuswnm03rlfsui7kr5fwk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuswnm03rlfsui7kr5fwk.png" alt="ssh Bağlantısı Başarılı" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;İçerideyim. 🎉&lt;/p&gt;

&lt;p&gt;Ancak titiz bir &lt;strong&gt;Linux&lt;/strong&gt; kullanıcısı olarak, ilk iş &lt;code&gt;htop&lt;/code&gt; ve &lt;code&gt;systemd-analyze&lt;/code&gt; komutlarını çalıştırdığımda gördüğüm manzara beni tatmin etmedi. Kullanmadığım donanımlar için çalışan servisler ve arka plandaki gereksiz yükler (bloatware), açılış süresini uzatıyordu.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hakan@pi-hole:~ &lt;span class="nv"&gt;$ &lt;/span&gt;systemd-analyze
Startup finished &lt;span class="k"&gt;in &lt;/span&gt;5.988s &lt;span class="o"&gt;(&lt;/span&gt;kernel&lt;span class="o"&gt;)&lt;/span&gt; + 52.832s &lt;span class="o"&gt;(&lt;/span&gt;userspace&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 58.821s 
multi-user.target reached after 22.577s &lt;span class="k"&gt;in &lt;/span&gt;userspace.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sıradaki adımda, elime dijital süpürgeyi alıp bu sistemi temizlemem ve sunucu kondisyonuna getirmem gerekiyordu.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧹 Bölüm 2: "Lite" Yeterince Hafif Değildir (System Hardening)
&lt;/h2&gt;

&lt;p&gt;Sisteme ilk bağlandığımda &lt;code&gt;htop&lt;/code&gt; ve &lt;code&gt;systemd-analyze blame&lt;/code&gt; komutlarını çalıştırdım. Gördüğüm manzara, bir sistem mühendisi için kabul edilemezdi. Boot süresi 1 dakikaya yakındı ve kullanmadığım donanımlar için servisler çalışıyordu.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fba88yh1d5ur7oy9vbhm5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fba88yh1d5ur7oy9vbhm5.png" alt="systemd-analyze blame" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Raspberry Pi OS Lite, genel uyumluluk için "herkese her şey" mantığıyla gelir. Ancak bizim senaryomuzda &lt;strong&gt;Headless (Monitörsüz)&lt;/strong&gt; ve &lt;strong&gt;Kablolu (Ethernet)&lt;/strong&gt; bir DNS sunucusu kuruyoruz. Fazlalıklara yer yok.&lt;/p&gt;

&lt;p&gt;İşte uyguladığım "diyet" programı:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Baş Şüpheli: Cloud-Init
&lt;/h3&gt;

&lt;p&gt;En büyük gecikmeyi (yaklaşık 50 saniye) &lt;code&gt;cloud-init&lt;/code&gt; servisi yaratıyordu. Bu servis, cihaz bir bulut ortamında (AWS, Azure vb.) çalışıyorsa metadata çekmeye yarar. Benim Pi'm masamın üstündeydi, bulutta değil.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Servisleri durdur&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl disable &lt;span class="nt"&gt;--now&lt;/span&gt; cloud-init-local.service cloud-config.service cloud-final.service

&lt;span class="c"&gt;# Paketi ve kalıntılarını sistemden kazı&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt purge &lt;span class="nt"&gt;-y&lt;/span&gt; cloud-init
&lt;span class="nb"&gt;sudo rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /etc/cloud /var/lib/cloud
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Gereksiz Donanım Servisleri
&lt;/h3&gt;

&lt;p&gt;Sunucumda hoparlör, bluetooth kulaklık veya Wi-Fi kullanmayacağım. Bunları kapatmak hem RAM kazandırır hem de saldırı yüzeyini (attack surface) daraltır.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Bluetooth ve Ses (ALSA) servislerini kaldır&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt purge &lt;span class="nt"&gt;-y&lt;/span&gt; bluez bluez-firmware alsa-utils

&lt;span class="c"&gt;# ModemManager (3G/4G dongle kullanmayacaksanız gereksiz)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt purge &lt;span class="nt"&gt;-y&lt;/span&gt; modemmanager

&lt;span class="c"&gt;# Wi-Fi Servisi (Ethernet kullandığım için)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl disable &lt;span class="nt"&gt;--now&lt;/span&gt; wpa_supplicant
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl mask wpa_supplicant
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Avahi (mDNS)
&lt;/h3&gt;

&lt;p&gt;Sabit IP kullanacağım ve DNS yönetimini kendim yapacağım için &lt;code&gt;raspberrypi.local&lt;/code&gt; gibi mDNS yayınlarına (Bonjour) ihtiyacım yoktu.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl disable &lt;span class="nt"&gt;--now&lt;/span&gt; avahi-daemon
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt purge &lt;span class="nt"&gt;-y&lt;/span&gt; avahi-daemon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Son Temizlik, Güncellemeler ve Yeniden Başlatma
&lt;/h3&gt;

&lt;p&gt;Sistemi gereksiz servislerden arındırdık. Sistemde yaptığım &lt;code&gt;cloud-init&lt;/code&gt; ve diğer temizliklerden sonra geriye, artık hiçbir işe yaramayan "yetim" paketler (orphan packages) kalmıştı. Terminal bana bunları temizlememi öneriyordu, ben de öneriye uydum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt autoremove &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Artık elimizde, üzerine bina inşa edebileceğimiz tertemiz bir temel var. Bu temeli en son güncellemeler ile güçlendirelim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sistemi yeniden başlatıp sonuca bakalım:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;reboot now
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yeni sonuçlar ise daha tatmin edici:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;hakan@pi-hole:~ &lt;span class="nv"&gt;$ &lt;/span&gt;systemd-analyze
Startup finished &lt;span class="k"&gt;in &lt;/span&gt;9.046s &lt;span class="o"&gt;(&lt;/span&gt;kernel&lt;span class="o"&gt;)&lt;/span&gt; + 21.894s &lt;span class="o"&gt;(&lt;/span&gt;userspace&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 30.941s 
multi-user.target reached after 20.891s &lt;span class="k"&gt;in &lt;/span&gt;userspace.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  ⚓ Sabit IP (Static IP) Ayarı
&lt;/h3&gt;

&lt;p&gt;Temizlik bitince, ağdaki yerimizi sağlamlaştırmamız gerekiyordu. DNS sunucusunun IP adresi değişirse tüm evin interneti kesilir.&lt;/p&gt;

&lt;p&gt;Modern Raspberry Pi OS sürümleri &lt;strong&gt;NetworkManager&lt;/strong&gt; kullanır. IP sabitlemek için en temiz yol &lt;code&gt;nmtui&lt;/code&gt; aracıdır.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Terminale &lt;code&gt;sudo nmtui&lt;/code&gt; yazdım.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edit a connection&lt;/strong&gt; -&amp;gt; &lt;strong&gt;netplan-eth0&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IPv4 CONFIGURATION&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Manual&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Addresses:&lt;/strong&gt; &lt;code&gt;192.168.1.4/24&lt;/code&gt; (Siz kendi ağınıza göre belirleyin).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gateway:&lt;/strong&gt; &lt;code&gt;192.168.1.1&lt;/code&gt; (Modem IP'si).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DNS Servers:&lt;/strong&gt; Şimdilik &lt;code&gt;1.1.1.1&lt;/code&gt; (Kurulum bitince &lt;code&gt;127.0.0.1&lt;/code&gt; yapacağız).&lt;/li&gt;
&lt;li&gt;(Opsiyonel) &lt;strong&gt;IPv6 CONFIGURATION&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Disabled&lt;/strong&gt; (Eğer IPv6 kullanmıyorsanız yapabilirsiniz).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4es3zllr10f2ea74rrf2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4es3zllr10f2ea74rrf2.png" alt="nmtui ile konfigürasyon" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Sistemi yeniden başlatabiliriz:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;reboot now
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🛡️ Bölüm 3: Savunma Hattı (Pi-hole &amp;amp; Unbound)
&lt;/h2&gt;

&lt;p&gt;Temiz bir işletim sistemimiz var. Şimdi onu bir ağ cihazına (Network Appliance) dönüştüreceğiz. Buradaki stratejimiz iki katmanlı:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Pi-hole:&lt;/strong&gt; Reklamları ve izleyicileri çöpe atan bekçi.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unbound:&lt;/strong&gt; Sorguları Google'a sormak yerine, doğrudan internetin kök sunucularından (Root Servers) öğrenen çözümleyici.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Adım 1: Pi-hole Kurulumu (Bekçi)
&lt;/h3&gt;

&lt;p&gt;Pi-hole kurulumu, Linux dünyasının en pratik scriptlerinden birine sahip. Terminale şu komutu yapıştırarak kurulum sihirbazı başlattım:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://install.pi-hole.net | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sihirbaz sırasında dikkat ettiğim kritik noktalar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Static IP:&lt;/strong&gt; Burada size basit bir uyarı veriyor. Cihazın IP'sinin statik olması gerektiğini özellikle belirtiyor. Biz bunu önceki adımda tamamladık.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upstream DNS:&lt;/strong&gt; Kurulum sırasında herhangi birini (örn: Google) seçebilirsiniz, birazdan bunu değiştireceğiz.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bloclist:&lt;/strong&gt; Burada pihole un kullandığı 3. pari filtreler için bildirge var. Ben kullanmak istediğim için 'yes'i seçtim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Query Logging:&lt;/strong&gt; Eğer aşırı gizlilik isterneniz 'no' yu seçebilirsiniz. Ben 'yes' ile devam ettim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privacy mode for FTL:&lt;/strong&gt; Kullanıcıların hangi siteye sorgu gönderdiğini web arayüzünde  göstermek için &lt;code&gt;Show Everything&lt;/code&gt; ile devam ettim.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Adım 2: Erişim ve Yetkilendirme (Post-Install)
&lt;/h3&gt;

&lt;p&gt;Kurulum sihirbazı bitti ama terminalden henüz çıkmıyoruz. Özellikle &lt;strong&gt;Pi-hole v6&lt;/strong&gt; mimarisiyle gelen önemli bir değişikliği yapılandırmamız gerekiyor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CLI için API Yetkilendirmesi&lt;/strong&gt;&lt;br&gt;
Pi-hole v6, CLI (Komut Satırı) komutları için artık doğrudan veritabanı manipülasyonu yerine yeni API'sini kullanıyor. Bu güvenlik açısından harika olsa da, her komut girdiğimizde bizden parola istemesi (API authentication) can sıkıcı olabilir.&lt;/p&gt;

&lt;p&gt;Bir sistemci "sudo" yazmaya alışkındır ama gereksiz parola girmekten nefret eder. Kendi kullanıcımızı &lt;code&gt;pihole&lt;/code&gt; grubuna ekleyerek, terminalden parola girmeden yönetim komutlarını çalıştırabilme yetkisi verelim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Mevcut kullanıcımızı ($USER), pihole grubuna ekle&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; pihole &lt;span class="nv"&gt;$USER&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Not: Bu değişikliğin aktif olması için SSH oturumunu kapatıp (&lt;code&gt;exit&lt;/code&gt;) tekrar bağlanmanız gerekebilir.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Web Arayüzü Şifresi&lt;/strong&gt;&lt;br&gt;
Pi-hole kurulum sırasında rastgele bir şifre atar. Web arayüzüne (&lt;code&gt;http://192.168.1.4/admin&lt;/code&gt;) her girişte loglara bakmak için o karmaşık şifreyi aramak istemeyiz.&lt;/p&gt;

&lt;p&gt;Aklımızda kalacak güçlü bir şifre belirleyelim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pihole setpassword
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Komutu girdikten sonra yeni şifrenizi yazın (ekranda görünmeyecektir) ve onaylayın.&lt;/p&gt;

&lt;p&gt;Artık hem terminalde hem de web arayüzünde tam yetkiliyiz. Sıra geldi DNS sorgularını özgürleştirmeye: &lt;strong&gt;Unbound Kurulumu.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Adım 3: Unbound Kurulumu (Özgürlük)
&lt;/h3&gt;

&lt;p&gt;İşte işin mühendislik kısmı burada başlıyor. Çoğu kullanıcı Pi-hole'u kurar ve DNS olarak Google (8.8.8.8) kullanmaya devam eder. Bu, reklamları engeller ama gizliliğinizi korumaz. Verileriniz hala Google'a akar.&lt;/p&gt;

&lt;p&gt;Biz &lt;strong&gt;Recursive DNS&lt;/strong&gt; kuracağız. Yani aracıları aradan çıkaracağız.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;unbound &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adım 3: Konfigürasyon ve Hız Optimizasyonu 🚀
&lt;/h3&gt;

&lt;p&gt;Unbound'un varsayılan ayarları güvenlik odaklıdır ancak biraz hantaldır. Benim buradaki amacım ise &lt;strong&gt;gecikme hissini&lt;/strong&gt; biraz da olsa azaltmak.&lt;/p&gt;

&lt;p&gt;Bunun için Unbound konfigürasyon dosyasını oluşturdum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/unbound/unbound.conf.d/pi-hole.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ve içine şu optimize edilmiş ayarları girdim. (Buradaki &lt;code&gt;serve-expired&lt;/code&gt; parametresi sihirli dokunuştur):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Log seviyesi (Hata ayıklama gerekmedikçe 0)&lt;/span&gt;
    &lt;span class="na"&gt;verbosity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
    &lt;span class="na"&gt;interface&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;127.0.0.1&lt;/span&gt;
    &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5335&lt;/span&gt;
    &lt;span class="na"&gt;do-ip4&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
    &lt;span class="na"&gt;do-udp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
    &lt;span class="na"&gt;do-tcp&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;

    &lt;span class="c1"&gt;# IPv6'yı kapat (Ev ağında gecikme yaratabilir)&lt;/span&gt;
    &lt;span class="na"&gt;do-ip6&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;no&lt;/span&gt;

    &lt;span class="c1"&gt;# Root Hints dosyası&lt;/span&gt;
    &lt;span class="na"&gt;root-hints&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/var/lib/unbound/root.hints"&lt;/span&gt;

    &lt;span class="c1"&gt;# Gizlilik Ayarları&lt;/span&gt;
    &lt;span class="na"&gt;hide-identity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
    &lt;span class="na"&gt;hide-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
    &lt;span class="na"&gt;harden-glue&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
    &lt;span class="na"&gt;harden-dnssec-stripped&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;

    &lt;span class="c1"&gt;# --- PERFORMANS OPTİMİZASYONLARI ---&lt;/span&gt;

    &lt;span class="c1"&gt;# Süresi bitmiş kayıtları (expired) anında sun, arkada güncelle&lt;/span&gt;
    &lt;span class="na"&gt;serve-expired&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
    &lt;span class="na"&gt;serve-expired-ttl&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;86400&lt;/span&gt;  &lt;span class="c1"&gt;# 1 gün&lt;/span&gt;

    &lt;span class="c1"&gt;# Cache boyutlarını Pi 3'ün RAM'ine göre ayarla&lt;/span&gt;
    &lt;span class="na"&gt;msg-cache-size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;50m&lt;/span&gt;
    &lt;span class="na"&gt;rrset-cache-size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;100m&lt;/span&gt;

    &lt;span class="c1"&gt;# İşlemci çekirdeklerini kullan&lt;/span&gt;
    &lt;span class="na"&gt;num-threads&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dosyayı kaydettikten sonra kök sunucuları resmi kaynaktan (InterNIC) en güncel &lt;code&gt;Root Hints&lt;/code&gt; listesini çekip Unbound'un beklediği klasöre koyalım ve izinlerini sağlama alalım:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Dosyayı indir&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;wget &lt;span class="nt"&gt;-O&lt;/span&gt; /var/lib/unbound/root.hints https://www.internic.net/domain/named.root

&lt;span class="c"&gt;# İzinleri ayarla (Unbound kullanıcısının okuyabildiğinden emin olalım)&lt;/span&gt;
&lt;span class="nb"&gt;sudo chown &lt;/span&gt;unbound:unbound /var/lib/unbound/root.hints
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dosyayı kaydedip (CTRL+X, Y, Enter) Servisi yeniden başlatalım:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart unbound
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ayrıca unbound servisi her açılışta otomatik açılacak şekilde ayarlayalım:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;unbound
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adım 4: Büyük Buluşma (Entegrasyon)
&lt;/h3&gt;

&lt;p&gt;Artık Pi-hole'a "Google ile konuşma, yan odadaki Unbound ile konuş" dememiz lazım.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sabit IP (Static IP) Ayarı Yaptığımızda DNS Servers kısmına &lt;code&gt;1.1.1.1&lt;/code&gt; vererek DNS sunucusunu cloudflare olarak ayarlamıştık. Şimdi o ayarı değiştirerek &lt;code&gt;127.0.0.1&lt;/code&gt; yapıp dns sunucusunu yerel cihaz olarak değiştirdim.&lt;/li&gt;
&lt;li&gt;Web tarayıcısından &lt;code&gt;http://192.168.1.4/admin&lt;/code&gt; adresine girdim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Settings &amp;gt; DNS&lt;/strong&gt; sekmesine geldim.&lt;/li&gt;
&lt;li&gt;Sağdaki hazır listelerin (Google, OpenDNS vb.) hepsinin tikini &lt;strong&gt;kaldırdım&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom 1 (IPv4)&lt;/strong&gt; kutusuna şunu yazdım: &lt;code&gt;127.0.0.1#5335&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbsjxyywc1c63bbwh8m4l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbsjxyywc1c63bbwh8m4l.png" alt="DNS Ayarı" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sonuç:&lt;/strong&gt;&lt;br&gt;
Şu anda ağımda bir reklam engelleme servisi çalışıyor ve DNS sorgularım şifreli, doğrulanmış ve aracı olmadan çözülüyor. Ancak bir sorun var: Cihazlarım (Telefon, TV) hala modemi dinliyor.&lt;/p&gt;

&lt;p&gt;Sıradaki adımda "Ağ Yönetimini Ele Geçirme" (DHCP Handover) operasyonunu yapacağız.&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚔️ Bölüm 4: Modemi "Aptallaştırmak" (DHCP Operasyonu)
&lt;/h2&gt;

&lt;p&gt;Pi-hole ve Unbound hazırdı. Normal şartlarda, modem arayüzüne girip DNS adresini &lt;code&gt;192.168.1.4&lt;/code&gt; olarak değiştirmek yeterli olmalıydı.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu0gnrekv56iv8m1b82i5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu0gnrekv56iv8m1b82i5.png" alt="Modem DNS Ayarı" width="758" height="684"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ancak teori ve pratik, ISS modemlerinde asla uyuşmaz.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Kullandığım modem (Vodafone H300s), çoğu ISS cihazı gibi "kilitli" bir kutuydu. DNS ayarlarını değiştirmeme izin verse bile, arka planda ikincil DNS olarak kendi sunucularını zorluyor veya bazı cihazlar (özellikle Android TV ve Chromecast) inatla modemin önerdiği DNS'e gidiyordu. Sonuç? Reklamlar sızmaya devam ediyordu.&lt;/p&gt;

&lt;p&gt;"Kibarca" rica ettim olmadı. Ben de yönetimi zorla almaya karar verdim.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Çözüm:&lt;/strong&gt; Modemin &lt;strong&gt;DHCP sunucusunu&lt;/strong&gt; kapatmak ve IP dağıtma yetkisini &lt;strong&gt;Pi-hole'a&lt;/strong&gt; vermek.&lt;/p&gt;

&lt;p&gt;Bu yöntem iki devasa avantaj sağlar:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Garanti Yönlendirme:&lt;/strong&gt; Pi-hole, IP dağıtırken cihazlara "Tek DNS benim, başka yere bakma" der. Kaçış yoktur.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detaylı Analiz:&lt;/strong&gt; Modem DHCP iken Pi-hole loglarında tüm trafiği tek bir cihazdan (Modem) geliyormuş gibi görürsünüz. Pi-hole DHCP olduğunda, hangi cihazın (iPad, TV, Laptop) hangi siteye girdiğini tek tek görebilirsiniz.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Operasyon Sırası (Dikkat!)
&lt;/h3&gt;

&lt;p&gt;Ağdan kopmamak için sıralama hayati önem taşır. Önce yeni patronu (Pi-hole) devreye almalı, sonra eskisini (Modem) emekli etmelisiniz.&lt;/p&gt;
&lt;h4&gt;
  
  
  Adım 1: Yeni Patronu Hazırla (Pi-hole)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Pi-hole panelinde &lt;strong&gt;Settings &amp;gt; DHCP&lt;/strong&gt; sekmesine gittim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DHCP server enabled&lt;/strong&gt; kutusunu işaretledim.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Range:&lt;/strong&gt; Modeminkiyle çakışmayacak bir aralık verdim (Örn: &lt;code&gt;192.168.1.5&lt;/code&gt; - &lt;code&gt;192.168.1.254&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Router (Gateway):&lt;/strong&gt; Modemin IP adresini (&lt;code&gt;192.168.1.1&lt;/code&gt;) girdim. &lt;em&gt;Burası çok kritik, yanlış girerseniz internete çıkamazsınız.&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxomqrrr5st017knf57m0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxomqrrr5st017knf57m0.png" alt="DHCP Ayarı" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Adım 2: Eskisini Sustur (Modem)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Modem arayüzüne girdim.&lt;/li&gt;
&lt;li&gt;LAN / Yerel Ağ ayarlarından &lt;strong&gt;DHCP Sunucusu&lt;/strong&gt; seçeneğini &lt;strong&gt;KAPALI (Disable)&lt;/strong&gt; konuma getirdim.&lt;/li&gt;
&lt;li&gt;Kaydettim.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fshx3kyj11wfkftuio7o5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fshx3kyj11wfkftuio7o5.png" alt="Son Modem Ayarı" width="758" height="662"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Adım 3: Sözleşme Yenileme (Renew Leases)
&lt;/h4&gt;

&lt;p&gt;Şu an ağda bir kaos yok ama cihazların hala eski "kira sözleşmeleri" (IP Lease) var. Onları yenilemek için:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Telefonun Wi-Fi özelliğini kapatıp açtım.&lt;/li&gt;
&lt;li&gt;Bilgisayarın Ethernet kablosunu çıkarıp taktım.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Sonuç:&lt;/strong&gt; Pi-hole panelindeki "DHCP Leases" kısmında cihazlarımın tek tek belirdiğini gördüm. Artık ağın mutlak hakimi Raspberry Pi idi. Modem ise sadece internet sinyalini içeri taşıyan "aptal" bir kutuya (Dumb Pipe) dönüşmüştü. Tam istediğim gibi.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8lel6oams3sj65dfykao.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8lel6oams3sj65dfykao.png" alt="Pi-Hole Üzerinden IP Leases" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  🌍 Bölüm 5: Duvarların İçinden Tünel Açmak (CGNAT ve Tailscale)
&lt;/h2&gt;

&lt;p&gt;Ev ağım artık bir kaleydi: Reklamlar giremiyor, DNS sorguları dışarı sızmıyordu. Ancak büyük bir sorunum vardı: &lt;strong&gt;Ben de eve giremiyordum.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Evden çıktığım anda (mobil veri veya kafe Wi-Fi'ı), ISS'mın güvenli olmayan ağına veya halka açık güvensiz ağlara mahkum kalıyordum. Eve bağlanmak için geleneksel yöntem, modemden port açmaktır. Ancak Türkiye'deki çoğu ev kullanıcısı gibi ben de &lt;strong&gt;CGNAT&lt;/strong&gt; (Carrier Grade NAT) havuzundayım. Yani gerçek bir genel (public) IP adresim yok, bir apartman bloğu gibi binlerce kişiyle aynı IP'yi paylaşıyorum. Dolayısıyla dışarıdan içeriye kapı (port) açmam teknik olarak imkansız.&lt;/p&gt;

&lt;p&gt;Çözüm? &lt;strong&gt;NAT Traversal (NAT Aşımı) ve Overlay Network.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Burada &lt;strong&gt;Tailscale&lt;/strong&gt; devreye giriyor. Tailscale, ISS'nın karmaşık NAT duvarlarını yıkmaz (bunu yapamayız), ancak &lt;strong&gt;"NAT Traversal"&lt;/strong&gt; tekniklerini kullanarak bu duvarların içinden şifreli bir tünel (WireGuard) açar.&lt;/p&gt;

&lt;p&gt;Bu sayede ISS altyapısını kullanmaya devam ederiz ancak ISS, paketlerimizin içeriğini veya nereye gittiğini (DNS) göremez. Sadece şifreli bir veri akışı görür. Kısacası ISS'yı, veriyi sadece A noktasından B noktasına taşıyan "kör" bir taşıyıcıya (Dumb Pipe) dönüştürürüz.&lt;/p&gt;
&lt;h3&gt;
  
  
  Adım 1: Kurulum ve IP Yönlendirme
&lt;/h3&gt;

&lt;p&gt;Headless sunucuma tek satırla Tailscale'i kurdum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://tailscale.com/install.sh | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tailscale bir "Overlay Network" (Katman Ağı) oluşturur. Ancak Linux çekirdeği varsayılan olarak üzerinden geçen trafiği (packet forwarding) engeller. Pi'nin gelen trafiği internete taşıması için çekirdek ayarlarını değiştirdim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# IPv4 Forwarding'i aç&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'net.ipv4.ip_forward = 1'&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; /etc/sysctl.d/99-tailscale.conf
&lt;span class="c"&gt;# Eğer IPv6 Kullanacaksanız:&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'net.ipv6.conf.all.forwarding = 1'&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; /etc/sysctl.d/99-tailscale.conf
&lt;span class="nb"&gt;sudo &lt;/span&gt;sysctl &lt;span class="nt"&gt;-p&lt;/span&gt; /etc/sysctl.d/99-tailscale.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adım 2: Sihirli Komut (Exit Node)
&lt;/h3&gt;

&lt;p&gt;Servisi başlatırken Pi'ye "Sen artık bu sanal ağın internete çıkış kapısısın" dedim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;tailscale up &lt;span class="nt"&gt;--advertise-exit-node&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bana verdiği linke tıklayıp cihazı hesabımla eşleştirdim.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adım 3: Admin Onayı (Güvenlik)
&lt;/h3&gt;

&lt;p&gt;Bu adım genellikle unutulur. Terminalden "ben çıkış kapısıyım" demek yetmez, Tailscale yönetim panelinden (Web) buna izin vermeniz gerekir.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Admin Paneli &amp;gt; Machines &amp;gt; &lt;code&gt;pi-hole&lt;/code&gt; &amp;gt; &lt;strong&gt;Edit Route Settings&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use as exit node&lt;/strong&gt; seçeneğini aktif ettim.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Adım 4 (Opsiyonel ama Önemli): Anahtar Süresini Uzatmak (Disable Key Expiry)
&lt;/h3&gt;

&lt;p&gt;Tailscale, güvenlik tedbiri olarak cihazların oturum anahtarlarını belirli aralıklarla (varsayılan 180 gün) geçersiz kılar. 7/24 çalışan bir sunucu için bu risklidir; tam ihtiyacınız olduğu anda erişiminiz kesilebilir.&lt;/p&gt;

&lt;p&gt;Bu "baş ağrısını" yaşamamak için Pi-hole sunucumuzun oturum süresini kalıcı hale getiriyoruz:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Admin Paneli &amp;gt; Machines&lt;/strong&gt; listesinden &lt;code&gt;pi-hole&lt;/code&gt; cihazını bulun.&lt;/li&gt;
&lt;li&gt;Sağdaki üç noktaya tıklayıp &lt;strong&gt;Disable Key Expiry&lt;/strong&gt; seçeneğini işaretledik. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftg6x91nj5wawkmibbyh1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftg6x91nj5wawkmibbyh1.png" alt="Son Durum" width="363" height="215"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🎉 Sonuç: Dijital Özgürlük
&lt;/h2&gt;

&lt;p&gt;Telefonumun Wi-Fi'ını kapattım, mobil veriye geçtim. Tailscale uygulamasından "Exit Node" olarak evdeki Pi'mi seçtim ve testi başlattım:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fce95wg8qtix2dud4llkk.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fce95wg8qtix2dud4llkk.jpeg" alt="Çıkış Node Seçme" width="800" height="1733"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tünel Testi (Exit Node):&lt;/strong&gt; &lt;code&gt;whatismyip.com&lt;/code&gt;'a girdiğimde, mobil operatörümün IP'sini değil, evimdeki fiber hattın IP'sini gördüm. Trafiğim şifreli bir tünelden eve gidiyor, oradan internete çıkıyordu.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sanal Yerel Ağ:&lt;/strong&gt; Tarayıcıya Pi-hole'un &lt;strong&gt;Tailscale IP adresini&lt;/strong&gt; (100.x.x.x) yazdığımda, sanki evde masamda oturuyormuşum gibi yönetim paneli karşımdaydı. CGNAT engelini, sanal bir ağ katmanıyla aşmıştım.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Termux ile Tam Kontrol:&lt;/strong&gt; Mobil telefonumdan Termux'u açıp, yine aynı Tailscale IP'sine SSH bağlantısı kurdum.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffa1bd6124v1rewjqp0sr.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffa1bd6124v1rewjqp0sr.jpeg" alt="Mobil Durumu" width="800" height="1733"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Özetle:&lt;/strong&gt;&lt;br&gt;
ISS'yi veya CGNAT'ı yok etmedik; bu fiziksel olarak imkansızdı. Ancak kurduğumuz bu yapı ile onları sadece &lt;strong&gt;şifreli paket taşıyan bir altyapıya&lt;/strong&gt; indirgedik.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DNS sorgularımızı göremiyorlar (Unbound + Şifreleme).&lt;/li&gt;
&lt;li&gt;Hangi sitelere girdiğimizi analiz edemiyorlar (VPN Tüneli).&lt;/li&gt;
&lt;li&gt;Bize "public IP vermiyoruz, eve bağlanamazsın" diyemiyorlar (Tailscale/NAT Traversal).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eski bir Raspberry Pi ve doğru mühendislik yaklaşımıyla; binlerce liralık kurumsal cihazların sunduğu "Zero Trust" konforunu evimize getirdik.&lt;/p&gt;

&lt;p&gt;Çekmecenizdeki o kartı çıkarın. İnternetiniz size ait olsun.&lt;/p&gt;

</description>
      <category>raspberrypi</category>
      <category>pihole</category>
      <category>tailscale</category>
      <category>unbound</category>
    </item>
  </channel>
</rss>
