Managing Kubernetes Resources Using Helm - Rimantas Mocevicius - E-Book

Managing Kubernetes Resources Using Helm E-Book

Rimantas Mocevicius

0,0
37,19 €

-100%
Sammeln Sie Punkte in unserem Gutscheinprogramm und kaufen Sie E-Books und Hörbücher mit bis zu 100% Rabatt.

Mehr erfahren.
Beschreibung

Containerization is one of the best ways to implement DevOps, and learning how to execute it effectively is an essential part of a developer’s skillset. Kubernetes is the current industry standard for container orchestration. This book will help you discover the efficiency of managing applications running on Kubernetes with Helm.
Starting with a brief introduction to Helm and its impact on users working with containers and Kubernetes, you’ll delve into the primitives of Helm charts and their architecture and use cases. From there, you’ll understand how to write Helm charts in order to automate application deployment on Kubernetes and work your way toward more advanced strategies. These enterprise-ready patterns are focused on concepts beyond the basics so that you can use Helm optimally, looking at topics related to automation, application development, delivery, lifecycle management, and security.
By the end of this book, you’ll have learned how to leverage Helm to build, deploy, and manage applications on Kubernetes.

Das E-Book können Sie in Legimi-Apps oder einer beliebigen App lesen, die das folgende Format unterstützen:

EPUB
MOBI

Seitenzahl: 380

Veröffentlichungsjahr: 2022

Bewertungen
0,0
0
0
0
0
0
Mehr Informationen
Mehr Informationen
Legimi prüft nicht, ob Rezensionen von Nutzern stammen, die den betreffenden Titel tatsächlich gekauft oder gelesen/gehört haben. Wir entfernen aber gefälschte Rezensionen.



Managing Kubernetes Resources Using Helm Second Edition

Simplifying how to build, package, and distribute applications for Kubernetes

Andrew Block

Austin Dewey

BIRMINGHAM—MUMBAI

Managing Kubernetes Resources Using Helm 
Second Edition

Copyright © 2022 Packt Publishing

All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews.

Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the authors, nor Packt Publishing or its dealers and distributors, will be held liable for any damages caused or alleged to have been caused directly or indirectly by this book.

Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.

Group Product Manager: Rahul Nair

Publishing Product Manager: Niranjan Naikwadi

Senior Editor: Arun Nadar

Content Development Editor: Adrija Mitra

Technical Editor: Arjun Varma

Copy Editor: Safis Editing

Book Project Manager: Aishwarya Mohan

Proofreader: Safis Editing

Indexer: Tejal Daruwale Soni

Production Designer: Shankar Kalbhor

Marketing Coordinator: Nimisha Dua

First published: June 2020

Second Edition: September 2022

Production reference: 1070922

Published by Packt Publishing Ltd.

Livery Place

35 Livery Street

Birmingham

B3 2PB, UK.

978-1-80324-289-7

www.packt.com

To the open source community for their ongoing support and collaboration.

– Andrew Block

To my wife, Lindsey, for her unwavering love and support.

– Austin Dewey

Foreword

This is an enjoyable and informative book about Helm, the Kubernetes Package Manager, from Andrew Block and Austin Block. I do not know the authors personally, but can tell that they have a wealth of knowledge and experience in the subject. Andrew Block recently became the core maintainer of the Helm project, so to him I say: nice to have to you there!

This book is for all levels, from basic to advanced, and everyone will find useful information and tips within it.

This book has three parts, starting with introduction to Kubernetes, and finishing with advanced deployment patterns for Helm.

Part 1 will explain Kubernetes at a high level, alongside the basics of Kubernetes app installation with kubectl. You will then learn what Helm is, and learn about its bases. This part of the book covers how to decompose monolithic apps into smaller applications. You will learn how to setup a local Kubernetes environment, install kubectl and Helm cli, and install, upgrade, and rollback your first application with Helm.

If you are an advanced user, you can skip this part and move straight to Part 2.

Part 2 will take you through Helm charts development, dependency management, and a thorough explanation of all chart templates. This part also covers Helm lifecycle hooks, which allow you to extend helm charts to another level of usefulness. You’ll also learn how to publish charts to the Helm repository and OCI registry. Finally, you’ll learn how to validate charts using helm lint locally and against a live cluster.

I really recommend learning to use the chart testing tool. Making it part of your local and CI process will save you a lot of time, as you won’t be looking for chart bugs at the end of your process.

Of course you aren’t going to write all the Helm charts you need during your normal working life, as there are many Helm charts that have been written by the community or by existing companies. However, understanding how to develop Helm charts will also allow you to use third party charts, modify their values, and even enhance them too. It will also aid you in learning how to provide PRs (pull requests) to the charts’ git repositories.

This section of the book is extremely valuable if you want to learn how to develop Helm charts, and therefore should not be skipped.

In Part 3, you will learn how to automate Helm releases with CD and GitOps. There is a very detailed explanation of how to do that with Argo CD (which happens to be my favourite GitOps Kubernetes operator as well)

