Helm
December 16, 2024 · View on GitHub
Package Manager for Kubernetes.
Helm is the original Kubernetes app manager before the rise of Kustomize and still the primary mechanism of deploying public Kubernetes applications.
Key Points
- templated Kubernetes YAML manifests
- release is a deployed combination of Chart bundle + your custom
values.yamlvariables - stores release info in k8s secret in same namespace as the release, no DB needed
Chart.yaml- master file with name, version, description, maintainers, sourcesrequirements.yaml- links to other charts this one depends on eg. MySQL/MariaDBvalues.yaml- variable defaults, common to use your own values.yaml with an upstream charttemplates/- dir of Kubernetes YAML resource manifests Go templates, that use values.yaml variables- hooks - pre-install / post-install / delete / upgrade / rollback
- usage examples include to load a configmap / secret or run a backup at specific point in the deployment lifecycle
Helm v3
- no more Tiller pod needed like v2 (was considered a security bad practice)
- software installation no longer generates a name automatically.
One must be provided, or use the
--generate-nameoption
Install
On Mac with Homebrew:
brew install helm
or
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
or portable binary install with optional version specified using script from DevOps-Bash-tools: repo:
install_helm.sh # <version>
Repos
Add repos from which to search and install helm chart packages.
Helm repos you should probably have installed:
| Repo Label | URL |
|---|---|
| stable | https://charts.helm.sh/stable |
| bitnami | https://charts.bitnami.com/bitnami |
| fairwinds-stable | https://charts.fairwinds.com/stable |
Table generated from HariSekhon/Kubernetes-configs file helm-repos.txt by script generate_repos_markdown_table.sh
These repos can be quickly installed in one command using the script install_repos.sh:
./github/k8s/install_repos.sh
or the old fashioned manual way:
helm repo add stable https://charts.helm.sh/stable
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add fairwinds-stable https://charts.fairwinds.com/stable
Search for Packages
Refresh the package lists:
helm repo update
Search ArtifactHub:
helm search hub database
Search your locally installed repos:
helm search repo stable
helm search repo bitnami
helm search repo fairwinds-stable
Show chart metadata:
helm show chart bitnami/mysql
Show chart metadata, values.yaml and notes (warning this is a huge output):
helm show all bitnami/mysql
Show available versions:
helm search repo fairwinds-stable/goldilocks --versions
Install Chart
helm show values stable/mysql > values.yaml
Name must be lowercase:
helm install "$name" -f values.yaml stable/nginx-ingress
--set key=value,key2=value2 CLI values overrides - saved in a configmap, run helm get values "$name" to see them
WARNING: helm status doesn't detect if k8s objects deleted / modified - this is why you need ArgoCD
for GitOps:
helm status "$name"
Show user customized values:
helm get values "$name"
Also repairs missing objects eg. a deleted svc:
helm upgrade "$name" -f values.yaml stable/mysql
--reset-values clears the custom config values:
helm upgrade "$name" stable/mysql --reset-values
helm uninstall "$name" # --keep-history - for 'helm status' to show as uninstalled
List all installed applications in all namespaces:
helm list --all-namespaces
or shorthand:
helm ls -A
See revisions deployed (starts at 1):
helm history "$name"
Can even undelete a release:
helm rollback "$name" "$revision"
Extract Chart and templates from cache, copy values.yaml to custom.yaml:
~/.cache/helm/repository/mariadb-7.3.14.tgz
Install a chart from a local tarball:
helm install "$name" chart-0.1.1.tgz
Install a chart from a local directory containing the unpacked tarball contents seen in the Create Your Own Helm Chart section below:
helm install "$name" chart/
or
helm install "$name" https://.../foo-1.2.3.tgz
Docker Registries
helm registry login -u myuser localhost:5000
helm registry logout
helm chart save mychart/ localhost:5000/myrepo/mychart:2.7.0
helm chart list
helm chart export localhost:5000/myrepo/mychart:2.7.0
helm chart push localhost:5000/myrepo/mychart:2.7.0
helm chart pull localhost:5000/myrepo/mychart:2.7.0
helm chart remove localhost:5000/myrepo/mychart:2.7.0
Create Your Own Helm Chart
I personally prefer to create Kustomize deployments for internal apps as they're more flexible and you don't have to anticipate all variations and created template variables for them all up front.
But some people are still using Helm charts for internal apps, so here is how you do it.
Create template
helm create "$name"
creates a $name/ directory with tree contents:
$name/
├── Chart.yaml # names app and remote dependency charts
├── charts # for dependency charts, you probably won't need this
├── templates # K8s yaml content templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── deployment.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml # the file you usually configure for public charts
4 directories, 10 files
Edit
Edit the templates/ and values.yaml files to suit your needs.
Print the yaml that Helm generates:
helm template "$USER-test" .
Lint
Defaults to checking $PWD/Chart.yaml:
helm lint
or given directory containing Chart.yaml:
helm lint "$name"
Install Custom Chart
Install it from source assuming you're in the "$name/" directory to your currently configured Kubernetes kubectl
cluster context:
helm install "$USER-test" .
Generate "$name"-0.1.0.tgz
helm package "$name"
Install from tarball:
helm install "$name" ./"$name"-0.1.0.tgz
Chart Repo
GitHub
Turn a GitHub repo into helm chart repo:
https://helm.sh/docs/howto/chart_releaser_action/
AWS ECR
AWS ECR can be used as an OCI repo, requires Helm 3.7+.
OCI registries do not support the helm repo add command.
Helm uses oci:// protocol directly with helm push / helm pull / helm install.
IAM role used needs to have IAM permissions to ECR repo:
ecr:GetAuthorizationToken
ecr:BatchCheckLayerAvailability
ecr:BatchGetImage
ecr:GetDownloadUrlForLayer
Log Helm in to AWS:
aws ecr get-login-password |
helm registry login \
--username AWS \
--password-stdin \
"$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com"
Package your chart to my-chart-0.1.0.tgz:
helm package my-chart
Push it to AWS ECR using OCI:
helm push my-chart-0.1.0.tgz "oci://$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com"
Pull a chart from AWS ECR using OCI to a local file my-chart-0.1.0.tgz:
helm pull "oci://$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/my-chart" --version 0.1.0
Install a chart (implicitly pulls if needed):
helm install my-release "oci://$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/my-chart" --version 0.1.0
GCP GCS
Manual Repo on GCS:
https://helm.sh/docs/howto/chart_repository_sync_example/
Create an index file supporting the given URL:
helm repo index "$chartsdir"/ --url https://"$bucket_name".storage.googleapis.com
Sync the dir to GCS to serve:
gsutil rsync -d "$chartsdir/" "gs://$bucket_name"
Helm + Kustomize
Kustomize + Helm dynamically
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
helmCharts:
- name: myapp
repo: https://...
version: 1.0.0
releaseName: myrelease
namespace: myapp
includeCRDs: true
valuesFile: values.yaml
Kustomize + Helm statically
This has the benefit that you can revision control the helm yaml to see the diffs and control changes more tightly:
helm show values "$repo/$chart" > values.yaml
helm template "$name" "$repo/$chart" --version "$version" --values values.yaml > output.yaml
Add output.yaml to kustomization.yaml
resources and run kustomize build and kubectl apply as usual:
kustomize build | kubectl apply -f -
You can then proceed to add standard Kustomize patches as usual too.
Static Templating Helm Tarball
helm fetch --untar stable/mariadb
helm template -f values.yaml mariadb/ > mariadb.yaml
Or Manually:
mkdir -p charts
helm fetch \
--untar \
--untardir charts \
stable/nginx-ingress
mkdir -p base
helm template \
--name ingress-controller \
--output-dir base \
--namespace ingress \
--values values.yaml \
charts/nginx-ingress
mv base/nginx-ingress/templates/* base/nginx-ingress &&
rm -rf base/nginx-ingress/templates
Instantiate new Templates
new namespace.yaml
new kustomization.yaml # list all the *.yaml name under resources: and add patches to override/extend
Old: Helm v2
curl https://git.io/get_helm.sh | bash
Create helm service acccount and grant it ClusterRole full access in GKE using [Template](https://github. com/HariSekhon/Templates) repo:
kubectl apply -f "$templates/k8s_tiller-serviceaccount.yaml"
Installs Tiller in cluster - Tiller needs access to entire cluster and is going away:
helm init --service-account helm
kubectl get deploy,svc tiller-deploy -n system
Rest of commands are same as above sections.
Change from ClusterIP to LoadBalancer service:
helm upgrade --set service.type='LoadBalancer' myrelease stable/wordpress
Tiller will delete even persistent disks:
helm delete myrelease
Ported from private Knowledge Base page 2019+