Helm helps you manage Kubernetes applications. Helm Charts help you define, install, and upgrade even the most complex Kubernetes application. Helm charts are a collection of Kubernetes YAML manifests distributed as a single package. They make it faster and easier to deploy complex applications in your cluster. Using GitLab as a ledger allows your team to store charts with your code in an organization-managed repository.
Also check:
- How to Install ChartMuseum on Kubernetes Using Helm
- How to install and set up ChartMuseum in Linux
- How to Deploy with ArgoCD Using GitHub Actions and Helm Templating
- How to Set up self-hosted Private Docker Registry
Using the Helm GitLab repository
Helm chart support in the package registry arrived in GitLab 14.1 and is available on all tiers, including Free. If you use GitLab.com, or a self-managed instance on any supported release, you already have everything you need. If you run your own server, see How to Install GitLab CE on Rocky Linux / AlmaLinux 9.
Switch over to your GitLab instance. Either create a new project or find an existing one. Using the left sidebar, navigate to Deploy > Package registry within your project (older GitLab versions label this Packages & Registries > Package Registry). If you don’t see the menu, head to Settings > General, expand the “Visibility, project features, permissions” section, and enable the Package registry toggle.
Creating a Helm chart
To create a helm chart, use the helm create command.
➜ helm create nginx
Creating nginx
Helm create a directory with the name you supplied. The directory contains the templates and chart definition. Inspect using this command:
➜ tree nginx
nginx
├── Chart.yaml
├── charts
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml
4 directories, 10 files
Helm creates a starter chart directory along with the common files and directories used in a chart with NGINX as an example. We can install this into our Kubernetes cluster:
helm install nginx ./nginx
Package for distribution
To distribute helm chart, it has to be hosted in a repo. You can build the helm chart into a compressed file for ease of distribution using this command:
➜ helm package nginx
Successfully packaged chart and saved it to: /tmp/helm/nginx-0.1.0.tgz
The command creates a new tar.gz archive ready to upload. Before doing so, you can inspect the archive with the tar command to verify its content.
➜ tar ztf nginx-0.1.0.tgz
nginx/Chart.yaml
nginx/values.yaml
nginx/templates/NOTES.txt
nginx/templates/_helpers.tpl
nginx/templates/deployment.yaml
nginx/templates/hpa.yaml
nginx/templates/ingress.yaml
nginx/templates/service.yaml
nginx/templates/serviceaccount.yaml
nginx/templates/tests/test-connection.yaml
nginx/.helmignore
Publish a package in Gitlab Package registry
For this, you need a username and an access token. To create a personal access token, select your avatar, then Edit profile > Access tokens (called Personal access tokens in newer releases), and add a token with the api scope. The write_repository scope might look correct but won’t actually work; it only facilitates access using Git over HTTP, whereas Helm requires API integration. A deploy token with the read_package_registry and write_package_registry scopes also works and is a better fit for automation. See the GitLab Helm repository docs for details.
Once built, a chart can be uploaded to the desired channel with curl or helm cm-push:
With curl:
curl --fail-with-body --request POST \
--form 'chart=@mychart-0.1.0.tgz' \
--user <username>:<access_token> \
https://gitlab.example.com/api/v4/projects/<project_id>/packages/helm/api/<channel>/charts
<username>: the GitLab username or the deploy token username.<access_token>: the personal access token or the deploy token.<project_id>: the project ID (like42) or the URL-encoded path of the project (likegroup/project).<channel>: the name of the channel (likestable).
This is the output on my server
➜ curl --request POST \
--form 'chart=@nginx-0.1.0.tgz' \
--user api-token:glpat-xxxxxxxxxxxxx \
https://gitlab.com/api/v4/projects/34000009/packages/helm/api/helm/charts
{"message":"201 Created"}
With the helm cm-push plugin
For this you will need the plugin installed. Use this command:
helm plugin install https://github.com/chartmuseum/helm-push
Helm 4 verifies plugin signatures by default, and helm-push is not signed, so on Helm 4 the install fails unless you skip verification explicitly:
helm plugin install https://github.com/chartmuseum/helm-push --verify=false
The plugin command is
helm cm-push, nothelm push. Since Helm 3.7,helm pushis a built-in command that pushes charts to OCI registries, which is not what the GitLab Helm channel API expects.
Then you need to register it with your Helm client to begin with. Use this command:
helm repo add --username <username> --password <access_token> citizix \
https://gitlab.example.com/api/v4/projects/<project_id>/packages/helm/<channel>
helm cm-push mychart-0.1.0.tgz citizix
<username>: the GitLab username or the deploy token username.<access_token>: the personal access token or the deploy token.<project_id>: the project ID (like42).<channel>: the name of the channel (likestable).
This is it in my machine
➜ helm repo add --username api-token --password glpat-xxxxx citizix https://gitlab.com/api/v4/projects/34000000/packages/helm/stable
"citizix" has been added to your repositories
Then push
➜ helm cm-push nginx-0.1.0.tgz citizix
Pushing nginx-0.1.0.tgz to citizix...
Done.
Confirm
➜ helm search repo citizix
NAME CHART VERSION APP VERSION DESCRIPTION
citizix/nginx 0.1.0 1.16.0 A Helm chart for Kubernetes
Using Charts in the Repository
With the chart in your repository, you can deploy it into your Kubernetes cluster. helm install commands should work straightaway:
# load the contents of repositories
helm repo update
# install the chart (Helm 3+ requires a release name)
helm install nginx citizix/nginx
This will start a new chart deployment into your active cluster. Use the --kubeconfig and --namespace Helm flags if necessary to select an appropriate Kubernetes configuration file and specify the namespace to deploy into.
Accessing GitLab’s Repository in a CI Pipeline
As with its other package formats, GitLab’s Helm repository benefits from built-in integration with the software’s CI/CD system. Your pipelines will receive preset environment variables which simplify the chart publication process. You don’t need to set any custom CI variables to configure authentication.
Here’s an example pipeline which packages a chart and publishes it to the stable channel of your project’s repository:
stages:
- helm-package
- helm-publish
helm-package:
stage: helm-package
image:
name: alpine/helm:latest
entrypoint: [""]
script:
- helm package my-chart
artifacts:
paths:
- "*.tgz"
helm-publish:
stage: helm-publish
image: curlimages/curl:latest
script:
- |
for chart in *.tgz; do
curl --fail-with-body --request POST \
--user "gitlab-ci-token:${CI_JOB_TOKEN}" \
--form "chart=@${chart}" \
"${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/helm/api/stable/charts"
done
CI_JOB_TOKEN, CI_API_V4_URL and CI_PROJECT_ID are predefined in every job, so the job token authenticates the upload with no extra setup. Don’t use $CI_REGISTRY and helm push here: those target the project’s container registry (OCI), not the Helm package registry.