← blog · 19 Ağustos 2026

GitOps nasıl yapılır ve bir projeye ne katar

Çekme modeli itme tabanlı dağıtımdan neden farklıdır, kayma düzeltme nerede kavgaya dönüşür, depoyu dallara değil dizinlere neden bölmek gerekir, sırlar ve imaj etiketleri nasıl yönetilir, geri alma gerçekte nasıl çalışır ve GitOps'un küçük bir ekipte ne zaman aşırı mühendislik olduğu.

Bir kümede o an gerçekten ne çalıştığını sormak zorunda kalıyorsanız ve cevabı kubectl get çıktısını okuyarak arıyorsanız, dağıtım sisteminiz size gerçeği söylemiyor demektir. CI hattı aylar önce bir manifest uyguladı, biri gece yarısı replika sayısını elle artırdı, bir başkası bir ConfigMap'i düzeltti. Hiçbiri hiçbir yerde yazılı değil. GitOps'un çözmeye çalıştığı asıl problem dağıtımı otomatikleştirmek değildir, o zaten çözülmüştü. Çözdüğü şey, kümenin içindeki durumu tek ve denetlenebilir bir kaynağa bağlamaktır.

İtme ile çekmenin gerçek farkı

Klasik hatta CI işi kümeye doğru kubectl apply ya da helm upgrade çeker. Hattın küme kimlik bilgisine ihtiyacı vardır ve o kimlik çoğu zaman paylaşılan bir runner'ın ortam değişkeninde durur. Çekme modelinde ise kümenin içinde bir denetleyici çalışır, depoyu kendisi izler, kendisi uygular.

Fark üç yerde somutlaşır.

Kimliğin yönü değişir: itmede dışarıdaki bir sistemin küme üzerinde geniş yetkisi vardır. Çekmede küme dışarıya yetki vermez, yalnızca depoya okuma hakkı olan bir kimlikle çıkar. API sunucusu özel ağda duran kümelerde itme modeli ya bir VPN ya bir sıçrama makinesi gerektirir; çekmede böyle bir sorun yoktur.

İkincisi süreklilik. İtme bir olaydır; iş biter, sistem bakmaz. Çekme bir döngüdür; depo ile küme arasındaki fark her uzlaştırma turunda yeniden ölçülür.

Üçüncüsü kapsam. İtme modelinde "bu kümede olması gerekenlerin tam listesi" hiçbir yerde yoktur, yalnızca geçmişte çalışmış işlerin toplamı. Silinmesi gereken bir nesne, onu silen işi kimse yazmadıysa yıllarca ayakta kalır.

Kayma ve otomatik düzeltme

Kayma, depodaki bildirimle kümedeki nesnenin ayrışmasıdır: elle yapılan bir düzeltme, bir operatörün eklediği alan, silinmemiş bir eski nesne. Otomatik düzeltme bunu geri sarar.

Argo CD tarafında bu iki bayrağa bakar:

spec:
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

prune varsayılan olarak kapalıdır ve bunun iyi bir sebebi vardır: açıkken depodan yanlışlıkla silinen bir dosya kümeden nesne siler. Aynı sebeple, depo tamamen boşaldığında her şeyi silmeyi engelleyen bir koruma daha vardır; onu devre dışı bırakmak için allowEmpty: true yazmak gerekir. Flux tarafında .spec.prune zaten zorunlu bir alandır, yani kararı vermeden kaynağı oluşturamazsınız. Bu tasarım tercihini beğeniyorum: sessiz bir varsayılan yerine açık bir cevap ister.

Tuzak şurada: otomatik düzeltmeyi açıp kümede replika sayısını değiştiren bir yatay ölçekleyici çalıştırıyorsanız, denetleyici ile ölçekleyici birbiriyle kavga eder. Depoda replicas: 2 yazdığı sürece her ölçeklenme geri alınır. Doğru çözüm o alanı bildirimden çıkarmak ya da denetleyiciye yok saydırmaktır. Aynısı kabul denetleyicilerinin ve operatörlerin sonradan eklediği alanlar için de geçerlidir; hiç dokunulmadığı hâlde sürekli "senkron değil" gösteren bir uygulamanın sebebi genellikle budur.

Uzlaştırma sonsuz sık değildir. Argo CD'de depo yoklaması varsayılan olarak üç dakikalık bir zaman aşımına bağlıdır (argocd-cm içindeki timeout.reconciliation), Flux'ta ise aralık her kaynağın kendi interval alanında yazılıdır. İkisinde de depodan gelen bir webhook kurup gecikmeyi saniyelere indirebilirsiniz, ama yoklamayı kapatmayın: webhook kaçtığında döngünün kendisi tek güvenceniz olur.