You will also learn about the Operator Framework, which is an advanced topic. This section covers Kubernetes operator bases, how to create Helm operators, and how to manage them with Custom Resources Definitions (CRDs) and Custom Recourses (CRs).

This part of the book also covers Helm security best practices, which is a very important topic. You’ll also learn how to verify Helm binaries, how to sign and verify Helm charts, use secure images, and, of course, how to set up charts resources requests and limits. Finally, you’ll also learn how to handle secrets in Helm charts which is an important feature to know, as at the end Helm releases should be deployed in the most secure way.

Rimantas Mocevicius “rimusz”

Helm Co-Founder

Author of kubectl: Command-Line Kubernetes in a Nutshell Book

Senior DevOps Engineer at JFrog Ltd (Nasdaq: FROG)

Contributors

About the authors

Andrew Block is a core maintainer on the Helm project and a Distinguished Architect at Red Hat. He specializes in the use of continuous integration and continuous delivery methodologies to streamline the delivery process and incorporate security at each stage. He works with organizations to adopt and implement these technologies and concepts within their organization. As an open source enthusiast, Andrew not only has authored several publications, but he is also a contributor to several open source communities and a lead within the sigstore project, which aims at simplifying how software is signed and verified.

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 Fortune 500 companies by automating deployments on Red Hat’s Kubernetes-based PaaS, OpenShift Container Platform. Currently, Austin works at fintech start-up Prime Trust, where he builds automation to scale financial infrastructure and supports developers on Kubernetes and AWS.

About the reviewers

Shashikant Bangera is a DevOps architect with 22 years of IT experience. His technical expertise spans across digital transformation, DevOps, the cloud, and containerization. He has helped a wide range of customers, from small, medium, and large businesses, with digital adoption for domains such as banking, e-commerce, and retail. He has architected and implemented enterprise DevOps at a large scale and also contributes to many open source platforms. He has authored and reviewed a number of books on DevOps with Packt. Shashikant has also contributed to lots of blogs on DevOps. He has designed an automated on-demand environment with a set of open source tools that is available on GitHub. You can reach him on Twitter @shzshi.

Suraj S. Pujari is an accomplished customer engineer working with Microsoft India Corp. Ltd and has more than 11 years of experience in the IT industry. He has extensive experience in working with Azure app and infrastructure technologies. From his work as a systems engineer with one of the largest Indian multi-national corporations, his career has evolved through constant learning and applying his inquisitive side.

I would like to express my gratitude to my mom, Vidya, and wife, Pooja, who had to look after my 20-month-old son, Likhit, while I was busy reviewing this book. A big shoutout to all my friends and colleagues who have encouraged me to review books.

Table of Contents

Preface

Part 1: Introduction and Setup

1

Understanding Kubernetes and Helm

From monoliths to modern microservices

What is Kubernetes?

Container orchestration

HA

Scalability

Active community

Deploying a Kubernetes application

Approaches to resource management

Imperative and declarative configurations

Resource configuration challenges

The many types of Kubernetes resources

Keeping live and local states in sync

Application life cycles are hard to manage

Resource files are static

Helm to the rescue!

Understanding package managers

The Kubernetes package manager

The benefits of Helm

Summary

Further reading

Questions

2

Preparing a Kubernetes and Helm Environment

Technical requirements

Preparing a local Kubernetes environment with minikube

Installing minikube

Installing VirtualBox

Configuring VirtualBox as the default driver

Configuring minikube resource allocation

Exploring the basic usage of minikube

Setting up kubectl

Installing kubectl

Setting up Helm

Installing Helm

Configuring Helm

Adding upstream repositories

Adding plugins

Environment variables

Tab completion

Authentication

Authorization/RBAC

Summary

Further reading

Questions

3

Installing Your First App with Helm

Technical requirements

Understanding the WordPress application

Finding a WordPress chart

Searching for WordPress charts from the command line

Viewing the WordPress chart in a browser

Bitnami repository chart retention policy

Adding the full Bitnami repository

Showing the WordPress chart information from the command line

Creating a Kubernetes environment

Installing a WordPress chart

Creating a values file for configuration

Running the installation

Inspecting your release

Choosing between --set and --values

Accessing the WordPress application

Upgrading the WordPress release

Modifying the Helm values

Running the upgrade

Reusing and resetting values during an upgrade

Rolling back the WordPress release

Inspecting the WordPress history

Running the rollback

Uninstalling the WordPress release

Shutting down your environment

Summary

Further reading

Questions

Part 2: Helm Chart Development

4

Scaffolding a New Helm Chart

Technical requirements

Understanding the Guestbook application

Understanding the YAML format

Defining key-value pairs

Value types

The JSON format

Scaffolding the Guestbook Helm chart

Deploying the scaffolded Guestbook chart

Understanding the Chart.yaml file

Updating the Guestbook Chart.yaml file

Summary

Further reading

Questions

5

Helm Dependency Management

Technical requirements

Declaring chart dependencies

The dependencies map

Downloading chart dependencies

Creating conditionals

Altering dependency names and values

Updating the guestbook Helm chart

Cleaning up

Summary

Further reading

Questions

6

Understanding Helm Templates

Technical requirements

Helm template basics

