Skip to content

Instantly share code, notes, and snippets.

@cemtopkaya
Created October 29, 2025 06:26
Show Gist options
  • Select an option

  • Save cemtopkaya/8d51735e13aad6e04782017de0ca911e to your computer and use it in GitHub Desktop.

Select an option

Save cemtopkaya/8d51735e13aad6e04782017de0ca911e to your computer and use it in GitHub Desktop.
Kind ile kubernetes kümesi oluşturma

💡 Kind Nedir?

Kind (Kubernetes in Docker), yerel Kubernetes kümelerini Docker kapsayıcılarını düğüm olarak kullanarak çalıştırmak için tasarlanmış hafif bir araçtır.

  • Amaç: Başlangıçta Kubernetes'in kendisini test etmek için geliştirilmiştir, ancak artık yerel geliştirme, prototip oluşturma ve CI (Sürekli Entegrasyon) ortamları için idealdir.
  • Çalışma Prensibi: Her Kind düğümü (Node), bir Docker kapsayıcısı içinde çalışır ve Kubernetes, kubeadm kullanılarak bu kapsayıcıların içinde başlatılır.
  • Avantajları:
    • Hafif ve hızlıdır; sadece Docker veya Podman gerektirir.
    • Sanal makine (VM) ek yükü olmadan doğrudan kapsayıcılarda çalışır.
    • Hızlı prototipleme ve test etme imkanı sunar.

⚙️ Kind Küme Yapısı ve Bileşenleri

Kind, Kubernetes'i yerel olarak taklit etmek için Docker'dan yararlanır:

1. Düğüm Türleri (Nodes)

Bir Kind kümesindeki her bir Kubernetes düğümü bir Docker kapsayıcısıdır.

  • Kontrol Düzlemi (Control-Plane): Kubernetes yönetim bileşenlerinin (API Sunucusu, etcd, Kontrol Yöneticisi vb.) çalıştığı ana düğüm. Kümenizin beynidir.
  • İşçi Düğümü (Worker): Uygulama kapsayıcılarınızın (Pod'larınızın) çalıştığı düğümlerdir. Gelişmiş küme yapılandırmalarında eklenebilir.

2. Kapsayıcı Çalışma Zamanı

Kind düğümleri, Pod'ları çalıştırmak için Docker'ın kendisini değil, containerd adlı bir çalışma zamanını kullanır.

  • Önemli Not: Kind düğümü içindeki görüntülere erişmek için docker images yerine crictl (veya nerdctl) kullanılmalıdır.
    • crictl images: Kind'ın kullandığı containerd içindeki görüntüleri listeler (Pod'ların görebildiği).
    • docker images: Ana bilgisayarınızdaki Docker görüntülerini listeler.

3. Gelişmiş Yapılandırma (kind: Cluster)

Özel gereksinimler için bir yapılandırma dosyası (genellikle YAML) kullanılabilir:

  • extraMounts: Kind düğümü kapsayıcısının ana bilgisayardaki bir dosyaya/sokete erişmesini sağlar. Örneğin, docker.sock dosyasını bağlamak, Kind'ın ana bilgisayardaki Docker görüntülerini görmesini sağlar.
  • extraHosts: Kapsayıcı içinden erişilebilmesi için isim-IP eşleşmeleri tanımlar.

Örnek Yapılandırma:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
    extraMounts:
      - hostPath: /var/run/docker.sock
        containerPath: /var/run/docker.sock # Host'un docker'ına erişim

🛠️ Kind Ana Komutları

Kind ile hızlıca bir küme oluşturmak, yönetmek ve görüntü yüklemek için kullanılan temel komutlar şunlardır:

1. Küme Yönetimi

Komut Açıklama
kind get clusters Yerel olarak çalışan tüm Kind kümelerini listeler.
kind create cluster --name <isim> Yeni bir Kind kümesi oluşturur (Varsayılan isim: kind).
kind create cluster --name <isim> --config=- YAML yapılandırması kullanarak gelişmiş küme oluşturur.
kind delete cluster --name <isim> Belirtilen isimdeki Kind kümesini siler.
kind get kubeconfig --name <isim> > ~/.kube/config Kümenin kubectl yapılandırmasını yeniden oluşturur.

2. Görüntü (Image) Yönetimi

Kind'ın bir görüntüyü kullanabilmesi için, bu görüntünün ana bilgisayarınızdaki Docker'dan Kind düğümlerinin içindeki containerd'e yüklenmesi gerekir.

