Docker Nedir? Nasıl Kullanılır?

Güncelleme 29/09/2020 Yayın 07/08/2020

Uzun bir süredir Docker ile ilgili bilgi dağarcığımı geliştirmeye çalışıyordum. Ancak, gerçek anlamda pratik yapma ve sorunları kavrama sürecine Mixture ile sahip oldum. Sonda söyleyeceğimi başta söyleyeyim, kesinlikle alışkanlık yapıyor. Bu yazıda, yeterli deneyime sahip olmadığım için docker ile ilgili derinlemesine açıklamalarda bulunmam mümkün değil. Amacım, bu yazı temelinde bir başlangıç yapmak, öğrendiklerimi olabildiğince basit bir şekilde aktarmak ve zamanla karşılaştığım sorunları ve çözümleri bir arada sunabilmek. Tekrarlamakta fayda var; docker, hem uygulama geliştirme hem de bilgisayarınızı organize etme anlamında bir alışkanlık haline geliyor. Bu sayede, ilerleyan yazılarda, ilişkili olan her örnek senaryoda gitlab/github bağlantılarının yanı sıra docker hub bağlantısı notlarım ile birlikte paylaşmaya çalışacağım.

Unutmadan, yazının alt bölümünde, Önerdiğim Eğitimler başlığı altında benim öğrenme bu süreçte faydalandığım ve özellikle tavsiye ettiğim bazı kaynak bağlantılara yer verdim, fayda göreceğinizden eminim. Şimdi, konumuza geçelim.

Docker Nedir?

Docker

Docker, özet bir ifade ile, yazılımların/uygulamaların hızlı ve pratik bir şekilde çalışır hale getirilebilmesi amacıyla geliştirilen, yazılımın gereksinimlerinin bir arada ya da haberleşebilir şekilde yönetilebildiği ve paylaşılabildiği bir uygulama dağıtım çözümü. Örneğin, bir veritabanı ile ilişkili node.js CRUD uygulamanız var diyelim. DigitalOcean üzerinde bir droplet oluşturduğumuzda -eğer droplet bu şekilde yapılandırılmamışsa- Nodejs ve PostgreSQL (ya da diğer bir veritabanı motoru) kurulumunu yapmamız gerekir. Ardından, npm aracılığı ile node.js modüllerini indirir ve uygulamayı çalıştırırız. Uygulamayı bir başka sunucuya kurmak veya taşımak istediğimizde bu adımları tekrarlarız. Kimi durumda sunucudaki uygulamaların güncellenmesi, yazma ve kullanıcı izinlerinin de yapılandırılması gerekebilir. Docker, bu sürecin komutlar ve/ya bir yaml dosyası aracılığı ile yürütülmesini sağlar. Hatta, daha karmaşık uygulamalarda, Swarm ile bu işlemleri farklı sunuculardaki (veya aynı sunucudaki) konteynerler (TDK karşılığı taşımalık) üzerinden de gerçekleştirebilir ki buna süreç orkestrasyon olarak ifade edilmekte. Şimdi, temel bir kaç kavram var; konteyner ve imaj.

Öncelikle, temel bir bilgi aktarmakta fayda var. Bir işletim sisteminin merkezinde çekirdek (kernel) olarak bir bileşen bulunur. Bu merkezi bileşen işletim sistemindeki her şeyin üzerinde denetime sahiptir, kurulu olduğu sistemin kaynaklarını yönetir, işletim sisteminin yüklü olduğu cihazda kurulu uygulamaları ve bu cihazın fiziksel parçası olan donanımlar arasındaki bilgi işlemlerinde bir köprü görevi görürür1. Şimdi, Docker Linux temelinde işlemler gerçekleştirdiği için işletim sistemi olarak Linux‘u temel alalım. Linux çekirdeği (kernel), Unix benzeri açık kaynak bir monolitik işletim sistemi çekirdeğidir. Kullandığımız tüm Linux dağıtımları (Ubuntu, CentOS, Arch Linux, Debian, OpenSUSE, Fedora vb.) bu çekirdek üzerine inşa edilmiştir.

Docker Nedir?

Docker Çalışma Biçimi

Linux çekirdeğine 2008 yılında2 Linux Containers (LXC) özelliği eklenir. LXC ile işletim sistemi düzeyinde sanallaştırma işlemleri gerçekleştirilebilmektedir. Yani, bir bilgisayar üzerinde birden çok yalıtılmış Linux sistemi izole (kendi kaynaklarına sahip ve bu kaynakları yönetebilir) şekilde çalıştırılabilmektedir. Elbette bu yeni bir konsept değil2. Ancak, en etkilisi olduğu söylenebilir. Bu izole sistemler konteyner olaral ifade edilmektedir. Evet, tıpkı yük gemilerindekiler gibi. Konteynerler aksi istenmediği sürece birbirleri ile iletişime geçmezler.

