Docker ve Kubernetes (K8s) Nedir?

Docker konteyner teknolojisi ve Kubernetes (K8s) orkestrasyonu nedir? Sanal makinelerle farkları, Pod yönetimi, otomatik ölçekleme ve bulut yerel mimari.

Yozel

15 dakika

Docker ve Kubernetes (K8s) Nedir?
İçindekiler (16)

Bulut yerel (Cloud-Native) yazılım mimarilerinin yükselişiyle birlikte, uygulamaların geliştirilme, paketlenme ve üretim sunucularında çalıştırılma biçimi köklü bir devrim geçirmiştir. Geçmişte yazılım mühendislerinin en büyük kabusu olan "Benim bilgisayarımda çalışıyordu ama canlı sunucuda çöktü" problemi, konteyner teknolojisi ve orkestrasyon motorları sayesinde tarihe karışmıştır. Bugün uygulama ve yazılım dünyasında ölçeklenebilir bir sistem inşa etmenin temel standardı haline gelen Docker ve Kubernetes (K8s) ikilisi, küçük girişimlerden küresel teknoloji devlerine kadar tüm modern altyapıların omurgasını oluşturur. Bu kapsamlı teknik rehberde; işletim sistemi çekirdeği düzeyinde konteyner izolasyonundan (Linux namespaces ve cgroups) sanal makinelerle (VM) olan mimari farklara, çok aşamalı (multi-stage) Dockerfile optimizasyonundan Kubernetes Control Plane, Pod, Service, Ingress ve Otomatik Ölçekleme (HPA) mekanizmalarına kadar tüm süreci uçtan uca inceliyoruz.

Konteyner Teknolojisi ve Docker Nedir?

Docker, bir yazılım uygulamasını çalışması için ihtiyaç duyduğu tüm bağımlılıklarla —çalışma zamanı motoru (runtime), sistem kütüphaneleri, ortam değişkenleri ve yapılandırma dosyalarıyla— birlikte standart, taşınabilir ve izole edilmiş bir paket (Container Image) haline getiren açık kaynaklı bir konteynerleştirme platformudur. Docker sayesinde oluşturulan bir konteyner imajı; geliştiricinin dizüstü bilgisayarında, şirket içi (on-premise) test sunucusunda veya AWS, Google Cloud ve Azure gibi bulut teknolojisi ve SaaS ortamlarında tek bir bit bile değişmeden %100 aynı davranışla çalışır.

Peki bir konteyner işletim sistemi düzeyinde tam olarak nedir? Sanılanın aksine bir konteyner, içinde küçük bir işletim sistemi barındıran hafif bir sanal makine değildir. Bir konteyner, doğrudan ana sunucunun (Host OS) Linux çekirdeği (Kernel) üzerinde çalışan, ancak çekirdeğin iki temel özelliği sayesinde diğer süreçlerden tamamen yalıtılmış izole bir işletim sistemi sürecidir (isolated process):

  • Linux Namespaces (İsim Alanları - Görünürlük İzolasyonu): Bir sürecin sistemde neleri görebileceğini sınırlar. PID Namespace sayesinde konteyner içindeki uygulama kendisini sunucudaki 1 numaralı süreç (PID 1) sanır; NET Namespace sayesinde kendine ait özel bir sanal ağ kartı, IP adresi ve port tablosu alır; MNT Namespace ile kendine özel izole bir kök dosya sistemi (rootfs) görür.
  • Linux Control Groups (cgroups - Kaynak Sınırlaması): Bir konteynerin ana sunucudaki donanım kaynaklarını (CPU çekirdek süresi, RAM miktarı, Disk I/O bant genişliği ve ağ trafiği) ne kadar tüketebileceğini kesin sınırlarla belirler. Böylece tek bir konteynerin aşırı bellek tüketerek sunucudaki diğer konteynerleri çökertmesi (Noisy Neighbor problemi) engellenir.

Docker Konteynerleri ve Sanal Makineler (Virtual Machines) Arasındaki Farklar

Geleneksel sanallaştırma mimarisinde (VMware ESXi, KVM, Hyper-V), fiziksel donanım veya ana işletim sistemi üzerinde bir Hypervisor katmanı çalışır. Oluşturulan her Sanal Makine (VM); kendi sanal donanım sürücülerini, kendi tam işletim sistemi çekirdeğini (Guest OS Kernel) ve gigabaytlarca büyüklükteki sistem dosyalarını içerir. Sadece 100 MB'lık bir Node.js veya Go mikroservisini çalıştırmak için 8 GB disk alanı ve 2 GB RAM tüketen tam bir Ubuntu sanal makinesi ayağa kaldırmak büyük bir donanım israfıdır.

