---
title: 'Alt Yapı Teknolojileri'
source: 'https://academia.sh/tr/kurslar/konteynerler/alt-yapi-teknolojileri'
course: Konteynerler
language: tr
updated: '2026-08-17T18:09:04+00:00'
license: 'CC BY-SA 4.0'
---

# Alt Yapı Teknolojileri

Konteyner yalıtımını kuran üç mekanizma ayrı ayrı modellenir: ad alanı bir görünürlük eşlemesi, denetim grubu bir pay dağıtıcı, birleşim dosya sistemi bir katman yığını olarak; her birinin bedeli ve delindiği yer sayılır.

Önceki ders konteynerin beş ölçütten dördünü ayırdığını yazdı: dosya sistemi, ağ, süreç tablosu
ve kullanıcı. Nasıl ayırdığını sormadı. Soru boş değildir, çünkü ayrılan şeyler tek makinede tek
tanedir — süreç tablosu bir tanedir, bellek bir tanedir, disk bir tanedir. "Ayırmak" burada
ikinci bir tane üretmek olamaz; başka bir şey olmalıdır.

Bu ders o başka şeyi üç ayrı mekanizma olarak modeller. **Ad alanı** aynı tablonun üzerine bir
görünürlük eşlemesi koyar. **Denetim grubu** aynı kaynağı pay olarak dağıtır ve sınır aşıldığında
bir karar verir. **Birleşim dosya sistemi** aynı dosyaları bir yığın olarak üst üste koyar.
Üçünün ortak yanı şudur: hiçbiri yeni bir kaynak üretmez, üçü de **tek bir kaynağın üzerine bir
kural** koyar. Kuralın olduğu yerde delik de vardır ve her bölüm deliği adıyla yazar.

**KK13.** Üç mekanizma ayrı ayrı modellenir; birlikte çalıştıkları hâl modellenmez. **KK14.**
Ad alanı modelinde tek bir küresel tablo vardır ve görünüm hiçbir kaydı silmez.

## Ad Alanı: Bir Görünürlük Eşlemesi

```js
// olcum-agi/adalani.mjs — ad alani bir gorunurluk eslemesi olarak (model)
// Tek bir kuresel surec tablosu vardir; ad alani o tablonun uzerine bir
// gorunurluk eslemesi koyar. Kayit silinmez, yalniz gorunmez olur.

const TABLO = [                       // kuresel tablo: numara, ad, sahip ad alani
  [1, "yonetici", "kok"], [17, "gunluk-toplayici", "kok"], [41, "zamanlayici", "kok"],
  [102, "okuma-toplayici", "A"], [103, "okuma-isleyici", "A"], [110, "okuma-kuyrugu", "A"],
  [121, "dogrulayici", "A"], [140, "dogrulama-onbellegi", "A"],
  [205, "faturalama", "B"], [206, "fatura-yazici", "B"], [219, "tarife-cozucu", "B"],
  [233, "is-emri", "B"], [301, "gecelik-is", "C"], [305, "gecelik-yazici", "C"],
];

// Gorunurluk kurali: bir ad alani yalniz kendi kayitlarini gorur ve onlari
// 1'den baslayan yerel numaralarla numaralandirir. Kok her kaydi gorur.
function gorunum(adAlani) {
  const kayitlar = adAlani === "kok" ? TABLO : TABLO.filter((k) => k[2] === adAlani);
  return kayitlar.map(([kuresel, ad], i) => ({ yerel: i + 1, kuresel, ad }));
}

const ALANLAR = ["kok", "A", "B", "C"];
console.log(`kuresel tabloda ${TABLO.length} kayit var; hicbir gorunum kayit silmez`);
console.log("ad alani".padEnd(10) + "goren".padEnd(8) + "gormeyen".padEnd(10) + "yerel -> kuresel");
for (const a of ALANLAR) {
  const g = gorunum(a);
  console.log(a.padEnd(10) + `${g.length}/${TABLO.length}`.padEnd(8) +
    String(TABLO.length - g.length).padEnd(10) +
    g.slice(0, 3).map((k) => `${k.yerel}->${k.kuresel}`).join(" ") + (g.length > 3 ? " ..." : ""));
}

console.log("\nayni kayit iki numara tasir:");
for (const a of ["A", "B", "C"]) {
  const ilk = gorunum(a)[0];
  console.log(`  ${ilk.ad.padEnd(20)} ${a} icinde ${ilk.yerel}, kok icinde ${ilk.kuresel}`);
}

const HAVUZ = 32768;
console.log(`\ndelik: numara havuzu ortaktir (${HAVUZ} numara, ${TABLO.length} kullanimda)`);
const enBuyuk = ALANLAR.slice(1)
  .map((a) => [a, gorunum(a).length]).sort((x, y) => y[1] - x[1])[0];
console.log(`  kok ${gorunum("kok").length} kaydin hepsini gorur; ad alanlari birbirini gormez`);
console.log(`  en cok kayit acan ad alani ${enBuyuk[0]} (${enBuyuk[1]} kayit); ` +
  `havuzu tuketen ad alani digerlerini de durdurur`);
console.log(`  gorunmeyen kayit yine de kaynak tuketir: kok gorunumunde ` +
  `${TABLO.length - gorunum("A").length} kayit A'nin disinda ama ayni makinede`);
