Produkty Poradenství O nás Blog Kontakt English
arrow_back Zpět na blog

Nahrazení Flux Bootstrap operátorem Flux: GitOps na autopilota

Nahrazení Flux Bootstrap operátorem Flux: GitOps na autopilota

Správa Flux CD v produkci dříve znamenala spuštění flux bootstrap, commitnutí stovek řádků generovaného YAML a manuální koordinaci upgradů napříč clustery. S Flux Operátorem je toto vše nahrazeno jediným Kubernetes custom resource — FluxInstance — který deklaruje celou vaši Flux instalaci jako kód.

V tomto článku projdeme, jak jsme migrovali z tradičního Flux bootstrap přístupu na Flux Operator na GKE Autopilot clusteru, celé řízeno Terraformem.

Co je Flux Operator?

Flux Operator

Flux Operator je Kubernetes controller vyvinutý společností ControlPlane, který spravuje životní cyklus instalací Flux CD. Místo bootstrapování Fluxu přes CLI (které generuje a commituje gotk-components.yaml a gotk-sync.yaml do vašeho repozitáře) nainstalujete operátor jednou a pak deklarujete FluxInstance custom resource popisující, co chcete.

Operátor zajišťuje:

  • Instalaci všech Flux controllerů (source, kustomize, helm, notification, image reflector, image automation)
  • Upgrady — změňte verzi ve FluxInstance spec a operátor provede rollout nové Flux distribuce
  • Konfiguraci — síťové politiky, multi-tenancy, dešifrování secretů, limity zdrojů a Kustomize patche jsou součástí CRD
  • Vestavěné webové UI — lehký, mobilní dashboard pro monitoring vašich GitOps pipeline

Představte si to jako rozdíl mezi imperativním spuštěním apt install a deklarací balíčku v Nix flake. Flux Operator dělá samotný Flux GitOps-řízeným.

Odkazy:

Co je Flux CD?

Pro ty, kdo neznají — Flux CD je CNCF Graduated GitOps toolkit pro Kubernetes. Kontinuálně srovnává stav vašeho clusteru s deklaracemi uloženými v Git repozitáři. Když pushnete změnu do vašeho GitOps repo, Flux ji detekuje a aplikuje na cluster — žádné kubectl apply není potřeba.

Flux se skládá ze specializovaných controllerů:

ControllerÚčel
source-controllerStahuje manifesty z Git repozitářů, Helm chartů, OCI artefaktů a S3 bucketů
kustomize-controllerAplikuje Kustomize overlays a plain YAML na cluster
helm-controllerSpravuje životní cyklus HelmRelease (install, upgrade, rollback, test)
notification-controllerOdesílá alerty do Slacku, Teams, webhooků a přijímá webhooky od Git providerů
image-reflector-controllerSkenuje container registry pro nové image tagy
image-automation-controllerAutomaticky commituje nové image tagy zpět do GitOps repo

Flux graduoval z CNCF v listopadu 2022, čímž se zařadil po bok Kubernetes, Prometheus a Helm.

Odkazy:

Problém s Flux Bootstrap

Tradiční způsob instalace Fluxu je flux bootstrap github. Ten generuje dva soubory commitnuté do vašeho GitOps repo:

  • gotk-components.yaml — ~660KB soubor obsahující všechny Flux controller manifesty, CRDs, RBAC pravidla a namespaces
  • gotk-sync.yaml — GitRepository + Kustomization, který ukazuje Flux na sebe sama

Funguje to, ale má to nevýhody:

  1. Masivní generované souborygotk-components.yaml je 660KB YAML, který nikdy needitujete, ale vždy diffujete
  2. Imperativní upgrady — pro upgrade Fluxu znovu spustíte flux bootstrap, který přegeneruje components soubor a vytvoří commit
  3. Žádná deklarativní konfigurace — dešifrování secretů, limity zdrojů a patche vyžadují manuální Kustomize overlays nad generovanými soubory
  4. Těžko řiditelné s Terraformem — bootstrap proces je navržen pro CLI použití, ne pro infrastructure-as-code

Instalace Flux Operátoru s Terraformem