Docker konteyner mimarisinde ise Hypervisor ve Guest OS katmanları tamamen ortadan kaldırılır. Tüm konteynerler ana makinenin (Host OS) mevcut Linux çekirdeğini paylaşır. Bu mimari fark şu devasa avantajları sağlar:

  1. Saniyeler Yerine Milisaniyeler İçinde Başlatma (Boot Time): Bir sanal makinenin işletim sistemini başlatması 30 ila 90 saniye sürerken, bir Docker konteyneri sadece yeni bir Linux süreci başlattığı için 100-500 milisaniye içinde trafiği karşılamaya hazır hale gelir.
  2. Bellek ve Disk Tasarrufu: Sanal makineler GB'larca yer kaplarken, Alpine veya Distroless tabanlı bir Docker imajı yalnızca 15 ila 80 MB boyutundadır. Bir fiziksel sunucuda 10 sanal makine yerine 150+ konteyner yüksek performansla çalıştırılabilir.
  3. Birleşik Dosya Sistemi (UnionFS / OverlayFS) ve Katmanlı İmaj Mimari: Docker imajları salt okunur (read-only) katmanlardan oluşur. Aynı sunucuda çalışan 20 farklı mikroservis aynı temel node:20-alpine katmanını kullanıyorsa, bu temel katman diskte ve önbellekte yalnızca bir kez tutulur ve tüm konteynerler tarafından ortaklaşa okunur; her konteynerin en üstüne yalnızca ince bir yazılabilir katman (Copy-on-Write) eklenir.
Docker İmaj Katmanları ve Sanal Makine Mimari Farkları
Hypervisor tabanlı Sanal Makineler (VM) ile işletim sistemi çekirdeğini paylaşan Docker Konteyner mimarisinin ve katmanlı imaj yapısının karşılaştırılması.

Üretim Ortamı İçin Çok Aşamalı (Multi-Stage) Dockerfile Optimizasyonu

Kurumsal yazılım geliştirmede en kritik güvenlik ve performans kuralı, derleme araçlarını (SDK, Maven, GCC, npm devDependencies) canlı sunucuya taşımamaktır. Multi-Stage Build (Çok Aşamalı Derleme) tekniği ile ilk aşamada kod derlenir, ikinci aşamada ise yalnızca derlenmiş çalıştırılabilir dosya (binary/artifact) çok küçük ve güvenli bir çalışma zamanı (runtime) imajına kopyalanır:

# 1. Aşama: Derleme Ortamı (Build Stage)
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o payment-service ./cmd/api

# 2. Aşama: Üretim Ortamı (Production Stage - Sadece 15 MB ve Root Olmayan Kullanıcı)
FROM alpine:3.19
RUN adduser -D -g '' appuser
WORKDIR /app
COPY --from=builder /app/payment-service .
USER appuser
EXPOSE 8080
ENTRYPOINT ["./payment-service"]

Kubernetes (K8s) Nedir ve Neden Docker Tek Başına Yetmez?

Tek bir sunucuda 3-5 adet konteyneri docker run veya docker compose ile yönetmek son derece kolaydır. Ancak Headless Commerce ve mikroservis mimarisi kullanan büyük ölçekli bir sistemde, 20 farklı fiziksel/bulut sunucuya yayılmış 800 konteyneriniz olduğunda işler tamamen değişir. Hangi konteyner hangi sunucuda çalışacak? Bir sunucu donanımsal olarak çöktüğünde üzerindeki 40 konteyner diğer sağlıklı sunuculara nasıl taşınacak? Kampanya anında trafik 10 katına çıktığında yeni konteynerler nasıl otomatik başlatılacak ve yük dengeleyiciye (Load Balancer) nasıl tanıtılacak? Yeni sürüm çıkarken sıfır kesinti (Zero-Downtime) nasıl sağlanacak?

İşte bu karmaşık dağıtık sistem problemlerini çözmek için Google'ın kendi iç altyapısında (Borg sistemi) 15 yıl boyunca edindiği tecrübeyle geliştirip açık kaynak olarak CNCF'e (Cloud Native Computing Foundation) bağışladığı Kubernetes (K8s) devreye girer. Kubernetes; konteynerleştirilmiş uygulamaların dağıtımını, ölçeklendirilmesini, ağ iletişimini ve kendi kendini iyileştirmesini (self-healing) tamamen otomatize eden endüstri standardı bir konteyner orkestrasyon platformudur.

Kubernetes Mimarisinin Temel Bileşenleri: Control Plane ve Worker Nodes

