İçeriğe geç
NetDevOps
7 dk okuma DevOps

Crossplane ile Kubernetes Uzerinde Altyapi Yonetimi

Bir AWS hesabında RDS instansını biri konsoldan, biri Terraform apply ile değiştirdiyse hangisi kazançlı çıkar? Cevap ne konsol ne Terraform: kazanan, değişikliği sürekli izleyip geri çeviren kontrol düzlemi. Crossplane tam bu cümleyi ürünleştiren proje. Kubernetes cluster içine kuruluyor, dış kaynakları S3 bucket, RDS instansı, DNS kaydı, GitHub reposu ne olursa olsun custom resource olarak modelliyor ve pod gibi sürekli reconcile ediyor. 2025 Ekim ayında CNCF graduated seviyesine ulaştı, yani Kubernetes, Prometheus ve Helm ile aynı olgunluk kademesinde.

Kontrol düzlemi fikri neden farklı

Terraform çalışma modeli plan ve apply üzerine kurulu. Biri komutu çalıştırır, dünya değişir, sonra bir sonraki apply anına kadar kimse gerçeği izlemez. Aradaki süre dakikalar da olabilir aylar da. Bu boşlukta bir SRE break-glass dokunuşuyla, bir başka araç ya da insan cloud tarafında değişiklik yaptıysa buna drift deniyor ve bu drift ancak bir sonraki apply'da, o da şanslıysanız plan çıktısında görünür.

Crossplane'de apply adımı yok. İstenen durum etcd içinde yaşıyor, controller sürekli gerçek duruma doğru çekiyor. RDS instansı cluster dışında biri tarafından silinirse reconcile aralığı içinde fark edilip yeniden oluşturuluyor. Deployment pod'ları nasıl hizalı tutuyorsa Crossplane de altyapıyı aynı düzenle hizalı tutuyor. Bu davranışı bir kez kafanızda oturttuysanız gerisi konfigürasyon.

Terminoloji hızlı tur

Crossplane kurulunca crossplane-system namespace'inde pod'lar ayağa kalkıyor ve çekirdek CRD'ler geliyor: providers.pkg.crossplane.io, locks.pkg.crossplane.io gibi. Çalışma modelinin dört ana parçası var.

Provider, Kubernetes'i dış bir servise bağlayan köprü. provider-aws kurunca RDSInstance, Bucket, VPC gibi yüzlerce yeni CRD ve bunları yöneten controller'lar geliyor. Major bulutlar için resmi provider'lar Terraform provider'larından Upjet ile otomatik üretiliyor, bu yüzden API kapsamı Terraform'la büyük ölçüde eş. provider-kubernetes, provider-helm, provider-terraform gibi özel amaçlı olanları da var.

Managed resource, yani MR, provider'ın tanıdığı ham kaynak. apiVersion: rds.aws.upbound.io/v1beta1, kind: Instance yazıp kubectl apply ile gerçek bir RDS instansı alınır. Bulut konsoluna gitmeye gerek yok.

CompositeResourceDefinition yani XRD, platform ekibinin kendi API şemasını tanımladığı yer. group: database.example.org, kind: PostgreSQLInstance gibi kendi tipinizi tanımlıyorsunuz, altında hangi bulut kaynaklarının saklandığı tüketiciyi ilgilendirmiyor.

Composition, XRD ile tanımlanan soyut tipin hangi MR'ları üreteceğinin şablonu. PostgreSQLInstance isteği geldiğinde RDS instansı, security group, subnet group tek nesne altında paketleniyor. Connection detayları writeConnectionSecretsToNamespace ile belirtilen namespace'e Secret olarak yazılıyor, uygulama pod'u bunu doğrudan mount edebiliyor.

Helm ile kurulum

Resmi kurulum yolu Helm chart. Getting started dokümanındaki adımlar şu şekilde:

kubectl create namespace crossplane-system
helm repo add crossplane-stable https://charts.crossplane.io/stable
helm repo update
helm install crossplane --namespace crossplane-system crossplane-stable/crossplane