Celý Flux setup balíme jako znovupoužitelný Terraform modul (modules/flux-operator/), který řeší čtyři záležitosti: namespace, secrety, samotný operátor a FluxInstance deklaraci. Zde je průchod každým resource a proč existuje.

Krok 1: Namespace a secrety

Nejprve modul vytvoří namespace flux-system a dva Kubernetes secrety — jeden pro přístup ke Git repozitáři a volitelně jeden pro SOPS dešifrování:

HCL
# Namespace kde žijí všechny Flux komponenty
resource "kubernetes_namespace" "flux_system" {
  metadata {
    name = "flux-system"
  }

  lifecycle {
    # Flux controllery přidávají vlastní labels/annotations — nebojujte s nimi
    ignore_changes = [metadata[0].labels, metadata[0].annotations]
  }
}

# Git SSH přihlašovací údaje — source-controller je používá pro pull z GitOps repo
resource "kubernetes_secret" "flux_system" {
  metadata {
    name      = "flux-system"
    namespace = kubernetes_namespace.flux_system.metadata[0].name
  }

  data = {
    "identity"     = var.git_ssh_key      # SSH privátní klíč (sensitive)
    "identity.pub" = var.git_ssh_key_pub  # SSH veřejný klíč
    "known_hosts"  = var.known_hosts      # GitHub SSH host key fingerprint
  }

  type = "Opaque"
}

# SOPS age klíč pro dešifrování secretů v Gitu (volitelný)
resource "kubernetes_secret" "sops_age" {
  count = var.age_key != "" ? 1 : 0

  metadata {
    name      = "sops-age"
    namespace = kubernetes_namespace.flux_system.metadata[0].name
  }

  data = {
    "age.agekey" = var.age_key  # Age privátní klíč (sensitive)
  }

  type = "Opaque"
}

lifecycle.ignore_changes na namespace je důležitý — Flux controllery přidávají labels a annotations během reconciliace, a bez této direktivy by se Terraform při každém apply pokoušel je odebrat, čímž by vznikla nekonečná smyčka driftu.

SOPS secret je podmíněně vytvořen (count = var.age_key != "" ? 1 : 0), takže prostředí bez šifrovaných secretů nemusí poskytovat age klíč.

Krok 2: Instalace operátoru přes Helm

Flux Operator je distribuován jako OCI Helm chart. Jeden helm_release nainstaluje CRDs operátoru a controller:

HCL
resource "helm_release" "flux_operator" {
  name       = "flux-operator"
  repository = "oci://ghcr.io/controlplaneio-fluxcd/charts"
  chart      = "flux-operator"
  namespace  = kubernetes_namespace.flux_system.metadata[0].name
  version    = var.flux_operator_version  # Připněte na otestovanou verzi
  wait       = true  # Počkejte na CRDs před pokračováním

  # Povolení vestavěného Web UI
  set {
    name  = "web.enabled"
    value = var.web_ui_enabled ? "true" : "false"
  }

  depends_on = [kubernetes_namespace.flux_system]
}

Nastavení wait = true je kritické — další resource vytváří FluxInstance custom resource a CRD musí existovat dříve, než ho Terraform může aplikovat. Bez wait by Terraform předběhl a selhal s chybou “no matches for kind FluxInstance”.

Krok 3: Deklarace FluxInstance

Toto je srdce modulu. Jediný kubectl_manifest resource deklaruje vše o vaší Flux instalaci — které controllery spustit, odkud synchronizovat a jak je nakonfigurovat:

