Mavi Balina — Docker #S1B1

Docker 🐳, uygulamalarınızı hızla derlemenize, test etmenize ve dağıtmanıza imkân tanıyan bir yazılım platformudur.

Cihat Solak
lTunes Tribe
9 min readAug 3, 2021

--

Docker, uygulamalarınızı hızla derlemenize, test etmenize ve dağıtmanıza imkân tanıyan bir yazılım platformudur.
Docker — Build & Ship & Run
Docker ile sanal makineler arasındaki fark nedir?
Sanallaştırma mimarisi vs Docker

Klasik sanallaştırma mimarisinde (Şekil-A) işletim sisteminin kurulu bulunduğu fiziksel makine ve üzerinde de Hypervisor ⌨️ bulunmaktadır. Hypervisor üzerinde ise Şekil A da görüleceği üzere konfigürasyonları birbirinden farklı 3 Guest OS bulunuyor. Guest OS sistemlerinde uygulamanın ayağa kalkabilmesi için uygulamanın ihtiyaç duyacağı .exe ve kütüphanelerin yüklenmiş olması gereklidir. Sonuç olarak App 3 üzerinde Python uygulaması🐍 ayağa kaldırmak istiyorsak, uygulamanın ihtiyaç duyacağı .exe/dosyaları yüklemeliyiz. Anlaşılacağı üzere docker kullanmadığımızda önce misafir işletim sistemi ayağa kaldırıp, konfigürasyonları belirleyeceğiz ve gerekli kütüphaneleri yükleyip arkasından uygulamayı ayağa kaldıracağız.

Docker tarafında (Şekil B) aynı şekilde ilk katman olan fiziksel bir makineye ve hemen üstündeki katmandan da anlaşılacağı üzere işletim sistemine ihtiyaç duyuyoruz. Klasik yaklaşımda (Şekil A) makineleri ayağa kaldırmak için 3. katmanda sanallaştırma teknolojisi kullanılırken Şekil B’de docker engine 🐬 kullanılarak sanallaştırma işlemini gerçekleştiriyoruz. Docker ile uygulamayı ayağa kaldırmak istediğimizde Guest OS ihtiyacımız yoktur, direkt docker engine ile hareket edebiliyoruz. Engine üzerinde uygulamanın ayağa kalkması için tek yapılması gereken uygulamanın ihtiyaç duyduğu kütüphanelerin, 📚 exelerin olacağı dosyaların yüklenmesi ve bu katmanın üstüne de uygulamanın eklenmesidir.

Şekil B’de App1 ve Bins/Lib ikilisi (container) uygulamanın çalışacağı ortamla beraber, uygulamayı ayağa kaldırmamıza imkan vermektedir.

Ne Farkı Var?

  • Şekil A’ da (Klasik VM) uygulamanın çalışır hale gelmesi Şekil B’ den (Docker) daha meşakkatli ve zaman ⏳ alıcıdır.
  • Şekil A’da uygulamanın farklı versiyonlarını ayağa kaldırmak gibi bir versiyonlama bulunmamaktadır. Docker olmadan versiyonlama yapabilmek için farklı sunucular kurmanız gerekmektedir, bir işletim sistemi üzerinde 5 farklı versiyon çalıştıramazsınız.
  • İzolasyon, sanal makine tarafında işletim sistemi seviyesindedir fakat docker tarafında container seviyesindedir.
  • Şekil A tarafında işletim sistemi kuruyorken Şekil B tarafında docker ile uygulama ayağa kaldırmak için hali hazırdaki 🏗 uygulamayı çalıştırmaya imkân veren minimize edilmiş işletim sistemi kurulmaktadır.
  • Paylaşılabilirlik konusunda Şekil A tarafında uygulamayı farklı bir sunucuya göndermek istediğimizde vakit kaybederken, docker tarafında (Şekil B) container ile basit şekilde farklı sunuculara taşıma gerçekleştirebiliriz.

Dockerfile/Image/Container Nedir?

Dockerfile, Docker Image, Docker Container nedir?
Dockerfile -> Docker Image -> Docker Container

Uygulamamızı dockerize🐋edebilmemiz için (Örn: Net Core) temel 3 aşamadan bahsedebiliriz.