Bu aşamada, yanlış bir bilgi vermemek adına sanallaştırmaya dair daha teorik bir anlatım için şu yazıyı önerebilirim: Docker Bölüm 1: Nedir, Nasıl Çalışır, Nerede Kullanılır?

Docker bir PaaS LXC üzerinde geliştirilmiş bir sistem olarak 2013 yılında yine dotCloud adlı şirket tarafından duyurulur3 ve çok kısa zamanda büyük bir ilgi uyandırır.

Yaklaşık 1 yıl sonra, 0.9 versiyonu ile birlikte Docker yürütme ortamı olarak LXC yerine Go programlama dili ile tamamen baştan yazılmış olarak sunulur4. Docker, 2013 yılı itibariyle Docker, Inc. liderliğinde geliştirilmektedir ve 2016 yılından bu yana Windows ortamında da çalışabilmektedir3.

Docker Nedir?

Docker Yapısı

Docker, Linux ortamı dışında (macOS ve Windows) iki yapı sayesinde işlemler gerçekleştirir; Linux çekirdeği ile iletişim içerisinde olan Docker Daemon (veya dockerd)5 ve dockerd ile REST API aracılığıyla iletişimi sağlayan Docker CLI. macOS ve Windows üzerinde dockerd (docker daemon) Docker Desktop uygulaması aracılığı ile işlemler gerçekleştirir. Özetle, Docker engine, dockerd, Docker REST API ve Docker CLI’a sahip bir istemci-sunucu uygulamasıdır6. Docker CLI, verilen komutları TCP ile docker engine‘e iletir, işler ve sonucu döner. dockerd komutları işletim sistemlerinde bir Hypervisor (veya VMware, VirtualBox, Hyperkit, Hyper-V) yardımıyla çalıştırılan izole Linux çekirdeği üzerinden uygular.

daemond, docker nesnelerini (veya komponent) oluşturur ve yönetir. Bu nesnelere cli komutları (management commands) olarak ulaşılabilir; image, container, network, volume vs.

Image

Docker konteyneri oluşturulurken temel alacağı bilgiler (dosya içerikleri, ilişkilendirilecek network, service, volume ve diğer image isimleri vb.) docker image içerisinde tanımlanır. Özetle, bir yemek tarifi gibi düşünebiliriz. Ancak, bu tarifte kullanılacak malzemelerin bulunduğu rafların, ürünlerin satılan marketlerin de tanımlı olduğunu düşünün. Üzerine çalışılan uygulama bir imaj haline getirilir ve saklanır. Uygulamanın tekrar yapılandırılması veya çoklanması aşamasında bu imajdan faydalanılır. Bir imaj başka imajları da barındırabilir. Docker hub ön tanımlı imaj kaynağıdır. Ancak, farklı çevrimiçi, kapalı sistemler ve hatta fiziksel kaynaklar da kullanılabilir.

docker image pull node:current

Yukarıdaki kod ile current olarak işaretlenmiş node.js imajı indirilir.

Container

Linux çekirdeği içerisinde izole edilerek oluşturulan ve çalıştırılan sanal işletim sistemlerinin her birini ifade eder. Konteynerler çok kısa bir sürede oluşturulabilir, durdurulabilir, yeniden başlatılabilir ve silinebilirler.

docker container run nginx:latest

Yukarıdaki komut ile latest olarak etiketlenmiş nginx imajı konteyner haline getirilir.

Network

Oluşturulan konterneyerlerin haberleşebileceği ağ yapılandırmasını sağlar. Ön tanımlı olarak bridge seçimi uygulanır.

docker network create --driver=bridge network_ismi

Volume

Oluşturulan konteynerler tarafından ele alınan/alınacak bilgilerin içe/dışa aktarımı ve yedeklenmesi amacıyla kullanılır.

docker volume create volume_ismi

Şimdilik, aktarabileceğim özet bilgiler bu kadar. Dahası detaylı ve teknik bilgiler için Önerdiğim Eğitimler ve İleri Okumalar başlığı altında listelediğim bağlantıları inceleyebilirsiniz. Ayrıca, örnek komut kullanımları için Docker Cheat Sheet (Türkçe) sayfası da işinize oldukça yarayacaktır. Bir sonraki yazıda PostgreSQL + Nodejs ile basit bir CRUD uygulaması hazırlayacak ve bu uygulamanın nasıl docker imajı haline getirebileceğine değineceğim.

Docker CLI – Cheat Sheet

Aşağıdaki tabloda sıklıkla kullanılan bazı cli komutlarını görebilirsiniz. Öncelikle, hatırlatmakta fayda var. docker --help komutu ile image, volume ve container gibi docker yönetim işlemlerine ait komutlar (management commands) başta olmak üzere pek çok detaya ulaşabilirsiniz. Aynı şekilde, ilgili bir komutun detaylarını da yine --help ile görüntüleyebilirsiniz.