HCL
resource "kubectl_manifest" "flux_instance" {
  yaml_body = <<-YAML
    apiVersion: fluxcd.controlplane.io/v1
    kind: FluxInstance
    metadata:
      name: flux
      namespace: flux-system
    spec:
      distribution:
        version: "${var.flux_version}"
        registry: "ghcr.io/fluxcd"
      components:
        - source-controller
        - kustomize-controller
        - helm-controller
        - notification-controller
        - image-reflector-controller
        - image-automation-controller
      cluster:
        type: kubernetes
        size: small
        multitenant: false
        networkPolicy: true
        domain: "cluster.local"
      sync:
        kind: GitRepository
        url: "ssh://git@github.com/${var.github_owner}/${var.github_repository}.git"
        ref: "refs/heads/${var.github_branch}"
        path: "clusters/${var.cluster_name}"
        pullSecret: "flux-system"
      kustomize:
        patches:
          # SOPS dešifrování pro všechny Kustomizations
          - patch: |
              - op: add
                path: /spec/decryption
                value:
                  provider: sops
                  secretRef:
                    name: sops-age
            target:
              kind: Kustomization
          # GKE Autopilot vyžaduje seccompProfile na všech podech
          - patch: |
              - op: add
                path: /spec/template/spec/securityContext
                value:
                  seccompProfile:
                    type: RuntimeDefault
            target:
              kind: Deployment
          # Správné dimenzování resource requests controllerů
          - patch: |
              apiVersion: apps/v1
              kind: Deployment
              metadata:
                name: source-controller
              spec:
                template:
                  spec:
                    containers:
                      - name: manager
                        resources:
                          requests:
                            cpu: 20m
                            memory: 32Mi
            target:
              kind: Deployment
              name: source-controller
          # ... podobné patche pro každý controller
  YAML

  depends_on = [
    helm_release.flux_operator,
    kubernetes_secret.sops_age,
    kubernetes_secret.flux_system
  ]
}

Používáme gavinbunney/kubectl provider místo kubernetes_manifest, protože spolehlivěji zvládá CRD-based resources — kubernetes_manifest vyžaduje existenci CRD v době plánování, což vytváří problém slepice a vejce, když je CRD instalováno Helm chartem ve stejném apply.

Řetězec depends_on zajišťuje správné pořadí: nejdříve namespace, pak secrety, pak Helm chart (který nainstaluje CRD) a nakonec FluxInstance, který je všechny využívá.

Několik poznámek k sekci sync:

  • path: "clusters/${var.cluster_name}" — každý cluster má vlastní adresář v GitOps repo. Toto je standardní Flux pattern pro multi-cluster setupy.
  • pullSecret: "flux-system" — odkazuje na SSH secret vytvořený v Kroku 1. Source-controller ho používá k autentizaci s GitHubem.
  • ref: "refs/heads/${var.github_branch}" — typicky main v produkci. Staging cluster můžete nasměrovat na jinou větev pro testování GitOps změn před nasazením do produkce.

Krok 4: Propojení dohromady

Kořenová Terraform konfigurace vyvolává modul podmíněně:

HCL
module "flux_operator" {
  source = "./modules/flux-operator"
  count  = var.enable_flux ? 1 : 0

  cluster_name      = var.cluster_name
  github_owner      = var.github_owner
  github_repository = var.github_repository
  github_branch     = var.github_branch
  git_credentials   = var.git_credentials
  web_ui_enabled    = true

  depends_on = [module.gke]
}

depends_on = [module.gke] je nezbytné — modul potřebuje funkční Kubernetes cluster a platné přihlašovací údaje, než může vytvářet namespaces a instalovat Helm charty.

Přepínač count = var.enable_flux ? 1 : 0 umožňuje vypnout GitOps pro konkrétní prostředí (např. dev cluster, který ještě nemá odpovídající adresář v GitOps repo).

Co se stane při terraform apply

Celá sekvence:

Text
terraform apply
  1. module.gke vytvoří Kubernetes cluster
  2. module.flux_operator vytvoří:
     a. flux-system namespace
     b. Git SSH credentials secret
     c. SOPS age key secret (pokud je poskytnut)
     d. Helm release: flux-operator (nainstaluje CRDs + operátor pod)
     e. FluxInstance CR (operátor ho přečte a nasadí 6 Flux controllerů)
  3. Flux source-controller naklonuje GitOps repo přes SSH
  4. Flux kustomize-controller přečte clusters/<name>/kustomization.yaml
  5. Všechna odkazovaná infrastruktura a aplikace jsou srovnány na cluster

Od studeného startu po plně GitOps-řízený cluster v jediném terraform apply. Následné změny clusteru se provádějí pushnutím do GitOps repo — Terraform spravuje pouze samotnou Flux instalaci, ne workloady.

Správa secretů v GitOps

Jednou z prvních otázek při adopci GitOps je: jak ukládáte secrety v Gitu? Nemůžete commitovat plaintext Kubernetes Secrets, ale zároveň chcete mít celý stav clusteru verzovaný. Sekce kustomize.patches ve FluxInstance usnadňuje napojení jakéhokoli poskytovatele dešifrování.