Aşama 1 [Dockerfile]: Projenin root dizininde yer alan, ilk harfi büyük olup uzantısı olmayan, uygulamanın çalışacağı ortama ilişkin talimatları satır satır barındıran dosyadır. 📑 Örneğin Net Core uygulamamızın çalışabilmesi için bir işletim sistemine, ilgili .dll dosya/larına ve projenin publish edilmiş verilerine ihtiyacımız vardır. Tüm bileşenleri Dockerfile dosyasında tanımlıyoruz. Bunlar haricinde projenin bağımlı olduğu dependecyler ve projenin environment (ortam) değişkenleri varsa bu bileşenleri de Dockerfile dosyasına tanımlamamız gereklidir. Bu aşamadan sonra “docker build” komutuyla Dockerfile dosyasındaki talimatlara göre Docker Image oluşturulur.

Aşama 2 [Docker Image]: Statik ve sadece okunabilir (readonly) dosyadır. Dockerfile dosyasındaki her bir satıra karşılık Docker Image içerisinde bir katman (layer) oluşur. Anlaşılacağı üzere Docker Image katmanlar topluluğudur. Örneğin Dockerfile dosyanızda 7 satır varsa 7 katmanlı 🧮Docker Image oluşur. Özünde Dockerfile dosyasında belirtilmiş talimatlara göre bir işletim sistemi ve işletim sistemi üzerinde Net Core uygulamasının çalışacağı environment (ortam) ve bu ortamın üzerinde uygulamanın publish edilmiş dosyaları bulundurur. Bu aşamadan sonra “docker run” komutuyla beraber container ayağa kaldırabiliriz.

Aşama 3 [Container]: Container’lar Docker Image’ler gibi statik değildir. Yeniden başlatabilir, silebilir, durdurulabilirdir. Bunlar haricinde container’lar docker image’lerin çalışabilen instance’larıdır ve istenilen miktar kadar ayağa kaldırılabilir.

Tüm bu senaryoları seri üretim yapan bir firmanın süreçlerine benzetebiliriz. Örneğin basit bir kalem ✏️ üretimi yaptığımızı düşünelim. Kalemi üretebilmek için öncesinde planladığımız yapım aşamalarını Dockerfile 📑 olarak nitelendirebiliriz. Kalemi seri üretime dahil edebilmek için belli bir formatta, kalıpta, şekilde olduğunu varsayarsak bu kalıpta aslında bizim Docker Image dosyamızdır diyebiliriz. Şu dakikadan sonra elimizde hazır kalıbımızda olduğu için sınırsız şekilde aynı niteliklere sahip kalem üretimi yapabiliriz. Dockerda da mantık buna benzemektedir. Docker Image’dan aynı niteliklere sahip birden fazla container 📦 ayağa kaldırabiliriz.

Docker CLI

Docker CLI nedir? Nasıl Çalışır?
Docker CLI

Docker birden fazla parçadan oluşan yapıdır. Server tarafında “docker daemon” , client tarafında “docker cli” bulunur. Docker CLI docker ile iletişimimizi sağlayan komut satırıdır. Server tarafında docker daemon 1 adet iken client tarafı bir ya da birden fazla olabilir. Docker cli’yı bir Web API projesi olarak düşünebiliriz. API projesini herhangi bir mobil uygulama, 📱front end uygulama veya tv uygulamaları 📺 kullanabilir. Mantık benzerdir ve docker cli’ımız da aslında api projemize bağlı clientlardan herhangi biridir diyebiliriz.

Docker daemon kendisiyle haberleşilebilmesi için REST API lere sahiptir. Client olarak Docker CLI üzerinden bir komut yazdığımızda Docker deamon’a bir API isteği gerçekleştiririz. Docker daemon gelen isteğe karşılık işlemi gerçekleştirir ve böylelikle client-server 💻 arasındaki iletişim sağlanmış olur.

Docker Registry

Docker Registry Nedir? Kaç farklı registry servisi bulunur?
Docker Registry, Imageleri kaydedeceğimiz bir depodur.