Argo CD ve Flux aynı işi farklı yerden tutar

Argo CD uygulama merkezlidir: güçlü bir arayüz, çok kümeli tek bir kontrol düzlemi, kendi yetkilendirme ve tekil oturum katmanı. Kubernetes'e hakim olmayan geliştiricilerin de bakabileceği bir pano istiyorsanız bu tek başına belirleyici olabilir.

Flux küme yerlisidir. Arayüz yerine özel kaynak tanımları ve bir komut satırı aracı vardır; Helm, Kustomize, OCI deposu ve SOPS ile şifre çözme doğrudan içeridedir.

Ölçütüm şu: panoya insan bakacaksa ve merkezî, çok kiracılı bir yönetim istiyorsanız Argo CD; platformun kendisi de bildirimsel olsun, her şey depoda dursun istiyorsanız Flux. İkisini aynı kümede çalıştırmak mümkündür, ama iki uzlaştırıcının aynı nesneye dokunmasına asla izin vermeyin; kimin kazandığı öngörülemez.

Depo düzeni: dizin evet, dal hayır

Uygulama kodu ile bildirimler ayrı depolarda dursun. Aynı depoda tutunca imaj etiketini güncelleyen otomatik commit'ler kod hattını tetikler ve kendini besleyen bir döngü kurulur. Commit mesajına konan bir atlama işaretiyle çözenler var, ama o bant yamasıdır.

Ortamları dallarla ayırmak yaygın bir hatadır. Sebepleri sırayla:

Değişiklik terfisi cherry-pick'e döner. Bir düzeltmeyi test ortamından üretime taşırken çözmek zorunda kaldığınız çakışmalar, ortamlar arasındaki gerçek farklarla iç içe geçer. Üretime ait olmayan bir replika sayısı bir gün tam olarak böyle sızar.

Dallar zamanla birbirinden uzaklaşır. Altı ay sonra "test ile üretim arasındaki fark ne" sorusunun cevabı bir diff olmaktan çıkar, arkeolojiye döner.

Üstelik gereksizdir. Kustomize katmanları ya da Helm değer dosyaları ortam farkını ifade etmek için zaten vardır; dalları bu iş için kullanmak sürüm kontrolünü yapılandırma katmanının yerine koymaktır.

Dizin düzeni tek dalda böyle görünür:

apps/
  odeme/
    base/
    overlays/
      test/
      uretim/
infra/
  base/
  overlays/

Terfi artık tek satırlık bir diff'tir: test katmanındaki imaj etiketi üretim katmanına taşınır, gözden geçiren kişi ne değiştiğini bir bakışta görür.

Sırlar

Üç makul yol var.

Kümedeki denetleyicinin açık anahtarıyla şifrelenip depoya konan mühürlü sırlar en az bağımlılığı olan yoldur. Değeri yalnızca o kümedeki özel anahtar açar ve varsayılan kapsam adı ad alanıyla birlikte bağlar, yani şifreli metni başka bir ad alanına kopyalayıp çözemezsiniz. Bedeli şu: o anahtarın yedeği artık felaket kurtarma planınızın parçasıdır, kaybolursa depodaki bütün sırlar çöpe döner.

SOPS dosya düzeyinde şifreler ve anahtarı bir bulut anahtar servisinde ya da bir age anahtarında tutar. Flux'ta yerleşiktir, Kustomization kaynağına .spec.decryption.provider: sops yazmak yeter; Argo CD'de bir eklenti gerekir. Değeri değişmeyen satırların şifreli hâli de değişmediği için diff okunabilir kalır, ve bu küçük ayrıntı gözden geçirmede büyük fark yaratır.

Harici bir kasa ve onu kümeye taşıyan bir operatör kullanırsanız depoda yalnızca referans durur. En temiz ayrım budur; karşılığında depo tek gerçek kaynak olmaktan çıkar ve dağıtım çalışma anında bir servise daha bağımlı hâle gelir.

Küçük ve orta ekipler için SOPS ile age öneriyorum: kurulumu bir öğleden sonra sürer, kasa işletmeyi gerektirmez. Zaten kasanız varsa harici operatör doğru cevaptır. Depoya düz Secret koymak hiçbir koşulda cevap değildir; base64 kodlamadır, şifreleme değil.

İmaj etiketini kim günceller