Bir Kubernetes kümesi (Cluster), beyni oluşturan Control Plane (Kontrol Düzlemi) düğümleri ile uygulama iş yüklerini (konteynerleri) fiilen çalıştıran Worker Nodes (İşçi Düğümler) olmak üzere iki ana katmandan oluşur.

1. Control Plane (Kümenin Beyni ve Yönetim Merkezi)

  • kube-apiserver: Kubernetes kümesinin dış dünyaya ve iç bileşenlere açılan tek giriş kapısıdır. Tüm kubectl komutları ve YAML bildirimleri RESTful API üzerinden buraya gelir, kimlik doğrulama (Authentication), yetkilendirme (RBAC) ve kabul kontrolünden (Admission Control) geçer.
  • etcd: Kümenin tüm durum bilgisini (State), yapılandırmalarını ve hangi Pod'un nerede çalıştığını yüksek tutarlılıkla saklayan dağıtık, anahtar-değer (Key-Value) tabanlı veritabanıdır.
  • kube-scheduler: Yeni oluşturulacak bir Pod'un; CPU/RAM gereksinimlerini, düğüm yakınlık kurallarını (Node Affinity / Taints & Tolerations) ve sunucuların doluluk oranlarını analiz ederek hangi Worker Node üzerinde çalıştırılacağına karar verir.
  • kube-controller-manager: Kümenin mevcut durumu (Current State) ile kullanıcının YAML dosyasında tanımladığı arzu edilen durumu (Desired State) sürekli karşılaştıran kontrol döngülerini (Control Loops) çalıştırır. Örneğin "3 adet Ödeme Pod'u çalışsın" dediğinizde 1 tanesi çökerse, bunu anında fark edip yeni bir Pod başlatılmasını tetikler.

2. Worker Nodes (Uygulamaların Çalıştığı İşçi Sunucular)

  • kubelet: Her işçi sunucuda çalışan ajandır. API Server'dan aldığı talimatlara göre Pod içindeki konteynerlerin sağlıklı çalışıp çalışmadığını (Liveness & Readiness Probes) denetler.
  • Container Runtime (containerd / CRI-O): Konteyner imajlarını kayıt defterinden (Registry) çeken ve işletim sistemi düzeyinde başlatıp durduran alt katman çalışma motorudur.
  • kube-proxy: Küme içindeki sanal ağ kurallarını (iptables / IPVS) yöneterek Service nesnelerine gelen ağ trafiğini sağlıklı Pod IP adreslerine yönlendirir.
Kubernetes Pod Service Ingress ve Otomatik Ölçekleme Mimarisi
Kubernetes kümesinde Ingress, Service ve Deployment nesneleri üzerinden Pod trafiğinin yönetimi ve Horizontal Pod Autoscaler (HPA) ile otomatik ölçekleme.

Kubernetes Nesneleri: Pod, Deployment, Service ve Ingress

Kubernetes'te doğrudan konteyner yönetilmez; bunun yerine bildirimsel (Declarative) YAML manifestoları aracılığıyla soyutlanmış mimari nesneler yönetilir:

  1. Pod: Kubernetes'teki en küçük dağıtım birimidir. Bir Pod genellikle tek bir uygulama konteyneri barındırır (veya log toplama/Service Mesh için yardımcı bir Sidecar konteyner içerir). Aynı Pod içindeki konteynerler aynı IP adresini (localhost) ve disk hacmini paylaşır. Pod'lar ölümlüdür (ephemeral); çöktüklerinde silinir ve yerlerine yeni bir IP adresiyle yeni bir Pod oluşturulur.
  2. Deployment ve ReplicaSet: Durumsuz (Stateless) uygulamaların yaşam döngüsünü yönetir. Kaç kopya (replica) Pod çalışacağını, yeni imaj sürümü çıktığında kesintisiz geçişin (Rolling Update) nasıl yapılacağını ve bir sorun olduğunda tek komutla eski sürüme nasıl dönüleceğini (Rollback) kontrol eder. Veritabanı gibi durum bilgisi tutan iş yükleri için ise StatefulSet kullanılır.
  3. Service (ClusterIP, NodePort, LoadBalancer): Pod'lar sürekli silinip yeni IP adresleriyle yeniden doğduğu için diğer servisler doğrudan Pod IP'sine bağlanamaz. Service nesnesi, belirli etiketlere (Labels & Selectors) sahip Pod grubunun önüne sabit bir sanal IP ve DNS adı (örneğin payment-service.prod.svc.cluster.local) koyarak dahili yük dengelemesi yapar.
  4. Ingress: Küme dışından gelen HTTP/HTTPS trafiğini karşılayan, SSL/TLS sertifikalarını yöneten ve alan adı veya URL yoluna (örneğin api.sirket.com/orders) göre trafiği ilgili iç Service nesnelerine yönlendiren akıllı katmandır.
  5. ConfigMap ve Secret: Uygulama kodunu imajdan ayırmak için ortam yapılandırmaları ConfigMap içinde, veritabanı şifreleri ve API anahtarları ise şifrelenmiş olarak Secret nesnelerinde tutulur ve Pod'lara çalışma anında enjekte edilir.

