How to Deploy a Helm Chart on a Kubernetes Cluster
How to deploy a Helm chart on a Kubernetes cluster
Install the Helm CLI, point it at a Quake AI Kubernetes cluster (OpenStack Magnum), and deploy a chart with a values file. This guide covers adding a chart repository, running helm upgrade --install, supplying image-pull credentials for private registries, exposing a release through a Kubernetes Service of type LoadBalancer, and rolling back a release.
Prerequisites
- CLIOpenStack CLI installed and authenticated (
clouds.yamloropenrcsourced)
Windows: CLI examples use bash. Set up a Linux CLI environment on Windows before proceeding.
- A Quake AI Kubernetes cluster in
CREATE_COMPLETEstatus. See How to create a Kubernetes cluster. kubectlinstalled on your workstation. The cluster creation guide covers retrieving a kubeconfig.- The
openstackCLI authenticated with a password-scoped session.openstack coe cluster configreads the cluster's kubeconfig through Magnum. See the Kubernetes FAQ for the password-scope requirement. - Network access from your workstation to the cluster's Kubernetes API endpoint.
Install the Helm CLI#
Helm is a single client-side binary. It stores release state as Secrets inside the cluster, so no server-side component (no Tiller) runs on the cluster. Helm 3 and Helm 4 share the same command set used in this guide.
Install Helm with the official script:
curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bashOn macOS, install Helm with Homebrew instead:
brew install helmConfirm the version:
helm versionExpected output names a current Helm release (for example v3.15.x or v4.x):
version.BuildInfo{Version:"v4.2.2", GitTreeState:"clean", GoVersion:"go1.24.0"}Connect Helm to your cluster#
Helm reads the same kubeconfig as kubectl. Retrieve the cluster's kubeconfig from Magnum, then confirm both tools target the cluster.
Retrieve and load the kubeconfig:
openstack coe cluster config production-k8s --dir "$HOME/.kube/production-k8s"
export KUBECONFIG="$HOME/.kube/production-k8s/config"openstack coe cluster config with --dir writes the cluster's config file to the directory you name. Without --dir the command writes config into the current working directory, which fails when that directory already holds a config entry (for example a Helm chart's config/ folder). Set KUBECONFIG to the written file so both kubectl and helm read it.
Confirm kubectl reaches the cluster:
kubectl get nodesConfirm Helm resolves the same context:
helm list --all-namespacesAn empty release table confirms Helm connects to a cluster with no Helm-managed releases yet.
Add a chart repository#
A chart repository is an index of packaged charts served over HTTP. Add the repository that hosts the chart you want, then refresh the local index.
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo updateSearch the repository for a chart and inspect its configurable values:
helm search repo bitnami/nginx
helm show values bitnami/nginx > default-values.yamlhelm show values writes the chart's full default values to default-values.yaml. Use it as the reference for the keys you override in your own values file.
Install a chart with a values file#
Keep your overrides in a version-controlled values file rather than passing every setting on the command line. Create values.yaml with the settings your deployment needs:
replicaCount: 2
service:
type: ClusterIP
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256MiInstall the chart with helm upgrade --install. This command installs the release if it does not exist and upgrades it in place if it does, so the same command works for the first deploy and every later change:
helm upgrade --install web bitnami/nginx \
--namespace web \
--create-namespace \
--values values.yaml| Flag | Description |
|---|---|
web | The release name. Helm tracks all resources it creates under this name. |
bitnami/nginx | The chart reference in repository/chart form. |
--namespace | The target namespace for the release. |
--create-namespace | Creates the namespace if it does not already exist. |
--values | Path to your values file. Repeat the flag to layer multiple files; later files win. |
Confirm the release and its pods:
helm status web --namespace web
kubectl get pods --namespace webTo preview the manifests a release would apply without changing the cluster, add --dry-run to the helm upgrade --install command.
Pull images from a private registry#
If your chart references images in a private registry, create an image-pull secret in the release namespace and reference it from your values file. Without it, pods fail to start with ImagePullBackOff.
Create the secret:
kubectl create secret docker-registry regcred \
--namespace web \
--docker-server=registry.example.com \
--docker-username=YOUR_REGISTRY_USER \
--docker-password=YOUR_REGISTRY_TOKENReference the secret from your values file. Most charts expose an image-pull-secrets key; some read a global key:
global:
imagePullSecrets:
- regcredCharts vary in where they expose this key. Check the output of helm show values for the exact path before you set it. Re-run the helm upgrade --install command to apply the change.
Expose a release with a load balancer#
A chart that serves traffic outside the cluster can expose it through a Kubernetes Service of type LoadBalancer. The cluster assigns a public address to the Service and routes traffic to the release pods.
Set the Service type in your values file:
service:
type: LoadBalancerApply the change and watch for the assigned address:
helm upgrade --install web bitnami/nginx \
--namespace web \
--values values.yaml
kubectl get svc web-nginx --namespace web --watchWhen provisioning completes, the EXTERNAL-IP column shows the load balancer address. On a healthy cluster, the address usually appears within a few minutes. Wait up to 10 minutes before you treat a pending address as a failure.
When EXTERNAL-IP stays pending#
The cluster provisions the public Service endpoint asynchronously. If EXTERNAL-IP is still empty after about 10 minutes, inspect the Service and its events:
kubectl describe svc web-nginx --namespace web
kubectl get events --namespace web --field-selector involvedObject.name=web-nginx
openstack quota show --floatingipHealthy provisioning emits EnsuringLoadBalancer and EnsuredLoadBalancer events on the Service. Repeated error events point to cluster networking, cloud-controller-manager, or floating IP quota problems rather than Helm. Capture the command output above before you file a platform ticket if provisioning never completes.
Roll back a release#
Helm records a numbered revision on every install and upgrade. When an upgrade misbehaves, roll back to a known-good revision.
List the revision history:
helm history web --namespace webRoll back to a specific revision:
helm rollback web 1 --namespace webhelm rollback creates a new revision that restores the resource state of the target revision, so the rollback is itself recorded in the history and is reversible. Confirm the result:
helm status web --namespace webTo remove a release and the resources it created:
helm uninstall web --namespace webhelm uninstall deletes the release's Kubernetes objects, including any LoadBalancer Service, which releases the associated floating IP back to your project.
Next steps#
- How to deploy to a Quake AI Kubernetes cluster from CI: automate
helm upgradeorkubectl applyfrom GitHub Actions or GitLab CI - How to use a container registry with Quake AI: image pull secrets for private charts
- How to create a Kubernetes cluster: provision the cluster this guide deploys to
- How to create a cluster template: control boot volumes, node addressing, and the control-plane endpoint
- How to manage a Kubernetes cluster: scale workers, retrieve the kubeconfig, and delete clusters
- Kubernetes FAQ: control plane ownership, quotas, and CLI authentication
- Kubernetes CLI reference: the
openstack coe clustercommand set
Usage Guidelines
The sample code, software libraries, command line tools, proofs of concept, templates, and other related technology on this page (including any of the foregoing that is provided by Quake AI personnel) is provided to you as Quake AI Content under the Quake AI Customer Agreement, or the relevant written agreement between you and Quake AI (whichever applies). Do not use this Quake AI Content in your production accounts, or on production or other critical data. You are responsible for testing, securing, and optimizing the Quake AI Content (such as sample code) as appropriate for production grade use based on your specific quality control practices and standards. Deploying Quake AI Content may incur Quake AI charges for creating or using Quake AI chargeable resources, such as running Compute instances or storing data in Object Storage. Your use is also subject to the Acceptable Use Policy.
For the full policy, see Usage Guidelines.
Last validated: 30.06.2026
Quick answers
- Why does `openstack coe cluster create` fail with a Keystone trust or unauthorized error when I use an application credential?CLIAPITerraform
- Why does a Kubernetes LoadBalancer service stay `<pending>` for several minutes?CLI
- Why does my GitHub Actions or GitLab CI job fail to run `openstack coe` or `kubectl` on a Magnum cluster?CLI