Docker Nedir ve Nasıl Çalışır? #1

İlhan Mert Alan
5 min readFeb 27, 2022

--

Docker, yazılım geliştiricilere oldukça kolaylık sağlayan, bu sebeple bilinmesi ve kullanılması elzem hale gelen oldukça önemli bir teknolojidir. Bu yazı kapsamında Docker’ı nasıl kullanabiliriz, nasıl image yaratırız, konteynır çalıştırırız sorularından ziyade, Docker nedir, nasıl çalışır, altında yatan teknoloji nedir bunları irdelemeye çalışacağız.

Docker kısaca, ‘container’ adını verdiğimiz sanal yapılar oluşturup, geliştirdiğimiz uygulamalarımızı bağımlılıklarıyla birlikte bu konteynırlar içerisinden çalıştırmamıza yardımcı olur. Bu konteynırlar sayesinde yazılımı bir geliştirme ortamından diğerine taşırken yaşayacağımız problemlerden kurtuluruz. Bu problemler, ”Benim makinede çalışıyordu ya” cümlesinin kurulmasına sebep olan sorunlarla aynıdır. Yani genel olarak bağımlılıklar, paketler, versiyonlar gibi iki geliştirme ortamı arasındaki potansiyel farklılıklardır. Docker konteynırlarıyla yepyeni bir ortam yaratmış oluruz.

Konsepti daha iyi anlamak için bir de sanal makinelere (virtual machine) lere bakalım.

Virtual Machines

Virtual Machine Yapısı

Sanal makineler ile bir OS üzerinde farklı bir OS’e sahip bir server yaratırız. Cloud hosting serverlardan kiralayabildiğimiz bu sanal makineler bize linux-benzeri sistemler sunar ve hosting vb çeşitli işlemler için bu sanal makineler kullanılabilirler. Yapısal olarak altında fiziksel bir sunucu bulunur. Bu sunucu ana bir işletim sistemine sahiptir ve Hypervisor adı verilen yazılımlar aracılığıyla sanal makineler yaratıp, çalıştırabilirler. Oracle’ın Virtual Box’u , WMWare en bilinen hypervisor yazılımlarıdır. Bu sanal makinelere istenilen Guest-OS kurulup kullanılabilir. Burada önemli olan nokta sanal makinelerin her birisinin kendine ait bir OS’i olduğudur.

Gelin bir de konteynırların mantığına bakalım.

Docker Container Yapısı

Yapı, öncekine çok benzer olmasına rağmen burada Hypervisor yapısı yerine ana işletim sistemiyle konteynır yapıları arasında Docker Engine bulunur. Docker Engine sayesinde Linux çekirdeği ve konteynırlar arası iletişimler sağlanır. Buradaki en önemli nokta ise konteynırların her birinde ayrı ayrı bir Guest-OS bulunmamasıdır, yani konteynır içinde bir işletim sistemi yoktur. Koskoca işletim sistemlerini tutan bir yapı yerine, daha hafif bir yapıyla karşı karşıyayız diyebiliriz. Ayrıca bu konteynırlara tek tek kaynak atamayız, bunun yerine Docker Engine’e belirli bir kaynak veririz ve konteynırlar aralarında bu kaynağı paylaşırlar.

Özetle; Konteynırlar OS bulundurmazlar, uygulama ve o uygulamanın çalışmasını gerektirecek bağımlılıkları, paketleri bulundururlar. Ana işletim sisteminin üzerinde bir Docker Engine mevcuttur, Docker Engine’in çalışması için Linux kernel’ine ihtiyacı vardır. Konteynırlar, Linux Kernel’ini paylaşır ve bu paylaşımla ana bilgisayarın birden çok konteynırı çalıştırmasına olanak tanır.

Neden Linux ? Mac veya Windows Değil ?

Docker Engine Linux çekirdeğini kullanarak bütün bu konteynır işlemlerini gerçekleştirebiliyor. Peki bunu yapabilmesini sağlayan nedir ? Bunu Linux’un “namespaces” adını verdiğimiz bir özelliği ile yapabiliyoruz.

Namespaces are a feature of the Linux kernel that partitions kernel resources such that one set of processes sees one set of resources while another set of processes sees a different set of resources. (Wiki)

Yukarıda Wikipedia’den aldığım tanım itibariyle Linux’ta Namespaces adı verilen özellik sayesinde; bir grup prosesin belirli bir grup kaynağı görebildiğini ve başka bir grup prosesin ise başka bir kaynağı görebildiğini anlıyoruz. Yani Docker bize ne sunuyorsa, temelinde Linux’un bu özelliğinin yattığını görüyoruz. Örnek olarak ben 10 farklı NodeJS konteynırı çalıştıracağım ve her bir konteynır içinde farklı bir NodeJS versiyonu kullanabileceğim, ve bunu Linux’un prosesleri ayırabilme yeteğini sayesinde gerçekleştireceğim.