Docker registry, Image’lerin tutulduğu ve dağıtıldığı yerdir. Görseldeki registry kutularını içeren dolapsa, rafın içerisindeki her bir kutu da📦📦📦 image’dir. Bu imagelerin her biri tek bir amaca yöneliktir. Örneğin bir kutu sadece Net Core uygulamalarını çalıştıracak, diğer kutu java uygulamalarını çalıştıracak gibi tek bir amaca hizmet edecek türdedir.

İkinci evrede farkettiyseniz kutu üzerinde linux 🐧 işletim sistemi ve net core projesini çalıştıracak ilgili kütüphanelerin kurulu olduğu ortam bulunuyor. Bu iki yapı üzerine uygulamayı publish edip, oluşan image’den bir container oluşturarak ilgili uygulamamızı çalıştırabiliriz. Hemen sol taraftaki kutuda ise node.js uygulamalarını çalıştırabilecek image bulunuyor. Bu image içerisinde mini bir işletim sistemi ve bu işletim sistemi içerisinde de node.js uygulamasını çalıştırabilecek ortamlar kurulu bir şekilde (hazır) geliyor.

Neden Registry’ye İhtiyacım Var?

Örneğin Net Core ile proje geliştirdik ve projemizi dockerize etmek istiyoruz. Yukarıda da belirttiğim 3 aşamadan 1.aşama olan Dockerfile 📃 dosyasını root klasörünü altına oluşturup gerekli komutları yazdığımızı düşünelim. Sırada Docker Image oluşturma işlemi var. Burada mini bir işletim sistemine ve uygulamamızı işletim sistemi içerisinde çalıştırabilecek ortama ihtiyacımız var. Bu yapıyı kendimiz oluşturmak yerine Microsoft, Google gibi firmaların hazır olarak yayınlamış olduğu image’i indirip kullanabiliriz.

Şimdi image’i indirdiğimizi düşünelim. İndirilen image üzerine uygulamamızı publish edip yeniden image oluşturuyoruz. Yeni oluşturduğumuz image üzerinden de container ayağa kaldırıyoruz. Farkettiyseniz, ☁️ Cloud ☁️üzerinde registry hizmeti veren firmaların hazır image’lerini kullanarak ortam hazırlamak için ekstra bir çaba içerisine girmedik. Tabii dikkat edilmesi gereken husus bu image’ler içerisinde herhangi bir kurulum yok. Image’i indirdikten sonra üzerine uygulamamızı publish etmemiz gereklidir.

Node.js, Java, Net Core farketmeksizin uygulamayı hangi ortam ile geliştiriyorsanız registry’den geliştirdiğiniz ortama uygun image’i indirip, image üzerine projenizi publish ettikten sonra yeni oluşturduğunuz image üzerinden container ayağa kaldırabilirsiniz.

Resmi Net Core Image (Official Images)

Azure, Google, Docker Hub gibi birden fazla registry servisi bulunmaktadır. Yazımızda docker hub 🐳 üzerinden ilerleyeceğiz. Docker Hub sitesi üzerinden üyelik işlemlerini tamamlandığınızı varsayıyorum. Üyelik işlemleri sonrasında Docker Hub üzerinde 1 adet private image oluşturma hakkınız vardır, birden fazlası için ücreti dahilinde istenilen kadar private image oluşturabilirsiniz.

Docker Hub üzerinde Net Core Runtime Images
Docker Hub — ASP.NET Core Runtime

ASP.NET Core Runtime uygulamanızı yayımlamak için ortam sağlarken ASP.NET Core SDK hem uygulamanızı çalıştırmanızı hem de geliştirme için ortam sağlamaktadır. Ayrıca SDK içerisinde Runtime’ı barındırır ama Runtime içerisinde SDK barındırmaz. Runtime ve SDK arasındaki farkı linkten inceleyebilirsiniz.

İlgili image içerisinde öne çıkan etiketler kısmında image’i bilgisayarınıza indirebileceğimiz komutlar bulunmaktadır. (Örneğin: docker pull mcr.microsoft.com/dotnet/aspnet:5.0) İndirilen image üzerine projemizi publish edip yeni oluşan image üzerinden container oluşturabiliriz.

Docker Hangi Yarama Merhem Oldu? 🥂

Docker ile dil bağımsızlığı
Versiyon, platform farklılıkları

