Docker storage driver, imaj katmanlarının ve container'ın yazılabilir katmanının host diskinde nasıl saklanacağını ve birbirleriyle nasıl birleştirileceğini yöneten bileşendir. Klasik storage driver'lar arasında Linux dağıtımlarının neredeyse tamamında varsayılan olan ve belgelerin en yüksek kararlılığı sağladığını söylediği sürücü overlay2'dir. Ancak bir ayrıntıyı baştan bilmeniz gerekir: Docker Engine 29.0 ve sonrasının yeni kurulumlarında varsayılan, klasik storage driver değil, snapshotter kullanan containerd image store'dur. Eski bir sürümden yükselttiyseniz daemon'ınız hâlâ overlay2 kullanıyor olabilir.
Bu yazı klasik storage driver'ları anlatıyor: katmanların ve copy-on-write stratejisinin nasıl çalıştığı, overlay2'nin diskteki yapısı, okuma ve yazma senaryoları, performans etkileri, uyumluluk sınırları, sürücü seçimi ve değiştirme adımları. Belgelerin de belirttiği gibi, containerd image store kullansanız bile katmanlara dair kavramlar geçerlidir; ama komutlar ve örnekler sisteminizin imajları nasıl sakladığını birebir yansıtmaz. containerd tarafının işletim ayrıntıları için Docker containerd image store yazısına bakın.
Storage driver ile volume arasındaki fark

Docker storage driver'ları imaj katmanlarını ve container'ın yazılabilir katmanındaki veriyi saklamak için kullanır. Yazılabilir katman container silindiğinde kaybolur ve çalışma anında üretilen geçici veriler için uygundur. Storage driver'lar disk alanı verimliliği için optimize edilmiştir, ama sürücüye bağlı olarak yazma hızları yerel dosya sistemi performansının altında kalır; bu özellikle copy-on-write kullanan sürücülerde belirgindir. Veritabanı gibi yazma yoğun uygulamalar, özellikle salt okunur katmanda önceden veri varsa, bu ek yükten etkilenir.
Belgelerin önerisi nettir: yazma yoğun veriler, container ömründen uzun yaşaması gereken veriler ve container'lar arasında paylaşılması gereken veriler için volume kullanın. Volume'lar storage driver'ı atladığı için ince provizyon ve copy-on-write kaynaklı ek yüklere maruz kalmaz ve en iyi, en öngörülebilir performansı verir. Volume kullanımı için Docker volume kullanımı yazısına bakabilirsiniz. Bu yazının geri kalanı, volume dışında kalan ve storage driver'ın yönettiği veriyi anlatıyor.
İmajlar ve katmanlar
Bir Docker imajı bir dizi katmandan oluşur ve her katman, imajın Dockerfile'ındaki bir talimatı temsil eder. Belgelerdeki örnek Dockerfile şöyledir:
# syntax=docker/dockerfile:1
FROM ubuntu:22.04
LABEL org.opencontainers.image.authors="org@example.com"
COPY . /app
RUN make /app
RUN rm -r $HOME/.cache
CMD python /app/app.pyDosya sistemini değiştiren talimatlar yeni bir katman oluşturur. FROM, ubuntu:22.04 imajından bir katmanla başlar. LABEL yalnızca imajın meta verisini değiştirir ve katman üretmez. COPY, istemcinin o anki dizininden dosya ekler. İlk RUN uygulamayı derleyip sonucu yeni bir katmana, ikinci RUN ise bir önbellek dizinini silip sonucu yine yeni bir katmana yazar. CMD de yalnızca meta veriyi değiştirir.
Burada çoğu kişinin gözden kaçırdığı nokta şudur: her katman yalnızca bir önceki katmana göre farkları içerir ve dosya eklemek de silmek de yeni bir katman üretir. Örnekte $HOME/.cache dizini silinmiş olsa bile önceki katmanda hâlâ bulunur ve imajın toplam boyutuna eklenir. Yani ayrı bir RUN satırında dosya silmek imajı küçültmez. Dockerfile'ı bu açıdan iyileştirmenin temelleri Dockerfile yazma rehberi yazısında anlatılıyor.
Container katmanı ve copy-on-write
Bir container oluşturduğunuzda alttaki katmanların üstüne yeni ve yazılabilir bir katman eklenir; buna genellikle container katmanı denir. Çalışan container'ın yaptığı tüm değişiklikler, yani yeni dosya yazma, mevcut dosyayı değiştirme ve dosya silme, bu ince katmana yazılır. Container ile imaj arasındaki temel fark da budur. Container silindiğinde yazılabilir katman da silinir, alttaki imaj değişmeden kalır. Her container'ın kendi yazılabilir katmanı olduğu için birden fazla container aynı imajı paylaşırken kendi veri durumlarını koruyabilir.
Tüm storage driver'lar üst üste binen imaj katmanlarını ve copy-on-write (CoW) stratejisini kullanır, ancak bunu farklı biçimlerde uygular. CoW mantığı şudur: bir dosya alt katmanlardan birinde varsa ve başka bir katman (yazılabilir katman dahil) onu yalnızca okumak isterse mevcut dosyayı kullanır. Dosyayı ilk kez değiştirmek gerektiğinde dosya o katmana kopyalanır ve kopya üzerinde değişiklik yapılır. Bu, G/Ç miktarını ve sonraki katmanların boyutunu en aza indirir.
overlay2 için bu işlem kabaca şu sırayla yürür: güncellenecek dosya en yeni katmandan başlayarak taban katmana kadar tek tek aranır ve bulunan sonuçlar sonraki işlemleri hızlandırmak için önbelleğe alınır; dosyanın bulunan ilk kopyası üzerinde copy_up işlemi yapılarak dosya container'ın yazılabilir katmanına kopyalanır; değişiklikler bu kopya üzerinde yapılır ve container alt katmandaki salt okunur kopyayı artık görmez.
Bu modelin pratik sonuçları önemlidir. Çok veri yazan container'lar daha fazla yer kaplar, çünkü yazma işlemlerinin çoğu ince üst katmanda yeni alan tüketir. Dosya izinlerini ya da sahibini değiştirmek gibi yalnızca meta veriyi değiştiren işlemler bile copy_up tetikleyebilir ve dosyanın tamamını yazılabilir katmana çoğaltabilir. Büyük dosyalar, çok sayıda katman ve derin dizin ağaçları copy_up maliyetini daha görünür hale getirir; bu maliyetin bir dosya için yalnızca ilk değişiklikte ödenmesi ise etkiyi hafifletir.
CoW yalnızca yer kazandırmaz, container başlangıç süresini de kısaltır: Docker'ın yeni bir container için yalnızca ince yazılabilir katmanı oluşturması yeterlidir. Docker her container için imaj yığınının tam bir kopyasını çıkarsaydı, sanal makinelerdeki sanal disklere benzer biçimde hem oluşturma süresi hem disk kullanımı belirgin şekilde artardı. CoW sağlamayan vfs sürücüsünde tam olarak bu olur.
Container'ların diskte kapladığı alan

