Deploy a Helm chart
Deploy the podinfo Helm chart from a HelmRegistry, and from an OCIRegistry as a variant.
This guide deploys the podinfo Helm chart to the cluster where convoy runs. The chart comes from
a HelmRegistry, which is an HTTP Helm repository with an index.yaml. The Release selects the
chart name and an exact chart version. It also adds two Helm values layers: a file from a Git
repository and an inline layer. At the end, the guide shows the same task with an OCIRegistry
source.
Before you start#
- convoy runs in the cluster.
kubectland the kubectl convoy plugin are on yourPATH.- You can create convoy objects in the
defaultnamespace. All examples use this namespace.
Steps#
1. Create the target Cluster#
Save this manifest as
cluster-auth-in-cluster.yaml:apiVersion: core.convoy.kumodo.io/v1alpha1 kind: Cluster metadata: name: dev-local namespace: default spec: connectionMode: inCluster metadata: type: kind role: managedApply the manifest:
kubectl apply -f cluster-auth-in-cluster.yamlWait until the Cluster is ready:
kubectl wait --for=condition=Ready clusters.core.convoy.kumodo.io/dev-local -n default --timeout=2m
The inCluster mode uses the credentials of the convoy pod. A Release does not render or apply
while its Cluster is not reachable. The Applied reason is then ClusterNotReady.
2. Create the sources#
Save this manifest as
helmregistry-podinfo.yaml:apiVersion: source.convoy.kumodo.io/v1alpha1 kind: HelmRegistry metadata: name: podinfo namespace: default spec: auth: type: none interval: 1m0s minSyncInterval: 30s tls: insecureSkipVerify: true url: https://stefanprodan.github.io/podinfoSave this manifest as
gitrepository-podinfo-values.yaml:apiVersion: source.convoy.kumodo.io/v1alpha1 kind: GitRepository metadata: name: podinfo-values namespace: default spec: auth: type: none interval: 1m0s minSyncInterval: 30s tls: insecureSkipVerify: true url: https://github.com/BROngineer/podinfo-values.gitApply the two manifests:
kubectl apply -f helmregistry-podinfo.yaml -f gitrepository-podinfo-values.yaml
The HelmRegistry holds the chart. The GitRepository holds a values file for the chart. A source
does not select a version. The Release selects it.
A Release does not wait for the Ready condition of a source. It fetches the content directly.
If the fetch fails, the Applied reason of the Release is SourceNotReady or ValuesNotReady.
3. Create the Release#
Save this manifest as
release-helmregistry-helm-in-cluster.yaml:apiVersion: core.convoy.kumodo.io/v1alpha1 kind: Release metadata: name: podinfo-helmreg-in-cluster namespace: default spec: clusterRef: name: dev-local source: type: helmRegistry helmRegistry: name: podinfo namespace: default chart: name: podinfo version: "6.12.0" content: type: helm helm: releaseName: podinfo-from-helmreg releaseNamespace: default dependencyMode: vendored values: - type: gitRepository gitRepository: name: podinfo-values namespace: default ref: branch: main paths: - podinfo/values.yaml - type: inline inline: image: tag: 6.13.0 syncPolicy: automatic: true prune: orphaned: false includeCRDs: false includeNamespaces: false interval: 1mApply the manifest:
kubectl apply -f release-helmregistry-helm-in-cluster.yamlWait until convoy applies the render:
kubectl wait --for=condition=Applied release/podinfo-helmreg-in-cluster -n default --timeout=5m
The Release has these parts:
spec.source.helmRegistry.chart. The chart name and the chart version. The version must be exact. convoy does not resolve a version range.spec.content.helm.values. Two values layers. convoy merges them in list order, and a later layer wins. The inlineimage.tagreplaces the tag from the Git file. Helm then merges the result over thevalues.yamlof the chart.dependencyMode: vendored. The chart must contain its dependencies incharts/. convoy does not download dependencies.spec.syncPolicy.automatic: true. convoy applies the render at each reconcile.
All references of a Release must be in the namespace of the Release. This includes the Cluster,
the source and each gitRepository values layer. The API server rejects a reference to another
namespace.
releaseNamespace sets only .Release.Namespace in the chart templates. convoy applies a
namespaced object without metadata.namespace to the default namespace.
Check the result#
Show the Release:
kubectl get releases -n defaultThe header line is
NAME CONTENT SOURCE CLUSTER STATE APPLIED INSYNC HEALTHY LIFECYCLE AGE. Forpodinfo-helmreg-in-cluster, make sure thatAPPLIEDisTrue.Show the objects of the render:
kubectl convoy release preview podinfo-helmreg-in-cluster -n defaultShow the health of each object:
kubectl convoy release health podinfo-helmreg-in-cluster -n default
The Release has no spec.healthAssessment. The observer then sets Healthy=True with reason
NotConfigured.
If APPLIED is not True, read the reason of the Applied condition:
kubectl describe release podinfo-helmreg-in-cluster -n defaultApplied · written by convoy-controller-manager (field manager convoy-release)
| Reason | Status | Meaning |
|---|---|---|
Applied | True | convoy applied the current render. In manual sync mode, the current render is equal to the last applied render. |
SourceNotReady | False | convoy could not fetch the source. convoy retries. |
ValuesNotReady | False | convoy could not read a Helm values layer (a ConfigMap, a Secret or a GitRepository path). convoy retries. |
ClusterNotReady | False | The Cluster does not exist or is not reachable. convoy retries. |
Unsupported | False | The Release uses a feature that convoy does not implement, for example a Git semver ref, Helm dependencyMode: resolve or jsonnet content. This is a configuration error, so convoy does not retry with backoff. |
Unappliable | False | The target cluster rejected the render in the pre-apply server-side dry run. convoy applies nothing. A forced /sync skips the dry run. |
DeployFailed | False | Rendering, mutation or the apply failed. The message and status.lastAttempted.failure.stage tell which step failed. convoy retries. |
PruneFailed | False | convoy applied the render, but could not delete an object that the render no longer contains. convoy retries. |
Pinned | False | convoy cannot apply the pinned render, because no render store is configured or the store does not contain that render. |
WaitingForSync | False | Manual sync mode. The current render differs from the last applied render. convoy waits for a /sync request. |
WaitingForWaveHealth | False | A sync wave waits until the resources of the previous wave are healthy. |
WaveFailed | False | A sync wave timed out while it waited for the previous wave. The Release has no failurePolicy. |
RolloutFailed | False | A sync wave timed out while it waited for the previous wave, and the failurePolicy did not roll back. |
RolledBack | True | The rollout failed and convoy applied the last healthy render again. |
WaitingForClusterWave | False | The Release waits for the Releases of a lower cluster wave on the same Cluster. |
ClusterWaveFailed | False | The Releases of a lower cluster wave did not become ready before the cluster-wave timeout. |
WaitingForHook | False | convoy waits for the workloads of a lifecycle hook phase to complete. |
HookFailed | False | A lifecycle hook with onFailure: Fail failed. convoy stops the sync. |
Variant: deploy the chart from an OCIRegistry#
An OCIRegistry source pulls Helm charts from an OCI registry. It does not pull other artifact
types. The Release selects the artifact name and an exact tag.
Save this manifest as
ociregistry-podinfo.yaml:apiVersion: source.convoy.kumodo.io/v1alpha1 kind: OCIRegistry metadata: name: podinfo namespace: default spec: auth: type: none interval: 1m0s minSyncInterval: 30s tls: insecureSkipVerify: true url: oci://ghcr.io/stefanprodan/charts defaultContentType: helmSave this manifest as
release-ociregistry-helm-in-cluster.yaml:apiVersion: core.convoy.kumodo.io/v1alpha1 kind: Release metadata: name: podinfo-ocireg-in-cluster namespace: default spec: clusterRef: name: dev-local source: type: ociRegistry ociRegistry: name: podinfo namespace: default artifact: name: podinfo version: "6.10.2" content: type: helm helm: releaseName: podinfo-from-ocireg releaseNamespace: default dependencyMode: vendored syncPolicy: automatic: true prune: orphaned: false includeCRDs: false includeNamespaces: false interval: 1m waveStrategy: strategy: waitForApplied wave: 1Apply the two manifests:
kubectl apply -f ociregistry-podinfo.yaml -f release-ociregistry-helm-in-cluster.yamlWait until convoy applies the render:
kubectl wait --for=condition=Applied release/podinfo-ocireg-in-cluster -n default --timeout=5m
This Release has no values layers. Helm uses the values.yaml of the chart.
This Release sets spec.syncPolicy.waveStrategy to wave 1 with waitForApplied. convoy applies
it only after each Release with a lower wave on the same Cluster has Applied=True. The Release
from step 3 has wave 0. Until that Release has Applied=True, the Applied reason of this
Release is WaitingForClusterWave. See Sync waves.
Clean up#
Delete the Releases:
kubectl delete release podinfo-helmreg-in-cluster podinfo-ocireg-in-cluster -n defaultDelete the sources:
kubectl delete -f helmregistry-podinfo.yaml -f gitrepository-podinfo-values.yaml -f ociregistry-podinfo.yamlDelete the Cluster, if no other Release uses it:
kubectl delete -f cluster-auth-in-cluster.yaml
Delete the Releases before the Cluster. A Release finalizer deletes the objects of the Release from the target cluster. If the Cluster does not exist, the objects stay on the cluster. See Deletion.
Next steps#
In the code
convoy v0.9.0
internal/fetch.(*coordinator).Ensureinternal/fetch/coordinator.go:107internal/render.ResolveValuesinternal/render/values.go:39internal/render.mergeValueLayersinternal/render/helm.go:167internal/render.renderHelminternal/render/helm.go:43api/core.validateSameNamespaceRefsapi/core/validation.go:168internal/waves.ClusterPredecessorsinternal/waves/cluster.go:68