Template values

Built-in objects

The .Release object

The .Chart object

The .Template object

The .Capabilities object

The .Files object

Helm template functions

Helm template control structures

Generating release notes

Helm template variables

Helm template validation

The fail function

The required function

The values.schema.json file

Enabling code reuse with named templates and library charts

Creating CRDs

Post rendering

Updating and deploying the Guestbook chart

Updating Redis values

Updating Guestbook’s deployment template and values.yaml file

Deploying the Guestbook chart

Summary

Further reading

Questions

7

Helm Lifecycle Hooks

Technical requirements

The basics of a Helm hook

Helm hook life cycle

Helm hook cleanup

Writing hooks in the Guestbook Helm chart

Creating the pre-upgrade hook to take a data snapshot

Creating the pre-rollback hook to restore the database

Executing the life cycle hooks

Cleaning up

Summary

Further reading

Questions

8

Publishing to a Helm Chart Repository

Technical requirements

Understanding Helm chart repositories

Publishing to an HTTP repository

Creating a GitHub Pages repository

Publishing the Guestbook chart

Publishing to an OCI registry

Pulling the OCI Guestbook chart

Summary

Further reading

Questions

9

Testing Helm Charts

Technical requirements

Setting up your environment

Verifying Helm templating

Validating template generation locally with helm template

Adding server-side validation to chart rendering

Linting Helm charts and templates

Testing in a live cluster

Running the chart test

Improving chart tests with the Chart Testing tool

Introducing the Chart Testing project

Installing the Chart Testing tools

Running the lint-and-install command

Cleaning up

Summary

Further reading

Questions

Part 3: Advanced Deployment Patterns

10

Automating Helm with CD and GitOps

Technical requirements

Understanding CI/CD and GitOps

CI/CD

Taking CI/CD to the next level using GitOps

Setting up your environment

Installing Argo CD

Deploying a Helm chart from a Git repository

Deploying an application from a remote Helm chart repository

Deploying a Helm chart to multiple environments

Cleaning up

Summary

Questions

11

Using Helm with the Operator Framework

Technical requirements

Understanding Kubernetes operators

Understanding the Guestbook operator control loop

Preparing a local development environment

Scaffolding the operator file structure

Building the operator image

Deploying the Guestbook operator

Deploying the Guestbook application

Using Helm to manage operators, CRDs, and CRs

Cleaning up

Summary

Further reading

Questions

12

Helm Security Considerations

Technical requirements

Data provenance and integrity

Creating a GPG key pair

Verifying Helm downloads

Signing and verifying Helm charts

Developing secure and stable Helm charts

Using secure images

Setting resource requests and limits

Handling secrets in Helm charts

Configuring RBAC rules

Accessing secure chart repositories

Summary

Further reading

Questions

Index

Other Books You May Enjoy

Preface

Containerization is currently known to be one of the best ways to implement DevOps. While Docker introduced containers and changed the DevOps era, Google developed an extensive container orchestration system, Kubernetes, which is now considered the industry standard. With the help of this book, you’ll explore the efficiency of managing applications running on Kubernetes using Helm.

Starting with a brief introduction to Helm and its impact on users working with containers and Kubernetes, you’ll delve into the primitives of Helm charts and its overall architecture and use cases. From there, you’ll learn how to write Helm charts in order to automate application deployment on Kubernetes and work your way toward more advanced strategies. These enterprise-ready patterns are focused on concepts beyond the basics so that you can get the most out of Helm, including topics related to automation, application development, delivery, life cycle management, and security.

By the end of this book, you’ll have learned how to leverage Helm to build, deploy, and manage applications on Kubernetes.

Who this book is for

This book is for Kubernetes developers or administrators who are interested in learning Helm to provide automation for app development on Kubernetes. Although no prior knowledge of Helm is required, basic knowledge of Kubernetes application development will be useful.

What this book covers

Chapter 1, Understanding Kubernetes and Helm, is where you learn about the challenges involved in deploying Kubernetes applications and how Helm can be used to simplify the deployment process.

Chapter 2, Preparing a Kubernetes and Helm Environment, is where you learn how to configure a local development environment. In this chapter, you will download Minikube and Helm. You will also learn basic Helm configurations.

Chapter 3, Installing Your First App with Helm, teaches you the ins and outs of the main Helm commands by having you deploy your first Helm chart.

Chapter 4, Scaffolding a New Helm Chart, is about how Helm charts are structured and helps you scaffold your own Helm chart.

Chapter 5, Helm Dependency Management, is where you learn how to manage and use dependencies to build and manage complex application deployments.

Chapter 6, Understanding Helm Templates, explores Helm templates and how to dynamically generate Kubernetes resources.

Chapter 7, Helm Lifecycle Hooks, is about lifecycle hooks and how to deploy arbitrary resources at different Helm lifecycle phases.

Chapter 8, Publishing to a Helm Chart Repository, teaches you about Helm chart repositories and how they can be used to publish Helm charts.

Chapter 9, Testing Helm Charts, is about different strategies for testing Helm charts during Helm chart development.