Çalışan bir container'ın yaklaşık boyutunu docker ps -s ile görebilirsiniz. Çıktıdaki iki sütun farklı şeyleri ölçer: size, her container'ın yazılabilir katmanı için diskte kullanılan veri miktarıdır; virtual size ise container'ın kullandığı salt okunur imaj verisi ile yazılabilir katmanın toplamıdır. Aynı imajdan başlatılan iki container salt okunur verinin tamamını paylaşır, bu yüzden sanal boyutları toplamak gerçek disk kullanımını ciddi biçimde abartır.
Belgelerdeki deneyde aynı imajdan beş container başlatılır; hepsi 0B (virtual 7.75MB) gösterir. Üç container'ın yazılabilir katmanına beş baytlık bir dosya yazıldıktan sonra bu üçü 5B (virtual 7.75MB) gösterir, diğer ikisi değişmez. Bu, verinin her container'a özel olduğunu ve salt okunur katmanların paylaşılmaya devam ettiğini gösterir. Ancak bu sayılar şunları içermez:
- Logging driver'ın sakladığı log dosyaları; container çok log üretiyor ve log döndürme yapılandırılmamışsa bu alan küçük değildir. Log boyutu sınırlama için Docker log boyutu sınırlama yazısına bakın.
- Container'ın kullandığı volume ve bind mount'lar.
- Container'ın genellikle küçük olan yapılandırma dosyaları.
- Swap etkinse diske yazılan bellek.
- Deneysel checkpoint/restore özelliğini kullanıyorsanız checkpoint'ler.
Disk doluluğunu araştırırken bu yüzden yalnızca docker ps -s'e değil, genel görünüm için docker system df'e de bakmanız gerekir. Kullanılmayan nesneleri temizlemek için Docker prune ile disk temizleme yazısı rehber olabilir.
overlay2 nasıl çalışır?
OverlayFS bir birleşik (union) dosya sistemidir. Belgeler Linux çekirdeğindeki sürücüye OverlayFS, Docker storage driver'ına overlay2 diyor. OverlayFS tek bir Linux host üzerindeki iki dizini katmanlar halinde üst üste koyup tek bir dizin olarak sunar. Alttaki dizine lowerdir, üsttekine upperdir denir; birleşik görünüm merged adlı bir dizinden sunulur. Docker açısından imaj katmanları salt okunur lowerdir'ler, container katmanı yazılabilir upperdir'dir ve merged fiilen container'ın bağlama noktasıdır.
overlay2 yerel olarak 128'e kadar alt OverlayFS katmanını destekler. Bu, docker build ve docker commit gibi katmanlarla ilgili komutlarda daha iyi performans sağlar ve arka plan dosya sisteminde daha az inode tüketir. Diskte her katman /var/lib/docker/overlay2 altında kendi dizinindedir. Buradaki l (küçük L) dizini, mount komutunun argümanlarındaki sayfa boyutu sınırına takılmamak için kısaltılmış katman kimliklerini sembolik bağlantılar olarak tutar. En alttaki katmanda kısaltılmış kimliği tutan bir link dosyası ve içeriği tutan diff dizini bulunur; üstteki katmanlarda ayrıca üst katmanı gösteren lower dosyası, birleşik içeriği gösteren merged ve OverlayFS'in iç kullanımı için work dizini vardır.
Var olan bir kurulumda hangi sürücünün kullanıldığını ve arka plan dosya sistemini docker info ile görürsünüz. Belgelerdeki örnek çıktı:
docker info
Containers: 0
Images: 0
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: true
<...>overlay2 ile okuma ve yazma senaryoları
Okuma tarafında üç durum vardır. Dosya container katmanında yoksa imajdan (lowerdir) okunur ve bu çok az ek yük getirir. Dosya yalnızca container katmanındaysa doğrudan oradan okunur. Dosya her iki katmanda da varsa container katmanındaki sürüm okunur; upperdir'deki dosyalar lowerdir'deki aynı adlı dosyaları örter.
Yazma tarafında ilk yazma en önemli andır. Container mevcut bir dosyaya ilk kez yazdığında dosya henüz upperdir'de değildir; overlay2 bir copy_up ile dosyayı imajdan container katmanına kopyalar ve değişiklikler bu yeni kopyaya yazılır. OverlayFS blok düzeyinde değil dosya düzeyinde çalıştığı için copy_up her zaman dosyanın tamamını kopyalar; dosya büyük ve değişen kısım küçük olsa bile. Bu, büyük bir dosyanın küçük bir parçasını değiştiren uygulamalarda yazma performansını belirgin biçimde etkileyebilir. Sonraki yazmalar ise zaten kopyalanmış dosya üzerinde yapılır.
Silme işlemlerinde alt katman salt okunur olduğu için dosya gerçekten silinmez. Bir dosya silindiğinde container katmanında bir whiteout dosyası oluşturulur ve bu dosya alttaki sürümün görünmesini engeller. Bir dizin silindiğinde ise opaque bir dizin oluşturulur ve aynı şekilde çalışır. Dizin yeniden adlandırmada da bir sınır vardır: bir dizin için rename(2) çağrısına yalnızca kaynak ve hedef yolun ikisi de en üst katmandaysa izin verilir; aksi halde EXDEV ("cross-device link not permitted") hatası döner. Uygulamanızın bu hatayı yakalayıp "kopyala ve sil" stratejisine geri dönebilmesi gerekir.
Performans ve uyumluluk sınırları
OverlayFS sayfa önbelleği paylaşımını destekler: aynı dosyaya erişen birden fazla container o dosya için tek bir sayfa önbelleği girdisini paylaşır. Bu, overlay2'yi bellek açısından verimli ve PaaS gibi yüksek yoğunluklu kullanımlar için iyi bir seçenek yapar. Öte yandan diğer copy-on-write dosya sistemlerinde olduğu gibi ilk yazmadaki copy-up işlemi, özellikle büyük dosyalarda yazma gecikmesi ekler. Belgelerin genel önerileri iki maddedir: hızlı depolama (SSD) kullanın ve yazma yoğun iş yükleri için volume kullanın.
OverlayFS POSIX standartlarının yalnızca bir alt kümesini uygular ve bu bazı işlemlerde standart dışı davranışlara yol açabilir. Belgelerdeki örnek open(2) ile ilgilidir: uygulama bir dosyayı önce salt okunur, sonra okuma yazma modunda açarsa ikinci açılıştan sonra yapılan copy-up nedeniyle iki dosya tanımlayıcısı farklı dosyaları gösterir; ilki imajdaki, ikincisi container katmanındaki dosyayı. Geçici çözüm dosyaları önceden touch ile değiştirip copy-up'ı baştan tetiklemektir. yum bu durumdan etkilenir; belgeler yum-plugin-ovl paketini ya da bu paket yoksa yum install öncesi touch /var/lib/rpm/* çalıştırmayı öneriyor. rename(2) de tam desteklenmez.
Hangi storage driver'ı seçmeli?

