Helm’s default behavior is to see all releases, across all namespaces. This can get noisy and confusing when you have many teams or applications sharing a cluster.
Let’s see this in action. Imagine a cluster with two namespaces, dev and prod, and a release named my-app in each.
# List all releases in the cluster
helm list -A
This will output something like:
NAME NAMESPACE REVISION DEPLOYED CHART APP VERSION
my-app dev 1 2023-10-27 app-0.1.0 1.0.0
my-app prod 2 2023-10-26 app-0.1.0 1.0.0
another-app dev 1 2023-10-25 other-1.2.3 2.1.0
Notice how my-app appears twice, once for each namespace. If you only care about the dev namespace, this output is unnecessarily cluttered.
The problem Helm solves here is visibility and management at scale. Without namespace scoping, managing releases becomes a needle-in-a-haystack problem. You might accidentally upgrade a release in the wrong environment, or struggle to find the specific version of an application you’re looking for. Namespace-level scoping provides a crucial organizational boundary, making Helm commands more targeted and less error-prone.
Internally, Helm uses Kubernetes’ namespace concept to segregate its release metadata. When you install a Helm release, it creates a Kubernetes Secret (by default) in the specified namespace. This secret contains all the information about the release: its manifest history, values, and status. The helm list command, when run with -A (all namespaces), queries all namespaces for these secrets and aggregates the results.
The primary lever you control for namespace scoping is the -n or --namespace flag when running Helm commands. This flag tells Helm to limit its operations to a specific namespace.
Let’s say you want to see only the releases in the dev namespace.
# List releases only in the 'dev' namespace
helm list -n dev
The output will be:
NAME NAMESPACE REVISION DEPLOYED CHART APP VERSION
my-app dev 1 2023-10-27 app-0.1.0 1.0.0
another-app dev 1 2023-10-25 other-1.2.3 2.1.0
This is much cleaner. You can apply this scoping to all Helm commands: helm install, helm upgrade, helm uninstall, helm status, and helm rollback.
For example, to upgrade my-app in the prod namespace:
# Upgrade my-app in the prod namespace
helm upgrade my-app ./charts/app -n prod
If you omit -n prod, Helm would attempt to upgrade the release named my-app in your current default Kubernetes namespace, which might not be prod at all, leading to unintended consequences.
When you use helm list without any namespace flags, it defaults to listing releases in your current Kubernetes context’s default namespace. This can be a source of confusion if you’re not paying close attention to your kubectl config current-context. Using -n explicitly avoids this ambiguity.
A common mistake is to forget the -n flag when performing operations, especially when switching between namespaces. Helm doesn’t have a persistent "current namespace" setting like kubectl does. Each command invocation is independent and relies on the flags provided or the cluster’s default namespace if no flag is given.
The fact that Helm release metadata is stored as Kubernetes Secrets means that RBAC (Role-Based Access Control) plays a critical role in what you can see and do. If a user doesn’t have permission to list Secrets in a particular namespace, helm list (even with -A) will simply not show releases in that namespace for them. This is a powerful security feature that allows you to enforce granular access control over Helm deployments.
Once you’re comfortable with namespace scoping, the next natural step is understanding how to manage Helm repositories effectively, including adding, updating, and removing them to ensure you’re always pulling the correct charts.