Görselde de görüleceği üzere 4 arkadaştan 2'si aynı teknoloji diğer 2'si farklı teknolojilerle ilgilenmektedir. Net geliştirici olan arkadaş geliştirdiği Net 5.0 sürümlü projesini kendi bilgisayarında 💻 test ediyor, çalıştırıyor ve bunu diğer arkadaşlarıyla paylaşmak, test etmek istiyor. Normal şartlarda bu gibi durumlarda uygulama canlıya alınmalı ya da projenin dosyaları .rar şeklinde paylaşılmalıdır. Buradaki senaryoda ilk sorun geliştirdiği uygulama .net uygulaması olduğu için .net ile ilgilenemeyen kişiler projeyi çalıştıramayacaktır. (Bu 3 arkadaşta herhangi bir net ortamı olmadığını varsayıyorum.) Elimizde tek seçenek kaldı. Net ile ilgilenen arkadaşa proje dosyalarını .rar 📇 şeklinde atmak fakat orada da şöyle bir problem var .Net geliştirici arkadaş 3.1 sürümüyle uygulama geliştirirken bizim aslan parçası 5.0 sürümüyle uygulama geliştiriyor. Hal böyleyken .Net geliştirici arkadaşta versiyon uyumsuzluğundan dolayı projeyi çalıştıramayacak.

Velhasıl... Docker selam diyerek ortama giriyor. Bu 4 geliştirici de docker’ın kurulu olduğunu düşünelim. Net 5.0 sürümüyle projesini geliştiren arkadaş geliştirmiş olduğu uygulamasını bir image oluşturduktan sonra registry’e public olarak kaydetse, (docker hub) diğer geliştirici arkadaşlar da kaydedilen image’i pull ederek çalıştırabilir. Çünkü pull etmiş olduğu image içerisinde hem projenin kendisi hem de net 5.0 sürümünü çalıştıracak environment yani runtime kurulu olarak gelir. Böylelikle diğer geliştirici arkadaşlarda neyin kurulu olduğunun bir önemi kalmaz.🎇 Çünkü docker işletim sisteminden, versiyonlardan bağımsız şekilde bizlere ortam sağlar.

Docker Kurulumu

Docker windows işletim sistemine kurulumu
Docker Windows Uygulaması
  • Adım 3: Uygulamaya hesabınızla giriş yapınız.
Linux ya da windows containerlar ile çalışmak
Switch to Windows & Linux containers

Windows işletim sistemine sahip bilgisayarlarda docker ile hem Linux 🐧 hem de Windows containerlarla çalışabilirsiniz. Linux türevi işletim sistemlerinde ise sadece linux containerlar ile çalışabilirsiniz. (Örn: Ubuntu üzerinde docker kurduğunuzda windows containerları çalıştıramazsınız.)

Görev çubuğu üzerinde bulunan docker simgesine tıkladığınızda “Switch to Windows containers” seçeneğini görüyorsanız bu sizin Linux 🐧 containerlarla çalıştığınız anlamına gelir.

Console Projesini Dockerize Etmek

Uygulamanın docker üzerinde çalıştırılması aşamasını dockerize olarak adlandırırız. Bu kadar teorik bilgiden sonra iki saniyede bir ekrana o anki tarihi yazan sıradan bir console uygulaması oluşturalım.

Dockerfile dosyası ile image oluşturabilmem için projenin publish dosyalarına ihtiyacım var. Bundan dolayı console uygulamasını publish edelim.

Visual Studio ile Docker Support özelliği

Uygulamayı dockerize edebilmemiz için ilk şartımız root klasöründe bir Dockerfile oluşturmaktır.

Soldaki görselde görüleceği üzere Docker Support’a tıkladıktan sonra hedef işletim sistemini soracaktır. İşletim sistemini seçtikten sonra Dockerfile dosyası eklenecektir.

Sonrasında projemi üzerinde çalıştırabileceğim image lazım. Microsoft tarafından resmi olarak Docker Hub üzerinden yayınlanmış olan image’i (ASP.NET Core Runtime) kullanmam yeterli olacaktır.

Docker Hub ASP.NET Core Runtime Image Pull
Docker Hub — AspNetCore Runtime

