Sıfırdan Docker Benzeri Konteyner Yaratma: Konteyner Mekanizmalarının İç Mekanizmaları

Sıfırdan Docker Benzeri Konteyner Yaratma: Konteyner Mekanizmalarının İç Mekanizmaları
audio-thumbnail
Sıfırdan Docker Benzeri Konteyner Yaratma: Konteyner Mekanizmalarının İç Mekanizmaları
0:00
/0

Sıfırdan Docker Benzeri Konteyner Yaratma: Konteyner Mekanizmalarının İç Mekanizmaları

Linux konteynerlerinin temelinde, sistem düzeyindeki izolasyon mekanizmalarına dayanan güçlü bir yapı yatıyor. Docker gibi bir ortamda bir konteyner çalıştırdığınızda, sanki kendi işletim sistemiyle birlikte çalışıyormuş gibi bir deneyim yaşarsınız. Ancak bu, sadece bir illüzyondur. Aslında, bu izolasyon, Linux’ın kendi içinde geliştirdiği birkaç teknik sayesinde sağlanır.

Bu makalede, Docker benzeri bir konteyneri sıfırdan, sadece standart Linux araçlarını kullanarak oluşturacağız. Amaç, geliştiricilerin konteynerlerin nasıl çalıştığını, hangi sistem düzeyi mekanizmalarının etkisinde olduğunu anlayarak, Docker veya Kubernetes gibi araçların arkasındaki mantığı kavramaktır.


Konteynerin Hedefi Nedir?

Bir konteynerin amacı, bir uygulamanın çalışmasını sağlamak için gerekli olan tüm dosyaları, kütüphaneleri ve yapılandırma dosyalarını izole bir ortamda barındırmaktır. Yani, bir uygulama çalışırken, bu ortamın ana sistemle (host) olan bağlantısını minimuma indirmek, aynı zamanda hem güvenliği hem de taşınabilirliği artırmaktır.

Örneğin, docker run nginx komutunu çalıştırdığınızda, Nginx bir Debian tabanlı bir ortamda çalışır, ancak bu, sunucunuzun işletim sistemi ne olursa olsun, aynı şekilde çalışır. Peki bu nasıl olur?


Konteynerin Temelleri: Namespace’lar ve Mount Mekanizması

Konteynerlerin çalışması için, Linux’un birkaç temel mekanizması kullanılır:

  • Mount Namespace
  • PID Namespace
  • Cgroup Namespace
  • UTS Namespace
  • Network Namespace

Ancak bu makalede, Mount Namespace’ın ne kadar temel bir rol oynadığını göstereceğiz. Çünkü konteynerlerin izolasyonu, dosya sistemi görünümlerindeki değişiklikten başlar.


Mount Namespace Nedir?

Mount Namespace, bir process’in hangi dosya sistemlerini görebileceğini belirler. Yani, aynı dosya sistemini paylaşan birden fazla süreç, farklı mount tablolarına sahip olabilir.

Bir Deney: Mount Namespace Oluşturma

Terminal 1’de aşağıdaki komutla bir mount namespace’i oluşturun:

sudo unshare --mount bash

Bu komut, yeni bir shell açar ve bu shell, ana sistemdeki dosya sistemini paylaşmaz. Yani, bu yeni shell’deki mount komutu, ana sistemdeki dosya sistemiyle aynı şeyi görmeyecektir.

Şimdi Terminal 2’de bir dosya oluşturun:

echo "Hello from host's mount namespace" | sudo tee /opt/marker.txt

Terminal 1’de şimdi bu dosyayı arayın:

cat /opt/marker.txt

Sonuç: Dosya görünmüyor! Çünkü bu iki terminal farklı mount namespace’lere sahiptir.


Mount Namespace’ı Doğrulama

Her iki terminalde de şu komutu çalıştırın:

findmnt

Terminal 1’de ve Terminal 2’de farklı findmnt çıktıları görünecektir. Bu, her bir namespace’in kendi dosya sistemini görmesini sağlar.


Mount Propagation Nedir?

Mount Propagation, bir mount’un başka bir mount namespace’e nasıl yansıtılacağını belirler. Örneğin, bir mount noktasına bir dosya sistemi bağlandıysa, bu bağlanma diğer namespace’lere nasıl görünür?

Bu konu, konteynerlerin içindeki dosya sistemlerinin nasıl çalıştığını anlamak için çok önemlidir. Ancak bu makalede, sadece temel fikri anlatılacaktır.


Konteynerin Sıfırdan Yaratılması

