convoy docs
Search

Fleet design

The design of ReleaseTemplate and Fleet, two planned kinds that generate one Release for each cluster.

A Release targets one Cluster, and its clusterRef is immutable. To deploy one application to many clusters, convoy adds two kinds that generate Releases. The Release kind and the full reconcile pipeline stay the same for each generated Release.

The two kinds#

  • ReleaseTemplate: one application. It holds a full Release under spec.template, without spec.clusterRef and without pin. String fields can hold {{ .cluster.* }} placeholders.
  • Fleet: where and how. It selects clusters with clusterSelector and templates with templateSelector. It generates one Release for each matching pair.

To add an application, create a ReleaseTemplate with the matching labels. To add a cluster, create a Cluster with the matching labels. You do not change the Fleet.

yaml
apiVersion: core.convoy.kumodo.io/v1alpha1
kind: Fleet
metadata:
  name: platform-prod
  namespace: platform
spec:
  clusterSelector:
    matchLabels: { env: prod }
  templateSelector:
    matchLabels: { fleet-group: platform }
  syncPolicy: { automatic: true, interval: 5m, prune: { orphaned: true } }
  deletionPolicy: { keepWorkloads: false }
  commonMutations:
    - type: goTemplate
      if: cluster.region.startsWith('eu-')
      inline:
        - |
          metadata:
            annotations:
              example.com/data-residency: eu
  rollout:
    strategy: allAtOnce

Responsibilities#

PartReleaseTemplateFleetGenerated Release
source, contentYes, with placeholdersValues with the placeholders resolved
clusterRefNoFrom clusterSelectorThe matched cluster
Sync, retention and deletion policyOptional overrideDefaultThe template value, else the fleet value
MutationsApplication mutationscommonMutationscommonMutations, then the template mutations
Rollout strategyYes

Generation#

  • The Fleet controller resolves the placeholders when it generates a Release. Only a fixed set of string fields can hold placeholders: the Release name, labels and annotations, values file paths, inline values and the content path.
  • Mutation bodies are not resolved at generation. They stay templates, and the usual mutation engine resolves them at render time.
  • A commonMutations entry can have an if. It is a CEL expression with cluster and self. When it is false for a cluster, the generated Release does not get that mutation.
  • The name of a generated Release is the resolved name and a short hash of the cluster name and the template name. The name stays the same when the content of the template changes.
  • Each generated Release is in the namespace of the Fleet, and has an owner reference to the Fleet.
  • When a cluster or a template stops matching, convoy deletes the generated Release. The deletion policy of the Release applies.

Rollout across clusters#

The first strategy is allAtOnce. Later strategies roll out to groups of clusters, one group after the other, with a health gate between groups. This is ordering between clusters. Traffic shifting inside a cluster is a non-goal.

Tenancy#

A Fleet, its templates and its clusters are in one namespace. Cross-namespace fleets need the planned ReferenceGrant model. See ReferenceGrant.