Chapter 10, Automating Helm with CD and GitOps, looks at how to automate Helm deployments using continuous delivery and GitOps methodologies.

Chapter 11, Using Helm with the Operator Framework, covers how to create a Helm operator using the operator-sdk toolkit.

Chapter 12, Helm Security Considerations, is about different security topics as they relate to Helm releases, charts, and repositories.

To get the most out of this book

To get the most out of this book, you should install the technologies in the following table to follow along with the examples. While these are the versions that were used during writing, the latest versions should work as well.

Software/hardware covered in the book

Operating system requirements

Minikube v1.22.0

Windows, macOS, or Linux

VirtualBox 6.1.26

Windows, macOS, or Linux

Kubectl v1.21.2

Windows, macOS, or Linux

Helm v3.6.3

Windows, macOS, or Linux

If you are using the digital version of this book, we advise you to type the code yourself or access the code from the book’s GitHub repository (a link is available in the next section). Doing so will help you avoid any potential errors related to the copying and pasting of code.

Download the example code files

You can download the example code files for this book from GitHub at https://github.com/PacktPublishing/Managing-Kubernetes-Resources-using-Helm. If there’s an update to the code, it will be updated in the GitHub repository.

We also have other code bundles from our rich catalog of books and videos available at https://github.com/PacktPublishing/. Check them out!

Download the color images

We also provide a PDF file that has color images of the screenshots and diagrams used in this book. You can download it here: https://packt.link/zeDY0.

Conventions used

There are a number of text conventions used throughout this book.

Code in text: Indicates code words in text, database table names, folder names, filenames, file extensions, pathnames, dummy URLs, user input, and Twitter handles. Here is an example: “Notice that a space is missing between the colon and the LearnHelm string.”

A block of code is set as follows:

configuration: |   server.port=8443   logging.file.path=/var/log

When we wish to draw your attention to a particular part of a code block, the relevant lines or items are set in bold:

$ cd ~$ git clone <repository URI>

Any command-line input or output is written as follows:

$ helm dependency update chapter8/guestbook

$ helm package guestbook chapter8/guestbook

Bold: Indicates a new term, an important word, or words that you see onscreen. For instance, words in menus or dialog boxes appear in bold. Here is an example: “Click the Generate Token button to create the token.”

Tips or Important Notes

Appear like this.

Get in touch

Feedback from our readers is always welcome.

General feedback: If you have questions about any aspect of this book, email us at [email protected] and mention the book title in the subject of your message.

Errata: Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you have found a mistake in this book, we would be grateful if you would report this to us. Please visit www.packtpub.com/support/errata and fill in the form.

Piracy: If you come across any illegal copies of our works in any form on the internet, we would be grateful if you would provide us with the location address or website name. Please contact us at [email protected] with a link to the material.

If you are interested in becoming an author: If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, please visit authors.packtpub.com.

Share Your Thoughts

Once you’ve read Managing Kubernetes Resources using Helm, Second Edition, we’d love to hear your thoughts! Please click here to go straight to the Amazon review page for this book and share your feedback.

Your review is important to us and the tech community and will help us make sure we’re delivering excellent quality content.

Part 1: Introduction and Setup

Kubernetes is a robust system with complex configurations. In Part 1, you will learn how Helm addresses such complexities by providing a package manager interface. By the end of this part, you will have gained hands-on experience by deploying your first Helm chart.

In this part, we will cover the following topics:

Chapter 1, Understanding Kubernetes and HelmChapter 2, Preparing a Kubernetes and Helm EnvironmentChapter 3, Installing Your First App with Helm

1

Understanding Kubernetes and Helm

Thank you for choosing this book, Learn Helm. If you are interested in this book, you are probably aware of the challenges that modern applications bring. Teams face tremendous pressure to ensure that applications are lightweight and scalable. Applications must also be highly available and able to withstand varying loads. Historically, applications have most commonly been deployed as monoliths or large, single-tiered applications served on a single system. As time has progressed, the industry has shifted toward a microservice approach or small, multi-tiered applications served on multiple systems. Often deployed using container technology, the industry has started leveraging tools such as Kubernetes to orchestrate and scale their containerized microservices.

Kubernetes, however, comes with its own set of challenges. While it is an effective container orchestration tool, it presents a steep learning curve that can be difficult for teams to overcome. One tool that helps simplify the challenges of running workloads on Kubernetes is Helm. Helm allows users to more simply deploy and manage the life cycle of Kubernetes applications. It abstracts many of the complexities behind configuring Kubernetes applications and allows teams to be more productive on the platform.

In this book, you will explore each of the benefits offered by Helm and discover how Helm makes application deployment much simpler on Kubernetes. You will first assume the role of an end user, consuming Helm charts written by the community and learning the best practices behind leveraging Helm as a package manager. As this book progresses, you will assume the role of a chart developer and learn how to package Kubernetes applications in ways that are easily consumable and efficient. Toward the end of this book, you’ll learn about advanced patterns around application management and security with Helm.

In this chapter, we will cover the following main topics:

From monoliths to modern microservicesWhat is Kubernetes?Deploying a Kubernetes applicationApproaches to resource managementResource configuration challengesHelm to the rescue!

