“Helm Get” – A Swiss Army Knife For Troubleshooting Helm Deployments

Photo by Michael Heng on Unsplash

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.

Austin Dewey

Austin Dewey is a DevOps engineer focused on delivering a streamlined developer experience on cloud and container technologies. Austin started his career with Red Hat’s consulting organization, where he helped drive success at many different Fortune 500 companies by automating deployments on Red Hat’s Kubernetes-based PaaS, OpenShift Container Platform. Currently, Austin works at fintech startup Prime Trust, building automation to scale financial infrastructure and support developers on Kubernetes and AWS. Austin is the author of "Learn Helm", a book focused on packaging and delivering applications to Kubernetes, and he enjoys writing about open source technologies at his blog in his free time, austindewey.com.

Leave a Reply