Peki bütün bunları Windows & Mac’te Nasıl Yaparız ?

Eğer Mac ya da Windows makinemize ufak bir Linux sanal makinesi kurarsak, karşılaşacağımız görsel aşağı yukarı aynı olur. Üstteki görselle alttaki görsel arasındaki fark, artık başka bir işletim sistemi içerisinde Linux bir VM kullanmamızdır.

Yani özetle buradan yapmamız gereken çıkarım Docker konteynırlarının Linux makinesinde çalıştığıdır. Eğer siz Windows & Mac makinenize Docker Desktop kurarsanız aslında beraberinde bir Linux VM kurmuş olursunuz.

Konteynırlar Kernel’le Nasıl Etkileşime Girer? Kaynakları Nasıl Kullanır ?

Docker Engine Linux’a kurulurken beraberinde “containerd” ve “runc” gibi bazı prosesleri de getirir. Bunlar Linux’un bahsettiğimiz namespaces özelliğini kullanarak her bir container için ayrı kaynaklar yaratırlar. Bir konteynır başlatıldığında Linux makinede o konteynırın dosyalarıyla bazı prosesler başlar ve bu prosesler Linux çekirdeğiyle ve ram, cpu gibi kaynaklarla da etkileşime girer.

Docker konteynırlarının kaynak kullanma limiti yoktur, yani Docker Engine’e ne kadar kaynak ayrıldıysa alayını kullanır/faydalanır diyebiliriz. Fakat konteynırların kaynaklarını limitlemek mümkündür, detaylı bilgi için cgroups’u (control groups) araştırabilirsiniz.

Her konteynırın kendi prosesi/prosesleri vardır. Bir konteynırda birden çok proses bulunabilir. Örneğin bir Python uygulaması düşünelim, bu uygulamanın bir veritabanı ve mail sunucusuna ihtiyaç duyduğunu varsayalım. Bu üç ayrı proses için (py, db , mail-server) tek bir konteynır kurabiliriz. Fakat bu çözüm scalability ve managebility açısından önerilmez. Bunun yerine 3 farklı konteynır kurulabilir, böylece her bir konteynırı ayrı ayrı yönetebilir, update edebilir, scale edebiliriz. (Örneğin scale edilecek ilgili konteynırın yerine 5 ayrı konteynır yaratılıp aralarında load balancing uygulanabilir.)

Docker’ın Bileşenleri

Bu kısımda da Docker’ın beraberinde getirdiği kavramlardan bahsedelim.

Docker Client

Docker Client, adından anlaşılabileceği üzere Docker Server’a komutlar gönderebilmek için kullanılır. Terminal veya CMD’ye gidip ‘docker’ yazdığımızda aslında Docker Client’ı başlatmış oluruz. Buradan Docker Client ile kullabileceğimiz komutları da görebiliriz.

Docker Server

Docker server aslında farklı proses kümeleridir. Bunlardan bir tanesi de Docker Deamon’dur. Komutu client’dan alır, işletim sistemiyle iletişimi kurar, konteynırları yönetir. Terminale gidip “docker version” yazdığımızda docker server’ın proseslerini görebiliriz.

Docker Host

Yukarıda server’ın prosesleri olduğundan bahsetmiştik. Peki bu prosesler nerede çalışıyor derseniz cevabımız Docker Host olacaktır. Peki Docker Host nedir? Docker Engine’in işlemlerinin gerçekleştiği yerdir. Eğer doğrudan Linux bir makinaya Docker Engine kurduysanız, o linux makina Docker Host’tur. Eğer Windows/Mac işletim sistemi kullanıyorsanız Docker Desktop ile beraber aslında bir Linux sanal makine kurduğumuzdan bahsetmiştik. Bu durumda Docker Host o sanal makine olmaktadır. Docker Server’daki prosesler ile Docker Host iletişimdedir.

Docker Image

Docker Image, kısaca bir dizi read-only dosyadır. Docker konteynırlarının yaratılmasında kullanılır. Kendi docker image’lerimizi yaratabilir veya Docker Hub üzerinden varolan image’leri indirebiliriz.

Docker Container

Aslında yazı boyunca bahsettiğimiz konteynır yapılarıdır. Belirli bir docker image’e bağlı olarak çalışırlar. Bir Docker Image ile bir veya birden fazla konteynır yaratabiliriz.

Docker Repository

Git Repository’i nasıl kodlarımızı versiyonlamak için kullanıyorsak, Docker Repository’i de Docker Image dosyalarımızı versiyonlamak için kullanabiliriz.

Docker Registry

Varsayalım Docker Image’lerimizi yarattık ve bunları paylaşmak istiyoruz. Bunları Docker Registry kullanarak dış dünyayla paylaşabiliriz. Docker Hub , bir Docker Registry dir. Docker Hub sayesinde başkalarının paylaştığı image’lere erişebilir, kendi image’lerimizi paylaşabiliriz.

--

--

No responses yet