Flux’s garbage collection is a powerful, if sometimes opaque, mechanism for cleaning up resources that are no longer declared in your Git repository.

Here’s a Flux Kustomization that’s set to remove stale resources.

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: my-app
  namespace: flux-system
spec:
  interval: 5m
  path: ./clusters/my-app
  prune: true
  sourceRef:
    kind: GitRepository
    name: flux-system
  validation: client

The key here is prune: true. When Flux reconciles this Kustomization, it compares the resources currently running in your cluster against the manifests found at the specified path in your sourceRef. If a resource exists in the cluster but not in your Git repository, Flux will delete it. This is the garbage collection in action.

To make this work, you need to ensure a few things are in place. First, your GitRepository source must be healthy and pointing to the correct branch and commit.

flux get sources git flux-system

This command will show you the status of your GitRepository. Look for Healthy and a recent commit. If it’s not healthy, check your Git credentials, repository URL, and branch name in the GitRepository manifest.

Second, the Kustomization itself needs to be reconciled successfully.

flux get kustomizations my-app

You’re looking for Healthy status and a Last Applied timestamp that’s recent. If it’s stuck or failing, flux logs --kustomization my-app will give you more insight into reconciliation errors. These errors often stem from invalid Kubernetes manifests or RBAC issues preventing Flux from managing resources.

The interval in the Kustomization defines how often Flux checks for changes. A shorter interval means faster detection of drifted or removed resources, but it also increases the load on your cluster and the Git provider. For most use cases, 5m (5 minutes) or 10m is a good balance.

prune: true is the direct enabler of garbage collection. Without it, Flux would ignore resources that are no longer in Git. It’s crucial to understand that this means any resource not present in the specified path will be deleted. This includes resources managed by other Kustomizations if they aren’t declared in the same path that’s being pruned.

When Flux deletes a resource, it does so by removing the Kubernetes OwnerReference that Flux itself (or a controller it manages) might have placed on the resource, and then issuing a standard kubectl delete operation. It doesn’t do anything magical; it just automates the process of identifying and removing what’s no longer desired.

One subtle but critical aspect of Flux’s garbage collection is its interaction with Helm releases. If you are using HelmRelease objects to manage deployments, Flux’s garbage collection on the Kustomization that includes the HelmRelease will not automatically delete the Helm release itself or the resources managed by that Helm release. Flux’s garbage collection operates at the Kubernetes object level. When a HelmRelease is pruned from Git, Flux will delete the HelmRelease custom resource. However, the underlying Helm release and its deployed resources will persist unless explicitly uninstalled via Helm or managed by a separate pruning mechanism. To ensure full cleanup, you’d typically have your Kustomization manage the HelmRelease object, and then the HelmRelease’s uninstall hook would handle the actual deletion of resources when the HelmRelease is removed.

The next thing you’ll likely want to configure is how Flux handles drift detection and remediation, ensuring that manual changes made directly to the cluster are reverted.

Want structured learning?

Take the full Flux course →