Možnost 1: SOPS + age (Co používáme my)

Mozilla SOPS šifruje YAML hodnoty na místě, nechává klíče a strukturu čitelné, zatímco šifruje hodnoty. V kombinaci s age pro správu klíčů je to nejjednodušší přístup — žádná externí infrastruktura není potřeba.

Jak to funguje:

  1. Vygenerujte age key pair:

    Bash
    age-keygen -o age.agekey
    # Public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
  2. Zašifrujte secrety před commitnutím:

    Bash
    sops --age=age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p \
         --encrypt --in-place secret.yaml
  3. Uložte privátní klíč jako Kubernetes secret:

    HCL
    resource "kubernetes_secret" "sops_age" {
      metadata {
        name      = "sops-age"
        namespace = "flux-system"
      }
      data = {
        "age.agekey" = var.age_private_key  # Z Terraform proměnných (sensitive)
      }
    }
  4. Řekněte Fluxu, aby dešifroval přes SOPS — přes kustomize patche FluxInstance:

    YAML
    kustomize:
      patches:
        - patch: |
            - op: add
              path: /spec/decryption
              value:
                provider: sops
                secretRef:
                  name: sops-age
          target:
            kind: Kustomization

Flux kustomize-controller dešifruje za běhu během reconciliace. Git repo obsahuje pouze zašifrované hodnoty.

Výhody: Nulové externí závislosti, funguje offline, snadný audit, klíče jsou jen soubory. Nevýhody: Distribuce klíčů je manuální (musíte dostat age privátní klíč do každého clusteru), žádná automatická rotace klíčů.

SOPS také podporuje AWS KMS, GCP KMS, Azure Key Vault a HashiCorp Vault jako backendy klíčů — takže můžete používat age pro vývoj a cloud KMS v produkci.

Možnost 2: HashiCorp Vault + External Secrets Operator

Pro organizace, které již provozují HashiCorp Vault, External Secrets Operator (ESO) propojuje Vault a Kubernetes. Místo šifrování secretů v Gitu ukládáte reference.

Jak to funguje:

  1. Secrety žijí ve Vaultu (nikdy v Gitu)
  2. Commitnete ExternalSecret manifesty, které odkazují na Vault cesty:
    YAML
    apiVersion: external-secrets.io/v1beta1
    kind: ExternalSecret
    metadata:
      name: my-app-secrets
    spec:
      refreshInterval: 1h
      secretStoreRef:
        name: vault-backend
        kind: ClusterSecretStore
      target:
        name: my-app-secrets
      data:
        - secretKey: db-password
          remoteRef:
            key: secret/data/my-app
            property: db-password
  3. ESO synchronizuje secrety z Vaultu do Kubernetes Secrets
  4. Flux spravuje ExternalSecret manifesty jako jakýkoli jiný resource

Výhody: Centralizovaná správa secretů, automatická rotace, bohaté přístupové politiky, audit logging. Nevýhody: Vyžaduje provoz Vaultu (nebo Vault-as-a-service), přidává provozní složitost, ESO je další controller ke správě.

Možnost 3: Sealed Secrets

Sealed Secrets od Bitnami mají jiný přístup: šifrujete secrety veřejným klíčem clusteru, čímž vznikne SealedSecret CRD bezpečný pro commit. Pouze controller clusteru ho může dešifrovat.

Bash
kubeseal --format yaml < secret.yaml > sealed-secret.yaml

Výhody: Jednoduché, žádné externí závislosti, šifrování vázané na cluster. Nevýhody: Secrety jsou vázané na konkrétní cluster (nelze sdílet napříč clustery bez opětovného zapečetění), rotace klíčů vyžaduje přešifrování všech secretů, žádná centralizovaná správa.

Možnost 4: Cloud Provider KMS + CSI Driver

Pokud běžíte na velkém cloudu, můžete použít nativního správce secretů poskytovatele se Secrets Store CSI Driver:

CloudSecret ManagerCSI Provider
GCPSecret ManagerGCP Provider
AWSSecrets ManagerAWS Provider
AzureKey VaultAzure Provider