Şimdi, bir konteyneri sıfırdan nasıl kuracağımızı adım adım görelim.

Adım 1: Root Filesystem Oluşturma

Konteynerler, bir root filesystem ile başlar. Bu, bir Linux dağıtımı gibi bir yapıdır. Örneğin, bir Ubuntu sistemini kullanabiliriz.

Daha önce bir chroot veya pivot_root gibi araçlarla bu işlem yapılır. Ancak günümüzde pivot_root daha güvenli ve doğru bir yoldur.

Adım 2: Mount Namespace ile İzolasyon

Aşağıdaki komutla bir mount namespace’i oluşturun:

sudo unshare --mount bash

Bu komut, yeni bir shell oluşturur ve bu shell, ana sistemdeki dosya sistemini paylaşmaz.

Adım 3: Root Filesystem’i Monte Etme

Şimdi, bir root filesystem’i monte etmek için bir dizin oluşturun ve üzerine bir dosya sistemi bağlayın:

mkdir /tmp/myroot
sudo mount --bind / /tmp/myroot

Bu, ana sistemdeki tüm dosyaları /tmp/myroot dizinine bağlar. Ancak bu, sadece bu namespace içinde geçerlidir.

Adım 4: Pivot Root ile Root Değiştirme

pivot_root komutu, yeni root dizinini sistemdeki root olarak belirler. Bu, konteynerin kendi dosya sistemini kullanmasını sağlar.

cd /tmp/myroot
sudo pivot_root . .

Bu komut, konteynerin root dizinini değiştirmeyi sağlar. Artık cd / komutu, konteynerin kendi root dizinini gösterir.


Diğer Namespace’lerin Rolü

Artık konteynerin dosya sistemi izole edilmiş. Ama bu sadece bir başlangıçtır. Konteynerin daha gerçekçi olması için aşağıdaki namespace’ler de eklenir:

  • PID Namespace: Konteyner içindeki süreçlerin kendine ait process ID’lerine sahip olmalarını sağlar. Böylece, konteyner içindeki init süreci, sistemdeki 1 numaralı süreç olur.
  • Cgroup Namespace: Süreçlerin kaynak kullanımı (CPU, bellek) için izolasyon sağlar.
  • UTS Namespace: Konteynerin kendi bilgisayar adı ve domain adı olmasına izin verir.
  • Network Namespace: Konteynerin kendi ağ yapılandırmasına sahip olmasına izin verir.

Ancak bu namespace’ler, mount namespace’inin oluşturduğu temel izolasyonun üzerine kurulur.


Konteynerlerin Gerçekleşmesi

Docker gibi bir runtime (örneğin runc), bu tüm adımları otomatikleştirir:

  1. unshare ile namespace’ler oluşturur.
  2. mount ile dosya sistemlerini monte eder.
  3. pivot_root ile root dizinini değiştirir.
  4. chroot veya exec ile komutu çalıştırır.

Bu süreç, sadece bir komutla tamamlanır: docker run nginx.


Sonuç

Konteynerler, sadece bir "iyi bir araç" değil, bir sistem düzeyi izolasyon mekanizmasıdır. Docker gibi bir araç, bu mekanizmaları kullanarak, bir uygulamanın farklı sistemlerde aynı şekilde çalışmasını sağlar.

Bu makalede, sadece birkaç komutla konteynerin nasıl çalıştığını anlattık. Ancak bu, geliştiricilerin Linux konteynerlerinin nasıl çalıştığını anlamasına yardımcı olur.


Ekstra Bilgi: Linux Konteynerlerinin Tarihi

Linux’ta ilk namespace mekanizması, 2002 yılında Linux 2.4 sürümünde tanıtılmıştır. Bu, konteyner teknolojisinin temelini oluşturmuştur. Daha sonra, cgroups, namespaces ve pivot_root gibi araçlar geliştirilerek, modern konteyner platformları oluşturulmuştur.


Özetle

  • Konteynerler, dosya sistemi izolasyonu ile başlar.
  • mount namespace, bu izolasyonun temelini oluşturur.
  • unshare, mount, pivot_root gibi araçlarla bu izolasyon sağlanır.
  • Diğer namespace’ler (PID, Cgroup, Network vb.) konteyneri daha gerçekçi hale getirir.

Konteyner teknolojisi, sadece bir araç değil, modern yazılım geliştirme dünyasının temel taşlarından biridir. Bu makale, bu yapıyı sadece kullanmak değil, aynı zamanda neden çalıştığını anlamanı sağlar.