Otomatik Ölçekleme (HPA) ve Kendi Kendini İyileştirme (Self-Healing)

Kubernetes'in işletmelere sağladığı en büyük operasyonel güç, insan müdahalesine gerek kalmadan trafiğe göre esneyebilmesi ve arızaları kendi kendine onarabilmesidir:

  • Horizontal Pod Autoscaler (HPA): Metrics Server üzerinden Pod'ların anlık CPU, RAM veya özel metrik (örneğin saniyedeki HTTP istek sayısı veya Kafka kuyruk uzunluğu) değerlerini izler. Örneğin ortalama CPU kullanımı %70'i aştığında Pod sayısını otomatik olarak 4'ten 32'ye çıkarır; gece trafik düştüğünde ise tekrar 4'e indirerek bulut faturasını minimize eder.
  • Cluster Autoscaler / Karpenter: Eğer mevcut işçi sunucularda (Worker Nodes) yeni açılacak Pod'lar için yeterli boş CPU/RAM kalmamışsa, bulut sağlayıcısına (AWS EKS, GCP GKE, Azure AKS) API çağrısı yaparak kümeye dakikalar içinde yeni sanal sunucular ekler.
  • Liveness, Readiness ve Startup Probes: Kubernetes, uygulamanızın gerçekten sağlıklı olup olmadığını sürekli yoklar. Eğer bir Pod kilitlenmişse (deadlock) livenessProbe başarısız olur ve kubelet o Pod'u otomatik olarak yeniden başlatır. Eğer bir Pod henüz veritabanı bağlantılarını hazırlamamışsa veya aşırı yük altındaysa readinessProbe başarısız olur ve Service o Pod'a yeni kullanıcı trafiği göndermeyi geçici olarak durdurur.

Modern yazılım ekiplerinde bu konteyner ve orkestrasyon altyapıları, yapay zeka destekli tersine mühendislik (REA) ile modernize edilen eski uygulamaların buluta taşınmasında standart hedef platformdur. Ayrıca Kubernetes üzerinde çalışan mikroservisler, kurum içi süreçleri hızlandıran No-Code uygulama geliştirme platformları için yüksek erişilebilirlikli arka uç (backend) sağlar ve Web3 ve merkezsiz web düğümlerinin (RPC nodes) küresel ölçekte kesintisiz barındırılmasında aktif olarak kullanılır.

Sanal Makine, Docker ve Kubernetes Karşılaştırma Tablosu

Altyapı mimarinizi tasarlarken geleneksel Sanal Makineler (VM), tekil Docker konteynerleri ve Kubernetes orkestrasyonunun farklarını aşağıdaki tabloda net olarak inceleyebilirsiniz:

Özellik / Kriter Sanal Makine (Virtual Machine) Tekil Docker (Docker Compose) Kubernetes (K8s) Orkestrasyonu
İzolasyon Seviyesi Donanım seviyesi (Hypervisor + Tam Guest OS) İşletim sistemi süreci (cgroups & namespaces) Pod ve Namespace seviyesinde çoklu düğüm izolasyonu
Başlatma Süresi (Boot Time) 30 - 90 saniye 100 - 500 milisaniye 1 - 3 saniye (İmaj önbellekteyse anlık)
Kaynak Tüketimi (Overhead) Yüksek (Her VM için ayrı OS Kernel ve RAM) Çok Düşük (Host Kernel paylaşılır) Düşük-Orta (Control Plane için ek kaynak gerekir)
Çoklu Sunucu (Cluster) Yönetimi Manuel veya VMware vCenter ile sınırlı Yok (Tek bir ana sunucu ile sınırlı) Yüzlerce sunucuyu tek bir havuz gibi yönetir
Otomatik Ölçekleme (Auto-Scaling) Yavaş ve kaba (Tüm sanal makine kopyalanır) Manuel müdahale gerektirir Tam otomatik (HPA, VPA ve Cluster Autoscaler)
Kendi Kendini İyileştirme (Self-Healing) Sadece sunucu bazlı yeniden başlatma Sadece restart: always (Aynı sunucuda) Çöken sunucudaki Pod'ları sağlam sunuculara taşır
Kesintisiz Dağıtım (Zero-Downtime) Harici Load Balancer ve karmaşık scriptler şart Kısa süreli kesinti yaşanabilir Yerleşik Rolling Update, Canary ve Blue/Green
İdeal Kullanım Senaryosu Eski (Legacy) monolitler, farklı OS çekirdeği ihtiyacı Yerel geliştirme, küçük projeler, tek sunuculu işler Orta/Büyük ölçekli mikroservisler, kritik üretim sistemleri