Secrety se mountují jako volumes — žádné Kubernetes Secret objekty vůbec. Toto je nejbezpečnější varianta, protože secrety nikdy neexistují v etcd, ale vyžaduje cloud-specifickou konfiguraci a nefunguje v multi-cloud nebo on-prem prostředí.

Kterou možnost zvolit?

PřístupSložitostExterní závislostiMulti-clusterRotace
SOPS + ageNízkáŽádnéManuální distribuce klíčůManuální
SOPS + Cloud KMSNízkáCloud KMSKlíč per cluster/projektAutomatická (KMS)
External Secrets + VaultStředníVault + ESOCentralizovanáAutomatická
Sealed SecretsNízkáŽádnéPřepečetění per clusterManuální
CSI DriverStředníCloud-specifickýPer-cloud konfiguraceAutomatická

Pro malé týmy a single clustery je SOPS + age těžko překonatelný — nulová infrastrukturní režie. Jak škálujete na více clusterů nebo potřebujete automatizovanou rotaci, External Secrets + Vault nebo SOPS + Cloud KMS stojí za tu přidanou složitost.

Optimalizace zdrojů pro GKE Autopilot

GKE Autopilot účtuje na základě requests zdrojů, takže správné dimenzování Flux controllerů přímo ovlivňuje náklady. Kustomize patche v našem FluxInstance (ukázané v Kroku 3 výše) požadují minimální CPU a paměť pro každý controller.

Důležité upozornění: GKE Autopilot vynucuje minimální resource requests per kontejner — aktuálně 50m CPU a ~52Mi paměti. Pokud požádáte o méně, Autopilot to tiše navýší na minimum. Patche jsou přesto hodnotné, protože zabraňují použití výchozích Flux requests (které jsou výrazně vyšší) jako baseline. Výsledkem je, že celá Flux GitOps infrastruktura — všech 6 controllerů — běží na výrazně méně než polovině CPU jádra, což je skromné na to, co dostanete.

Vestavěné webové UI

Jednou z nejpříjemnějších funkcí Flux Operátoru je jeho vestavěný web dashboard. Na rozdíl od staršího komunitního Capacitor UI nebo deprecated Weave GitOps UI je tento dodáván přímo v operátoru — žádná další instalace není potřeba.

Flux Operator Web UI zobrazující stav clusteru, synchronizaci a reconcilery

Dashboard poskytuje:

  • Přehled stavu clusteru — stav synchronizace, zdraví controllerů, využití zdrojů
  • Flux Reconcilers — živý stav všech Kustomizations, HelmReleases a zdrojů
  • Monitoring workloadů — stav deploymentů a počty replik napříč clusterem
  • GitOps graf — interaktivní vizualizace závislostí zdrojů
  • Vyhledávání a oblíbené — filtrování podle typu, namespace nebo stavu
  • Operační akce — spuštění reconciliace, pozastavení a obnovení zdrojů (chráněno RBAC)

Pro přístup přes port-forward:

Bash
kubectl -n flux-system port-forward svc/flux-operator 9080:80

Poté otevřete http://localhost:9080 v prohlížeči.

Zabezpečení webového UI

Web UI podporuje několik režimů autentizace. Pro produkční použití je doporučeno OpenID Connect SSO — operátor se integruje s Dex, Keycloak, Microsoft Entra a dalšími OIDC providery. Tím je zajištěno, že pouze autentizovaní uživatelé se správnými Kubernetes RBAC rolemi mohou zobrazit nebo interagovat s dashboardem.

Pro interní nebo vývojové použití je dostupná anonymní autentizace s dedikovaným RBAC uživatelem navázaným na read-only ClusterRole. Pokud zvolíte tuto cestu, ujistěte se, že UI je přístupné pouze přes port-forward nebo za VPN — nikdy nevystavujte neautentizovaný dashboard do internetu.

Zde je příklad minimální read-only ClusterRole pro Web UI:

HCL
resource "kubernetes_cluster_role" "flux_web_view" {
  metadata { name = "flux-web-view" }

  rule {
    api_groups = ["source.toolkit.fluxcd.io"]
    resources  = ["*"]
    verbs      = ["get", "list", "watch"]
  }
  rule {
    api_groups = ["kustomize.toolkit.fluxcd.io"]
    resources  = ["*"]
    verbs      = ["get", "list", "watch"]
  }
  # ... podobná pravidla pro helm, notification, image, fluxcd CRDs
}

