Docker volume ve ağ yönetimi: kalıcı veri ve konteynerler arası bağlantı
Docker'da volume ile kalıcı veri tutma, bind mount farkı, kullanıcı tanımlı ağ oluşturma ve port yayınlama: komutlar, örnekler ve sık yapılan hatalar.
Konteyner geçicidir: veri ve bağlantı sorunu
Docker konteynerleri silinip yeniden oluşturulmak üzere tasarlanır. Konteyner silindiğinde, yazılabilir katmanında biriken her şey de gider. Bir veritabanı konteynerini silip yeniden kurduğunuzda kayıtlarınızın kaybolması bu yüzdendir. Çözüm, veriyi konteynerin dışında tutmaktır: volume ya da bind mount.
İkinci sorun bağlantıdır. Bir web uygulaması ve bir veritabanı ayrı konteynerlerde çalışıyorsa, birbirlerini nasıl bulacaklarına karar verilmelidir. IP adresleri her başlatmada değişebilir. Docker'ın ağ sistemi bunu, konteynerleri aynı ağa koyup ada göre erişim sağlayarak çözer.
Volume, bind mount ve tmpfs: hangisi ne zaman?
Docker belgeleri depolama seçeneklerini ayırır.
- Volume: Docker'ın yönettiği depolama alanıdır. Konteyner silinse de kalır. Belgeler volume'ü, Docker konteynerlerinde üretilen ve kullanılan veriyi kalıcı kılmak için tercih edilen mekanizma olarak tanımlar. Veritabanı verisi, yedeklenecek veri ve konteynerler arasında paylaşılan veri için uygundur.
- Bind mount: Ana makinedeki belirli bir klasörü konteynere bağlar. Hem ana makine hem konteyner aynı dosyalara erişir. Geliştirme sırasında kaynak kodun konteyner içinde anında yansıması için idealdir.
- tmpfs: Veri diske yazılmaz, bellekte tutulur ve konteyner durunca kaybolur. Geçici ve hassas verinin diske izi bırakılmaması gereken durumlarda kullanılır.
Karar kuralı: Veri konteyner silindikten sonra da yaşamalı ve Docker yönetsin istiyorsanız volume. Ana makinedeki dosyalarla çalışmanız gerekiyorsa bind mount. Geçici ise tmpfs. Üretimde veri için volume, geliştirmede kod için bind mount en yaygın eşleşmedir.
Volume komutları adım adım
Temel yaşam döngüsü şu komutlarla yönetilir:
docker volume create veri-deposu docker volume ls docker volume inspect veri-deposu docker volume rm veri-deposu docker volume prune
create ile adlandırılmış bir volume oluşturur, ls ile listelersiniz. inspect, bağlama noktasını, sürücüyü ve kapsamı gösterir. rm tek bir volume'ü siler. prune ise kullanılmayan bütün volume'leri siler; bu komut geri alınamaz, çalıştırmadan önce listeyi kontrol edin.
Bir konteynere bağlamak için -v ya da --mount kullanılır:
docker run -d --name veritabani -v veri-deposu:/var/lib/data imaj-adi docker run -d --name veritabani --mount type=volume,src=veri-deposu,dst=/var/lib/data imaj-adi
Her iki biçim de aynı işi yapar. Docker belgeleri daha açık olduğu için --mount biçimini önerir; sürücü seçenekleri ve alt dizin bağlama gibi bazı kullanımlar yalnızca --mount ile yapılabilir. Adı olmayan -v kullanımı anonim volume oluşturur; adı olmayan volume'ü sonra bulmak zordur, ürün ortamında ad verin.
Yalnızca okunabilir bağlamak için ro seçeneğini ekleyin: -v veri-deposu:/veri:ro. Aynı volume'ü birden fazla konteynere bağlayabilirsiniz; bazılarını yazılabilir, bazılarını salt okunur yapmak güvenli bir paylaşım yoludur.
Kontrol: Konteyneri silip aynı volume ile yeniden başlatın. Veriniz yerindeyse yapılandırma doğrudur.
Ağ sürücüleri ve kullanıcı tanımlı köprü ağ
Docker birkaç ağ sürücüsü sunar. Günlük işte en çok karşılaşılanlar şunlardır:
- bridge: Varsayılan sürücü. Aynı köprü ağdaki konteynerler birbiriyle konuşabilir.
- host: Konteynerle ana makine arasındaki ağ yalıtımını kaldırır.
- none: Konteyneri ağdan tamamen yalıtır.
- overlay: Birden fazla Docker sunucusunu bağlar; Swarm gibi dağıtık kurulumlarda kullanılır.
Belgelerin vurguladığı kritik fark şudur: Docker'ın kendiliğinden oluşturduğu varsayılan köprü ağda konteynerler yalnızca IP adresiyle birbirine ulaşır. Kullanıcı tanımlı köprü ağda ise adla erişim vardır; Docker yerleşik bir DNS hizmeti çalıştırır. Bu nedenle uygulama konteynerinin veritabanına "veritabani" adıyla bağlanabilmesi için kendi ağınızı oluşturmalısınız.
docker network create uygulama-agi docker run -d --name veritabani --network uygulama-agi -v veri-deposu:/var/lib/data imaj-adi docker run -d --name web --network uygulama-agi -p <ana-makine-portu>:<konteyner-portu> web-imaji
Web konteyneri bağlantı dizesinde ana makine adı olarak "veritabani" yazar. Veritabanını dış dünyaya açmamış olursunuz; yalnızca aynı ağdaki konteynerler ona erişebilir. Ağlar aynı zamanda gruplama aracıdır: farklı ağlardaki konteynerler birbirini göremez.
Port yayınlama: dışarıya hangi kapı açılır?
Bir köprü ağındaki konteynerler, hiçbir şey yayınlamadan birbirlerinin portlarına ulaşabilir. Ancak ana makineden ya da başka bir ağdan erişilmek isteniyorsa portun -p (veya --publish) ile yayınlanması gerekir. Biçim ana-makine-portu:konteyner-portu şeklindedir.
Güvenlik açısından kural basit: yalnızca dışarıya açılması gereken hizmeti yayınlayın. Veritabanını yayınlamak çoğu durumda gereksizdir, çünkü web konteyneri ona ağ üzerinden zaten ulaşır. Geliştirme makinesinde yalnızca yerel erişim için portu yerel adrese bağlamak, açığı daraltır.
Mevcut bir konteyneri sonradan başka bir ağa bağlamak için docker network connect kullanılır, durumu görmek için docker network inspect. Bir konteyneri birden fazla ağa bağlamak, örneğin ön yüzün ve arka yüzün farklı ağlarda ayrışması, kademeli bir yalıtım sağlar.
Sık yapılan hatalar
- Volume yerine konteyner katmanına yazmak: Veritabanı verisinin yolunu volume'e bağlamadan çalıştırmak, konteyner yenilendiğinde veri kaybı demektir. İmajın veri yolunu belgeden doğrulayın.
- Anonim volume'leri biriktirmek: Adsız -v kullanımı sahipsiz volume'ler bırakır. Disk dolduğunda hangisinin neye ait olduğu bilinmez.
- Bind mount ile izin sorunu: Ana makinedeki klasör sahipliği ile konteyner içindeki kullanıcı uyuşmazsa yazma hatası alınır. Konteyner kullanıcısını ve klasör izinlerini hizalayın.
- Varsayılan köprü ağda ad ile bağlanmaya çalışmak: Çalışmaz; kullanıcı tanımlı ağ oluşturun.
- Her portu yayınlamak: Gereksiz saldırı yüzeyi yaratır.
- prune komutunu düşünmeden çalıştırmak: Kullanılmayan görünen ama kapalı bir konteynerin verisini siler. Önce listeleyin.
- Verinin yedeğini düşünmemek: Volume kalıcıdır ama kendiliğinden yedeklenmez. Düzenli yedek planı ayrıca gerekir.
Mindset programlarında nerede çalışılır?
Temel Docker Eğitimi'nin müfredatında "Docker Volumes ve Network Yönetimi" ayrı bir başlıktır; geliştirici ya da sistem yöneticisi olarak ilk kez konteynerleştirme yapacaklar için bu konuları uygulama düzeyinde ele alır. Docker ve Container Teknolojileri eğitimi ise "Docker Ağ ve Depolama" modülüyle aynı konuyu üretim ortamına yakın bir bakışla işler ve "Üretim Docker Ortamı" modülüyle birleştirir.
Kurumsal ekiplerde bu bilgi, veri kaybı yaşamadan konteyner güncellemek ve servisler arası bağlantıyı öngörülebilir kılmak için temel bir yetkinliktir.
İlgili Mindset programı
Temel Docker Eğitimi
Sık sorulan sorular
Volume ile bind mount arasındaki en önemli fark nedir?
Volume'ü Docker yönetir ve konteynerlerden bağımsız olarak kalıcıdır; bind mount ise ana makinedeki gerçek bir klasörü konteynere bağlar. Veriyi Docker yönetsin ve yedeklenebilir olsun istiyorsanız volume, geliştirme sırasında kodu anında konteynere yansıtmak istiyorsanız bind mount seçilir.
Konteynerler birbirine neden adla erişemiyor?
Büyük olasılıkla varsayılan köprü ağdasınız. Bu ağda konteynerler yalnızca IP adresiyle birbirini bulur. Kendi ağınızı docker network create ile oluşturup konteynerleri --network seçeneğiyle bu ağa koyduğunuzda Docker'ın yerleşik DNS'i ad çözümlemesini sağlar.
-v ile --mount arasında hangisini kullanmalıyım?
Her iki biçim de volume bağlar. Docker belgeleri --mount'ı daha açık ve okunabilir olduğu için önerir; sürücü seçenekleri ve alt dizin bağlama gibi bazı kullanımlar yalnızca --mount ile mümkündür. Kısa denemeler için -v yeterlidir ama betik ve belgelerde --mount okunabilirlik kazandırır.
Volume'deki veriyi nasıl yedeklerim?
Volume'ü geçici bir konteynere bağlayıp içeriğini arşivleyerek ana makineye çıkarmak yaygın bir yoldur. Veritabanları için ise veritabanının kendi yedekleme aracını kullanmak, dosyaları kopyalamaktan daha tutarlıdır. Hangi yöntem seçilirse seçilsin, geri yükleme prosedürü önceden denenmelidir.
Host ağ sürücüsü ne zaman kullanılır?
Host sürücüsü konteyner ile ana makine arasındaki ağ yalıtımını kaldırır. Port yayınlama gerekmez ama konteyner ana makinenin ağını doğrudan kullandığı için yalıtım kaybolur. Yalnızca bu doğrudan erişimin gerçekten gerektiği özel durumlarda ve etkisi anlaşılarak seçilmelidir.