```

```
kuresel tabloda 14 kayit var; hicbir gorunum kayit silmez
ad alani  goren   gormeyen  yerel -> kuresel
kok       14/14   0         1->1 2->17 3->41 ...
A         5/14    9         1->102 2->103 3->110 ...
B         4/14    10        1->205 2->206 3->219 ...
C         2/14    12        1->301 2->305

ayni kayit iki numara tasir:
  okuma-toplayici      A icinde 1, kok icinde 102
  faturalama           B icinde 1, kok icinde 205
  gecelik-is           C icinde 1, kok icinde 301

delik: numara havuzu ortaktir (32768 numara, 14 kullanimda)
  kok 14 kaydin hepsini gorur; ad alanlari birbirini gormez
  en cok kayit acan ad alani A (5 kayit); havuzu tuketen ad alani digerlerini de durdurur
  gorunmeyen kayit yine de kaynak tuketir: kok gorunumunde 9 kayit A'nin disinda ama ayni makinede
```

Ad alanı bir silme değil, bir **filtredir**. On dört kaydın hepsi tabloda durur; A görünümü
beşini, B dördünü, C ikisini görür. Aynı kayıt iki numara taşır — okuma toplayıcı A içinde 1'dir,
kök içinde 102 — ve bu ikilik yalıtımın tam olarak neye dayandığını gösterir: **numaranın kendisi
değil, numaranın hangi tablodan okunduğu** ayrılmıştır.

Deliğin üç adı vardır. Kök görünümü on dört kaydın hepsini görür; yalıtım aşağı doğru değil,
yalnız yana doğru çalışır. Numara havuzu ortaktır: 32.768 numaranın tümü paylaşılır ve havuzu
tüketen bir ad alanı diğerlerinin kayıt açmasını da engeller. Ve görünmeyen kayıt yok değildir —
A'nın görmediği dokuz kayıt aynı makinede işlemci ve bellek tüketmeyi sürdürür. Ad alanının
bedeli bayt değil, bir eşleme tablosudur; kapattığı ortam farkı ise sıfırdır.

## Denetim Grubu: Bir Pay Dağıtıcı

**KK15.** Sert sınırlı kaynak ile esnek paylaşılan kaynak ayrı modellenir; istekler sırayla
gelir. **KK16.** Sınır aşıldığında verilen karar kaynağın türüne bağlıdır.

```js
// olcum-agi/denetimgrubu.mjs — denetim grubu bir pay dagitici olarak (model)
// Iki ayri davranis modellenir: sert sinirli kaynakta sinir asilinca verilen
// KARAR, esnek paylasilan kaynakta agirliga gore yapilan DAGITIM.

const GRUP = {                          // kurgu bolgesel olcum aginin uc grubu
  toplama:    { bellekSiniriMB: 512, agirlik: 20, islemciTalebi: 60 },
  faturalama: { bellekSiniriMB: 768, agirlik: 50, islemciTalebi: 90 },
  gecelikIs:  { bellekSiniriMB: 256, agirlik: 30, islemciTalebi: 80 },
};