Komut Açıklama
kind load docker-image <GÖRÜNTÜ_ADI> --name <KÜME_ADI> Ana bilgisayardaki bir Docker görüntüsünü belirtilen Kind kümesine yükler.
docker exec -it <KÜME_ADI>-control-plane crictl images Kontrol düzlemi kapsayıcısının içindeki containerd görüntülerini listeler (Kubernetes'in görebildiği görüntüler).
` docker exec -it <KÜME_ADI>-control-plane sh -c "crictl images grep " `

3. Bağlantı ve Hata Ayıklama

Komut Açıklama
docker network connect <AĞ_ADI> <KAPSAYICI_ADI> Kind kontrol düzlemi kapsayıcısını belirtilen Docker ağına bağlar (Örnek: Devcontainer ağı).
kubectl config set-cluster kind-<isim> --server=https://<KAPSAYICI_ADI>:6443 ... kubectl'ın API sunucusuyla iletişim kuracağı adresi manuel olarak ayarlar.
kubectl get pods -A Tüm ad alanlarındaki Pod'ların durumunu kontrol eder.

🌟 Kind'da Detaylı İnceleme ve Çoklu Düğüm Oluşturma

1. Çoklu Düğüm (Multi-Node) Küme Yapısı

Kind varsayılan olarak tek bir kontrol düzlemi düğümü ile gelir. Ancak gerçekçi test ortamları için birden fazla düğüm tanımlayabilirsiniz.

Çoklu düğüm yapısı, kind: Cluster yapılandırma dosyasında (YAML) nodes listesine ek girdiler ekleyerek sağlanır.

Parametre Değer Rolü Açıklama
role control-plane 1 Düğüm Kubernetes yönetim bileşenlerini barındırır.
role worker 1+ Düğüm Uygulama Pod'larının çalıştığı işçi düğümleridir.

Çoklu Düğüm Küme Örneği

Aşağıdaki YAML, bir kontrol düzlemi ve bir işçi düğümü içeren bir Kind kümesi oluşturur:

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  # --- 1. Kontrol Düzlemi Düğümü ---
  - role: control-plane
    # Opsiyonel: Ana bilgisayarın Docker soketini bağlama
    extraMounts:
      - hostPath: /var/run/docker.sock
        containerPath: /var/run/docker.sock
  
  # --- 2. İşçi Düğümü ---
  - role: worker
    # Opsiyonel: İşçi düğümüne de soketi bağlayabilirsiniz
    extraMounts:
      - hostPath: /var/run/docker.sock
        containerPath: /var/run/docker.sock

Komut: Çoklu Düğüm Kümesi Oluşturma

Bu yapılandırmayı doğrudan komut satırından kind'a besleyerek kümeyi oluşturabilirsiniz:

X_KIND_CLUSTER_NAME=multi-node-cluster
cat <<EOF | kind create cluster --name "$X_KIND_CLUSTER_NAME" --config=-
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
  - role: worker # İlk işçi düğümü
  - role: worker # İkinci işçi düğümü
EOF

Sonuç: Bu komut, ana bilgisayarınızda toplam 3 adet Docker kapsayıcısı çalıştıracaktır: multi-node-cluster-control-plane, multi-node-cluster-worker ve multi-node-cluster-worker2.

2. Gelişmiş Bağlantı ve İmaj Yönetimi Detayları

A. extraMounts Detayı (Docker Soketi Erişimi)

extraMounts kullanarak /var/run/docker.sock dosyasını Kind düğümünün içine bağlamak, düğümün ana bilgisayarın Docker servisiyle konuşmasını sağlar.

  • Neden Önemli? Eğer bir Devcontainer (VS Code Geliştirme Kapsayıcısı) kullanıyorsanız veya ana bilgisayarda yeni bir Docker imajı oluşturup hemen Kind'a yüklemek istiyorsanız bu gereklidir. Kind bu sayede ana bilgisayarda oluşturulan imajları görebilir ve yükleyebilir.

B. containerdConfigPatches (Özel Kayıt Defterleri)

Kind, görüntüleri almak için Kubernetes'in varsayılan çalışma zamanı olan containerd'ı kullanır. Özel veya güvensiz (insecure) bir Docker kayıt defteri (Registry) kullanıyorsanız, Kind düğümlerinin bu kaydı görmesi için containerdConfigPatches kullanmanız gerekir.

# ... (Kind Cluster tanımı içinde)
containerdConfigPatches:
  - |
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."nexus.telenity.com"]
      endpoint = ["http://X.X.X.X:5000"]
    [plugins."io.containerd.grpc.v1.cri".registry.configs."nexus.telenity.com".tls]
      insecure_skip_verify = true
  • Bu örnek, nexus.telenity.com adresini Kind düğümünün içindeki containerd'a tanıtır.