From monoliths to modern microservices

Software applications are a fundamental component of most modern technology. Whether they take the form of a word processor, web browser, or streaming service, they enable user interaction to complete one or more tasks. Applications have a long and storied history, from the days of Electronic Numerical Integrator and Computer (ENIAC)—the first general-purpose computer—to taking man to the moon in the Apollo space missions, to the rise of the World Wide Web (WWW), social media, and online retail.

These applications can operate on a wide range of platforms and systems, leveraging either physical or virtual computing resources. Depending on their purpose and resource requirements, entire machines may be dedicated to serving the compute and/or storage needs of an application. Fortunately, thanks in part to the realization of Moore’s law, the power and performance of microprocessors initially increased with each passing year, along with the overall cost associated with the physical resources used. This trend has subsided in recent years, but the advent of this trend and its persistence for the first 30 years of the existence of processors was instrumental to the advances in technology.

Software developers took full advantage of this opportunity and bundled more features and components into their applications. As a result, a single application could consist of several smaller components, each of which, on its own, could be written as its own individual services. Initially, bundling components together yielded several benefits, including a simplified deployment process. However, as industry trends began to change and businesses focused more on the ability to deliver features more rapidly, the design of a single deployable application brought with it a number of challenges. Whenever a change was required, the entire application and all of its underlying components needed to be validated once again to ensure the change had no adverse features. This process potentially required coordination from multiple teams, which slowed the overall delivery of the feature.

Delivering features more rapidly, especially across traditional divisions within organizations, was also something that organizations wanted. This concept of rapid delivery is fundamental to a practice called development-operations (DevOps), whose rise in popularity occurred around 2010. DevOps encouraged more iterative changes to applications over time, instead of extensive planning prior to development. In order to be sustainable in this new model, architectures evolved from being a single large application to instead favoring several smaller applications that could be delivered faster. Because of this change in thinking, the more traditional application design was labeled as monolithic. This new approach of breaking components down into separate applications coined a name for these components: microservices. The traits that were inherent in microservices applications brought with them several desirable features, including the ability to develop and deploy services concurrently from one another as well as to scale them (increase the number of instances) independently.

The change in software architecture from monolithic to microservices also resulted in re-evaluating how applications are packaged and deployed at runtime. Traditionally, entire machines were dedicated to either one or two applications. Now, as microservices resulted in the overall reduction of resources required for a single application, dedicating an entire machine to one or two microservices was no longer viable.

