Photo by AbsolutVision on Unsplash

Here’s an error I often come across with Golang applications:

invalid character '<' looking for beginning of value

This error is frustrating to those who first encounter it because it comes across as archaic. Where is the < character coming from, and why is it causing errors? What underlying library is throwing this, and how can you fix it?

Unfortunately, the resolution depends on a case-by-case basis. However, in this post, I hope to help troubleshoot to lead you down the right path.

The Root Cause

This error message is thrown by the encoding/json Golang package. This error happens when the json package…


Photo by JOSHUA COLEMAN on Unsplash

The Twelve-Factor App, a commonly used set of guidelines for building cloud-native applications, requires an application to exhibit “strict separation of config from code”. A key takeaway from this guideline is that you should not configure credentials to data sources or other services as constants in your code. Instead, credentials should be stored separately from your code to keep your application more generic and easier to deploy if credentials change or differ across environments.

The other day, I installed WordPress on a CentOS AMI and wrote a Terraform config to deploy it alongside an RDS instance. One of my primary…


Photo by Denise Jans on Unsplash

There are plenty of useful blog posts on how to write a GitHub Action, but while writing my own Action, I didn’t find much material out there on how to help me properly test it. In this blog post, I want to talk about how I implemented automated testing of my Action, hoping that you can benefit from this as well.

Project Structure

Part of the reason you use the GitHub Actions offering is likely to perform automated testing within your project. You can use this same idea for testing GitHub Actions. …


Photo by ready-made from Pexels | Modified from original

This is Part 2 of Reducing Helm Chart Boilerplate with Named Templates and Library Charts.

In Part 1 of this blog series, I talked about how you can use named templates to reduce boilerplate throughout a single Helm chart. Now, we’re going to expand on that idea by discussing how you can use library charts to reduce boilerplate across multiple Helm charts. To do this, we will focus on the concept of library charts.

Understanding Library Charts

A library chart is a Helm chart consisting entirely of named templates. As you can recall from Part 1, a named template is a reusable template…


Photo from Pexels | Modified from original

This is Part 1 of Reducing Helm Chart Boilerplate with Named Templates and Library Charts.

Part 2 is called How to Reduce Helm Chart Boilerplate with Library Charts.

One of the key benefits of Helm is that it helps reduce the amount of configuration a user needs to provide to deploy applications to Kubernetes. However, as Helm chart developers, there are times when you will also want to focus on reducing the amount of configuration required to create your chart templates. Consider a Helm chart template used to create a deployment, which might look like this:

apiVersion: apps/v1 kind: Deployment…


Photo by Every Angle on Unsplash

When I first started using Helm, I assumed that the sky was the limit in terms of what you could configure in a Helm chart. Need to add volumes? I believed you could always change that. Labels? “No problem,” I thought.

Being much more experienced with Helm today, I know that my assumption was not correct because there was no way to change parts of a Helm chart that were not exposed by values…until now. Helm 3.1 …


Photo by Jordan Madrid on Unsplash

Earlier, I wrote a post about how to troubleshoot errors in Kubernetes using a blocking command. This trick, however, only applied to CrashLoopBackoffs. Today, I want to talk about how you can get back on your feet if your Kubernetes pods fail to start due to other errors or non-ready statuses, such as ErrImagePull, Pending, and 0/1 Ready. To do this, you can use the kubectl describe command.

The “kubectl describe” Command

The kubectl describe command is like a close cousin to “kubectl get” in that they both fetch information about a particular resource. However, while “kubectl get” without arguments is used to return…


Photo by Markus Winkler on Unsplash

When developing Helm charts, you may encounter a use case where you need to create a specific Kubernetes resource only if that particular resource is registered with the API. For example, imagine you maintain a Helm chart that should be made deployable to different Kubernetes distributions. In your Helm chart, you want your application to be externally accessible to clients outside of your cluster. Many Kubernetes distributions achieve this by using an Ingress resource. However, in OpenShift (Red Hat’s Kubernetes distro), you would likely create a Route instead. …


Photo by Nick Jio on Unsplash

Everyone who has worked with Kubernetes has seen that awful status before — CrashLoopBackoff. A CrashLoopBackoff indicates that the process running in your container is failing. Your container’s process could fail for a variety of reasons. Perhaps you are trying to run a server that is failing to load a configuration file. Or, maybe you are trying to deploy an application that fails due to being unable to reach another service.

In an attempt to recover from CrashLoopBackoff errors, Kubernetes will continuously restart the pod, but often there is something fundamentally wrong with your process, and a simple restart will…


Squash..Get it? | Photo by Melanie Hughes on Unsplash

When you build a Docker image, a series of layers get cached to speed up subsequent builds. However, this caching can have adverse effects if an image layer contains secrets, such as credentials. A malicious person or process could find the layer containing your secrets and discover its contents.

Luckily, when performing Docker builds in OpenShift, you can quickly destroy secret layers by setting imageOptimizationPolicy to SkipLayers in your BuildConfig.

Let’s first consider the following Dockerfile:

This Dockerfile installs jq to a UBI8-based image. However, rather than download jq from their releases page, it instead downloads from a local…

Austin Dewey

Kubernetes enthusiast and not-terrible guitarist. Co-author of Learn Helm. | https://austindewey.com

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store