Fleet is Rancher’s way of doing GitOps across multiple Kubernetes clusters.

Let’s see Fleet in action. Imagine you have a single Git repository holding all your desired cluster states. Fleet watches this repo and applies the changes to your clusters.

Here’s a fleet.yaml file that tells Fleet to deploy a hello-world application.

# fleet.yaml
# This is the main Fleet configuration file for a GitRepo resource.
# It defines how Fleet should manage resources from a Git repository.
spec:
  repo:
    # The Git repository URL. Fleet will clone this repository.
    url: https://github.com/your-username/your-fleet-repo.git
    # The branch within the repository to monitor.
    branch: main
    # Optional: A path within the repository to look for Fleet resources.
    # If not specified, Fleet will look in the root of the repository.
    path: clusters/staging
  # Define how Fleet should target clusters.
  # In this example, we're targeting all clusters managed by Rancher.
  # You could also specify cluster labels for more granular control.
  targets:
    - selector:
        matchLabels:
          # This label is applied to all clusters managed by Rancher.
          # If you want to target specific clusters, you'd use their custom labels.
          management.cattle.io/cluster-display-name: "*"
  # Define the Helm chart or raw Kubernetes manifests to deploy.
  # Here, we're deploying a Helm chart.
  helm:
    # The name of the Helm chart to deploy.
    chart: hello-world
    # The repository where the Helm chart is located.
    repo: https://charts.rancher.io
    # The version of the Helm chart to deploy.
    version: 0.1.0
    # Values to override in the Helm chart.
    values:
      replicaCount: 3
      image:
        tag: latest

When Fleet processes this, it first clones the specified Git repository. Then, it looks for a directory named clusters/staging (as defined in path). Inside this directory, it expects to find Kubernetes manifests or Helm chart configurations.

Fleet then identifies the target clusters based on the selector. In this case, it’s all clusters that Rancher is managing (indicated by the wildcard * on management.cattle.io/cluster-display-name). For each matching cluster, Fleet will deploy the hello-world Helm chart from https://charts.rancher.io with the specified values.

The core problem Fleet solves is the drift between your desired state in Git and the actual state of your Kubernetes clusters. Without GitOps, you might manually apply changes, forget to update a cluster, or introduce inconsistencies. Fleet automates this reconciliation.

Here’s how it works internally. Fleet consists of two main components:

  1. Fleet Controller: This runs in your management cluster (where Rancher is installed). It monitors your Git repositories for changes. When it detects a difference, it creates Bundle and BundleDeployment resources.
  2. Fleet Agent: This runs in each managed cluster. It watches for BundleDeployment resources targeted at its cluster. When it finds one, it fetches the associated Git content (the manifests or Helm chart) and applies it to the cluster using its own Kubernetes API client.

The Bundle resource is essentially a snapshot of the Git content at a specific commit. A BundleDeployment is the instance of that Bundle that Fleet is trying to deploy to a particular cluster. The agent in the managed cluster then executes the deployment.

The selector in the fleet.yaml is a powerful way to manage which clusters get which deployments. You can use standard Kubernetes label selectors. For example, to target only clusters in your "production" environment, you might have a label like environment: production on those clusters and use selector: { matchLabels: { environment: production } }.

This means you can have one Git repository containing all your application configurations, and Fleet can intelligently deploy them to the correct subsets of your clusters. It’s a declarative way to manage infrastructure and applications across an entire fleet of Kubernetes clusters.

The most surprising thing about Fleet is how it handles secrets. You don’t typically commit secrets directly into your GitOps repository. Instead, Fleet leverages Kubernetes Secrets and can integrate with external secret management systems. For example, you can define a Secret resource in Git that points to a secret stored elsewhere, and Fleet will fetch and inject it into the target cluster’s namespace only when needed for a deployment, without ever storing the sensitive data in the Git repo itself.

The next concept you’ll want to explore is managing environments and progressive rollouts with Fleet’s GitRepo and Bundle customization options.

Want structured learning?

Take the full K3s course →