Ana içeriğe geç
Blog'a Dön
KubernetesDevOpsGoCloud Native
Ağaç (Tamamlanmış)

Kubernetes Operatörleri: Kendi Kontrolcünü Yazmak

2025-11-1813 dk

Kubernetes, Deployment ve Service gibi kaynaklarla stateless (durumsuz) uygulamaları yönetmek konusunda harikadır. Bir web sunucusunu ölçeklemek mi istiyorsunuz? replicas: 5 yaparsınız ve biter. Bir pod ölürse yenisi açılır, kimse fark etmez.

Ancak iş veritabanlarına, cache kümelerine veya mesaj kuyruklarına (StatefulSet) geldiğinde işler karışır. Bir PostgreSQL kümesini yönetmek, sadece pod'ları ayağa kaldırmaktan ibaret değildir.

  • Master hangisi olacak?
  • Replica'lar senkronize mi?
  • Master çökerse (Failover) kim devralacak?
  • Backup ne zaman alınacak?
  • Versiyon yükseltirken veri kaybı nasıl önlenecek?

Bu soruların cevabı "insan bilgisi" (domain knowledge) gerektirir. İşte "Operator Pattern", bu insan bilgisini koda döküp Kubernetes'e öğretme sanatıdır.

Operatör Nedir?

Operatör, Kubernetes API'sini genişleten (CRD - Custom Resource Definition) ve bu yeni kaynakları yöneten bir kontrolcüdür (Controller). Basitçe, Kubernetes'e yeni bir kelime öğretirsiniz.

Örneğin, PostgresCluster diye bir kaynak tanımlayabilir ve Kubernetes'e şunu diyebilirsiniz: "Bana 3 nodelu, versiyon 14 olan, 100GB diskli bir Postgres kümesi ver."

apiVersion: db.enginhan.com/v1
kind: PostgresCluster
metadata:
  name: main-db
spec:
  replicas: 3
  version: "14"
  storage: "100Gi"

Siz bu YAML'ı apply ettiğinizde, arka planda çalışan Operatör (sizin yazdığınız Go kodu) uyanır ve şunları yapar:

  1. Gerekli StatefulSet'i oluşturur.
  2. Service ve Secret'ları ayarlar.
  3. Pod'lar ayağa kalkınca replikasyonu konfigüre eder.
  4. Gerektiğinde backup alır.

Nasıl Çalışır? (Reconciliation Loop)

Operatör mantığı, Kubernetes'in kalbi olan basit bir döngüye dayanır: Reconciliation Loop.

  1. Observe (Gözlemle): Mevcut durum ne? (Örn: Şu an 2 pod çalışıyor)
  2. Diff (Karşılaştır): İstenen durum (Desired State) ne? (Örn: Kullanıcı 3 pod istemiş)
  3. Act (Eylem): Farkı kapat. (Örn: 1 pod daha başlat)

Bu döngü sonsuza kadar döner. Eğer biri gidip manuel olarak bir pod'u silerse, operatör bunu fark eder ve hemen yenisini açar. Sistem sürekli kendini iyileştirir (Self-healing).

Kendi Operatörünü Yazmak

Operatör yazmak için en popüler araçlar Operator SDK ve Kubebuilder'dır. Genellikle Go dili tercih edilir çünkü Kubernetes'in kendisi de Go ile yazılmıştır ve kütüphaneler çok gelişmiştir.

Adım 1: API Tanımı (CRD)

Önce veri yapımızı Go struct'ı olarak tanımlarız:

type PostgresClusterSpec struct {
    Replicas int32  `json:"replicas"`
    Version  string `json:"version"`
    Storage  string `json:"storage"`
}

type PostgresClusterStatus struct {
    ReadyReplicas int32 `json:"readyReplicas"`
    State         string `json:"state"` // "Creating", "Ready", "Failed"
}

Adım 2: Controller Mantığı

Sonra "Reconcile" fonksiyonunu yazarız. Burası beynin olduğu yerdir:

func (r *PostgresClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    log := log.FromContext(ctx)

    // 1. CRD'yi getir
    var cluster myv1.PostgresCluster
    if err := r.Get(ctx, req.NamespacedName, &cluster); err != nil {
        return ctrl.Result{}, client.IgnoreNotFound(err)
    }

    // 2. StatefulSet var mı kontrol et
    var sts appsv1.StatefulSet
    err := r.Get(ctx, req.NamespacedName, &sts)
    
    if errors.IsNotFound(err) {
        // Yoksa yarat
        sts = r.buildStatefulSet(&cluster)
        if err := r.Create(ctx, &sts); err != nil {
            return ctrl.Result{}, err
        }
        return ctrl.Result{Requeue: true}, nil
    }

    // 3. Replica sayısını kontrol et, gerekirse scale et
    if *sts.Spec.Replicas != cluster.Spec.Replicas {
        sts.Spec.Replicas = &cluster.Spec.Replicas
        if err := r.Update(ctx, &sts); err != nil {
            return ctrl.Result{}, err
        }
    }
    
    return ctrl.Result{}, nil
}

Ne Zaman Kullanmalı?

Her uygulama için operatör yazmak "Over-engineering" olabilir. Basit bir Helm chart çoğu zaman yeterlidir. Ancak:

  • Karmaşık, stateful bir uygulamanız varsa (DB, Cache, Queue),
  • Operasyonel süreçleriniz (Backup, Restore, Upgrade) manuel ve hataya açıksa,
  • Uygulamanızı "As a Service" olarak şirket içinde sunmak istiyorsanız,

Operatör yazmak, yatırım getirisini (ROI) fazlasıyla karşılar. Bu, DevOps'tan Platform Mühendisliğine geçişin en somut adımıdır.

Bağlantı Haritası

Mühendislik
Tarih
Anlatılar
Graph Loading...