Docker Hub üzerinden “net core runtime” araması yaptıktan sonra yukarıdaki görselde görünen image’in öne çıkan etiketlerine (featured tags) göre ilgili komut ile beraber istenilen versiyonu indirebiliriz. Eğer komut sonunda bulunan versiyon etiketini (:5.0/:3.1) belirtmezseniz docker hub üzerinde bulunan son güncel (LTS) image neyse o indirilir.

Dockerfile Komutlar

FROM: Docker hub üzerinden image indirmemizi sağlar. Hazır image’lerin kullanımı yaygın olduğu için genelde Dockerfile dosyaları from komutuyla başlar. Yukarıdaki Dockerfile dosyasında Runtime 3.1 Image’ ini base alacağımı belirttim.

WORKDIR: Image içerisinde dosya oluşturacak komuttur. Katmanın bir üstüne çıkarak, image içerisinde bir klasör oluşturup, projeyi de bu oluşturulan klasör içerisine atmak hedefimiz. Eğer bu komut ile belirttiğiniz klasör, dizinde yok ise önce klasör oluşturulur sonra oluşturulan klasör içerisinde konumlandırılır.

COPY: Dosya transferi için kullanılır. Belirttiğimiz konumdaki dosyaları yine belirttiğimiz konuma kopyalama görevini üstlenir. Yukarıdaki Dockerfile içerisinde console uygulamasının publish edilmiş dosyalarını image içerisinde belirlenen konuma kopyalamasını belirttim.

ENTRYPOINT: Bir image’den bir container ayağa kalktığı zaman çalışacak komuttur. Container’ların çalışabilmesi için “.dll” vermemiz gereklidir. Bir image’dem bir container ayağa kalktığı anda komutumuz çalışıyor olacaktır. Ayrıca Entrypoint komutu ezilemezdir.

Dockerfile içerisinde yazılan her bir satıra karşılık bir katman oluştuğuna göre, Image’ler katman topluluğudur.

Buraya kadar her şey okeyse Image oluşturma adımlarına geçelim. Kullanacağımız komut şeması “docker build -t {imagename} {dosyayolu}”. Image isminin tamamı küçük harflerden oluşmalıdır. Dosya yoluna “. (nokta)” koymamızdaki aynı dizin içerisinde olduğumuzu belirtmektir.

dockerfile dosyasından image oluşturmak
Image oluşturma & Image listeme

Powershell üzerinden Dockerfile dosyası yardımıyla yeni bir image oluşturdum ardından “docker images” ile image’leri listeledim. (Eğer image üzerinde herhangi bir değişiklik yaparsanız tekrar image oluşturmanız gereklidir.) Farkettiyseniz listelenen her iki image’in de boyutları aynı. Bunun nedeni bizim console projemizin 1 MB dan daha boyutta olmasıdır. Bu iki image arasında boyut farkını docker uygulaması üzerinden daha net görüntüleyebilirsiniz.

docker uygulamasından image’leri listelemek
Docker Images

Image oluşturduğumuza göre son adım olarak container oluşturabiliriz.

Docker Image üzerinden container oluşturmak
  • docker images: Var olan image’leri listeler.
  • docker create --name {container adı} {hangi image?}: container oluşturmak için kullanılacak komut.
  • docker ps -a: Mevcut containerları listeler.
  • docker ps: Çalışan containerları listeler.

Buraya kadar baya uğraştık artık bu işin çıktısını görme vakti geldi. Ne yaptık? Dockerfile oluşturduk sonra dosya aracılığıyla bir image aldık ve son adımda da container oluşturduk. Sıra geldi bu container’ı start etmeye.

Docker ile oluşturulan container’a attach olmak
Container çalıştırma

docker attach {container adı veya container adının ilk 3 harfi}: docker attach 00a

yukarıdakı komutla beraber start ettiğimiz container’a attach olup çıktısını görüntüledik. Ve yolun sonuna geldik! Tebrikler!

Sektörde Neler Oluyor? 🏬

Sayı olarak güncel olmayabilir fakat stackshare verilerine göre 7479 şirket Docker kullanmakta ve bize tanıdık gelecek bazı isimler;

Hepsiburada, Medium, Spotify, Twitter, Udemy, Shopify, ebay, Microsoft, Trivago, Asana

#S1B2 bölümünde görüşmek üzere. Wir Sehen Uns 😎

--

--