Hareketli bir etiket GitOps'u sessizce bozar. Etiket sabit kalıp arkasındaki imaj değişirse depodaki commit ile kümede koşan ikili arasındaki bağ kopar, geri alma anlamını yitirir. Etiket ya bir sürüm ya da imaj özeti olmalı, güncellemesi de otomatik.

Flux'ta bu işi üç kaynak yapar: kayıt defterini tarayan ImageRepository, hangi etiketin seçileceğini söyleyen ImagePolicy ve seçimi depoya commit'leyen ImageUpdateAutomation. Hangi alanın güncelleneceğini dosyadaki bir yorum işaretler:

spec:
  template:
    spec:
      containers:
        - name: api
          image: registry.example.com/api:1.4.2 # {"$imagepolicy": "flux-system:api"}

Argo CD tarafında aynı işi ayrı bir bileşen, açıklama etiketleriyle yapar. Dikkat edilecek nokta yazma yöntemidir: depoya commit atanı seçin. Uygulama nesnesine doğrudan yazan yöntem daha hızlıdır ama depo artık gerçeği anlatmaz ve depoyu yeniden uyguladığınız gün etiket eski değerine döner.

Makul ayrım şu: test ortamında etiket otomatik güncellensin, üretime terfi bir çekme isteğiyle olsun. Otomasyon sıkıcı işi yapar, kararı insan verir.

Geri alma gerçekte nasıl çalışır

Geri alma bir commit'i geri almak ve uzlaştırmayı beklemektir. Kağıt üzerinde bu kadar; pratikte üç yerde tökezler.

Veritabanı göçleri geri gitmez. Bildirimi geri almak şemayı geri almaz, dolayısıyla eski sürüm yeni şemaya bakmak zorunda kalır. Tek çözüm göçleri geriye uyumlu yazmaktır: önce yeni sütunu ekleyin, sonra onu kullanan sürümü yayınlayın, eskisini ancak geri dönmeyeceğinizden emin olduğunuzda silin.

Kalıcı diskler ve durum tutan iş yükleri geri gitmez: bir StatefulSet'in bildirimini eski hâline döndürmek diskteki veriyi döndürmez.

Arayüzdeki geri alma düğmesi kümeyi eski commit'e alır ama depoyu değiştirmez. Otomatik düzeltme açıksa bir sonraki turda geri sarılır. O düğme olay anında zaman kazandırır, çözüm değildir; gerçek geri alma depoda olur.

Acil müdahalede ayak bağı olduğu an

Gece yarısı bir alanı değiştirmeniz gerekiyor, çekme isteği açıp gözden geçirme bekleyecek hâliniz yok, üstelik denetleyici elle yaptığınız değişikliği birkaç dakika içinde geri alıyor. Bu senaryoyu olay anında keşfetmeyin, önceden yazın.

Askıya alma yolu belgeli olsun. Flux'ta flux suspend kustomization <ad> bir kaynağın uzlaştırmasını durdurur, flux resume geri açar; Argo CD'de otomatik senkronu geçici kapatmak aynı işi görür. Runbook'ta yazılı değilse kimse gece yarısı hatırlamaz.

Askıya alma bir alarm doğursun. Askıda unutulmuş bir kaynak sessiz bir bombadır: haftalar sonra kimse dağıtımların neden gitmediğini anlayamaz.

Süreci kaldırmayın, kısaltın: tek onaylı ve otomatik birleşen bir acil durum çekme isteği yolu, süreci tamamen atlamaktan iyidir.

Askıdan çıkarmadan önce elle yaptığınız değişikliği depoya yazın. Yazmazsanız uzlaştırma onu geri alır ve aynı olayı ikinci kez yaşarsınız.

Ne zaman gerek yok

Üç kişilik bir ekip, tek küme, günde birkaç dağıtım. Bu tabloda GitOps size bir denetleyici, bir depo düzeni, bir şifreleme zinciri ve yeni bir arıza yüzeyi getirir. Karşılığında verdiği şeyin büyük kısmını çok daha ucuza alabilirsiniz: bildirimleri depoda tutun ve hattan uygulayın. Kayma düzeltmenin ve denetim izinin bu bedeli hak etmesi için önce kümeye birden fazla elin dokunuyor olması gerekir.

Şu üçünden ikisi doğruysa geçin: birden fazla ortam ya da küme var; kümeye üçten fazla kişi dokunuyor; kimin neyi ne zaman değiştirdiğini gösterme yükümlülüğünüz var. Değilse işin ucuz yarısıyla başlayın. Bildirimleri sürüm kontrolüne almak neredeyse bedava; sürekli uzlaştırma katmanı ise küçük ekipte çoğu zaman bakım masrafı olarak geri döner.