title | description | icon | weight | toc |
---|---|---|---|---|
Deploying a Helm Chart |
Demonstrates how to deploy a Helm Chart from an OCM component version using OCM K8s Toolkit, kro, and FluxCD. |
🛥️ |
true |
This guide demonstrates how to deploy a Helm Chart from an OCM component version using OCM K8s Toolkit, kro, and FluxCD.
It is a rather basic example, in which it is assumed that a developer created an application, packaged it as a Helm
chart, and publishes it as OCM component version in an OCI registry. Then, an operator who wants to deploy the
application via Helm chart in a Kubernetes cluster, creates a ResourceGraphDefinition
with resources that point to
this OCM component version. Using CEL expressions inside the ResourceGraphDefinition
, the information about the
resource location will be passed to FluxCD, which will then configure the Helm chart and deploy it into the Kubernetes
cluster.
Important
Before starting, make sure you have set up your environment as described in the setup guide.
First, we will create an OCM component version containing a Helm chart. For this example, we will use the podinfo
Helm chart, which is a simple web application that serves a pod information page. For more details on how to create an
OCM component version, please refer to the OCM documentation.
To create the OCM component version, we will use the following component-constructor.yaml
file:
components:
- name: ocm.software/ocm-k8s-toolkit/simple
provider:
name: ocm.software
version: "1.0.0"
resources:
- name: helm-resource
type: helmChart
version: 1.0.0
access:
type: ociArtifact
imageReference: ghcr.io/stefanprodan/charts/podinfo:6.7.1
After creating the file, we can create the OCM component version:
ocm add componentversion --create --file ./ctf component-constructor.yaml
This will create a local CTF (Component Transfer Format) directory ./ctf
containing the OCM component version. Since
the OCM component version must be accessible for the OCM K8s Toolkit controllers, we will transfer the CTF to a
registry. For this example, we will use GitHub's container registry, but you can use any OCI registry:
ocm transfer ctf ./ctf ghcr.io/<your-namespace>
Note
If you are using a registry that requires authentication, you need to provide credentials for ocm. Please refer to the OCM CLI credentials documentation for more information on how to set up and use credentials.
If everything went well, you should see the following output:
ocm get componentversion ghcr.io/<your-namespace>//ocm.software/ocm-k8s-toolkit/simple:1.0.0
COMPONENT VERSION PROVIDER
ocm.software/ocm-k8s-toolkit/simple 1.0.0 ocm.software
To deploy the Helm chart from the OCM component version, we will first create a ResourceGraphDefinition
that contains
all required resources. Additionally, we will add a configuration to the HelmRelease
resource that can be passed
through the instance of that ResourceGraphDefinition
. After the ResourceGraphDefinition
is created and applied, we
create the instance of the ResourceGraphDefinition
that will deploy the Helm chart.
The ResourceGraphDefinition
is a custom resource that defines all the resources that should be applied. To proceed
with the example, create a file named rgd.yaml
and add the following content:
apiVersion: kro.run/v1alpha1
kind: ResourceGraphDefinition
metadata:
name: simple
spec:
schema:
apiVersion: v1alpha1
# The name of the CRD that is created by this ResourceGraphDefinition when applied
kind: Simple
spec:
# This spec defines values that can be referenced in the ResourceGraphDefinition and that can be set in the
# instances of this ResourceGraphDefinition.
# We will use it to pass a value to the Helm chart and configure the message the application shows
# (see resource HelmRelease).
message: string | default="foo"
resources:
# Repository points to the OCM repository in which the OCM component version is stored and checks if it is
# reachable by pinging it.
- id: repository
template:
apiVersion: delivery.ocm.software/v1alpha1
kind: Repository
metadata:
name: simple-repository
spec:
repositorySpec:
baseUrl: ghcr.io/<your-namespace>
type: OCIRegistry
interval: 1m
# ocmConfig is required, if the OCM repository requires credentials to access it.
# ocmConfig:
# Component refers to the Repository, downloads and verifies the OCM component version descriptor.
- id: component
template:
apiVersion: delivery.ocm.software/v1alpha1
kind: Component
metadata:
name: simple-component
spec:
repositoryRef:
name: ${repository.metadata.name}
component: ocm.software/ocm-k8s-toolkit/simple
semver: 1.0.0
interval: 1m
# ocmConfig is required, if the OCM repository requires credentials to access it.
# ocmConfig:
# Resource points to the Component, downloads the resource passed by reference-name and verifies it. It then
# publishes the location of the resource in its status.
- id: resourceChart
template:
apiVersion: delivery.ocm.software/v1alpha1
kind: Resource
metadata:
name: simple-resource
spec:
componentRef:
name: ${component.metadata.name}
resource:
byReference:
resource:
name: helm-resource # This must match the resource name set in the OCM component version (see above)
interval: 1m
# ocmConfig is required, if the OCM repository requires credentials to access it.
# ocmConfig:
# OCIRepository watches and downloads the resource from the location provided by the Resource status.
# The Helm chart location (url) refers to the status of the above resource.
- id: ocirepository
template:
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: OCIRepository
metadata:
name: simple-ocirepository
spec:
interval: 1m0s
layerSelector:
mediaType: "application/vnd.cncf.helm.chart.content.v1.tar+gzip"
operation: copy
url: oci://${resourceChart.status.reference.registry}/${resourceChart.status.reference.repository}
ref:
tag: ${resourceChart.status.reference.tag}
# secretRef is required, if the OCI repository requires credentials to access it.
# secretRef:
# HelmRelease refers to the OCIRepository, lets you configure the helm chart and deploys the Helm Chart into the
# Kubernetes cluster.
- id: helmrelease
template:
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: simple-helmrelease
spec:
releaseName: simple
interval: 1m
timeout: 5m
chartRef:
kind: OCIRepository
name: ${ocirepository.metadata.name}
namespace: default
values:
# We configure the Helm chart using FluxCDs HelmRelease 'values' field. We pass the value that we set in
# the instance of the CRD created by the ResourceGraphDefinition (see below).
ui:
message: ${schema.spec.message}
Note
If you pushed the OCM component version to a private registry, you need to set up the credentials for the OCM K8s
Toolkit resources. You can do this by uncommenting the ocmConfig
fields in the Repository
, Component
, and
Resource
resources and providing the necessary credentials. For more information on how to set up and pass the
credentials, please check out the guide configure credentials for OCM K8s Toolkit resources.
Be aware that FluxCD's OCIRepository
also needs access to the OCI registry that contains the Helm chart. However,
OCIRepository
only accepts
imagePullSecrets
in the same namespace.
If you want to use the same credentials for FluxCD and for the OCM K8s Toolkit resources, create a
Kubernetes secret of type dockerconfigjson
and keep all the resources in the same namespace.
After creating the file rgd.yaml
with the above content and adjusting Repository's baseUrl
to point to your OCM
repository, you can apply the ResourceGraphDefinition
to your Kubernetes cluster:
kubectl apply -f rgd.yaml
If everything went well, you should see the following output:
kubectl get rgd
NAME APIVERSION KIND STATE AGE
simple v1alpha1 Simple Active 19s
This creates a Kubernetes Custom Resource Definition (CRD) Simple
that can be used to create instances. An applied
instance of the CRD will create all resources defined in the ResourceGraphDefinition
.
To create an instance of the Simple
CRD, create a file named instance.yaml
and add the following content:
apiVersion: kro.run/v1alpha1
# Kind is the CRD name that was created by the ResourceGraphDefinition
kind: Simple
metadata:
name: simple
spec:
# This field is passed to the Helm chart and configures the message that podinfo will show
message: "bar"
Proceed by applying the instance which will create all the resources defined in the ResourceGraphDefinition
:
kubectl apply -f instance.yaml
This will take some time, but if everything went well, you should see the following output:
kubectl get simple
NAME STATE SYNCED AGE
simple ACTIVE True 5m28s
and the deployment should be in the state Available
:
kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
simple-podinfo 1/1 1 1 40m
To make sure that the deployment was configured successfully, take a look at the pod itself or execute the following command:
kubectl get pods -l app.kubernetes.io/name=simple-podinfo -o jsonpath='{.items[0].spec.containers[0].env[?(@.name=="PODINFO_UI_MESSAGE")].value}'
which should return the value you passed in the instance:
bar
You now have successfully created an OCM component version containing a Helm chart and deployed as well as configured it using the OCM K8s Toolkit, kro, and FluxCD.
One common issue, when using GitHub's container registry, is that the transferred OCM component is by default a private package. If so, you might see an error like the following:
failed to list versions: failed to list tags: GET "https://ghcr.io/v2...": response status code 401: unauthorized: authentication required
You can resolve this issue by making the package public or by providing credentials to the respective resources.