Docker & DevOps

    GitOps ve Argo CD Nedir

    Git'i tek doğruluk kaynağı yapan dağıtım modeli ve Argo CD ile pratik kurulumu.

    10 dk okuma Güncellendi: 25 Ağustos 2026

    Bir sistemin canlıda gerçekte ne çalıştırdığını kimse tam olarak bilmiyorsa, orada bir sorun vardır. Üç ay önce birinin acil bir düzeltme için elle değiştirdiği bir ayar, kimsenin haberi olmadan hâlâ oradadır; bir sonraki dağıtım o ayarı sessizce ezer ve gece yarısı kimse neyin değiştiğini açıklayamaz. GitOps nedir sorusunun en kısa cevabı budur: sistemin olması gereken hâlini Git'te tutmak ve gerçek durumu sürekli o hâle yaklaştırmak.

    Bu rehberde GitOps'un klasik CI/CD'den hangi noktada ayrıldığını, itme (push) yerine çekme (pull) modelinin neden daha güvenli olduğunu ve sürüklenme (drift) tespitinin ne işe yaradığını anlatacağım. Argo CD'yi kuracak, bir Application tanımı yazacak, senkronizasyon politikalarını ayarlayacak ve depo yapısını nasıl kuracağını göreceğiz. Sonunda gizli bilgi yönetimi gibi GitOps'un en çetrefil konusunu ve en sık düşülen tuzakları konuşacağız.

    GitOps'un Dört İlkesi#

    GitOps bir ürün değil, bir çalışma biçimidir ve dört ilkeye dayanır. Bunları anlamadan Argo CD kurmak, aracı bir dağıtım düğmesine indirger.

    Bildirimsel tanım. Sistemin istenen hâli, adım adım komutlarla değil, bildirimsel dosyalarla tanımlanır. "Şu konteyneri başlat, sonra şu portu aç" değil; "bu uygulamanın 3 kopyası, şu imajla, şu kaynak sınırlarıyla çalışıyor olmalı" dersin. Aradaki fark, bildirimsel tanımın arzu edilen durum olmasıdır; nasıl oraya gidileceği aracın işidir.

    Versiyonlanmış ve değişmez kaynak. Bu tanım Git'te durur. Yani her değişikliğin bir yazarı, bir zamanı, bir açıklaması ve bir inceleme kaydı vardır. Geri alma, git revert kadar basittir.

    Otomatik çekme. Bir ajan kümenin içinde çalışır, depoyu düzenli olarak okur ve değişikliği kendisi uygular. CI sistemine kümenin anahtarı verilmez.

    Sürekli uzlaştırma. Ajan yalnızca değişiklik anında değil, sürekli olarak gerçek durumu istenen durumla karşılaştırır. Biri elle bir ayarı değiştirdiyse bunu fark eder, raporlar ve istersen otomatik olarak geri alır.

    KonuKlasik CI/CD (push)GitOps (pull)
    Dağıtımı kim başlatırCI işi dışarıdan uygularKüme içindeki ajan çeker
    Küme kimlik bilgisiCI sisteminde dururKümeden çıkmaz
    Elle yapılan değişiklikFark edilmezSürüklenme olarak raporlanır
    Geri almaYeni bir iş çalıştırılırgit revert yeter
    Canlının gerçek hâliBilinmez, tahmin edilirDepoda yazılıdır
    Denetim kaydıCI günlükleriGit geçmişi

    Bu tablodaki "küme kimlik bilgisi" satırı, GitOps'un en az konuşulan ama en somut güvenlik kazancıdır. Klasik modelde CI sisteminin canlı ortama yazma yetkisi vardır; CI hesabı ele geçirilirse canlı da düşer. Çekme modelinde ajan dışarıya bağlantı açar, dışarıdan bağlantı kabul etmez.

    Argo CD Kurulumu#

    Argo CD bir Kubernetes kümesine kurulur ve depodaki bildirimleri kümeye uygular. Kurulum tek komuttur:

    # Kendi ad alanını oluştur ve kararlı sürümü kur
    kubectl create namespace argocd
    kubectl apply -n argocd \
      -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
    
    # Tüm bileşenlerin hazır olmasını bekle
    kubectl wait --for=condition=available --timeout=300s \
      deployment --all -n argocd
    

    İlk giriş parolası bir gizli nesnede tutulur ve kurulumdan hemen sonra değiştirilmelidir:

    # Başlangıç admin parolasını oku
    kubectl -n argocd get secret argocd-initial-admin-secret \
      -o jsonpath="{.data.password}" | base64 -d; echo
    
    # Arayüze yerelden eriş
    kubectl port-forward -n argocd svc/argocd-server 8080:443
    
    # CLI ile giriş yap ve parolayı hemen değiştir
    argocd login localhost:8080 --username admin --insecure
    argocd account update-password
    

    Arayüzü kalıcı olarak dışarı açacaksan mutlaka gerçek bir TLS sertifikası, kimlik doğrulama ve mümkünse IP kısıtı koy; Argo CD kümenin tamamına yazma yetkisine sahiptir, dolayısıyla ele geçirilmesi tüm ortamın ele geçirilmesi demektir. Önüne konacak bir ters proxy ve SSL sertifikası bu kurulumun asgari şartıdır; saldırı yüzeyini daraltmak için WAF katmanı da mantıklı bir ek olur.

    Application Tanımı ve Senkronizasyon Politikaları#

    Argo CD'de her uygulama bir Application kaynağıyla tanımlanır. Bu kaynak üç şeyi söyler: bildirimler nerede, hangi kümeye ve hangi ad alanına uygulanacak, ve senkronizasyon nasıl davranacak.

    apiVersion: argoproj.io/v1alpha1
    kind: Application
    metadata:
      name: siparis-api-prod
      namespace: argocd
      finalizers:
        # Application silinince kaynakları da temizle
        - resources-finalizer.argocd.argoproj.io
    spec:
      project: default
    
      source:
        repoURL: https://github.com/firmaniz/altyapi.git
        targetRevision: main          # asla 'HEAD' değil, açık bir dal veya etiket
        path: ortamlar/prod/siparis-api
    
      destination:
        server: https://kubernetes.default.svc
        namespace: siparis
    
      syncPolicy:
        automated:
          prune: true                 # depodan silinen kaynağı kümeden de sil
          selfHeal: true              # elle yapılan değişikliği geri al
          allowEmpty: false           # boş bildirim seti her şeyi silmesin
        syncOptions:
          - CreateNamespace=true
          - PrunePropagationPolicy=foreground
        retry:
          limit: 5
          backoff:
            duration: 10s
            factor: 2
            maxDuration: 3m
    

    Buradaki üç ayar davranışı tamamen belirler ve dikkatli seçilmelidir:

    • prune: true — depodan bir dosyayı sildiğinde ilgili kaynak kümeden de silinir. Kapalıysa depo ile küme zamanla ayrışır ve kimsenin bilmediği artık kaynaklar birikir. Açıkken ise yanlışlıkla silinen bir dosya canlı bir servisi düşürebilir; bu yüzden allowEmpty: false bir emniyet kemeridir.
    • selfHeal: true — biri kümede elle değişiklik yaparsa Argo CD bunu geri alır. GitOps'un asıl vaadi budur ama ilk kurulumda kapalı başlatmak, ekibin alışkanlıklarını görmek açısından mantıklıdır.
    • targetRevisionHEAD yerine açık bir dal ya da etiket yaz. Canlı ortamda etiket kullanmak, hangi sürümün çalıştığını tartışmasız hâle getirir.

    Senkronizasyonu elle tetiklemek ve durumu görmek için:

    # Uygulamanın durumunu gör (Synced / OutOfSync, Healthy / Degraded)
    argocd app get siparis-api-prod
    
    # Elle senkronize et
    argocd app sync siparis-api-prod
    
    # Depo ile küme arasındaki farkı göster
    argocd app diff siparis-api-prod
    
    # Bir önceki sürüme dön
    argocd app history siparis-api-prod
    argocd app rollback siparis-api-prod 12
    

    argocd app diff çıktısı, GitOps'un günlük hayatta en çok kullanılan komutudur: canlının depodan nerede ayrıldığını satır satır gösterir.

    Depo Yapısı ve Ortam Ayrımı#

    GitOps'ta en çok tartışılan konu depo yapısıdır. Yaygın ve sağlam yaklaşım, uygulama kodu ile altyapı bildirimlerini ayrı depolarda tutmaktır. Sebebi pratiktir: aynı depoda tutarsan, CI imajı derleyip bildirimdeki etiketi güncellediğinde yeni bir commit oluşur, o commit yeni bir CI çalışması tetikler ve sonsuz döngüye girersin.

    altyapi/                        # bildirimler deposu
    ├── temel/                      # tüm ortamlarda ortak taban
    │   └── siparis-api/
    │       ├── deployment.yaml
    │       ├── service.yaml
    │       └── kustomization.yaml
    └── ortamlar/
        ├── staging/
        │   └── siparis-api/
        │       ├── kustomization.yaml   # temeli çağırır
        │       └── yamalar.yaml         # kopya sayısı, kaynak, imaj etiketi
        └── prod/
            └── siparis-api/
                ├── kustomization.yaml
                └── yamalar.yaml
    

    Ortam farkları yama (patch) olarak tutulur; taban tanım tek yerde kalır:

    # ortamlar/prod/siparis-api/kustomization.yaml
    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    namespace: siparis
    
    resources:
      - ../../../temel/siparis-api
    
    images:
      - name: registry.firmaniz.com/siparis-api
        newTag: a1b2c3d          # CI bu satırı günceller
    
    replicas:
      - name: siparis-api
        count: 3
    
    patches:
      - path: yamalar.yaml
    

    Bu yapı, dev, staging ve prod ortam ayrımı yazısındaki "aynı kod, farklı yapılandırma" ilkesinin bildirimsel karşılığıdır. Terfi akışı da orada anlattığım mantığın aynısıdır: CI bir kez imaj üretir, staging klasöründeki etiketi günceller, onaydan sonra aynı etiket prod klasörüne taşınır. Yeniden derleme yoktur, dolayısıyla test edilen artefaktla canlıya giden birebir aynıdır. İmajın kendisini küçük ve yeniden üretilebilir tutmak için Dockerfile en iyi pratikler yazısındaki katman kuralları hâlâ geçerlidir.

    Gizli Bilgiler: GitOps'un En Zor Konusu#

    "Her şey Git'te" ilkesinin doğal sonucu şudur: veritabanı parolası da Git'te mi duracak? Kubernetes'in Secret nesnesi yalnızca base64 ile kodlanmıştır, şifrelenmiş değildir; olduğu gibi depoya koymak, parolayı düz metin yazmakla neredeyse aynıdır. Bu yanlış anlama, GitOps kurulumlarında gördüğüm en tehlikeli hatadır.

    Üç makul yaklaşım vardır:

    1. Şifrelenmiş gizli nesneler. Değeri, yalnızca kümedeki bir anahtarla çözülebilecek biçimde şifreleyip depoya koyarsın. Depoyu okuyan biri değeri çözemez, küme çözebilir.
    2. Harici gizli bilgi yöneticisi. Gerçek değer bir kasada durur; depoda yalnızca "şu kasadaki şu anahtarı al" diyen bir referans nesnesi bulunur. En temiz yol budur.
    3. Küme dışı bir yolla enjekte etmek. Gizli nesneleri GitOps akışının dışında, elle ya da ayrı bir otomasyonla oluşturursun. Basit ama denetim kaydı zayıftır.

    Hangisini seçersen seç, iki kural değişmez: düz metin gizli bilgi asla depoya girmez ve her ortamın kendi değerleri olur. Bir kez düz metin girdiyse, o değer artık yanmıştır — dosyayı silmek yetmez, Git geçmişinde durur ve parolayı döndürmen gerekir. Bu kazanın nasıl gerçekleştiğini ve ne yapılması gerektiğini .git klasörü ve .env dosyası ifşası yazısında ayrıntılı anlattım. Yeni ve güçlü değerler üretmek için şifre üretici aracımızı kullanabilirsin.

    Sık Yapılan Hatalar ve GitOps'a Ne Zaman Geçmemeli#

    Kümede elle değişiklik yapmaya devam etmek. kubectl edit ile yapılan bir düzeltme, selfHeal açıkken dakikalar içinde geri alınır ve "değişikliğim neden kayboldu" şaşkınlığı yaratır. Kapalıysa daha kötüsü olur: depo ile küme sessizce ayrışır. Kural nettir — değişiklik depoya yazılır, kümeye değil.

    targetRevision: HEAD kullanmak. Bu, "ana dalın o anki hâli" demektir; birinin gece attığı bir commit istemeden canlıya gider. Canlı ortamda açık bir etiket kullan.

    Uygulama kodu ve bildirimleri aynı depoda tutmak. Yukarıda anlattığım döngü sorununun yanı sıra, altyapı değişikliği için kod deposuna erişim vermek zorunda kalırsın. İki depo, iki farklı inceleme akışı demektir.

    prune ayarını düşünmeden açmak. Depodan bir dosyayı yanlışlıkla silmek, prune: true ile birlikte canlı bir servisi silmek anlamına gelir. allowEmpty: false ve dikkatli inceleme bunun tek savunmasıdır.

    Argo CD'yi izlemeyi unutmak. Ajan çalışmıyorsa depoya yazdığın değişiklik hiçbir yere gitmez ve bunu ancak "neden dağıtılmadı" diye bakarken fark edersin. Uygulama durumlarını ve senkronizasyon başarısızlıklarını bir bildirim kanalına bağlamak şarttır.

    Son olarak dürüst bir uyarı: GitOps'un anlamlı olduğu yer, bildirimsel bir hedef sistemin bulunduğu ortamlardır ve pratikte bu çoğunlukla Kubernetes demektir. Tek sunucuda Docker Compose ile çalışan bir uygulama için Argo CD kurmak, çözdüğünden fazla karmaşıklık getirir. O ölçekte aynı disiplini çok daha ucuza elde edebilirsin: yapılandırmayı Git'te tut, dağıtımı Makefile ile görev otomasyonu hedeflerine bağla ve sunucuda elle değişiklik yapmama kuralını uygula. GitOps'un asıl değeri araçta değil, bu disiplindedir.

    Sıkça Sorulan Sorular#

    GitOps ile CI/CD arasındaki fark nedir#

    CI/CD, kodun derlenip test edilmesinden dağıtılmasına kadar olan sürecin tamamıdır ve dağıtımı genellikle dışarıdan iterek yapar. GitOps ise yalnızca dağıtım kısmına odaklanır ve bunu tersine çevirir: kümenin içindeki bir ajan depoyu okuyup değişikliği kendisi çeker. İkisi rakip değildir; tipik bir kurulumda CI imajı üretir ve bildirimdeki etiketi günceller, GitOps ajanı da bu değişikliği kümeye uygular.

    Argo CD ücretsiz mi#

    Evet, Argo CD Apache 2.0 lisanslı açık kaynaklı bir projedir ve kendi kümene kurup kullanman ücretsizdir. Lisans maliyeti yoktur; maliyet, çalıştığı kümenin kaynaklarından ve bakımından gelir. Ticari destek ya da yönetilen sürüm sunan sağlayıcılar varsa da temel kurulum için hiçbirine ihtiyacın yoktur.

    Argo CD Kubernetes olmadan çalışır mı#

    Hayır, Argo CD Kubernetes kaynaklarını yönetmek üzere tasarlanmıştır ve bir küme gerektirir. Tek sunucuda Docker ya da Docker Compose ile çalışan bir kurulum için uygun değildir. O ölçekte aynı ilkeleri uygulamak istiyorsan, yapılandırmayı Git'te tutup sunucuda düzenli olarak depoyu çeken ve değişiklikleri uygulayan basit bir otomasyon kurabilirsin; kazanç aynı disiplinden gelir.

    Sürüklenme (drift) tespiti tam olarak ne yapar#

    Argo CD, depodaki istenen durum ile kümedeki gerçek durumu sürekli karşılaştırır. İkisi ayrıştığında uygulamayı OutOfSync olarak işaretler ve farkı satır satır gösterir. selfHeal açıksa farkı otomatik olarak geri alır, kapalıysa yalnızca raporlar ve kararı sana bırakır. Bu mekanizma, kimsenin haberi olmadan yapılan elle değişikliklerin aylarca gizli kalmasını engeller.

    Gizli bilgileri Git'te tutmak güvenli mi#

    Düz metin ya da yalnızca base64 ile kodlanmış hâlde tutmak kesinlikle güvenli değildir; base64 şifreleme değil, kodlamadır ve saniyeler içinde çözülür. Güvenli yollar, değeri yalnızca kümenin çözebileceği biçimde şifreleyip depoya koymak ya da gerçek değeri harici bir kasada tutup depoda sadece referans bulundurmaktır. Bir kez düz metin girdiyse, dosyayı silmek yetmez; değer Git geçmişinde kalır ve mutlaka döndürülmelidir.

    GitOps'a geçmek ne kadar sürer#

    Mevcut kurulumun bildirimsel olup olmadığına bağlıdır. Zaten Kubernetes bildirimleriyle çalışıyorsan Argo CD'yi kurup ilk uygulamayı bağlamak birkaç saatlik iştir. Asıl zaman, elle yapılmış tüm değişiklikleri tespit edip depoya yazmaya ve ekibin "kümeye elle dokunmama" alışkanlığını kazanmasına gider. Tek uygulamayla başlayıp kademeli ilerlemek, her şeyi bir hafta sonunda taşımaya çalışmaktan çok daha sağlıklıdır.

    Kapanış#

    GitOps, dağıtımı bir düğmeye basmaktan çıkarıp bir depo durumuna dönüştürür ve bunun en büyük kazancı hız değil, belirliliktir: canlının ne çalıştırdığını okuyabildiğin bir yer olur. Aklında tutman gereken dört alışkanlık şu: bildirimleri uygulama kodundan ayrı bir depoda tut, targetRevision olarak açık bir etiket kullan, gizli bilgileri asla düz metin koyma ve kümeye elle dokunma kuralını istisnasız uygula.

    Bu modeli çalıştıracak bir küme, öngörülebilir kaynak ve tam yetki ister. Kendi düğümlerini kurmak için bulut sunucu ve VDS paketlerimize, birden fazla sanal makineyi aynı altyapıda çalıştırmak isterseniz nested sanallaştırma seçeneğimize göz atabilirsiniz. Kurulum ve bakım yükünü devretmek isterseniz sunucu yönetimi hizmetimiz bu işi üstlenir.

    GitOpsArgo CDKubernetes

    Uygulamaya geçmeye hazır mısınız?

    NVMe SSD, ücretsiz SSL ve %99.9 uptime garantisiyle Clou.TR hosting ve sunucu çözümleriyle projenizi hayata geçirin.