// Sert sinir: her istek sirayla gelir; sinir asilirsa karar kaynagin turune baglidir.
const KARAR = { bellek: "istegi yapan surec durdurulur", tanitici: "istek reddedilir" };
const ISTEK = {                         // MB cinsinden ardisik bellek istekleri
  toplama: [180, 140, 120, 90], faturalama: [300, 260, 150, 200], gecelikIs: [120, 100, 90],
};

console.log("sert sinir: bellek (MB)");
console.log("grup".padEnd(12) + "sinir".padEnd(8) + "verilen".padEnd(9) +
  "sigmayan".padEnd(11) + "karar (bellek)");
let toplamVerilen = 0, toplamSigmayan = 0;
for (const [ad, istekler] of Object.entries(ISTEK)) {
  const sinir = GRUP[ad].bellekSiniriMB;
  let kullanim = 0, sigmayan = [];
  for (const i of istekler) (kullanim + i <= sinir) ? (kullanim += i) : sigmayan.push(i);
  toplamVerilen += kullanim; toplamSigmayan += sigmayan.length;
  console.log(ad.padEnd(12) + String(sinir).padEnd(8) + String(kullanim).padEnd(9) +
    `${sigmayan.length} istek`.padEnd(11) + (sigmayan.length ? KARAR.bellek : "-"));
}
console.log(`toplam verilen ${toplamVerilen} MB, sigmayan ${toplamSigmayan} istek; ` +
  `sinirlarin toplami ${Object.values(GRUP).reduce((t, g) => t + g.bellekSiniriMB, 0)} MB`);
console.log(`ayni asim dosya taniticisinda baska bir karar verir: ${KARAR.tanitici}`);

// Esnek paylasim: agirlik bir sinir degil, rekabet halinde pay oranidir.
const TOPLAM_PAY = 100;
const agirlikToplam = Object.values(GRUP).reduce((t, g) => t + g.agirlik, 0);
const talepToplam = Object.values(GRUP).reduce((t, g) => t + g.islemciTalebi, 0);
console.log(`\nesnek paylasim: islemci (toplam ${TOPLAM_PAY} birim, talep ${talepToplam} birim)`);
console.log("grup".padEnd(12) + "agirlik".padEnd(9) + "talep".padEnd(8) +
  "rekabette".padEnd(11) + "tek basina");
for (const [ad, g] of Object.entries(GRUP)) {
  const pay = Math.round((g.agirlik / agirlikToplam) * TOPLAM_PAY);
  console.log(ad.padEnd(12) + String(g.agirlik).padEnd(9) + String(g.islemciTalebi).padEnd(8) +
    String(Math.min(pay, g.islemciTalebi)).padEnd(11) + Math.min(TOPLAM_PAY, g.islemciTalebi));
}
console.log("delik: agirlik bir tavan degildir; rekabet yoksa grup payinin " +
  `${Math.round(Math.min(TOPLAM_PAY, GRUP.gecelikIs.islemciTalebi) / ((GRUP.gecelikIs.agirlik / agirlikToplam) * TOPLAM_PAY) * 10) / 10}` +
  " katini alir");
console.log(`delik: sinirlarin toplami ${Object.values(GRUP).reduce((t, g) => t + g.bellekSiniriMB, 0)}` +
  " MB, makinenin belleginden bagimsizdir; asiri bindirme cekirdek karariyla sonuclanir");
```

```
sert sinir: bellek (MB)
grup        sinir   verilen  sigmayan   karar (bellek)
toplama     512     440      1 istek    istegi yapan surec durdurulur
faturalama  768     710      1 istek    istegi yapan surec durdurulur
gecelikIs   256     220      1 istek    istegi yapan surec durdurulur
toplam verilen 1370 MB, sigmayan 3 istek; sinirlarin toplami 1536 MB
ayni asim dosya taniticisinda baska bir karar verir: istek reddedilir