Flux MCP Server: AI potkává GitOps

Flux ekosystém také zahrnuje MCP Server — most mezi AI asistenty a vašimi Kubernetes clustery využívající Model Context Protocol. To vám umožňuje interagovat s vaší GitOps infrastrukturou přirozeným jazykem v nástrojích jako Claude, GitHub Copilot nebo Gemini.

Co MCP Server umožňuje:

  • Porozumění stavu — zeptejte se svého AI asistenta na aktuální stav Flux zdrojů, synchronizaci a zdraví controllerů napříč prostředími
  • Porovnání prostředí — porovnejte konfigurace Fluxu mezi dev, staging a produkčními clustery
  • Reakce na incidenty — zkraťte průměrný čas řešení výpadků díky kontextové analýze událostí a logů
  • Analýza kořenových příčin — korelujte události, logy a změny konfigurace pro identifikaci zdrojů selhání
  • Správa pipeline — spouštějte reconciliace, pozastavujte nebo obnovujte Flux zdroje přirozeným jazykem
  • Vizualizace — generujte diagramy závislostí mapující vaše Flux delivery workflows

Server implementuje rozumná bezpečnostní nastavení: režim pouze pro čtení, automatické maskování hodnot Kubernetes Secrets a provoz v rámci vašich stávajících kubeconfig oprávnění. Podporuje také Kubernetes impersonation pro omezený přístup.

Pokud již používáte AI coding asistenta, Flux MCP Server z něj udělá GitOps-aware operačního společníka — žádné přepínání kontextu mezi editorem a kubectl.

Odkazy:

Licencování

Je důležité pochopit licenční krajinu:

KomponentaLicencePoznámky
Flux CDApache 2.0CNCF Graduated projekt, plně open source
Flux OperatorAGPL-3.0Open source, copyleft — jakékoli modifikace musí být sdíleny
ControlPlane Enterprise DistributionKomerčníEnterprise podpora, zpevněné image, CVE patche

Flux CD je Apache 2.0 — nejpermisivnější open-source licence. Můžete ho používat, modifikovat a distribuovat bez omezení.

Flux Operator používá AGPL-3.0, což je stále open source, ale s copyleft požadavkem: pokud modifikujete operátor a poskytujete ho jako službu, musíte své modifikace uvolnit pod stejnou licencí. Pro většinu uživatelů, kteří operátor jednoduše deployují bez modifikace zdrojového kódu, to nemá žádný praktický dopad.

ControlPlane nabízí komerční Enterprise Distribution pro organizace, které potřebují enterprise podporu, zpevněné kontejnerové image a garantované reakční časy na CVE.

Co jsme získali

Migrace z Flux bootstrap na Flux Operator nám přinesla:

  1. Žádné 660KB generované YAML — FluxInstance CRD je ~50 řádků
  2. Deklarativní Flux upgrady — změňte version: "2.x" a operátor zajistí rollout
  3. Terraform-native — celý Flux životní cyklus je spravován společně s Kubernetes clusterem
  4. Vestavěná observabilita — Web UI poskytuje okamžitý přehled bez dalších nástrojů
  5. Platformově specifické patche — GKE Autopilot seccomp profily a ladění zdrojů na jednom místě
  6. Dešifrování secretů jako konfigurace — SOPS/Vault/KMS integrace je součástí FluxInstance spec, ne manuální overlay

Jak začít

Pokud chcete vyzkoušet Flux Operator:

Bash
# Instalace přes Helm
helm install flux-operator \
  oci://ghcr.io/controlplaneio-fluxcd/charts/flux-operator \
  --namespace flux-system \
  --create-namespace \
  --set web.enabled=true

# Vytvoření FluxInstance
kubectl apply -f flux-instance.yaml

# Přístup k Web UI
kubectl -n flux-system port-forward svc/flux-operator 9080:80

Podívejte se na dokumentaci Flux Operátoru pro kompletní referenci FluxInstance spec a pokročilé funkce jako multi-tenancy, sharding a horizontální škálování.


Další čtení:

Další z blogu