C. kind load docker-image Çalışma Mantığı

kind load docker-image komutu, yerel Docker'daki görüntüyü doğrudan alıp Kind kümesindeki tüm düğümlerdeki containerd çalışma zamanına yükler.

  • Bu, yerel geliştirmede kullanılan en hızlı yöntemdir ve görüntüleri uzak bir kayıt defterine itme (push) gereksinimini ortadan kaldırır.

3. kubectl Yapılandırma Detayları

Kind, küme oluşturulduğunda otomatik olarak ~/.kube/config dosyasına yeni bir bağlam (context) ekler.

  • Güvenlik Bypass'ı: Geliştirme ortamlarında, kubectl config set-cluster ... --insecure-skip-tls-verify=true komutu ile TLS sertifika doğrulamasını atlamak yaygın bir pratik olsa da, bu yalnızca yerel testler için yapılmalıdır.
  • Sertifika Sorunları (TLS Errors): Eğer bağlantı hataları alıyorsanız, API sunucusunun sertifikasının kapsadığı alan adlarını (SAN - Subject Alternative Name) kontrol edin:
    docker exec -it <KÜME_ADI>-control-plane openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout | grep -A3 "Subject Alternative Name"
    Eğer kubectl'ın erişmeye çalıştığı IP veya isim bu listede yoksa, TLS hatası alırsınız.

🔍 Sık Kullanılan Hata Ayıklama (Troubleshooting) Komutları

