Kubernetes dünyasına adım atmak ilk bakışta biraz ürkütücü gelebilir. “Pod nedir, cluster nedir, kubectl nasıl çalışır?” diye sorular birikiyor. Ama endişelenme, bu yazıda sıfırdan başlayarak kubectl kurulumunu yapacak, temel kavramları sindirilir hale getireceğiz ve her gün işine yarayacak komutları öğreneceğiz. Yıllarca bare-metal sunucularda ve VM’lerde iş yapmış biri olarak şunu söyleyeyim: Kubernetes öğrendikten sonra “bunu neden daha önce kullanmadım” diyeceksin.
Kubernetes Nedir, Neden Öğrenmeli?
Kubernetes, Google’ın kendi iç sistemlerinden ilham alınarak geliştirilen ve konteyner orkestrasyon platformudur. Docker ile konteyner oluşturmayı öğrendikten sonra şu soruyla karşılaşıyorsun: “Tamam, elimde 50 konteyner var, bunları nasıl yöneteceğim?” İşte Kubernetes tam burada devreye giriyor.
Birkaç yıl önce bir e-ticaret müşterimizin altyapısında tam anlamıyla kaos yaşandı. Black Friday döneminde trafik 10 katına çıktı, uygulamalar çöktü, ekip panikle sunucu ayağa kaldırmaya çalıştı. Kubernetes kullansaydık bu hikaye çok farklı biterdi. Horizontal Pod Autoscaler devreye girerdi, servis kesintisi yaşanmazdı.
Temel Kavramları Anlamak
Komutlara geçmeden önce kafanda netleşmesi gereken birkaç kavram var. Bunları atlarsan ilerleyen bölümlerde kaybolursun.
Cluster Nedir?
Cluster, Kubernetes’in temel yapısıdır. Birden fazla makinenin (fiziksel veya sanal) tek bir havuz olarak çalıştığı ortamdır. Cluster içinde iki tür node bulunur:
- Control Plane (Master Node): Tüm kararların alındığı, API sunucusunun çalıştığı, scheduler ve controller manager’ın barındığı yerdir. Cluster’ın beynidir.
- Worker Node: Asıl iş yükünün çalıştığı makinelerdir. Uygulamalarının konteynerleri burada hayat bulur.
Bir cluster düşün ki büyük bir fabrika gibi. Control plane fabrika müdürü, worker node’lar ise fabrika çalışanları. Müdür kararları verir, çalışanlar uygular.
Pod Nedir?
Pod, Kubernetes’teki en küçük dağıtım birimidir. “Konteyner değil mi?” diye soruyorsun, haklısın ama Pod biraz daha fazlası. Pod içinde bir veya birden fazla konteyner çalışabilir. Bu konteynerler aynı ağ namespace’ini ve storage’ı paylaşır.
Günlük hayattan bir örnek vereyim: Bir web uygulaması düşün. Ana uygulama konteynerin yanında bir de log toplama konteyneri çalıştırmak istiyorsun. Bunları aynı Pod içine koyarsın, ikisi de aynı localhost üzerinden haberleşir.
Pod’ların önemli bir özelliği var: Geçicidirler. Pod ölürse yeni bir Pod oluşturulur ve yeni bir IP alır. Bu yüzden Pod’lara direkt bağlanmak yerine Service kullanırız, ama bunu başka bir yazıya bırakalım.
Namespace Nedir?
Namespace, cluster içindeki sanal bölümlemedir. Geliştirme, test ve production ortamlarını tek cluster üzerinde izole etmek için kullanılır.
kubectl get namespaces
Varsayılan olarak default, kube-system, kube-public ve kube-node-lease namespace’leri gelir. kube-system içinde Kubernetes’in kendi bileşenleri çalışır, oraya dokunmamak gerekir.
kubectl Kurulumu
Artık kubectl kurulumuna geçebiliriz. kubectl, Kubernetes API’sine komut satırından konuşmamızı sağlayan araçtır.
Linux Üzerinde kubectl Kurulumu
# En güncel stabil versiyonu çek
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
# Binary'yi doğrula
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
echo "$(cat kubectl.sha256) kubectl" | sha256sum --check
# Sisteme kur
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# Versiyon kontrolü
kubectl version --client
macOS Üzerinde Homebrew ile Kurulum
brew install kubectl
kubectl version --client
Windows Üzerinde Kurulum
PowerShell ile yapabilirsin:
# Chocolatey ile
choco install kubernetes-cli
# Ya da winget ile
winget install -e --id Kubernetes.kubectl
Yerel Test Ortamı için Minikube
Gerçek bir cluster’a erişimin yoksa Minikube harika bir seçenek. Tek node’lu Kubernetes cluster’ını laptop’ında çalıştırırsın.
# Linux için Minikube kurulumu
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# Cluster'ı başlat
minikube start
# Durumu kontrol et
minikube status
Minikube başlatıldığında otomatik olarak kubeconfig dosyasını düzenler ve kubectl’in bu cluster’a bağlanmasını sağlar.
kubeconfig Dosyası
kubectl’in hangi cluster’a bağlanacağını ~/.kube/config dosyasından öğrenir. Bu dosyayı doğrudan düzenleyebilirsin ama kubectl komutlarıyla yönetmek daha temiz.
# Mevcut context'leri listele
kubectl config get-contexts
# Aktif context'i gör
kubectl config current-context
# Farklı bir context'e geç
kubectl config use-context minikube
# Cluster bilgilerini gör
kubectl config view
Birden fazla cluster yönetiyorsan, sabah işe gelince hangi context’te olduğunu mutlaka kontrol et. Yanlış cluster’da komut çalıştırmak üzücü deneyimlere yol açabilir. Production cluster’ında yanlışlıkla bir şey silmek, en deneyimli sysadmin’in bile gece uyku uyumamasına neden olur.
Günlük Kullanımda En Çok İhtiyaç Duyulan Komutlar
Pod İşlemleri
Çalışan Pod’ları görmek günlük rutininin parçası olacak:
# Default namespace'deki pod'ları listele
kubectl get pods
# Tüm namespace'lerdeki pod'ları gör
kubectl get pods --all-namespaces
# ya da kısa hali
kubectl get pods -A
# Belirli namespace'deki pod'ları gör
kubectl get pods -n kube-system
# Daha fazla detay için
kubectl get pods -o wide
# Pod detaylarına bak
kubectl describe pod <pod-adı>
# Pod loglarını takip et
kubectl logs <pod-adı> -f
# Çok konteynerli pod'da belirli konteynerin logları
kubectl logs <pod-adı> -c <konteyner-adı> -f
-o wide seçeneği gerçekten hayat kurtarır. Pod’un hangi node üzerinde çalıştığını ve IP adresini gösterir. Node bazında dağılımı kontrol ederken sürekli kullanırsın.
Pod İçine Bağlanma
Docker’da docker exec -it diyordun, Kubernetes’te de benzer bir şey yapabilirsin:
# Pod içine interaktif shell aç
kubectl exec -it <pod-adı> -- /bin/bash
# Eğer bash yoksa sh dene
kubectl exec -it <pod-adı> -- /bin/sh
# Çok konteynerli pod'da belirli konteynere gir
kubectl exec -it <pod-adı> -c <konteyner-adı> -- /bin/bash
# Pod içinde tek seferlik komut çalıştır
kubectl exec <pod-adı> -- ls /app
Deployment İşlemleri
Gerçek hayatta Pod’ları direkt oluşturmazsın, Deployment kullanırsın. Deployment, Pod’ların istenen sayıda çalışmasını garantiler.
# Deployment oluştur
kubectl create deployment nginx-demo --image=nginx:latest
# Deployment'ları listele
kubectl get deployments
# Deployment detayı
kubectl describe deployment nginx-demo
# Replica sayısını değiştir (scale out)
kubectl scale deployment nginx-demo --replicas=5
# Deployment'ı güncelle (rolling update)
kubectl set image deployment/nginx-demo nginx=nginx:1.25
# Güncelleme durumunu takip et
kubectl rollout status deployment/nginx-demo
# Önceki versiyona geri dön
kubectl rollout undo deployment/nginx-demo
# Belirli bir revizyona geri dön
kubectl rollout history deployment/nginx-demo
kubectl rollout undo deployment/nginx-demo --to-revision=2
Rolling update özelliği Kubernetes’in en güçlü yanlarından biridir. Yeni versiyon Pod’ları yavaş yavaş ayağa kalkarken eski Pod’lar hizmet vermeye devam eder. Sıfır kesintili deployment burada mümkün hale gelir.
YAML ile Kaynak Oluşturma
Komut satırı hızlı testler için iyidir ama production ortamında her şeyi YAML ile yönetirsin. Versiyon kontrolüne girebilir, değişiklikler takip edilebilir.
Basit bir Deployment YAML örneği:
# Önce YAML üret, uygulama
cat <<EOF > nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
EOF
# YAML'ı uygula
kubectl apply -f nginx-deployment.yaml
# Dry run ile önce test et
kubectl apply -f nginx-deployment.yaml --dry-run=client
# Kaynağı sil
kubectl delete -f nginx-deployment.yaml
kubectl apply ile kubectl create arasındaki farka dikkat: apply idempotent’tir, yani kaynak varsa günceller, yoksa oluşturur. create ise kaynak zaten varsa hata verir. Günlük kullanımda apply tercih edilir.
Node Yönetimi
Cluster’ın sağlığını kontrol etmek ve node’ları yönetmek de rutinin parçası:
# Node'ları listele
kubectl get nodes
# Node detayı
kubectl describe node <node-adı>
# Node kaynak kullanımı (metrics-server gerekli)
kubectl top nodes
# Pod kaynak kullanımı
kubectl top pods
# Node'u maintenance moduna al (pod'ları taşı)
kubectl drain <node-adı> --ignore-daemonsets --delete-emptydir-data
# Node'u tekrar schedule'a ekle
kubectl uncordon <node-adı>
# Node'a yeni pod schedule edilmesini engelle ama mevcutlara dokunma
kubectl cordon <node-adı>
drain komutu dikkatli kullanılmalı. Node üzerindeki tüm Pod’ları başka node’lara taşır. Fiziksel makineye bakım yapacaksan önce drain, sonra bakım, sonra uncordon sırası izlenir.
Troubleshooting: Sorun Giderme Senaryoları
Gerçek sysadmin işi sorun çözmektir. İşte sık karşılaşılan durumlar.
CrashLoopBackOff Durumu
Pod sürekli crash yapıp restart ediyorsa:
# Pod'un son loglarına bak
kubectl logs <pod-adı> --previous
# Pod'un event'lerine bak
kubectl describe pod <pod-adı>
# Eventleri ayrıca listele
kubectl get events --sort-by=.metadata.creationTimestamp
# Belirli namespace için
kubectl get events -n production --sort-by=.metadata.creationTimestamp
describe komutunun çıktısındaki Events bölümü genellikle sorunun nedenini söyler. Image pull hatası mı, resource yetersizliği mi, liveness probe başarısız mı, hemen görürsün.
Pending Pod Durumu
Pod çalışmıyor, Pending kalıyorsa genellikle kaynak sorunu vardır:
# Neden Pending? Events'e bak
kubectl describe pod <pending-pod-adı>
# Node'larda ne kadar yer var?
kubectl describe nodes | grep -A 5 "Allocated resources"
# Taint ve toleration kontrolü
kubectl describe node <node-adı> | grep Taint
Eğer “Insufficient cpu” veya “Insufficient memory” görüyorsan ya node’a kaynak eklemen ya da Pod’un resource request’lerini düşürmen gerekiyor.
Label ve Selector Kullanımı
Kubernetes’te her şey label’larla organize edilir. Bu kavramı anlamak çok önemli.
# Pod'lara label ekle
kubectl label pod <pod-adı> environment=production
# Label'a göre listele
kubectl get pods -l environment=production
# Birden fazla label ile filtrele
kubectl get pods -l app=nginx,environment=production
# Label kaldır
kubectl label pod <pod-adı> environment-
# Node'ları label'a göre listele
kubectl get nodes -l disktype=ssd
Label’lar sadece organizasyon için değil, Service’lerin Pod’ları bulması için de kullanılır. Bir Service’in selector’ı hangi Pod’lara trafik göndereceğini label’lara bakarak belirler.
Pratik kubectl Kısayolları ve İpuçları
Günlük hayatı kolaylaştıran birkaç pratik şey paylaşayım.
Alias Tanımlama
# .bashrc veya .zshrc dosyasına ekle
alias k='kubectl'
alias kgp='kubectl get pods'
alias kgs='kubectl get services'
alias kgd='kubectl get deployments'
alias kns='kubectl config set-context --current --namespace'
# Namespace değiştirmek artık çok kolay
kns production
Bu alias’ları kurduktan sonra kubectl get pods yerine sadece kgp yazarsın. Günde yüzlerce kez kubectl kullanıyorsan bu ciddi zaman kazancı sağlar.
kubectl Autocomplete
# Bash için
echo 'source <(kubectl completion bash)' >>~/.bashrc
source ~/.bashrc
# Zsh için
echo 'source <(kubectl completion zsh)' >>~/.zshrc
source ~/.zshrc
Autocomplete kurduktan sonra komutların yarısını yazıp Tab’a basabilirsin. Pod adını hatırlamıyorsan Tab iki kez basınca listelenir.
Çıktı Formatları
# JSON formatında çıktı
kubectl get pod <pod-adı> -o json
# YAML formatında çıktı
kubectl get pod <pod-adı> -o yaml
# jsonpath ile spesifik alan çek
kubectl get pods -o jsonpath='{.items[*].metadata.name}'
# Custom columns
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName
jsonpath gerçekten güçlü bir özellik. Script yazarken Pod’ların IP adreslerini veya status’larını çekmek istediğinde çok işe yarar.
Gerçek Dünya Senaryosu: Uygulama Deployment Süreci
Tipik bir uygulama güncellemesi nasıl yapılır, adım adım gösterelim:
# 1. Mevcut durumu kontrol et
kubectl get deployments -n production
kubectl get pods -n production
# 2. Yeni image ile güncelle
kubectl set image deployment/my-app my-app=myregistry/my-app:v2.1.0 -n production
# 3. Rollout'u izle
kubectl rollout status deployment/my-app -n production
# 4. Pod'ların yeni versiyon ile ayağa kalktığını doğrula
kubectl get pods -n production -l app=my-app
# 5. Bir sorun varsa hemen geri dön
kubectl rollout undo deployment/my-app -n production
# 6. Geri dönüş başarılı mı kontrol et
kubectl rollout status deployment/my-app -n production
Bu süreci CI/CD pipeline’ına entegre ettiğinde tam otomatik deployment yapabilirsin. Jenkins, GitLab CI veya GitHub Actions’tan bu komutları çalıştırabilirsin.
Resource Quota ve Limit Yönetimi
Paylaşımlı cluster’larda namespace bazında kaynak sınırları koymak şart. Bir ekip tüm cluster’ı yutmasın diye:
# Namespace'deki resource quota'ları gör
kubectl get resourcequota -n development
# Limit range'leri gör
kubectl get limitrange -n development
# Namespace'in kaynak kullanımını özetle
kubectl describe namespace development
Resource quota ve limit range YAML’ları oluşturmak ayrı bir konu ama en azından bunların varlığını ve nasıl sorgulanacağını bilmek lazım.
Sonuç
kubectl öğrenmek bir günde bitmez ama bu yazıdaki komutlarla günlük işlerinin büyük çoğunluğunu yapabilirsin. Pod kavramı, cluster yapısı, temel YAML yazımı ve troubleshooting becerileri sağlam bir temel oluşturuyor.
Önerdiğim öğrenme yolu şu: Önce Minikube ile yerel ortam kur, basit Deployment’lar oluştur ve sil. Sonra kasıtlı olarak hatalı konfigürasyonlar yaz ve kubectl describe ile logs ile sorunu bulmayı pratik yap. Hata yapmaktan korkma, Kubernetes’te büyük çoğunlukla geri alınabilir işlemler yapıyorsun.
Bir sonraki adım olarak Service, Ingress ve ConfigMap/Secret konularına geçmeni öneririm. Bu konular uygulamanın dış dünyayla nasıl iletişim kurduğunu ve konfigürasyon yönetimini kapsar. Kubernetes’in gücü bu parçaların bir araya geldiğinde ortaya çıkıyor.
Sorular veya eklemek istediklerin varsa yorumlara yazabilirsin. Kubernetes yolculuğu uzun ama kesinlikle değer.