Docker Engine Linux üzerinde şu depolama arka uçlarını sunar:
| Arka uç | Açıklama |
|---|---|
| containerd (snapshotter) | Engine 29.0 ve sonrasında yeni kurulumlarda varsayılan; çok platformlu imajları ve attestation'ları destekler |
| overlay2 | Klasik sürücü; desteklenen tüm Linux dağıtımlarında en geniş uyumluluk, ek yapılandırma gerektirmez |
| fuse-overlayfs | Yalnızca rootless overlay2 desteklemeyen host'larda Rootless Docker için; çekirdek 5.11'den beri gerekmez |
| btrfs ve zfs | Anlık görüntü gibi ileri seçenekler sunar, daha fazla kurulum ve bakım ister, arka plan dosya sisteminin doğru yapılandırılmasına bağlıdır |
| vfs | Test amaçlı ve CoW dosya sistemi kullanılamayan durumlar için; performansı düşüktür, üretim için genellikle önerilmez |
Belirli bir sürücü yapılandırılmadığında Docker Engine, ön koşulları karşılayan sürücüler arasından öncelikli bir listeye göre uyumlu olanı otomatik seçer. Bazı sürücüler arka plan dosya sisteminin, yani /var/lib/docker/ dizininin bulunduğu dosya sisteminin belirli bir türde olmasını ister:
| Sürücü | Desteklenen arka plan dosya sistemleri |
|---|---|
| overlay2 | ftype=1 ile xfs, ext4, btrfs ve diğerleri |
| fuse-overlayfs | Her dosya sistemi |
| btrfs | btrfs |
| zfs | zfs |
| vfs | Her dosya sistemi |
Belgelerin dağıtım tablosuna göre Ubuntu, Debian, CentOS, Fedora, SLES 15 ve RHEL'de varsayılan klasik sürücü overlay2'dir; Ubuntu, CentOS ve Fedora'da alternatif olarak zfs ve vfs, Debian, SLES 15 ve RHEL'de vfs listelenir. İş yükü açısından genellemeler şöyledir: overlay2 dosya düzeyinde çalışır ve belleği verimli kullanır, ama yazma yoğun iş yüklerinde yazılabilir katman çok büyüyebilir; btrfs ve zfs gibi blok düzeyinde çalışan sürücüler yazma yoğun iş yüklerinde daha iyidir (yine de volume kadar değil) ve çok bellek ister; zfs PaaS gibi yüksek yoğunluklu iş yükleri için iyi bir seçimdir. Kararlılık önemliyse belgeler genel olarak en yüksek kararlılığın overlay2'de olduğunu söylüyor.
Diğer sürücüler hakkında birkaç not: btrfs sayfası çoğu durumda overlay2 kullanmanız gerektiğini, sistemin kök dosya sisteminin Btrfs olmasının tek başına btrfs sürücüsünü gerektirmediğini ve sürücünün bilinen sorunları olduğunu belirtiyor. zfs sayfası, ZFS on Linux konusunda ciddi deneyiminiz yoksa üretimde önerilmediğini söylüyor; ZFS bir ya da daha fazla ayrılmış blok aygıtı ve ZFS biçimli bir /var/lib/docker/ ister. vfs birleşik dosya sistemi değildir; her yeni katman önceki katmanın derin kopyasıyla oluşturulur, bu da daha düşük performans ve daha fazla disk kullanımı demektir, ama her ortamda çalışır.
overlay2'yi yapılandırmak ve sürücü değiştirmek
overlay2 için ön koşullar Linux çekirdeği 4.0 veya üstü (RHEL ya da CentOS'ta 3.10.0-514 veya üstü) ve arka plan dosya sistemi xfs ise d_type=true olmasıdır. xfs için xfs_info ile ftype seçeneğinin 1 olduğunu doğrulayabilir, dosya sistemini doğru biçimlendirmek için -n ftype=1 bayrağını kullanabilirsiniz.
Belgelerdeki yapılandırma adımları şöyledir: Docker'ı durdurun, /var/lib/docker içeriğini geçici bir yere kopyalayın, isterseniz ayrı bir dosya sistemini biçimlendirip /var/lib/docker altına bağlayın ve kalıcı olması için /etc/fstab'a ekleyin, ardından /etc/docker/daemon.json dosyasına sürücüyü yazıp Docker'ı başlatın:
sudo systemctl stop docker
cp -au /var/lib/docker /var/lib/docker.bk
sudo systemctl start docker{
"storage-driver": "overlay2"
}daemon.json geçersiz JSON içerirse Docker başlamaz; bu yüzden dosyayı düzenledikten sonra sözdizimini kontrol edin. Daemon yapılandırmasının genel kuralları için Docker daemon.json yapılandırma yazısına, daemon başlamazsa Docker cannot connect to daemon hatası yazısına bakabilirsiniz.
Engine 29 sürüm notlarında klasik sürücüyle ilgili birkaç düzeltme de var: 29.0.1'de, önceden graph driver durumu bulunan sistemlerde açıkça yazılmış "storage-driver" ayarının containerd snapshotter gibi ele alınması düzeltildi; 29.1.3 ve 29.1.4'te sahipsiz kalabilen overlay2 katmanlarının oluşma olasılığı giderildi; 29.8.0'da btrfs sürücüsünde container kök dizininin herkesçe yazılabilir olması düzeltildi. Bu sürümlerin öncesindeyseniz güncellemeyi değerlendirin.
Sık yapılan hatalar
- Veritabanını yazılabilir katmanda tutmak: Yazma yoğun veriler için belgeler açıkça volume öneriyor.
- Ayrı bir RUN satırında dosya silip imajın küçülmesini beklemek: Silinen dosya önceki katmanda kalır.
- Sanal boyutları toplamak: Paylaşılan katmanlar birden çok kez sayılır ve gerçek disk kullanımı abartılır.
- /var/lib/docker altını elle temizlemek: Docker'ın yönettiği dosyaları bozabilir.
- Sürücüyü yedeksiz değiştirmek: Mevcut imaj ve container'lar görünmez olur.
- Yeni kurulumda overlay2 aramak: Engine 29.0 ve sonrası yeni kurulumlarda containerd image store kullanır;
docker infoçıktısını buna göre yorumlayın.
Sık Sorulan Sorular
Sunucumda hangi storage driver'ın kullanıldığını nasıl görürüm?
docker info çıktısındaki Storage Driver satırına bakın. containerd image store kullanıyorsanız docker info -f '{{ .DriverStatus }}' çıktısında snapshotter sürücü türü görünür; ayrıntısı containerd image store yazısında.
Kök dosya sistemim Btrfs, btrfs sürücüsünü kullanmalı mıyım?
Belgelere göre gerekmez. Çoğu durumda overlay2 önerilir; Btrfs kök dosya sistemi tek başına btrfs sürücüsünü gerektirmez ve bu sürücünün bilinen sorunları vardır.
Container'daki büyük bir dosyaya küçük bir yazma neden yavaş?
overlay2 dosya düzeyinde çalışır; bir dosyaya ilk yazmada dosyanın tamamı container katmanına kopyalanır. Bu tür veriler için volume kullanmak storage driver'ı devre dışı bırakır.
vfs sürücüsünü ne zaman kullanmalıyım?
Belgelere göre vfs esas olarak test ve hata ayıklama içindir ve başka hiçbir sürücünün desteklenmediği durumlar için düşünülmüştür. CoW olmadığından performansı düşük, disk kullanımı yüksektir.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Docker öğrenme rehberi · containerd image store · Docker volume kullanımı · daemon.json yapılandırma · Docker prune · Dockerfile yazma rehberi