Kurulumun sağlıklı olduğunu iki komutla doğruluyorsunuz: kubectl get pods -n crossplane-system crossplane pod'unun Running olduğunu, kubectl get crds | grep crossplane.io ile de çekirdek CRD'lerin listelendiğini görmeniz lazım.

CLI tarafında kubectl plugin'i tek satırda iniyor:

curl -sL https://raw.githubusercontent.com/crossplane/crossplane/master/install.sh | sh
sudo mv kubectl-crossplane /usr/local/bin

Plugin kurulduktan sonra kubectl crossplane --help ile komut setini görebilirsiniz. AWS blog'undaki kontrol cluster rehberinde de aynı desen var: EKS üzerine Crossplane ve Argo CD kuruluyor, kontrol cluster daha sonra yönettiği workload cluster'ları ve yönetilen servisleri provision ediyor.

Bulut kimlik bilgisini bağlamak

Provider'ın bulut API'sine erişmesi için kimlik bilgisi gerekir ve bu, her zaman Secret üzerinden verilir. AWS tarafında klasik yöntem access key profilini base64 ile paketleyip credentials anahtarıyla bir Secret içine koymak, ardından ProviderConfig nesnesiyle bu Secret'a referans vermek. AWS blog'unda iki ayrı Provider nesnesi kurup aynı Secret'ı kullanıp yalnızca region alanını us-west-2 ve us-east-1 olarak değiştiren bir desen anlatılıyor: tek hesap, iki bölge, tek secret. Bol parametreli production ortamında IRSA yani EKS service account'a bağlı IAM role daha temiz bir yol, External Secrets Operator ile cluster harici bir secret store'dan çekmek de yaygın.

Somut örnek: RDS instansı

RDS instansı MR olarak şöyle görünüyor:

apiVersion: rds.aws.upbound.io/v1beta1
kind: Instance
metadata:
  name: orders
spec:
  forProvider:
    region: us-east-1
    engine: postgres
    engineVersion: "16"
    instanceClass: db.t3.medium
    allocatedStorage: 20
    dbName: orders
    username: app
    passwordSecretRef:
      namespace: crossplane-system
      name: orders-db-password
      key: password
    skipFinalSnapshot: true
  writeConnectionSecretToRef:
    namespace: crossplane-system
    name: orders-conn
  providerConfigRef:
    name: aws-provider-config

kubectl apply ile gönderiyorsunuz, controller AWS API'sini çağırıyor, instans ayağa kalkıyor, endpoint ve şifre bilgisi orders-conn Secret'ına yazılıyor. Ekranda hiç konsol açmadan db.t3.medium bir PostgreSQL kurulmuş oluyor. vpcSecurityGroupIdRefs ve dbSubnetGroupNameRef alanlarıyla ağ tarafını da aynı manifest içinde bağlarsınız, multiAz: true ve storageEncrypted: true üretim için standart seçenekler.

State dosyası derdi yok

Terraform'ta state yönetimi ayrı bir mühendislik disiplini: S3 backend, DynamoDB lock tablosu, key rotasyonu, state bozulması halinde restore senaryoları. Crossplane'de bu dosya hiç yok. State, cluster'ın etcd'si. Depolama, kilitleme resourceVersion üzerinden, yedekleme cluster yedekleme stratejinizle birlikte çözülüyor.

Bunun bedeli şeffaf: Crossplane kullanmak için bir Kubernetes cluster işletmeniz gerekiyor. İlk bucket'ınızı provision etmeden önce cluster bakımını üstlenmiş oluyorsunuz. Terraform ise tek binary, her işletim sisteminde çalışıyor. Trade-off burada net.

GitOps ile aynı hatta

Tüm altyapı Kubernetes YAML olduğu için Argo CD ve Flux ile doğal bütünleşiyor. AWS blog'undaki rehber tam bu mimariyi kuruyor: infra dizinindeki manifest'ler Argo CD uygulaması olarak cluster'a apply ediliyor, VPC, subnet, EKS cluster ve RDS hepsi Git deposunda versiyonlanıyor. Pull request review'lu, auditable değişiklik akışı elde ediyorsunuz. Crossplane ekibinin kendi karşılaştırma yazısı buna API merkezli bakıyor: Terraform bir kontrol düzlemine komut satırı arayüzü, Crossplane kendisi bir kontrol düzlemi ve REST API'si otomasyonun ortak dili.

