> ## Documentation Index
> Fetch the complete documentation index at: https://docs.siderolabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Deploy Flux

> In this guide you will learn how to deploy Flux on Talos Linux with kubectl or at bootstrap time, or on Omni-managed clusters using manifest sync.

export const k8s_release = '1.36.1';

[Flux](https://fluxcd.io/) is a GitOps toolkit for Kubernetes built around a set of controllers that continuously reconcile your cluster state against configuration stored in a Git repository. It is designed to run entirely inside the cluster and requires no external UI or CLI to operate once bootstrapped.

This guide walks through how to get Flux running on Talos Linux and Omni.

## Prerequisites

Before you begin, ensure you have the following:

* Talos 1.3 or later.
* `kubectl` configured to access your cluster.
* `talosctl` installed and configured, if deploying on Talos without Omni.
* `omnictl` installed and configured, if deploying using Omni. See [Install and configure omnictl](../../omni/getting-started/install-and-configure-omnictl).

## Installation on Talos

On Talos, you can install Flux after the cluster is up, or reference the install manifest from the machine configuration so it is running as soon as the cluster is healthy.

<Tabs>
  <Tab title="After bootstrap">
    Install Flux with `kubectl` once the cluster is up and healthy.

    **Step 1.** Apply the Flux install manifest:

    ```bash theme={null}
    kubectl apply -f https://github.com/fluxcd/flux2/releases/latest/download/install.yaml
    ```

    **Step 2.** Confirm that the Flux controllers are running:

    ```bash theme={null}
    kubectl get pods -n flux-system
    ```

    You should see the source, kustomize, helm, and notification controllers in a `Running` state.
  </Tab>

  <Tab title="At bootstrap time">
    Reference the install manifest from the control plane machine configuration using `extraManifests`.

    <Note>
      `extraManifests` require the node to have outbound HTTPS access to the manifest URL at bootstrap time. If your environment is air-gapped, see [inlineManifests and extraManifests](./inlinemanifests) for alternatives.
    </Note>

    **Step 1.** Create a patch file named `flux-extra-manifest.yaml` that references the Flux install manifest:

    ```bash theme={null}
    cat <<EOF > flux-extra-manifest.yaml
    cluster:
      extraManifests:
        - "https://github.com/fluxcd/flux2/releases/latest/download/install.yaml"
    EOF
    ```

    **Step 2.** Set a variable containing the IP addresses of your control plane nodes:

    ```bash theme={null}
    CP_IPS="<control-plane-ip-1>,<control-plane-ip-2>,<control-plane-ip-3>"
    ```

    **Step 3.** Apply the patch to your control plane nodes:

    ```bash theme={null}
    talosctl patch machineconfig \
      --patch @flux-extra-manifest.yaml \
      --endpoints $CP_IPS \
      --nodes $CP_IPS \
      --talosconfig=./talosconfig
    ```

    **Step 4.** If this is a new cluster, bootstrap it. Run this **only once** per cluster:

    ```bash theme={null}
    talosctl bootstrap --nodes <control-plane-ip> --talosconfig=./talosconfig
    ```

    **Step 5.** Once the cluster is healthy, confirm that the Flux controllers are running:

    ```bash theme={null}
    kubectl get pods -n flux-system
    ```
  </Tab>
</Tabs>

From here, configure Flux to reconcile against your Git repository. See the [Flux documentation](https://fluxcd.io/flux/installation/) for bootstrapping against a repository.

## Installation on Omni

If your clusters are managed by [Omni](https://www.siderolabs.com/omni-for-kubernetes-cluster-management), you can include Flux as part of your cluster template using [Omni manifest sync](../../omni/cluster-management/sync-kubernetes-manifests). Omni applies the Flux install manifest once after the cluster becomes available, and the Flux controllers handle all subsequent reconciliation themselves.

Since manifest sync works with local files rather than remote URLs, you need to download the Flux install manifest before referencing it in the cluster template.

**Step 1:** Download the Flux install manifest:

```bash theme={null}
curl -Lo flux-install.yaml \
  https://github.com/fluxcd/flux2/releases/latest/download/install.yaml
```

**Step 2**: Use kustomize to inject namespace fields into every resource in the Flux upstream manifest. [Omni manifest sync](../../omni/cluster-management/sync-kubernetes-manifests) requires namespaces to be explicitly set on every resource:

```bash theme={null}
cat <<EOF > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: flux-system
resources:
  - flux-install.yaml
EOF
```

**Step 3:** Build the namespaced manifest:

```bash theme={null}
kubectl kustomize . > flux-install-namespaced.yaml
```

**Step 4:** Create the namespace prerequisite that defines the `flux-system` namespace:

```bash theme={null}
cat <<EOF > flux-prereqs.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: flux-system
EOF
```

**Step 5.** Create the cluster template and reference both manifests `flux-install-namespaced.yaml` and `flux-prereqs.yaml`:

```bash theme={null}
cat <<EOF > cluster-template.yaml
kind: Cluster
name: <your-cluster>
kubernetes:
  version: v1.x.x
  manifests:
    - name: flux-prereqs
      file: flux-prereqs.yaml
      mode: full
    - name: flux-install
      file: flux-install-namespaced.yaml
      mode: one-time
talos:
  version: v1.x.x
---
kind: ControlPlane
machines:
  - <machine-id>
---
kind: Workers
machines:
  - <machine-id>
EOF
```

The `flux-prereqs` manifest uses `mode: full` so Omni continuously ensures the namespace exists. The `flux-install` manifest uses `mode: one-time` because Flux manages its own resources after the initial apply.

**Step 6:** Apply the cluster template:

```bash theme={null}
omnictl cluster template sync --file cluster-template.yaml
```

Omni stores the manifest definitions and waits until the Kubernetes API is available and the cluster is healthy before applying them.

**Step 7:** Verify that the Flux pods are running:

```bash theme={null}
kubectl get pods -n flux-system -w
```

All Flux pods should appear in a `Running` state. To inspect the manifest sync status, run:

```bash theme={null}
omnictl get clusterkubernetesmanifestsstatuses <cluster-name>
```

See [Sync Kubernetes Manifests](../../omni/cluster-management/sync-kubernetes-manifests) for more details on sync modes and status monitoring.