esnek paylasim: islemci (toplam 100 birim, talep 230 birim)
grup        agirlik  talep   rekabette  tek basina
toplama     20       60      20         60
faturalama  50       90      50         90
gecelikIs   30       80      30         80
delik: agirlik bir tavan degildir; rekabet yoksa grup payinin 2.7 katini alir
delik: sinirlarin toplami 1536 MB, makinenin belleginden bagimsizdir; asiri bindirme cekirdek karariyla sonuclanir
```

Denetim grubunun iki ayrı davranışı vardır ve ikisi karıştırıldığında yanlış beklenti üretir.
Sert sınırda karar keskindir: üç grupta da bir istek sınıra sığmaz ve bellekte verilen karar
isteği yapan sürecin durdurulmasıdır — reddedilmek değil, durdurulmak. Aynı aşım dosya
tanıtıcısında başka bir karar verir; istek reddedilir ve süreç koşmayı sürdürür. Bu ayrım
kurgudaki gecelik iş için doğrudan sonuç taşır: 256 MB sınırla 220 MB verilir, dördüncü istek
sığmaz ve iş yarıda durur.

Esnek paylaşımda sınır yoktur, **ağırlık** vardır. Talep 230 birim, makine 100 birimdir;
rekabette paylar 20, 50 ve 30 olur. Ama ağırlık bir tavan değildir: rekabet yokken gecelik iş
payının 2,7 katını alır. İkinci delik daha sessizdir — üç sınırın toplamı 1.536 MB'dır ve bu
sayının makinenin belleğiyle bir ilgisi yoktur. Sınırlar makinenin belleğinden büyük
konabilir; aşırı bindirme durumunda karar denetim grubunda değil, çekirdekte verilir. Denetim
grubunun bedeli de bayt değildir, muhasebedir; kapattığı ortam farkı yine sıfırdır.

## Birleşim Dosya Sistemi: Bir Katman Yığını

**KK17.** Katmanlar gerçek dizinlerdir ve dosyalar gerçekten yazılıp ölçülür; silme işareti bir
dosya adı öneki ile modellenir. **KK18.** Yalnız en üst katman yazılabilir. **KK19.** Paylaşım
hesabı, alt katmanların içerik olarak aynı olduğunu varsayar.

```js
// olcum-agi/katman.mjs — birlesim dosya sistemi bir katman yigini olarak
// Katmanlar GERCEK dizinlerdir; dosyalar gercekten yazilir ve gercekten olculur.
import { mkdirSync, writeFileSync, readdirSync, statSync, copyFileSync, rmSync } from "node:fs";
import { join, dirname } from "node:path";

const KOK = "/tmp/olcum-agi-katman";
const KATMAN = ["katman0-taban", "katman1-kural", "katman2-yazilabilir"];  // altan uste
const ISARET = ".silindi.";                   // silme isareti onekidir; alttakini gizler
const ICERIK = {
  "katman0-taban": { "etc/tarife.json": 4096, "lib/cozumleyici.bin": 61440,
    "lib/kural.bin": 20480, "uygulama/toplayici.mjs": 3072, "uygulama/eski-ayar.json": 1024 },
  "katman1-kural": { "lib/kural.bin": 24576, "etc/kural-surum.txt": 32 },
  "katman2-yazilabilir": { "uygulama/toplayici.mjs": 3584, "uygulama/yeni-kural.mjs": 2048,
    ["uygulama/" + ISARET + "eski-ayar.json"]: 0 },
};

rmSync(KOK, { recursive: true, force: true });
for (const [k, dosyalar] of Object.entries(ICERIK))
  for (const [yol, boyut] of Object.entries(dosyalar)) {
    mkdirSync(dirname(join(KOK, k, yol)), { recursive: true });
    writeFileSync(join(KOK, k, yol), Buffer.alloc(boyut, k.charCodeAt(6)));
  }

const listele = (k, alt = "") => readdirSync(join(KOK, k, alt), { withFileTypes: true })
  .flatMap((g) => g.isDirectory() ? listele(k, join(alt, g.name)) : [join(alt, g.name)]);
const bayt = (k, yol) => statSync(join(KOK, k, yol)).size;
const katmanBayt = (k) => listele(k).reduce((s, y) => s + bayt(k, y), 0);