Sorun Kontrol Edilmesi Gereken Komut Açıklama
Pod ImagePullBackOff hatası veriyor. docker exec -it <KÜME>-control-plane crictl images Görüntünün gerçekten Kind düğümünün içinde (containerd'da) olup olmadığını kontrol edin.
Helm/kubectl yavaş veya erişilemiyor. docker network connect <AĞ_ADI> <KAPSAYICI_ADI> Kind kontrol düzlemi kapsayıcısının ana bilgisayar/devcontainer ağına bağlı olup olmadığını doğrulayın.
Uygulama Pod'ları çalışmıyor. kubectl logs <pod-adı> -n <namespace> Uygulama kapsayıcısının loglarını kontrol edin.
Düğüm (Node) durumu NotReady. kubectl get nodes Düğümlerin hazır olup olmadığını kontrol edin (Kind'ın başlatılması zaman alabilir).

Harika bir test senaryosu! Affinity ve Anti-Affinity kuralları, Pod'ların çok düğümlü bir kümedeki dağılımını veya bir araya toplanmasını sağlamak için kritik öneme sahiptir.

Aşağıda, Kind kullanarak çok düğümlü bir küme oluşturma, düğümlere özel etiketler (labels) atama ve bu etiketleri kullanarak Pod yerleşimini kontrol eden bir Helm Chart'ı test etme adımları bulunmaktadır.


🚀 Adım 1: Çok Düğümlü Kind Kümesi Oluşturma

İlk olarak, Pod'ları dağıtmak için en az iki işçi düğümü (worker node) olan bir Kind kümesi oluşturalım.

1.1. Küme Yapılandırması (multi-node-config.yaml)

Bu yapılandırma 1 Kontrol Düzlemi ve 2 İşçi Düğümü tanımlar.

# multi-node-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
    # Bu düğüme özel bir etiket ekleyelim
    labels:
      node-type: high-cpu
  - role: worker
    labels:
      node-type: high-cpu
  - role: worker
    labels:
      node-type: low-cpu # Bu düğüm diğerinden farklı olacak

1.2. Küme Oluşturma Komutu

# Küme adı
CLUSTER_NAME=affinity-test-cluster

# Mevcut kümeyi sil (opsiyonel)
kind delete cluster --name "$CLUSTER_NAME"

# Çok düğümlü kümeyi oluştur
cat <<EOF > multi-node-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
    labels:
      node-type: high-cpu
  - role: worker
    labels:
      node-type: high-cpu
  - role: worker
    labels:
      node-type: low-cpu
EOF

kind create cluster --name "$CLUSTER_NAME" --config=multi-node-config.yaml

1.3. Düğüm Etiketlerini Kontrol Etme

Kümenin oluşturulduğunu ve düğüm etiketlerinin doğru ayarlandığını doğrulayalım:

# Tüm düğümleri ve etiketlerini listele
kubectl get nodes --show-labels

Beklenen Çıktı Örneği:

İSİM ROL DURUM ETİKETLERİN BİR KISMI
affinity-test-cluster-control-plane control-plane Ready ...node-type=high-cpu
affinity-test-cluster-worker worker Ready ...node-type=high-cpu
affinity-test-cluster-worker2 worker Ready ...node-type=low-cpu

🛠️ Adım 2: Helm Chart Oluşturma ve Yapılandırma

myapp adında temel bir Helm Chart oluşturalım ve dağıtım şablonunda Affinity/Anti-Affinity ayarlarını kullanıma açalım.

# Temel chart yapısı oluşturma
helm create myapp

2.1. Deployment Şablonunu Düzenleme (myapp/templates/deployment.yaml)

Deployment'a affinity bloğunu ekleyelim ve değerleri values.yaml'dan okuyacak şekilde ayarlayalım:

# myapp/templates/deployment.yaml (Kritik kısımlar)
...
spec:
  ...
  template:
    ...
    spec:
      containers:
      ...
      {{- with .Values.affinity }}
      affinity:
        {{- toYaml . | nindent 8 }}
      {{- end }}

2.2. Values Dosyasını Düzenleme (myapp/values.yaml)

Varsayılan olarak affinity ayarını boş bırakalım.

# myapp/values.yaml (Alt kısma ekleyin)
affinity: {}

🧪 Adım 3: Affinity ve Anti-Affinity Testleri

Şimdi aynı chart'ı farklı değerlerle (farklı affinity ayarları) birden çok kez kurarak sonuçları test edelim.

Test A: Node Affinity (Zorunlu Bağlılık)

Amaç: Pod'ların mutlaka node-type: high-cpu etiketli düğümlere yerleşmesini sağlamak.

1. values.yaml Dosyası (affinity-high-cpu.yaml)

Bu yapılandırma, Pod'un node-type: high-cpu etiketi olan bir düğüme yerleşmesini zorunlu kılar (requiredDuringSchedulingIgnoredDuringExecution).

# affinity-high-cpu.yaml
replicaCount: 3

affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
        - key: node-type
          operator: In
          values:
          - high-cpu

2. Kurulum ve Kontrol Komutları

# Helm Kurulumu
helm install affinity-high-cpu myapp -f affinity-high-cpu.yaml

# Yerleşimi Kontrol Etme
kubectl get pods -o wide | grep affinity-high-cpu

Beklenen Sonuç: Tüm 3 Pod, high-cpu etiketli control-plane ve worker düğümlerine dağıtılacaktır. Hiçbir Pod low-cpu etiketli düğüme yerleşemez.

Test B: Pod Anti-Affinity (Pod Karşıtlığı)

Amaç: Pod'ların aynı düğüme yerleşmesini engellemek (yüksek erişilebilirlik).

1. values.yaml Dosyası (anti-affinity-test.yaml)

Bu yapılandırma, aynı Deployment'a ait iki Pod'un aynı düğüm üzerinde bulunmamasını tercih eder (preferredDuringSchedulingIgnoredDuringExecution).

# anti-affinity-test.yaml
replicaCount: 3

affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchLabels:
            app.kubernetes.io/name: myapp # Aynı chart'tan gelen Pod'lar
        topologyKey: kubernetes.io/hostname # Kuralı düğüm bazında uygula

2. Kurulum ve Kontrol Komutları

# Helm Kurulumu (Önceki kurulumu silin)
helm delete affinity-high-cpu

# Helm Kurulumu
helm install anti-affinity-test myapp -f anti-affinity-test.yaml

# Yerleşimi Kontrol Etme
kubectl get pods -o wide | grep anti-affinity-test

Beklenen Sonuç: 3 Pod'umuz olduğu ve 3 düğümümüz olduğu için, Pod'ların her bir düğüme birer tane olacak şekilde dağılması tercih edilecektir.

İSİM DURUM DÜĞÜM AÇIKLAMA
anti-affinity-test-pod-1 Running ...-control-plane 1. Düğümde
anti-affinity-test-pod-2 Running ...-worker 2. Düğümde
anti-affinity-test-pod-3 Running ...-worker2 3. Düğümde

Temizlik

Testleri bitirdikten sonra temizleme komutları:

# Helm sürümlerini sil
helm delete anti-affinity-test

# Kind kümesini sil
kind delete cluster --name "$CLUSTER_NAME"

Bu adımlar, Kind'ın çok düğümlü yapısını kullanarak Kubernetes zamanlayıcısının Affinity ve Anti-Affinity kurallarına nasıl uyduğunu net bir şekilde gösterir.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment