Fleet organization examples

The following examples show common fleet organization patterns using layered configuration and template placeholders to reduce fleet duplication.

Multi-region fleet

A fleet of point-of-sale terminals deployed across multiple regions. All terminals share base OS tuning and application configuration, but NTP servers and network settings differ by region. A single fleet definition with a region-specific override layer eliminates the need to create a separate fleet for each region.

apiVersion: flightctl.io/v1beta1
kind: Fleet
metadata:
  name: pos-terminals
spec:
  selector:
    matchLabels:
      type: pos-terminal
  template:
    metadata:
      labels:
        type: pos-terminal
    spec:
      os:
        image: quay.io/example/pos-rhel:9.5
      config:
        - name: base-config
          gitRef:
            repository: site-settings
            targetRevision: main
            path: /config/base
        - name: region-config
          gitRef:
            repository: site-settings
            targetRevision: main
            path: /config/regions/{{ .metadata.labels.region }}

Devices need the following labels: type: pos-terminal and region: eu-west (or us-east, ap-south, and so on). The region-config entry resolves a different directory for each device based on its region label.

The Git repository separates base files from region-specific overrides:

site-settings/
  config/
    base/
      motd.conf
      ntp.conf
      app.conf
    regions/
      eu-west/
        ntp.conf
      us-east/
        ntp.conf
      ap-south/
        ntp.conf

Mixed device types sharing base configuration

A fleet includes both point-of-sale terminals and self-service kiosks that share base monitoring and logging configuration but run different applications. A single fleet definition avoids duplicating the shared monitoring configuration across separate fleet resources.

apiVersion: flightctl.io/v1beta1
kind: Fleet
metadata:
  name: store-devices
spec:
  selector:
    matchLabels:
      environment: store
  template:
    metadata:
      labels:
        environment: store
    spec:
      os:
        image: quay.io/example/store-rhel:9.5
      config:
        - name: base-monitoring
          gitRef:
            repository: site-settings
            targetRevision: main
            path: /config/base
        - name: device-type-config
          gitRef:
            repository: site-settings
            targetRevision: main
            path: /config/types/{{ .metadata.labels.type }}

Devices need the following labels: environment: store and type: pos-terminal or type: kiosk. The device-type-config entry delivers application-specific configuration files based on the device type label, while every device receives the shared monitoring and logging files from the base layer.

The Git repository groups shared configuration separately from device-type-specific application configuration:

site-settings/
  config/
    base/
      logging.conf
      monitoring.conf
    types/
      pos-terminal/
        app.conf
      kiosk/
        app.conf

Staged rollout with canary batch

A fleet uses rolloutPolicy to deploy changes to canary devices first, then to the remaining production devices. This pattern reduces the risk of a faulty update reaching all devices at once.

apiVersion: flightctl.io/v1beta1
kind: Fleet
metadata:
  name: factory-controllers
spec:
  selector:
    matchLabels:
      role: factory-controller
  rolloutPolicy:
    deviceSelection:
      strategy: BatchSequence
      sequence:
        - selector:
            matchLabels:
              stage: canary
          successThreshold: "80%"
        - selector: {}
  template:
    metadata:
      labels:
        role: factory-controller
    spec:
      os:
        image: quay.io/example/factory-rhel:9.5
      config:
        - name: controller-config
          gitRef:
            repository: factory-settings
            targetRevision: main
            path: /config/controllers

Devices need the following labels: role: factory-controller and, for canary devices only, a label such as stage: canary. The label key and value are examples; use whichever label convention fits your environment. Production devices do not need the stage label.

The first batch targets devices labeled stage: canary. After 80% of canary devices report success, the second batch with an empty selector targets all remaining devices in the fleet.

Combined gitRef and secretRef for per-site credentials

Devices at different sites need site-specific network credentials stored as Kubernetes secrets, alongside shared application configuration from a Git repository. Combining gitRef and secretRef in a single fleet avoids creating separate fleet definitions for each site.

apiVersion: flightctl.io/v1beta1
kind: Fleet
metadata:
  name: site-devices
spec:
  selector:
    matchLabels:
      managed: "true"
  template:
    metadata:
      labels:
        managed: "true"
    spec:
      os:
        image: quay.io/example/site-rhel:9.5
      config:
        - name: base-app-config
          gitRef:
            repository: app-config
            targetRevision: main
            path: /config/app
        - name: site-credentials
          secretRef:
            name: network-creds-{{ .metadata.labels.site }}
            namespace: flightctl
            mountPath: /etc/network-credentials

Devices need the following labels: managed: "true" and site: factory-berlin (or factory-madrid, and so on). The secretRef name resolves per device, so a device labeled site: factory-berlin receives the secret network-creds-factory-berlin.