// Birlestirme: en ustteki katman kazanir; ustteki silme isareti alttakini gizler.
const gorunum = new Map(), golge = [], gizli = [];
for (const k of [...KATMAN].reverse())
  for (const yol of listele(k)) {
    if (yol.split("/").pop().startsWith(ISARET)) { gizli.push(yol.replace(ISARET, "")); continue; }
    gorunum.has(yol) ? golge.push(`${yol} (${gorunum.get(yol)} ustte)`) : gorunum.set(yol, k);
  }
for (const y of gizli) gorunum.delete(y);

console.log("katman".padEnd(22) + "dosya".padEnd(8) + "bayt");
for (const k of KATMAN)
  console.log(k.padEnd(22) + String(listele(k).length).padEnd(8) + katmanBayt(k));
console.log("\nbirlesik gorunum (yol -> saglayan katman)");
for (const [yol, k] of [...gorunum].sort()) console.log("  " + yol.padEnd(28) + k);
console.log(`gorunen ${gorunum.size} dosya, ` +
  `${[...gorunum].reduce((s, [y, k]) => s + bayt(k, y), 0)} bayt`);
console.log(`golgelenen ${golge.length}: ${golge.join(", ")}`);
console.log(`silme isaretiyle gizlenen ${gizli.length}: ${gizli.join(", ")} ` +
  `(alt katmanda hala ${bayt(KATMAN[0], gizli[0])} bayt duruyor)`);
console.log(`okuma icin kopyalanan dosya: 0 (${gorunum.size} dosya yerinde okunur)`);

// Kopya-yukari: alt katmandaki bir dosyaya yazilinca once ust katmana kopyalanir.
const HEDEF = "etc/tarife.json", ALT = gorunum.get(HEDEF);
mkdirSync(dirname(join(KOK, KATMAN[2], HEDEF)), { recursive: true });
copyFileSync(join(KOK, ALT, HEDEF), join(KOK, KATMAN[2], HEDEF));
writeFileSync(join(KOK, KATMAN[2], HEDEF), Buffer.alloc(4096 + 16, 122));
console.log(`\nkopya-yukari: ${HEDEF} ${ALT} icinde ${bayt(ALT, HEDEF)} bayt; ` +
  `16 baytlik degisiklik icin tasinan ${bayt(ALT, HEDEF)} bayt`);
console.log(`  alt katmandaki kopya degismedi (${bayt(ALT, HEDEF)} bayt), ` +
  `ustteki ${bayt(KATMAN[2], HEDEF)} bayt`);

const N = 5;                                  // salt okunur alt katmanlar paylasilir
const alt = katmanBayt(KATMAN[0]) + katmanBayt(KATMAN[1]), ust = katmanBayt(KATMAN[2]);
console.log(`\n${N} ornek alt katmanlari paylasirsa ${alt} + ${N} x ${ust} = ` +
  `${alt + N * ust} bayt; paylasmasaydi ${N} x ${alt + ust} = ${N * (alt + ust)} bayt ` +
  `(kazanc ${N * (alt + ust) - (alt + N * ust)} bayt)`);
rmSync(KOK, { recursive: true, force: true });
```

```
katman                dosya   bayt
katman0-taban         5       90112
katman1-kural         2       24608
katman2-yazilabilir   3       5632

birlesik gorunum (yol -> saglayan katman)
  etc/kural-surum.txt         katman1-kural
  etc/tarife.json             katman0-taban
  lib/cozumleyici.bin         katman0-taban
  lib/kural.bin               katman1-kural
  uygulama/toplayici.mjs      katman2-yazilabilir
  uygulama/yeni-kural.mjs     katman2-yazilabilir
gorunen 6 dosya, 95776 bayt
golgelenen 2: lib/kural.bin (katman1-kural ustte), uygulama/toplayici.mjs (katman2-yazilabilir ustte)
silme isaretiyle gizlenen 1: uygulama/eski-ayar.json (alt katmanda hala 1024 bayt duruyor)
okuma icin kopyalanan dosya: 0 (6 dosya yerinde okunur)

kopya-yukari: etc/tarife.json katman0-taban icinde 4096 bayt; 16 baytlik degisiklik icin tasinan 4096 bayt
  alt katmandaki kopya degismedi (4096 bayt), ustteki 4112 bayt

5 ornek alt katmanlari paylasirsa 114720 + 5 x 9744 = 163440 bayt; paylasmasaydi 5 x 124464 = 622320 bayt (kazanc 458880 bayt)
```

Üç katmanda on dosya vardır, birleşik görünümde altı. Fark iki gölgelemeden ve bir silme
işaretinden gelir: kural ikilisi ile toplayıcı üstteki katmandan okunur, eski ayar dosyası ise
hiç okunmaz. Okuma için **hiçbir dosya kopyalanmaz** — altı dosyanın altısı bulunduğu katmanda
yerinde okunur. Bu, önceki dersin "kütüphane kümesi örnek başına bir kez yinelenir" satırını
düzelten sayıdır: beş örnek alt katmanları paylaştığında toplam 163.440 bayt, paylaşmasaydı
622.320 bayt olurdu; kazanç 458.880 bayttır.

Bedel yazma anında ödenir. Alt katmandaki bir dosyaya yazmak için o dosya önce üst katmana
kopyalanır: 16 baytlık bir değişiklik için 4.096 bayt taşınır. Oran dosya boyutuyla büyür ve
tarife dosyası yerine çözümleyici ikilisine yazılsaydı taşınan bayt 61.440 olurdu.

Delik üç yerdedir. Silinen dosya silinmemiştir: eski ayar dosyası görünümde yoktur ama alt
katmanda 1.024 bayt olarak durmayı sürdürür — çıktıyı okuyan biri onu bulabilir. Kopya-yukarı
gecikmesi yazma anında ortaya çıkar ve önceden görünmez. Ve dosyaların hepsi çıktının içinde
olsa da dosya sahipliği ile ad eşleştirme kuralı alttaki dosya sisteminden gelir; ilk dersin
sınır kovasında duran boyut tam olarak buydu.

## Özet

- Üç mekanizmanın hiçbiri yeni kaynak üretmez; üçü de tek bir kaynağın üzerine bir kural koyar
  ve kuralın olduğu yerde delik vardır.
- Ad alanı bir görünürlük eşlemesidir: 14 kayıtlık tabloda görünümler 5, 4 ve 2 kayıt görür,
  kök 14'ünü de görür. Numara havuzu ortaktır ve görünmeyen kayıt kaynak tüketmeyi sürdürür.
- Denetim grubu bir pay dağıtıcıdır ve iki davranışı vardır: sert sınırda karar (bellekte süreci
  durdurma, tanıtıcıda isteği reddetme), esnek paylaşımda ağırlığa göre dağıtım. Ağırlık tavan
  değildir — rekabet yokken bir grup payının 2,7 katını alır.
- Birleşim dosya sistemi bir katman yığınıdır: 10 dosya 6'ya iner, okuma için 0 dosya kopyalanır,
  beş örnek paylaşımla 458.880 bayt tasarruf eder. Yazma anında 16 baytlık değişiklik 4.096 bayt
  taşır.
- Ortamdan fark çıkaran mekanizma yalnız birleşim dosya sistemidir; ad alanı ile denetim grubu
  0 fark kapatır, ölçüt ayırır. Silinen dosya alt katmanda durur, dosya sahipliği ve ad
  eşleştirme kuralı alttan gelir.

## Sonraki Adım

Bu üç mekanizma tek bir makinenin çekirdeğine aittir ve o çekirdeğin sunduğu biçimde çalışır.
Ölçülen katman yığını ise bir makineye ait değildir: dizinlerden oluşan bir yığındır, kopyalanıp
taşınabilir. Peki taşındığı yerde aynı biçimde açılacağını ne garanti eder — katmanların hangi
sırayla yığılacağını, hangi yapılandırmayla çalıştırılacağını ve bir katmanın taşınırken
bozulmadığını kim yazar? Sonraki ders bu sorunun karşılığı olan belirtimlerin ortak yapısını
ele alır: bir imaj biçimi belirtiminin taşıdığı sözü üç parçaya ayırır, özet zincirini denetleyen
küçük bir doğrulayıcı yazar ve taşınabilirliğin nereye kadar gittiğini — aynı belirtime uyan iki
çalışma zamanı arasında neyin değişmediğini, neyin değiştiğini — sayar.
