Ever installed an application with Helm and needed to end up troubleshooting? While it would be great if a Helm installation worked every time, you would likely need to troubleshoot from time to time due to the variety of deployment environments and cluster configurations. One of the best ways to start troubleshooting is to inspect what Helm has created for you.
Most customers I work with gravitate towards using kubectl (or the OpenShift equivalent “oc”) to get the YAML for each resource, but this can be cumbersome, especially since “kubectl get all” may not truly get “all” of the created resources.
Instead, Helm has a built-in feature called helm get that lets you get all of the information you’re looking for (and more). By the end of this article, you’ll see why I like to refer to “helm get” as a Swiss Army Knife for troubleshooting Helm deployments.
The “Helm Get” Subcommands
Let’s take a peek at helm get and its set of subcommands:
→ helm get --help
This command consists of multiple subcommands which can be used to
get extended information about the release, including:
- The values used to generate the release
- The generated manifest file
- The notes provided by the chart of the release
- The hooks associated with the release
Usage:
helm get [command]
Available Commands:
all download all information for a named release
hooks download all hooks for a named release
manifest download the manifest for a named release
notes download the notes for a named release
values download the values file for a named release
As you can see, the command provides five different subcommands you can use to get information about your Helm release. Out of these subcommands, I use “helm get manifest” and “helm get values” the most, though I’ll touch on each of these in this article. However, since I believe “helm get manifest” is the most helpful, I’ll start discussing this command.
Get YAML Resources With “Helm Get Manifest”
When you encounter an error with your Helm release, one of the most useful actions you can take is to inspect the created YAML resources. The helm get manifest command makes this very easy. Here’s an example output from an NGINX installation:
---
# Source: nginx/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx
labels:
helm.sh/chart: nginx-0.1.0
app.kubernetes.io/name: nginx
app.kubernetes.io/instance: nginx
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
---
# Source: nginx/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
helm.sh/chart: nginx-0.1.0
app.kubernetes.io/name: nginx
app.kubernetes.io/instance: nginx
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
spec:
type: ClusterIP
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: nginx
app.kubernetes.io/instance: nginx
---
# Source: nginx/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
labels:
helm.sh/chart: nginx-0.1.0
app.kubernetes.io/name: nginx
app.kubernetes.io/instance: nginx
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: nginx
app.kubernetes.io/instance: nginx
template:
metadata:
labels:
app.kubernetes.io/name: nginx
app.kubernetes.io/instance: nginx
spec:
serviceAccountName: nginx
securityContext:
{}
containers:
- name: nginx
securityContext:
{}
image: "nginx:1.16.0"
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
{}
As you can see, the “helm get manifest” command output each of the created Kubernetes resources. From here, you could inspect the YAML for issues, some of the most common I encounter being:
- Incorrect image
- Incorrect service port
- Incorrect liveness/readiness probe
- Lack of or incorrect NetworkPolicy
- Incorrect PVC/ConfigMap/Secret reference or mount path
To help discover where you should focus in the YAML, you can use the “kubectl describe” command if you have a failing Pod or a pending resource. This command gets a list of events that often help determine where you should be looking in your YAML. I wrote a blog post on the kubectl describe command if you’re interested in learning more.
Next, let’s learn how to recall the applied values for a Helm installation.
Get Applied Values With “Helm Get Values”
Given that values are the way to customize a Helm installation, knowing the applied values used is an important piece of information for troubleshooting. You can recall these values easily using the helm get values command:
→ helm get values nginx
USER-SUPPLIED VALUES:
replicas: 2
service:
type: NodePort
The “helm get values” command, when invoked without arguments, shows the values you provided that differ from the defaults. I find this output to be sufficient most of the time, but if you want to include the defaults, you can pass the –all flag:
→ helm get values nginx --all
COMPUTED VALUES:
affinity: {}
autoscaling:
enabled: false
maxReplicas: 100
minReplicas: 1
targetCPUUtilizationPercentage: 80
fullnameOverride: ""
image:
pullPolicy: IfNotPresent
repository: nginx
tag: ""
imagePullSecrets: []
ingress:
annotations: {}
enabled: false
hosts:
- host: chart-example.local
paths: []
tls: []
nameOverride: ""
nodeSelector: {}
podAnnotations: {}
podSecurityContext: {}
replicaCount: 1
replicas: 2
resources: {}
securityContext: {}
service:
port: 80
type: NodePort
serviceAccount:
annotations: {}
create: true
name: ""
tolerations: []
While you’ll probably use “helm get manifest” more, “helm get values” is a good way to understand how the YAML manifest came to be. If you observe a misconfiguration in the YAML manifest, you can check the list of applied values to make sure things match up the way you expect.
Let’s look at “helm get hooks” next.
Get Hook Manifests With “Helm Get Hooks”
If you need to know the YAML manifest for hook resources, use the helm get hooks command. Whereas “helm get manifest” output only non-hook resources, “helm get hooks” outputs only hook-related resources. Here’s an example below:
→ helm get hooks nginx
---
# Source: nginx/templates/tests/test-connection.yaml
apiVersion: v1
kind: Pod
metadata:
name: "nginx-test-connection"
labels:
helm.sh/chart: nginx-0.1.0
app.kubernetes.io/name: nginx
app.kubernetes.io/instance: nginx
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['nginx:80']
restartPolicy: Never
Since hooks often include short-lived Pods running a one-off command, the “helm get hooks” command can help you verify that the hook’s command is correct, as well as its args and image being used.
The next command we’ll look at is great for charts that contain a NOTES.txt template.
Display Release Notes With “Helm Get Notes”
Sometimes when you install a Helm chart, you see an output called the “release notes” that display information about your installation. While this information is displayed after running “helm install” or “helm upgrade”, you can recall these release notes any time you want using the helm get notes command. Here’s an example:
→ helm get notes nginx
NOTES:
1. Get the application URL by running these commands:
export NODE_PORT=$(kubectl get --namespace default -o jsonpath="{.spec.ports[0].nodePort}" services nginx)
export NODE_IP=$(kubectl get nodes --namespace default -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
Release notes often contain instructions on how to access your application that are handy when troubleshooting application issues. For example, if you tried to execute the release notes’ commands and could not access your application, there could be an issue with either the app or the Helm chart itself. You can then explore further using other “helm get” commands in addition to the “kubectl describe” command.
Let’s talk about the final command, “helm get all”.
Recall All Information With “Helm Get All”
Finally, if you want to display everything the “helm get” subcommands have to offer all in one, you can use the helm get all command. Since this outputs a lot of information, I won’t paste an example here, but the result is “helm get manifest”, “helm get values”, “helm get hooks”, and “helm get notes” concatenated together. I usually don’t use this command, opting instead for one of the specific “helm get” subcommands to limit some of the noise “helm get all” produces. Still, if you want a complete picture of your Helm installation in an all-in-one view, this is a good command to use.
Thanks For Reading
The “helm get” subcommands are a great way to get started troubleshooting an application deployed with Helm. For more information on these commands, check out the Helm documentation and my book, Learn Helm.