Komut Açıklama
docker images Docker ortamındaki lokal imajları (images) listeler
docker ps Çalışan konteynerleri (containers) listeler. Kullanılacak diğer komut:
docker container ps
docker ps -a Docker deamon (dockerd) üzerindeki tüm (çalışmayanlar da dahil) konteynerleri listeler. Kullanılabilecek diğer komut:
docker container ps -a
docker pull <repository_name> Belirtilen imajı docker ortamına indirir (ön tanımlı olarak hub.docker.com tanımlıdır). Official images ve verified publisher olarak tanımlı imajlarda yeterlidir. belirtilmediğinde latest değerini alır. Kullanılabilecek diğer komutlar:
docker container pull <repository_name>
docker pull <repository_name>/<image_name>:<image_tag>
docker container pull <repository_name>/<image_name>:<image_tag>
docker top Belirtilen docker konteyner tarafından yürütülen işlemleri listeler. Kullanılabilecek diğer komut:
docker container top
docker run Belirtilen imajı docker olarak çalıştırır. Eğer server gibi aktif durumda kalan bir uygulama ise terminal konteyner ile ilişkilendirilir. Diğer durumda işlem gerçekleştirilir ve sonuç döndürülür (Örn. hello-world)
docker run -it Belirtilen imajı konteyner olarak çalıştırır ve terminali konteyner ile ilişkilendirir.
docker run -d Belirtilen imaja ait konteyneri arka planda çalıştır. Örneğin, bir server uygulaması çalıştırdıysanız terminal uygulama ile ilişkilendirilmeyecek, uygulama arka planda çalışmaya devam edecektir.
docker rmi Belirtilen imaj(ları) siler. Eğer imaj(lar) konteyner olarak çalıştırılmakta ise hata dönecektir. Kullanılabilecek diğer komut:
docker image rm
docker rmi -f Belirtilen imaj(ları) zorlayarak siler. Eğer imaj(lar) konteyner olarak çalıştırılmakta ise hata dönecektir.
docker inspect Belirtilen imaja ait detayları verir. Kullanılabilecek diğer komut:
docker image inspect
docker container ls Aktif konteynerleri listeler.
docker container ls -a Tüm konteynerleri listeler.
docker pause Belirtilen konteyneri duraklatır.Kullanılabilecek diğer komut:
docker container pause
docker unpause Belirtilen ve duraklatılmış durumdaki konteyneri tekrar çalıştırır.Kullanılabilecek diğer komut:
docker container unpause
docker stop Belirtilen konteyneri durdurur.Kullanılabilecek diğer komut:
docker container stop
docker start Belirtilen konteyneri çalıştırır.Kullanılabilecek diğer komut:
docker container start
docker rm Belirtilen konteyner(ler)i siler. Ancak, diğer modüllere (image, volume, network vb.) dokunmaz.Kullanılabilecek diğer komut:
docker container rm
docker rm -v Belirtilen konteyner(ler)i ilişkili olduğu volume(ler) ile birlikte siler.Kullanılabilecek diğer komut:
docker container rm -v
docker rm -f Belitilen konteyner(ler) çalışıyor olsa dahi durdurularak silinir. Kullanılacak diğer komut:
docker container rm -f
docker container inspect Belirtilan konteyner ile ilgili detayları getirir.
docker logs Belirtilen konteyner(ler)e ait logları (stdin, stdout, stderr) getirir. Kullanılacak diğer komut:
docker container logs
docker logs -f Belirtilen konteyner(ler)e ait logları (stdin, stdout, stderr) getirir ve görüntülemeye devam eder. Kullanılacak diğer komut:
docker container logs -f
docker exec Çalışır durumdaki bir konteyner içerisinde komut çalıştırılmasını sağlar. Kullanılacak diğer komut:
docker container exec
docker exec -it /bin/bash Çalışır durumdaki bir konteynere ait terminale bağlanmamızı (kullanici@container-id olarak) ve komutlar uygulayabilmemizi sağlar. Kullanılacak diğer komut:
docker container exec -it /bin/bash
docker attach Arka planda çalışan belirtilen id değerine sahip konteyner terminaline bağlanabilmemizi sağlar. Kullanılacak diğer komut:
docker docker attach
docker commit Bir konterner içerisinde değişiklik yapıldığında, konteynere ait yeni bir imaj oluşturulmasını sağlar. Kullanılacak diğer komut:
docker container commit
docker cp <container_id>:<kaynak> <hedef> Konteyner ile lokal alan arasında dosya/klasör kopyala-yapıştır işlemi gerçekleştirir. Kullanılacak diğer komut:
docker container cp <container_id>:<kaynak> <hedef>

İleri Okumalar