convoy docs
Search

convoy

A Kubernetes-native continuous delivery system.

convoy deploys applications to Kubernetes clusters. You describe what to deploy, from where, and to which cluster as Kubernetes objects. convoy fetches the source, renders it and applies the result with Server-Side Apply. Then it reports two things on the status. Does the live state match the render (drift)? Are the workloads healthy?

convoy is an aggregated API server plus controllers. Its resources are real Kubernetes API objects. You manage them with kubectl, RBAC and admission. They are not CRDs.

Delivery flow One Release from kubectl apply to an applied, in-sync and healthy state. Pick a scenario and step through it.
convoy delivery flowThe controller-manager fetches, renders, mutates, dry-runs, stores and applies a render to the target cluster. The observer reads the cluster and writes the InSync and Healthy conditions.controller-managertarget clusterobserverFetchRenderMutateDry runStoreApply + pruneLive resourcesDriftwrites InSyncHealthwrites Healthy

Components#

convoy has three server components and a kubectl plugin.

ComponentWhat it does
convoy-apiserverServes the convoy API groups as an aggregated API server. Stores objects in etcd. Handles the /pin, /sync, /mutations and /lifecycle subresources. Sends /preview, /diff, /health and /history requests to the observer.
convoy-controller-managerReconciles Cluster, GitRepository, HelmRegistry, OCIRegistry and Release objects. For a Release, it fetches, renders, mutates, dry-runs, stores and applies.
convoy-observerCompares the live state with the render and writes InSync. Assesses health with CEL rules and writes Healthy. Serves the on-demand subresources.
kubectl convoyCLI plugin for the Release subresources: sync, pin, unpin, preview, diff, history, health, mutations, lifecycle.

Delivery steps#

A Release is one application, rendered from one source, applied to one cluster. For each Release, the controller-manager does these steps:

  1. Fetch the content from a GitRepository, HelmRegistry or OCIRegistry.
  2. Render the content: raw manifests, a Helm chart (rendered in-process), or a kustomization.
  3. Mutate the rendered objects with the spec.mutations pipeline.
  4. Dry-run the render with Server-Side Apply. A render that the cluster rejects stops here.
  5. Store the render in the render store, if one is configured.
  6. Apply the render with Server-Side Apply, in sync-wave order. Then prune the objects that the render no longer contains.

Then the observer reads the cluster:

  • The drift loop compares live objects with the render and writes the InSync condition. In automatic mode, drift starts a new sync.
  • The health loop evaluates the selected health rules and writes the Healthy condition.

Where to go next#

In the code

convoy v0.9.0