v2 ile ne değişti

2025'te çıkan Crossplane v2 çalışma modelini ciddi değiştirdi. Composite ve managed resource'lar artık varsayılan olarak namespaced, v1'deki claim kavramı kaldırıldı. Daha önemlisi composition artık yalnızca Crossplane'in kendi MR'larını değil herhangi bir Kubernetes nesnesini compose edebiliyor: normal bir Deployment'ı bile XR içine koyabilirsiniz. Ayrıca function pipeline'ları Job gibi çalışıp belirli görevleri yapıp sonuç raporlayan Operations kavramı geldi. v1.X rehberlerini okurken bu farklara dikkat edin, claim'li eski örnekler artık geçerli değil.

Pratikte pek çok ekip ikisini birlikte kullanıyor. Terraform VPC, IAM, EKS control plane gibi temel katmanı yönetiyor, Crossplane mikroservislerin ihtiyaç duyduğu RDS, S3, SQS gibi dinamik kaynakları üst katmanda yönetiyor. Cloudkeeper'ın paylaştığı müşteri vakasında aynen bu ayrım uygulanmış: Terraform pisti döşüyor, Crossplane üzerinde uçuyor, GitOps kuleyi kontrol ediyor.

Crossplane bir kere oturunca geri dönüş zor oluyor, iyi tarafı buna ihtiyaç duymuyorsunuz da. Küçük ekip ve statik altyapıysa Terraform sizi yeterince idare eder. Pull request başına kısa ömürlü ortam, self servis veritabanı API'si, sürekli drift düzeltme gibi ihtiyaclar belirginse kontrol düzlemi tartışmasını açmanın tam zamanı.

ctCertWatch

SSL sertifika yayınlarını gerçek zamanlı takip eden bir izleme servisi. Regex filtreleme, DNS çözümleme ve webhook uyarıları ile phishing domainlerini, marka taklidini ve yetkisiz sertifikaları anında…

Rust

ipReconary

IP aralıkları, alt ağlar ve ASN bilgilerine dayalı olarak host, domain ve servis keşfi yapan bir ağ keşif (recon) aracı. Güvenlik uzmanları ve OSINT araştırmacıları için ağ altyapısını hızlı ve güveni…

Rust

Wireguard-Server-Panel

Web arayüzüne sahip, kendi sunucunuzda barındırılan bir WireGuard VPN servisi. İstemci yönetimi, mobil bağlantı için QR kod desteği, gerçek zamanlı trafik istatistikleri ve bağlantı kayıtları sunar. T…

LoadAlertTracker

Sistem yükünü neredeyse hiç kaynak tüketmeden izleyen, hafif bir servis. Belirlenen eşikler aşıldığında Telegram, Discord ve Mattermost gibi platformlara gerçek zamanlı uyarı gönderir.

Rust

Trustsslroot

Tek komutla eksiksiz bir özel PKI yapısı (Kök CA → Ara CA → sunucu ve istemci sertifikaları) oluşturan araç. Farklı formatlarda (p12/bks/jks) paketler üretir ve kullanıma hazır çıktı klasörleri sunar.

Go

DDNS-FW

Değişken IP adresini DDNS üzerinden gerçek zamanlı takip eden, hafif ve güvenilir bir araç. İzin verilen IP listelerini otomatik güncelleyerek kesintisiz erişim ve güvenlik sağlar. Tek dosyadan çalışı…

Rust

Cloudfiltred

Sunucu üzerinde 80/443 portlarına erişimi yalnızca Cloudflare IP aralıklarıyla sınırlandıran, tek dosyadan çalışan bir Linux servisi. Kendini kurar, sistem servisi olarak çalışır ve IP listelerini düz…

Rust

node_exporter

Linux için geliştirilmiş, hafif ve tek dosyadan çalışan, güvenli erişim kontrollü bir sistem metrikleri servisi.

Rust