I tend to run tools as Docker containers, if their Docker images are provided. Such image for Helm is: alpine/helm - Docker Image | Docker Hub.
To run the container (and its default command which is helm -h):
$ docker run --rm alpine/helm
The Kubernetes package manager
Common actions for Helm:
- helm search: search for charts
- helm pull: download a chart to your local directory to view
- helm install: upload the chart to Kubernetes
- helm list: list releases of charts
Environment variables:
| Name | Description |
|------------------------------------|------------------------------------------------------------------------------------------------------------|
| $HELM_CACHE_HOME | set an alternative location for storing cached files. |
| $HELM_CONFIG_HOME | set an alternative location for storing Helm configuration. |
| $HELM_DATA_HOME | set an alternative location for storing Helm data. |
| $HELM_DEBUG | indicate whether or not Helm is running in Debug mode |
| $HELM_DRIVER | set the backend storage driver. Values are: configmap, secret, memory, sql. |
| $HELM_DRIVER_SQL_CONNECTION_STRING | set the connection string the SQL storage driver should use. |
| $HELM_MAX_HISTORY | set the maximum number of helm release history. |
| $HELM_NAMESPACE | set the namespace used for the helm operations. |
| $HELM_NO_PLUGINS | disable plugins. Set HELM_NO_PLUGINS=1 to disable plugins. |
| $HELM_PLUGINS | set the path to the plugins directory |
| $HELM_REGISTRY_CONFIG | set the path to the registry config file. |
| $HELM_REPOSITORY_CACHE | set the path to the repository cache directory |
| $HELM_REPOSITORY_CONFIG | set the path to the repositories file. |
| $KUBECONFIG | set an alternative Kubernetes configuration file (default "~/.kube/config") |
| $HELM_KUBEAPISERVER | set the Kubernetes API Server Endpoint for authentication |
| $HELM_KUBECAFILE | set the Kubernetes certificate authority file. |
| $HELM_KUBEASGROUPS | set the Groups to use for impersonation using a comma-separated list. |
| $HELM_KUBEASUSER | set the Username to impersonate for the operation. |
| $HELM_KUBECONTEXT | set the name of the kubeconfig context. |
| $HELM_KUBETOKEN | set the Bearer KubeToken used for authentication. |
| $HELM_KUBEINSECURE_SKIP_TLS_VERIFY | indicate if the Kubernetes API server's certificate validation should be skipped (insecure) |
| $HELM_KUBETLS_SERVER_NAME | set the server name used to validate the Kubernetes API server certificate |
| $HELM_BURST_LIMIT | set the default burst limit in the case the server contains many CRDs (default 100, -1 to disable) |
| $HELM_QPS | set the Queries Per Second in cases where a high number of calls exceed the option for higher burst values |
Helm stores cache, configuration, and data based on the following configuration order:
- If a HELM_*_HOME environment variable is set, it will be used
- Otherwise, on systems supporting the XDG base directory specification, the XDG variables will be used
- When no other location is set a default location will be used based on the operating system
By default, the default directories depend on the Operating System. The defaults are listed below:
| Operating System | Cache Path | Configuration Path | Data Path |
|------------------|---------------------------|--------------------------------|-------------------------|
| Linux | $HOME/.cache/helm | $HOME/.config/helm | $HOME/.local/share/helm |
| macOS | $HOME/Library/Caches/helm | $HOME/Library/Preferences/helm | $HOME/Library/helm |
| Windows | %TEMP%\helm | %APPDATA%\helm | %APPDATA%\helm |
Usage:
helm [command]
Available Commands:
completion generate autocompletion scripts for the specified shell
create create a new chart with the given name
dependency manage a chart's dependencies
env helm client environment information
get download extended information of a named release
help Help about any command
history fetch release history
install install a chart
lint examine a chart for possible issues
list list releases
package package a chart directory into a chart archive
plugin install, list, or uninstall Helm plugins
pull download a chart from a repository and (optionally) unpack it in local directory
push push a chart to remote
registry login to or logout from a registry
repo add, list, remove, update, and index chart repositories
rollback roll back a release to a previous revision
search search for a keyword in charts
show show information of a chart
status display the status of the named release
template locally render templates
test run tests for a release
uninstall uninstall a release
upgrade upgrade a release
verify verify that a chart at the given path has been signed and is valid
version print the client version information
Flags:
--burst-limit int client-side default throttling limit (default 100)
--debug enable verbose output
-h, --help help for helm
--kube-apiserver string the address and the port for the Kubernetes API server
--kube-as-group stringArray group to impersonate for the operation, this flag can be repeated to specify multiple groups.
--kube-as-user string username to impersonate for the operation
--kube-ca-file string the certificate authority file for the Kubernetes API server connection
--kube-context string name of the kubeconfig context to use
--kube-insecure-skip-tls-verify if true, the Kubernetes API server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--kube-tls-server-name string server name to use for Kubernetes API server certificate validation. If it is not provided, the hostname used to contact the server is used
--kube-token string bearer token used for authentication
--kubeconfig string path to the kubeconfig file
-n, --namespace string namespace scope for this request
--qps float32 queries per second used when communicating with the Kubernetes API, not including bursting
--registry-config string path to the registry config file (default "/root/.config/helm/registry/config.json")
--repository-cache string path to the file containing cached repository indexes (default "/root/.cache/helm/repository")
--repository-config string path to the file containing repository names and URLs (default "/root/.config/helm/repositories.yaml")
Use "helm [command] --help" for more information about a command.
We'd get the same output if we run:
$ docker run --rm alpine/helm -h
Let's check the Helm version:
$ docker run --rm alpine/helm version
version.BuildInfo{Version:"v3.15.3", GitCommit:"3bb50bbbdd9c946ba9989fbe4fb4104766302a64", GitTreeState:"clean", GoVersion:"go1.22.5"}
Let's say we want to list releases in the local Minikube cluster. Let's assume kubectl's current context is set to minikube.
If we run:
$ docker run --rm alpine/helm list
Error: Kubernetes cluster unreachable: Get "http://localhost:8080/version": dial tcp [::1]:8080: connect: connection refused
The error tells that Helm didn't find the right kubeconfig and it used default cluster API server url. We need to provide Helm the correct kubeconfig. In our case it's ~/.kube/config so we need to mount ~/.kube as a volume:
$ docker run --rm -v ~/.kube:/root/.kube alpine/helm list
Error: Kubernetes cluster unreachable: invalid configuration: [unable to read client-cert /home/bojan/.minikube/profiles/minikube/client.crt for minikube due to open /home/bojan/.minikube/profiles/minikube/client.crt: no such file or directory, unable to read client-key /home/bojan/.minikube/profiles/minikube/client.key for minikube due to open /home/bojan/.minikube/profiles/minikube/client.key: no such file or directory, unable to read certificate-authority /home/bojan/.minikube/ca.crt for minikube due to open /home/bojan/.minikube/ca.crt: no such file or directory]
This error shows Helm could not access certificates that are references in kubeconfig:
$ cat ~/.kube/config
or
$ kubectl config view
...give the following output:
apiVersion: v1
clusters:
...
- cluster:
certificate-authority: /home/bojan/.minikube/ca.crt
extensions:
- extension:
last-update: Sat, 03 Aug 2024 00:16:58 BST
provider: minikube.sigs.k8s.io
version: v1.33.0
name: cluster_info
server: https://192.168.59.100:8443
name: minikube
contexts:
...
- context:
cluster: minikube
extensions:
- extension:
last-update: Sat, 03 Aug 2024 00:16:58 BST
provider: minikube.sigs.k8s.io
version: v1.33.0
name: context_info
namespace: default
user: minikube
name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
...
- name: minikube
user:
client-certificate: /home/bojan/.minikube/profiles/minikube/client.crt
client-key: /home/bojan/.minikube/profiles/minikube/client.key
Helm in container needs to access both kubeconfig file and also all files referenced in it, in our case:
- /home/bojan/.minikube/ca.crt
- /home/bojan/.minikube/profiles/minikube/client.crt
- /home/bojan/.minikube/profiles/minikube/client.key
We can mount /home/bojan/.minikube/ as a volume (see
docker run | Docker Docs), at the same path (which will be created in container).
$ docker run --rm -v ~/.kube:/root/.kube -v /home/bojan/.minikube:/home/bojan/.minikube alpine/helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
This shows we don't have any releases in our Minikube cluster.
Converting the original (non-templated) manifests to Helm chart
Let's look at we have the following original (non-templated) manifest files:
If we run Helm as a Docker container and want to use it to create deployment in the Minikube cluster we can do:
$ docker run --rm \
-v ~/.kube:/root/.kube \
-v $(pwd)/minikube/php-fmp-nginx-demo:/apps \
-v /home/bojan/.minikube:/home/bojan/.minikube \
alpine/helm
Creating helm-chart
This creates a helm-chart directory:
Note that Docker's default user is root so this new directory and all its content will have root as an owner and any future local action on these objects will require elevated privileges:
$ ls -la ./minikube/php-fmp-nginx-demo/helm-chart/
total 28
drwxr-xr-x 4 root root 4096 Aug 3 13:36 .
drwxrwxr-x 4 bojan bojan 4096 Aug 3 13:36 ..
drwxr-xr-x 2 root root 4096 Aug 3 13:36 charts
-rw-r--r-- 1 root root 1146 Aug 3 13:36 Chart.yaml
-rw-r--r-- 1 root root 349 Aug 3 13:36 .helmignore
drwxr-xr-x 3 root root 4096 Aug 3 13:36 templates
-rw-r--r-- 1 root root 2363 Aug 3 13:36 values.yaml
To prevent this we can tell Docker to use non-root user.
$ id
uid=1000(bojan) gid=1000(bojan) groups=1000(bojan),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),116(lpadmin),126(sambashare),142(libvirt),999(docker)
$ sudo rm -rf ./minikube/php-fmp-nginx-demo/helm-chart/
$ docker run --rm -v ~/.kube:/root/.kube -v $(pwd)/minikube/php-fmp-nginx-demo:/apps -v /home/bojan/.minikube:/home/bojan/.minikube --user 1000:1000 alpine/helm create helm-chart
Creating helm-chart
$ ls -la ./minikube/php-fmp-nginx-demo/helm-chart/
total 28
drwxr-xr-x 4 bojan bojan 4096 Aug 3 14:24 .
drwxrwxr-x 4 bojan bojan 4096 Aug 3 14:24 ..
drwxr-xr-x 2 bojan bojan 4096 Aug 3 14:24 charts
-rw-r--r-- 1 bojan bojan 1146 Aug 3 14:24 Chart.yaml
-rw-r--r-- 1 bojan bojan 349 Aug 3 14:24 .helmignore
drwxr-xr-x 3 bojan bojan 4096 Aug 3 14:24 templates
-rw-r--r-- 1 bojan bojan 2363 Aug 3 14:24 values.yaml
minikube/php-fmp-nginx-demo/helm-chart/values.yaml:
deployment-nginx:
name: nginx-deployment
minikube/php-fmp-nginx-demo/helm-chart/templates/nginx-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.deployment-nginx.name }}
$ docker run --rm -v ~/.kube:/root/.kube -v $(pwd)/minikube/php-fmp-nginx-demo:/php-fmp-nginx-demo -v /home/bojan/.minikube:/home/bojan/.minikube alpine/helm install --dry-run --debug php-fmp-nginx-demo-release-v1.0 /php-fmp-nginx-demo/helm-chart
install.go:222: [debug] Original chart version: ""
install.go:239: [debug] CHART PATH: /php-fmp-nginx-demo/helm-chart
Error: INSTALLATION FAILED: parse error at (helm-chart/templates/nginx-deployment.yaml:4): bad character U+002D '-'
helm.go:84: [debug] parse error at (helm-chart/templates/nginx-deployment.yaml:4): bad character U+002D '-'
INSTALLATION FAILED
https://stackoverflow.com/questions/75375090/merge-annotations-in-helm
https://github.com/helm/helm/issues/2192
https://v2.helm.sh/docs/chart_best_practices/
https://github.com/helm/helm-www/issues/1272
https://stackoverflow.com/questions/63853679/helm-templating-doesnt-let-me-use-dash-in-names
https://stackoverflow.com/questions/47844377/how-can-i-create-a-volume-for-the-current-user-home-directory-in-docker-compose
https://helm.sh/docs/helm/helm_install/
https://github.com/roboll/helmfile/issues/176
https://controlplane.com/community-blog/post/kubeconfig-file-for-the-aws-eks-cluster
https://discuss.kubernetes.io/t/the-connection-to-the-server-localhost-8080-was-refused-did-you-specify-the-right-host-or-port/1464/4
https://stackoverflow.com/questions/63066604/error-kubernetes-cluster-unreachable-get-http-localhost8080-versiontimeou
https://k21academy.com/docker-kubernetes/the-connection-to-the-server-localhost8080-was-refused/
https://docs.docker.com/reference/cli/docker/container/run/#volume
References: