helm-k8s.jpg
Cover image for ron

Ron Northcutt Verified userVerified user

Head of DevRel

Appsmith

Helm Best Practices for Smoother Kubernetes Management

We have a great introduction to Helm article, a solid tutorial on how to install Helm, and an overview of advanced Helm features. At this point, you know it's like having a superpower. Helm helps you handle your applications' deployment, updating, and maintenance processes more smoothly. But with great power comes great responsibility! To make the most out of Helm, it's essential to follow some best practices. Let's dive into these practices to help you create more robust, secure, and efficient Helm charts.

Creating Robust, Reusable Charts

Developing charts that not only do the job well but can also be used in various situations is a big win when you're working with Helm. These charts are like Swiss Army knives - handy in multiple scenarios, whether you're setting up a test environment, rolling out a production deployment, or anything in between. But - you have to make sure they are set up properly to get the most out of them

Use Values for Configuration

The secret sauce to making your charts adaptable is to use the values.yaml file effectively. This file acts as a dashboard for your chart's settings, allowing you or anyone else using your chart to tweak how the application runs without messing with the chart's core templates (don't hack core!)

For instance, suppose your application runs on Nginx. Your values.yaml might look something like this:

replicaCount: 1
image:
  repository: nginx
  tag: "stable"
  pullPolicy: IfNotPresent
service:
  type: LoadBalancer
  port: 80

In this example, you've got settings for how many copies of your app to run (replicaCount), which Docker image to use (image), and how your app's service should be exposed (service). Users can easily change these settings to fit their needs, like using a different image tag or exposing the service on a different port.

Provide Sane Defaults

Imagine you're playing a video game that starts off on the hardest difficulty level. That wouldn't be much fun, right? Similarly, a Helm chart that requires a ton of adjustments just to get started can be off-putting. By setting reasonable default values in your values.yaml file, you make sure your chart works well right from the get-go, providing a pleasant experience from the start.

For example, setting the replicaCount to 1 ensures there's at least one instance of your application running. Choosing the stable tag for the Nginx image gives users a reliable and well-tested version of Nginx without them having to research which version to use.

Document Everything

A chart without documentation is like a treasure map without X marking the spot. Sure, there's treasure (your amazing chart), but finding it (figuring out how to use the chart) is unnecessarily hard. Good documentation includes:

  • Comments in your values.yaml: Each option should have a comment explaining what it does and, if not obvious, why it's set to its default value.

    # Number of replicas for the deployment
    replicaCount: 1
    
    # Image configuration
    image:
      repository: nginx # Docker image repository
      tag: "stable" # Image tag (version)
      pullPolicy: IfNotPresent # Image pull policy
  • A README.md file: This should explain what your chart does, how to install it, what each configuration option in the values.yaml file means, and how to customize the chart. You can also include examples of how to override values for different environments, like development, staging, and production.

Creating robust, reusable charts isn't just about making your life easier; it's also about contributing to the Helm community. By sharing well-crafted charts, you help others achieve their goals faster and learn from your approach to solving common problems. So, take a little extra time to externalize configurations, set smart defaults, and document your work. Your future self, and the community, will thank you.

Tip: For a good example of solid documentation, check out the Appsmith Helm config.

Stepping Up Security with Helm

When it comes to deploying and managing apps, keeping things secure is just as important as making sure they run smoothly. Helm has some built-in features to help keep everything locked down.

Tightening Things Up with Role-Based Access Control (RBAC)

RBAC is like giving out keys to your house. You wouldn't give everyone the key to every door, right? Similarly, RBAC lets you control who can do what in your Kubernetes cluster, ensuring that people only have access to what they need to do their jobs. This is crucial for preventing unauthorized access and potential mishaps.

When you're setting up Helm in your cluster, you'll use RBAC to define permissions through roles and role bindings. Here's a basic setup to give you an idea:

# rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: helm
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: helm-role
rules:
- apiGroups: [""]
  resources: ["pods", "services"]
  verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: helm-role-binding
subjects:
- kind: ServiceAccount
  name: helm
roleRef:
  kind: Role
  name: helm-role
  apiGroup: rbac.authorization.k8s.io

In this setup, we're creating a ServiceAccount named helm that Helm will use to interact with your Kubernetes cluster. We then create a Role that specifies what the account can do—in this case, it can only "get" and "list" pods and services, which are pretty safe, read-only operations. Finally, the RoleBinding ties the Role to the ServiceAccount, effectively applying those permissions.

The best part is that not only is this easy to do, but it is easy to extend. You don't need to worry about getting all your RBAC stuff figured out up front - you can simply define the roles and permissions you need fo your team today and adjust it easily in the future. Since it is just using yaml files, the time and effort to extend the system is pretty small. Once again, we see that Helm does the heavy lifting.

Keeping Your Chart Repository Safe

Think of your chart repository like a library of blueprints for deploying applications. Just like you wouldn't want those blueprints to fall into the wrong hands or get tampered with, you need to keep your chart repository secure.

  • Use HTTPS: This is like sending your blueprints in a secure, locked briefcase rather than a transparent plastic bag. HTTPS encrypts the data between your computer and the chart repository, making sure nobody can sneak a peek or tamper with the charts as they're being transferred.
  • Sign Your Charts with Provenance Files: Signing your charts is like putting a tamper-evident seal on that briefcase. Provenance files are digital signatures that confirm your charts haven't been messed with since you published them. They also verify that the charts really came from you, adding an extra layer of trust.

Here's how you might sign a chart:

helm package --sign --key 'YourKeyName' --keyring path/to/your/keyring/secring.gpg mychart/

And to verify a chart's signature:

helm verify mychart-0.1.0.tgz

Remember, keeping your Kubernetes deployments secure isn't just a one-time setup thing. It's an ongoing process of monitoring, updating, and adjusting your security practices as needed. By using RBAC to control access and keeping your chart repository secure, you're taking important steps to protect your applications and your data.

Boosting Your Helm Charts for Better Performance

When you're managing apps with Kubernetes and Helm, you want everything to run as smoothly and quickly as possible. After all, the faster and more reliable your deployments are, the happier everyone will be. To keep things running at top speed, it's important to focus on making your Helm charts as efficient as possible. Let's dive into some ways you can optimize your Helm charts for better performance.

Keeping It Simple (KISS)

Think of your Helm chart like a recipe. If the recipe is too complicated, with too many steps or ingredients you don't really need, it's going to take longer to make the dish, and there's more that can go wrong. The same goes for Helm charts. A chart that's packed with unnecessary features or overly complex configurations can slow down your deployments and make your charts harder to use and maintain.

To avoid this, try to keep your charts as straightforward as possible. Only include the resources and configurations that your application truly needs to run. For example, if your application doesn't require persistent storage, you can leave out PersistentVolumeClaims from your chart. This not only speeds up your deployments but also makes your charts easier for others to understand and use.

Breaking Down Big Charts

Sometimes, you might start with a simple chart, but as your application grows, so does the chart. Before you know it, you've got a giant chart that's unwieldy and slow to update. When you reach this point, it's a good idea to split your large chart into smaller, more manageable pieces, known as subcharts.

Subcharts are like mini-charts that you can piece together to form your overall application. By splitting a large chart into subcharts, you can isolate different parts of your application, making it easier to update and manage. Plus, you can reuse these subcharts in other projects, saving you time in the long run.

For instance, if your application consists of a web frontend, a backend API, and a database, you could create a subchart for each component. Here's a simple way to structure this:

my-application/
├── charts/
│   ├── frontend/
│   ├── backend/
│   └── database/
└── Chart.yaml

This structure makes your overall application chart cleaner and more modular, which can significantly improve deployment times and manageability. It also makes it much easier to find problems, fix issues, and manage updates. 

Using helm lint to Stay on Track

Just like a spellchecker helps you catch errors in your writing, helm lint can help you catch mistakes in your Helm charts. This command scans your chart for common issues and best practices, pointing out anything that might cause problems or slow down your deployments.

Regularly running helm lint on your charts is like giving them a quick health check. It can catch things like syntax errors, missing required fields, or inefficient configurations that you might have overlooked. Here's how you can use it:

helm lint my-chart/

The output will tell you if there are any problems with your chart and offer suggestions on how to fix them. Making helm lint a regular part of your workflow can help keep your charts in top shape and ensure your deployments run as efficiently as possible.

It is like writing good code

By keeping your Helm charts simple, breaking down large charts into subcharts, and regularly using helm lint to catch potential issues, you can greatly improve the performance of your Kubernetes deployments. That actually sounds a lot like the advice we have for writing good code. 

These practices help you maintain high availability and responsiveness in your applications, ensuring a smooth and efficient experience for both you and your users. So take a little time to review your charts and see where you can make improvements. Your future self (and your team) will thank you!

Wrapping Up

By following these best practices for chart development, security, and performance optimization, you can enhance your Helm experience and make your Kubernetes management process more effective and secure. Remember, the goal is to make your charts as reusable, secure, and efficient as possible. This not only helps you but also benefits the entire Helm community by sharing high-quality charts that everyone can rely on. So go ahead, apply these best practices, and take your Helm skills to the next level!