Sıkça Sorulan Sorular (SSS)

1. Kubernetes, Docker'ın yerini mi alıyor; ikisi rakip teknolojiler mi?

Hayır, Docker ve Kubernetes rakip değil, birbirini tamamlayan iki farklı katmandır. Docker, uygulamanızı bağımlılıklarıyla birlikte paketleyip konteyner imajı (OCI Image) oluşturmanızı sağlayan araçtır (uçağın kendisi gibi düşünebilirsiniz). Kubernetes ise oluşturulan bu yüzlerce konteyner imajını onlarca sunucu üzerinde yöneten, ölçekleyen ve ağ trafiğini düzenleyen orkestrasyon sistemidir (hava trafik kontrol merkezi gibi). Kubernetes, Docker ile üretilen imajları containerd çalışma zamanı üzerinde sorunsuzca çalıştırır.

2. Her yazılım projesinde Kubernetes kullanmak zorunlu mudur?

Kesinlikle hayır. Eğer günde birkaç bin ziyaretçi alan küçük veya orta ölçekli bir uygulamanız, 2-3 kişilik bir geliştirici ekibiniz ve yalnızca birkaç servisiniz varsa Kubernetes kurmak ve yönetmek gereksiz mühendislik maliyeti (over-engineering) yaratır. Bu tür projelerde tek bir sunucu üzerinde Docker Compose kullanmak veya AWS ECS, Google Cloud Run gibi yönetilen (serverless container) servisleri tercih etmek çok daha ekonomik ve pratiktir.

3. Kubernetes'te veritabanı (PostgreSQL, MySQL) çalıştırmak güvenli midir?

Pod'lar doğası gereği geçici (ephemeral) olduğu için normal bir Deployment içinde veritabanı çalıştırılırsa Pod yeniden başladığında tüm veriler silinir. Ancak Kubernetes'in StatefulSet nesnesi ve Persistent Volume (PV / PVC) depolama mimarisi ile bulut diskleri Pod'lara kalıcı olarak bağlanabilir ve CloudNativePG gibi operatörlerle Kubernetes içinde yüksek erişilebilirlikli veritabanları çalıştırılabilir. Yine de birçok kurumsal ekip operasyonel riskleri azaltmak için uygulama servislerini Kubernetes'te tutarken, veritabanlarını AWS RDS veya Google Cloud SQL gibi yönetilen servislerde barındırmayı tercih eder.

4. Docker konteyneri içindeki veriler konteyner silindiğinde neden kaybolur?

Docker konteynerlerinin en üstündeki yazılabilir katman (writable layer) konteynerin yaşam döngüsüne bağlıdır; konteyner durdurulup docker rm ile silindiğinde bu geçici katman da diskten temizlenir. Kalıcı olması gereken dosyalar, loglar veya veritabanı kayıtları için mutlaka Docker Volumes veya Bind Mounts kullanılarak verinin ana sunucunun (Host) fiziksel diskinde saklanması sağlanmalıdır.

5. Yönetilen Kubernetes (EKS, GKE, AKS) ile kendi kurduğumuz (Self-Hosted) Kubernetes arasındaki fark nedir?

Kendi fiziksel veya sanal sunucularınıza kubeadm veya Rancher ile sıfırdan Kubernetes kurduğunuzda (Self-Hosted), Control Plane bileşenlerinin (etcd yedeklemesi, API Server yüksek erişilebilirliği, sürüm yükseltmeleri ve güvenlik yamaları) tüm sorumluluğu sizin sistem ekibinizdedir. AWS EKS, Google GKE veya Azure AKS gibi yönetilen (Managed) servislerde ise bulut sağlayıcısı Control Plane katmanını sizin adınıza 7/24 yedekli olarak yönetir; siz yalnızca uygulamalarınızın çalıştığı Worker Node'lara ve Pod'lara odaklanırsınız.

Paylaş

Yozel

Codex haberleri en az iki bağımsız kaynakla doğrulanır; düzeltmeler yazının altında tarih ve saatle belirtilir. Yayın ilkelerimiz