Fortunately, a technology called containers was introduced and gained popularity in filling in the gaps for many missing features needed to create a microservices runtime environment. Red Hat defines a container as “a set of one or more processes that are isolated from the rest of the system and includes all of the files necessary to run”(https://www.redhat.com/en/topics/containers/whats-a-linux-container#:~:text=A%20Linux%C2%AE%20container%20is,testing%2C%20and%20finally%20to%20production.). Containerized technology has a long history in computing, dating back to the 1970s. Many of the foundational container technologies, including chroots (the ability to change the root directory of a process and any of its children to a new location on the filesystem) and jails, are still in use today.

The combination of a simple and portable packaging model, along with the ability to create many isolated sandboxes on each physical machine or virtual machine (VM), led to the rapid adoption of containers in the microservices space. This rise in container popularity in the mid-2010s can also be attributed to Docker, which brought containers to the masses through simplified packaging and runtimes that could be utilized on Linux, macOS, and Windows. The ability to distribute container images with ease led to the increase in the popularity of container technologies. This was because first-time users did not need to know how to create images but instead could make use of existing images that were created by others.

Containers and microservices became a match made in heaven. Applications had a packaging and distribution mechanism, along with the ability to share the same compute footprint while taking advantage of being isolated from one another. However, as more and more containerized microservices were deployed, the overall management became a concern. How do you ensure the health of each running container? What do you do if a container fails? What happens if your underlying machine does not have the compute capacity required? Enter Kubernetes, which helped answer this need for container orchestration.

In the next section, we will discuss how Kubernetes works and provides value to an enterprise.

What is Kubernetes?

Kubernetes, often abbreviated as k8s (pronounced as kaytes), is an open source container orchestration platform. Originating from Google’s proprietary orchestration tool, Borg, the project was open sourced in 2015 and was renamed Kubernetes. Following the v1.0 release on July 21, 2015, Google and the Linux Foundation partnered to form the Cloud Native Computing Foundation (CNCF), which acts as the current maintainer of the Kubernetes project.

The word Kubernetes is a Greek word, meaning helmsman or pilot. A helmsman is a person who is in charge of steering a ship and works closely with the ship’s officer to ensure a safe and steady course, along with the overall safety of the crew. Having similar responsibilities with regard to containers and microservices, Kubernetes is in charge of the orchestration and scheduling of containers. It is in charge of steering those containers to proper worker nodes that can handle their workloads. Kubernetes will also help ensure the safety of those microservices by providing high availability (HA) and health checks.

Let’s review some of the ways Kubernetes helps simplify the management of containerized workloads.

Container orchestration

The most prominent feature of Kubernetes is container orchestration. This is a fairly loaded term, so we’ll break it down into different pieces.

Container orchestration is about placing containers on certain machines from a pool of compute resources based on their requirements. The simplest use case for container orchestration is for deploying containers on machines that can handle their resource requirements. In the following diagram, there is an application that requests 2 Gibibytes (Gi) of memory (Kubernetes resource requests typically use their power-of-two values, which in this case is roughly equivalent to 2 gigabytes (GB)) and one central processing unit (CPU) core. This means that the container will be allocated 2 Gi of memory and 1 CPU core from the underlying machine that it is scheduled on. It is up to Kubernetes to track which machines, or nodes, have the required resources available and to place an incoming container on that machine. If a node does not have enough resources to satisfy the request, the container will not be scheduled on that node. If none of the nodes in a cluster have enough resources to run the workload, the container will not be deployed. Once a node has enough resources free, the container will be deployed on the node with sufficient resources:

Figure 1.1 – Kubernetes orchestration and scheduling

Container orchestration relieves you of the effort required to track the available resources on machines. Kubernetes and other monitoring tools provide insight into these metrics. So, a developer can simply declare the number of resources they expect a container to use, and Kubernetes will take care of the rest on the backend.

HA

Another benefit of Kubernetes is that it provides features that help take care of redundancy and HA. HA is a characteristic that prevents application downtime. It’s performed by a load balancer, which splits incoming traffic across multiple instances of an application. The premise of HA is that if one instance of an application goes down, other instances are still available to accept incoming traffic. In this regard, downtime is avoided, and the end user—whether a human or another microservice—remains completely unaware that there was a failed instance of the application. Kubernetes provides a networking mechanism, called a service, that allows applications to be load-balanced. We will talk about services in greater detail later on, in the Deploying a Kubernetes application section of this chapter.

Scalability

Given the lightweight nature of containers and microservices, developers can use Kubernetes to rapidly scale their workloads, both horizontally and vertically.

Horizontal scaling is the act of deploying more container instances. If a team running their workloads on Kubernetes were expecting increased load, they could simply tell Kubernetes to deploy more instances of their application. Since Kubernetes is a container orchestrator, developers would not need to worry about the physical infrastructure that those applications would be deployed on. It would simply locate a node within the cluster with the available resources and deploy the additional instances there. Each extra instance would be added to a load-balancing pool, which would allow the application to continue to be highly available.

Vertical scaling is the act of allocating additional memory and CPU to an application. Developers can modify the resource requirements of their applications while they are running. This will prompt Kubernetes to redeploy the running instances and reschedule them on nodes that can support the new resource requirements. Depending on how this is configured, Kubernetes can redeploy each instance in a way that prevents downtime while the new instances are being deployed.

Active community

The Kubernetes community is an incredibly active open source community. As a result, Kubernetes frequently receives patches and new features. The community has also made many contributions to documentation, both to the official Kubernetes documentation and to professional or hobbyist blog websites. In addition to documentation, the community is highly involved in planning and attending meetups and conferences around the world, which helps increase education about the platform and innovation surrounding it.

Another benefit of Kubernetes’ large community is the number of different tools built to augment the abilities that are provided. Helm is one such tool. As we’ll see later in this chapter and throughout this book, Helm—a tool built by members of the Kubernetes community—vastly improves a developer’s experience by simplifying application deployments and life cycle management.

With an understanding of the benefits Kubernetes brings to managing containerized workloads, let’s now discuss how an application can be deployed in Kubernetes.

Deploying a Kubernetes application

Deploying an application on Kubernetes is fundamentally similar to deploying an application outside of Kubernetes. All applications, whether containerized or not, must consider the following configuration details:

NetworkingPersistent storage and file mountsResource allocationAvailability and redundancyRuntime configurationSecurity

Configuring these details on Kubernetes is done by interacting with the Kubernetes application programming interface (API). The Kubernetes API serves as a set of endpoints that can be interacted with to view, modify, or delete different Kubernetes resources, many of which are used to configure different details of an application.

There are many different Kubernetes API resources, but the following table shows some of the most common ones:

Resource Name

Definition

Pod

The smallest deployable unit in Kubernetes. Encapsulates one or more containers.

Deployment

Used to deploy and manage a set of Pods. Maintains the desired amount of Pod replicas (1 by default).

StatefulSet

Similar to a Deployment resource, except a StatefulSet maintains a sticky identity for each Pod replica and can also provision PersistentVolumeClaims resources (explained further down in this table) unique to each Pod.

Service

Used to load-balance between Pod replicas.

Ingress

Provides external access to services within the cluster.

ConfigMap

Stores application configuration to decouple configuration from code.

Secret

Used to store sensitive data such as credentials and keys. Data stored in Secrets resources are only obfuscated using Base64 encoding, so administrators must ensure that proper access controls are in place.

PersistentVolumeClaim

A request for storage by a user. Used to provide persistence for running Pods.

Role

Represents a set of permissions to be allowed against the Kubernetes API.

RoleBinding

Grants the permissions defined in a role to a user or set of users.

Table 1.1 – Common Kubernetes resources

Creating resources is central to deploying and managing an application on Kubernetes, but what does a user need to do to create them? We will explore this question further in the next section.

Approaches to resource management

In order to deploy an application on Kubernetes, we need to interact with the Kubernetes API to create resources. kubectl is the tool we use to talk to the Kubernetes API. kubectl is a command-line interface (CLI) tool used to abstract the complexity of the Kubernetes API from end users, allowing them to more efficiently work on the platform.

Let’s discuss how kubectl can be used to manage Kubernetes resources.

Imperative and declarative configurations

The kubectl tool provides a series of subcommands to create and modify resources in an imperative fashion. Here is a small list of these commands:

createdescribeeditdelete

The kubectl commands follow a common format, as shown here:

kubectl <verb> <noun> <arguments>

The verb refers to one of the kubectl subcommands, and the noun refers to a particular Kubernetes resource. For example, the following command can be run to create a deployment:

kubectl create deployment my-deployment --image=busybox

This would instruct kubectl to talk to the Deployment API endpoint and create a new deployment called my-deployment, using the busybox image from Docker Hub.

You could use kubectl to get more information on the deployment that was created by using the describe subcommand, as follows:

kubectl describe deployment my-deployment

This command would retrieve information about the deployment and format the result in a readable format that allows developers to inspect the live my-deployment deployment on Kubernetes.

If a change to the deployment was desired, a developer could use the edit subcommand to modify it in place, like this:

kubectl edit deployment my-deployment

This command would open a text editor, allowing you to modify the deployment.

When it comes to deleting a resource, the user could run the delete subcommand, as illustrated here:

kubectl delete deployment my-deployment

This would call the appropriate API endpoint to delete the my-deployment deployment.

Kubernetes resources, once created, exist in the cluster as JavaScript Object Notation (JSON) resource files, which can be exported as YAML Ain’t Markup Language (YAML) files for greater human readability. An example resource in YAML format can be seen here:

apiVersion: apps/v1 kind: Deployment metadata:   name: busybox spec:   replicas: 1   selector:     matchLabels:       app: busybox   template:     metadata:       labels:         app: busybox     spec:       containers:         - name: main           image: busybox           args:             - sleep             - infinity

The preceding YAML format presents a very basic use case. It deploys the busybox image from Docker Hub and runs the sleep command indefinitely to keep the Pod running.

While it may be easier to create resources imperatively using the kubectl subcommands we have just described, Kubernetes allows you to directly manage the YAML resources in a declarative fashion to gain more control over resource creation. The kubectl subcommands do not always let you configure all the possible resource options, but creating YAML files directly allows you to more flexibly create resources and fill in the gaps that the kubectl subcommands may contain.

When creating resources declaratively, users first write out the resource they want to create in YAML format. Next, they use the kubectl tool to apply the resource against the Kubernetes API. While in imperative configuration developers use kubectl subcommands to manage resources, declarative configuration relies primarily on only one subcommand—apply.

Declarative configuration often takes the following form:

kubectl apply -f my-deployment.yaml

This command gives Kubernetes a YAML resource that contains a resource specification, although the JSON format can be used as well. Kubernetes infers the action to perform on resources (create or modify) based on whether or not they exist.

An application may be configured declaratively by following these steps:

First, the user can create a file called deployment.yaml and provide a YAML-formatted specification for the deployment. We will use the same example as before, as follows:

apiVersion: apps/v1

kind: Deployment

metadata:

  name: busybox

spec:

  replicas: 1

  selector:

    matchLabels:

      app: busybox

  template:

    metadata:

      labels:

        app: busybox

    spec:

      containers:

        - name: main

          image: busybox

          args:

            - sleep

            - infinity

A deployment can then be created with the following command:

kubectl apply –f deployment.yaml

Upon running this command, Kubernetes will attempt to create a deployment in the way you specified.

If you wanted to make a change to the deployment by changing the number of replicas to 2, you would first modify the deployment.yaml file, as follows:

apiVersion: apps/v1

kind: Deployment

metadata:

  name: busybox

spec:

  replicas: 2

  selector:

    matchLabels:

      app: busybox

  template:

    metadata:

      labels:

        app: busybox

    spec:

      containers:

        - name: main

          image: busybox

          args:

            - sleep

            - infinity

You would then apply the change with kubectl apply, like this:

kubectl apply –f deployment.yaml

After running that command, Kubernetes would apply the provided deployment declaration over the previously applied deployment. At this point, the application would scale up from a replica value of 1 to 2.

When it comes to deleting an application, the Kubernetes documentation actually recommends doing so in an imperative manner; that is, using the delete subcommand instead of apply, as illustrated here:

kubectl delete –f deployment.yaml

As you can see, the delete subcommand uses the –f flag to delete the resource from the given file.

With an understanding of how Kubernetes resources are created, let’s now discuss some of the challenges involved in resource configuration.

Resource configuration challenges

In the previous section, we covered how Kubernetes has two different configuration methods—imperative and declarative. One question to consider is this: What challenges do users need to be aware of when creating Kubernetes resources with imperative and declarative methodologies?

Let’s discuss some of the most common challenges.

The many types of Kubernetes resources

First of all, as described in the Deploying a Kubernetes application section, there are many different types of resources in Kubernetes. In order to be effective on Kubernetes, developers need to be able to determine which resources are required to deploy their applications, and they need to understand them at a deep enough level to configure them appropriately. This requires a lot of knowledge of and training on the platform. While understanding and creating resources may already sound like a large hurdle, this is actually just the beginning of many different operational challenges.

Keeping live and local states in sync

A method of configuring Kubernetes resources that we would encourage is to maintain their configuration in source control for teams to edit and share, which also allows the source control repository to become the source of truth. The configuration defined in source control (referred to as the local state) is then created by applying them to the Kubernetes environment, and the resources become live or enter what can be called a live state. This sounds simple enough, but what happens when developers need to make changes to their resources? The proper answer would be to modify the files in source control and apply the changes to synchronize the local state to the live state. However, this isn’t what always ends up happening. It is often simpler, in the short term, to modify the live resource in place with kubectl edit or kubectl patch and completely skip over modifying the local files. This results in state inconsistency between local and live states and is an act that makes scaling on Kubernetes difficult.

Application life cycles are hard to manage

Life cycle management is a loaded term, but in this context, we’ll refer to it as the concept of installing, upgrading, and rolling back applications. In the Kubernetes world, an installation would include API resources for deploying and configuring an application. The initial installation would create what we refer to here as version 1 of an application.

An upgrade, then, can be thought of as a modification to one or many of those Kubernetes resources. Each batch of edits can be thought of as a single upgrade. A developer could modify a single service resource, which would bump the version number to version 2. The developer could then modify a deployment, a configmap, and a service at the same time, bumping the version count to version 3.

As newer versions of an application continue to be rolled out onto Kubernetes, it becomes more difficult to keep track of changes that have occurred across relevant API resources. Kubernetes, in most cases, does not have an inherent way of keeping a history of changes. While this makes upgrades harder to keep track of, it also makes restoring a prior version of an application much more difficult. Say, for example, a developer previously made an incorrect edit on a particular resource. How would a team know where to roll back to? The n-1 case is particularly easy to work out, as that is the most recent version. What happens, however, if the latest stable release was five versions ago? Teams often end up scrambling to resolve issues because they cannot quickly identify the latest stable configuration that worked previously.

Resource files are static

This is a challenge that primarily affects the declarative configuration style of applying YAML resources. Part of the difficulty in following a declarative approach is that Kubernetes resource files are not natively designed to be parameterized. Resource files are largely designed to be written out in full before being applied, and the contents remain the source of truth (SOT) until the file is modified. When dealing with Kubernetes, this can be a frustrating reality. Some API resources can be lengthy, containing many different customizable fields, and it can be quite cumbersome to write and configure YAML resources in full.

Static files lend themselves to becoming boilerplate. Boilerplate represents text or code that remains largely consistent in different but similar contexts. This becomes an issue if developers manage multiple different applications, where they could potentially manage multiple different deployment resources, multiple different services, and so on. In comparing the different applications’ resource files, you may find large numbers of similar YAML configurations between them.

The following screenshot depicts an example of two resources with significant boilerplate configuration between them. The blue text denotes lines that are boilerplate, while the red text denotes lines that are unique:

Figure 1.2 – An example of two resources with boilerplate

Notice, in this example, that both files are almost exactly the same. When managing files that are as similar as this, boilerplate becomes a major headache for teams managing their applications in a declarative fashion.

Helm to the rescue!

Over time, the Kubernetes community discovered that creating and maintaining Kubernetes resources to deploy applications is difficult. This prompted the development of a simple yet powerful tool that would allow teams to overcome the challenges posed by deploying applications on Kubernetes. The tool that was created is called Helm. Helm is an open source tool used for packaging and deploying applications on Kubernetes. It is often referred to as the Kubernetes package manager because of its similarities to any other package manager you would find on your favorite operating system (OS). Helm is widely used throughout the Kubernetes community and is a CNCF graduated project.

Given Helm’s similarities to traditional package managers, let’s begin exploring Helm by first reviewing how a package manager works.

Understanding package managers

Package managers are used to simplify the process of installing, upgrading, reverting, and removing a system’s applications. These applications are defined as packages that contain metadata around target software and its dependencies.

The idea behind package managers is simple. First, the user passes the name of a software package as an argument. The package manager then performs a lookup against a repository to see whether that package exists. If it is found, the package manager installs the application defined by the package and its dependencies to specified locations on the system.

Package managers make managing software very easy. As an example, let’s imagine you wanted to install htop, a Linux system monitor, to a Fedora machine. Installing this would be as simple as typing a single command, as follows:

dnf install htop --assumeyes

This instructs dnf, the Fedora package manager, to find htop in the Fedora package repository and install it. dnf also takes care of installing the htop package’s dependencies, so you don’t have to worry about installing its requirements beforehand. After dnf finds the htop package from the upstream repository, it asks you whether you’re sure you want to proceed. The --assumeyes flag automatically answers yes to this question and any other prompts that dnf