FluxInstance ile Cluster Profile Kullanmak

Selamlar, bu yazımda Flux Operator'un sunduğu FluxInstance kaynağı üzerinde cluster profile kavramına biraz yakından bakacağız. Birden fazla Kubernetes kümesi yönetiyorsanız hepsine ayrı ayrı Flux kurulum YAML'ı yazmanın ne kadar yorucu olduğunu biliyorsunuzdur. Dev kümesinde minimum kaynak ister, prod'da network policy ve multi-tenancy ister, OpenShift kümesinde ise SCC tarafında ayrı oyunlar dönmesi gerekir. İşte FluxInstance'ın cluster alanı tam olarak bu farkları tek bir CRD üzerinden anlamlandırıyor. Hadi başlayalım.

FluxInstance ve cluster profile nedir?

FluxInstance, Flux Operator'un Flux kurulumunu deklaratif olarak ifade eden CRD'si. Yani siz kubectl apply dediğinizde controller arka planda source-controller, kustomize-controller, helm-controller gibi component'leri kurup ayağa kaldırıyor. spec.cluster alanı ise kümenizin tipine göre bir profil seçmenizi sağlıyor: kubernetes ya da openshift. Buna ek olarak multitenant, networkPolicy, domain gibi anahtarlar var. Aslında profil dediğimiz şey tek başına bir 'preset' düğmesi değil; bu küçük bayrakların toplamı.

Kabaca iskeleti şöyle:

spec:
  cluster:
    type: kubernetes
    multitenant: false
    networkPolicy: true
    domain: cluster.local

Buradaki kritik nokta şu: type değiştiğinde sadece etiket değişmiyor, controller'ların container security context'i, RBAC ayarları ve hatta route/ingress davranışı bile profile göre değişiyor.

Distribution ve Components alanları

Profil tek başına yetmez; FluxInstance'ın iki kardeş alanı daha var. distribution Flux sürümünü ve image registry'sini söylüyor; components ise hangi controller'ların kurulacağını seçiyor. Edge bir cluster'da notification-controller'ı kaldırıp kaynak yükünü azaltmak gayet meşru bir tercih mesela.

apiVersion: fluxcd.controlplane.io/v1
kind: FluxInstance
metadata:
  name: flux
  namespace: flux-system
spec:
  distribution:
    version: '2.x'
    registry: ghcr.io/fluxcd
  components:
    - source-controller
    - kustomize-controller
    - helm-controller
    - notification-controller
  cluster:
    type: kubernetes
    networkPolicy: true
    domain: cluster.local

Bu standart bir Kubernetes profili. OpenShift'e geçtiğinizde değişen tek şey cluster.type: openshift; gerisi aynı kalıyor. AKS, EKS, GKE için ayrı bir type yok, hepsi kubernetes altında. Cloud'a özgü ihtiyaçları (örneğin GKE'de workload identity, EKS'te IRSA) kustomize.patches ile sonra ekliyoruz.

Profil ozelinde patch

Bence FluxInstance'ın asıl gücü burada. spec.kustomize.patches ile profil temelinin uzerine küme bazlı yamalar atabiliyorsunuz. Multi-tenant prod kümesinde controller argümanlarına dokunmak isteyebilirsiniz:

spec:
  cluster:
    type: kubernetes
    multitenant: true
    networkPolicy: true
  kustomize:
    patches:
      - target:
          kind: Deployment
          name: '(kustomize-controller|helm-controller)'
        patch: |
          apiVersion: apps/v1
          kind: Deployment
          metadata:
            name: all
          spec:
            template:
              spec:
                containers:
                  - name: manager
                    args:
                      - --no-cross-namespace-refs=true
                      - --default-service-account=default
                      - --watch-all-namespaces=true

--no-cross-namespace-refs=true tenant'ların başka namespace'teki kaynaklara referans vermesini engelliyor; bunu multi-tenant senaryoda neredeyse olmazsa olmaz görüyorum. Edge bir cluster'da ise patch'i resource limit'lerini kısmak için kullanırsınız; HA prod'da ise replicas: 2 ve topologySpreadConstraints koyarsınız.

Tek Git kaynagiyla coklu kume

Şimdi işin GitOps tarafına gelelim. Her küme kendi flux-instance.yaml dosyasını tek bir fleet repo'sundan çekerse, profiller versiyon kontrolünden çıkmıyor:

fleet-infra/
  clusters/
    dev/flux-instance.yaml
    staging/flux-instance.yaml
    production/flux-instance.yaml
    edge/flux-instance.yaml
    openshift-prod/flux-instance.yaml

Her küme bootstrap sırasında kendi klasörünü hedef alıyor. Aynı Git ağacı, farklı profiller. Açıkçası ben başlarda bunu Helm values ile yapmaya çalıştım, sonra FluxInstance CRD'sinin işin hem deklaratif hem de Flux'a özgü kısmını çok daha temiz çözdüğünü gördüm.

Sik karsilasilan tuzaklar

  • Profili her şey sanmak: cluster.type tek başına HA, kaynak limiti veya replica sayısı belirlemez. Onları kustomize.patches ile siz veriyorsunuz.
  • OpenShift profilinde networkPolicy unutmak: OpenShift'in kendi SDN katmanı var, ama Flux pod'ları yine de policy'siz açık kalmasın. networkPolicy: true koymadan prod'a almayın.
  • multitenant: true ile namespace bilesenlerini karistirmak: Multi-tenant açıkken her tenant kendi service account'unu kullanmalı. default-service-account=default argümanı tenant tarafında bunun istenmesini şart koşuyor.
  • Distribution sürümünü 2.x bırakıp prod'a almak: Edge ve dev'de sorun değil, ama prod kümesinde 2.4.0 gibi sabit bir sürüm pinlemek tekrarlanabilirlik için önemli.

Kapanis

FluxInstance üzerindeki cluster profile mantığı, farklı kümeleri tek bir CRD şemasıyla ifade etmenin oldukça temiz bir yolu. Bence işin sırrı cluster profilini iskelet olarak görüp asıl ince ayarı kustomize.patches ile yapmak; profili her şey sanmaya başladığınız anda Flux size hak vermeyi bırakıyor. Umarım faydalı olur, bir sonraki yazıda görüşmek üzere.