Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Learn Helm
Learn Helm

Learn Helm: Improve productivity, reduce complexity, and speed up cloud-native adoption with Helm for Kubernetes

Arrow left icon
Profile Icon Andrew Block Profile Icon Austin Dewey
Arrow right icon
$43.99
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3 (4 Ratings)
Paperback Jun 2020 344 pages 1st Edition
eBook
$20.98 $29.99
Paperback
$43.99
Subscription
Free Trial
Renews at $19.99p/m
Arrow left icon
Profile Icon Andrew Block Profile Icon Austin Dewey
Arrow right icon
$43.99
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3 (4 Ratings)
Paperback Jun 2020 344 pages 1st Edition
eBook
$20.98 $29.99
Paperback
$43.99
Subscription
Free Trial
Renews at $19.99p/m
eBook
$20.98 $29.99
Paperback
$43.99
Subscription
Free Trial
Renews at $19.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning
Table of content icon View table of contents Preview book icon Preview Book

Learn Helm

From monoliths to modern microservices

Software applications are a foundational component of most modern technology. Whether they take the form of a word processor, web browser, or media player, they enable user interaction to complete one or more tasks. Applications have a long and storied history, from the days of 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, social media, and online retail.

These applications can operate on a wide range of platforms and system. We said in most cases they run on virtual or physical resources, but aren't these technically the only options? 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. 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 in their applications. As a result, a single application could consist of several smaller components, each of which, on their own, could be written as their 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 DevOps, whose rise in popularity occurred around the year 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 can 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 the name for these components as microservices. The traits that were inherent in microservice applications brought with them several desirable features, including the ability to develop and deploy services concurrently from one another as well as to scale (increase the number of instances) them 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 for 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). Containerized technology has a long history in computing, dating back to the 1970s. Many of the foundational container technologies, including chroot (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 or virtual machine, 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 a runtime that could be utilized on Linux, macOS, and Windows. The ability to distribute container images with ease led to the increase in 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 0my 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 the 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. Kubernetes has similar responsibilities with regards 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 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 Gi of memory (Kubernetes resource requests typically use their 'power of two' values, which in this case is roughly equivalent to 2 GB) and one 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, which in this case are called 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 all of the nodes in a cluster do not 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

Figure 1.1 - Kubernetes orchestration and scheduling

Container orchestration relieves you of putting in the effort to track the available resources on machines at all times. Kubernetes and other monitoring tools provide insight into these metrics. So, a day-to-day developer does not need to worry about available resources. A developer can simply declare the amount of resources they expect a container to use and Kubernetes will take care of the rest on the backend.

High availability

Another benefit of Kubernetes is that it provides features that help take care of redundancy and high availability. High availability 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 high availability 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 as well as 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 and innovation of the platform.

Another benefit of Kubernetes's large community is the number of different tools built to augment the abilities that are provided. Helm is one of those tools. 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 have configuration details around topics that include the following:

  • Networking
  • Persistent storage and file mounts
  • Availability and redundancy
  • Application configuration
  • Security

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.

Let's discuss some of the basic API endpoints users can interact with to deploy and configure an application on Kubernetes.

Deployment

The first Kubernetes resource we will explore is called a Deployment. Deployments determine the basic details required to deploy an application on Kubernetes. One of these basic details consists of the container image that Kubernetes should deploy. Container images can be built on local workstations using tools such as docker, and jib but images can also be built right on Kubernetes using kaniko. Because Kubernetes does not expose a native API endpoint for building container images, we will not go into detail about how a container image is built prior to configuring a Deployment resource.

In addition to specifying the container image, Deployments also specify the number of replicas, or instances, of an application to deploy. When a Deployment is created, it spawns an intermediate resource, called a ReplicaSet. The ReplicaSet deploys as many instances of the application as determined by the replicas field on the Deployment. The application is deployed inside a container, which itself is deployed inside a construct called a Pod. A Pod is the smallest unit in Kubernetes and encapsulates at least one container.

Deployments can additionally define an application's resource limits, health checks, and volume mounts. When a Deployment is created, Kubernetes creates the following architecture:

Figure 1.2: A deployment creates a set of Pods

Figure 1.2 - A Deployment creates a set of Pods

Another basic API endpoint in Kubernetes is used to create Service resources, which we will discuss next.

Services

While Deployments are used to deploy an application to Kubernetes, they do not configure the networking components that allow an application to be communicated with Kubernetes exposes a separate API endpoint used to define the networking layer, called a Service. Services allow users and other applications to talk to each other by allocating a static IP address to a Service endpoint. The Service endpoint can then be configured to route traffic to one or more application instances. This kind of configuration provides load balancing and high availability.

An example architecture using a Service is described in the following diagram. Notice that the Service sits in between the client and the Pods to provide load balancing and high availability:

Figure 1.3: A Service load balancing an incoming request

Figure 1.3 - A Service load balancing an incoming request

As a final example, we will discuss the PersistentVolumeClaim API endpoint.

PersistentVolumeClaim

Microservice-style applications embrace being self-sufficient by maintaining their state in an ephemeral manner. However, there are numerous use cases where data must live beyond the life span of a single container. Kubernetes addresses this issue by providing a subsystem for abstracting the underlying details of how storage is provided and how it is consumed. To allocate persistent storage for their application, users can create a PersistentVolumeClaim endpoint, which specifies the type and amount of storage that is desired. Kubernetes administrators are responsible for either statically allocating storage, expressed as PersistentVolume, or dynamically provisioning storage using StorageClass, which allocates PersistentVolume in response to a PersistentVolumeClaim endpoint. PersistentVolume captures all of the necessary storage details, including the type (such as network file system [NFS], internet small computer systems interface [iSCSI], or from a cloud provider), along with the size of the storage. From a user's perspective, regardless of which method of the PersistentVolume allocation method or storage backend that is used within the cluster, they do not need to manage the underlying details of managing storage. The ability to leverage persistent storage within Kubernetes increases the number of potential applications that can be deployed on the platform.

An example of persistent storage being provisioned is depicted in the following diagram. The diagram assumes that an administrator has configured dynamic provisioning via StorageClass:

Figure 1.4: A Pod mounting PersistentVolume created by PersistentVolumeClaim

Figure 1.4 - A Pod mounting PersistentVolume created by PersistentVolumeClaim

There are many more resources in Kubernetes, but by now, you have probably got the picture. The question now is how are these resources actually created?

We will explore this question further in the next section.

Approaches in 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 configuration

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

  • create
  • describe
  • edit
  • delete

The kubectl commands follow a common format:

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 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:

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:

kubectl edit deployment my-deployment

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

When it comes to deleting the resource, the user can run the delete subcommand:

kubectl delete deployment my-deployment

This would instruct the API to delete the Deployment called my-deployment.

Kubernetes resources, once created, exist in the cluster as JSON resource files, which can be exported as 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 the 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:

  1. 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:
    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
  2. The Deployment can then be created with the following command:
    kubectl apply -f deployment.yaml

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

  3. If you wanted to make a change to the Deployment, say by changing the number of replicas to 2, you would first modify the deployment.yaml file:
    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
  4. You would then apply the change with kubectl apply:
    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.

  5. 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:
    kubectl delete -f deployment.yaml
  6. The delete subcommand can be made more declarative by passing in the -f flag and a filename. This gives kubectl the name of the resource to delete that is declared in a specific file and it allows the developers to continue managing resources with declarative YAML files.

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 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, there are many, many different resources in Kubernetes. Here's a short list of resources a developer should be aware of:

  • Deployment
  • StatefulSet
  • Service
  • Ingress
  • ConfigMap
  • Secret
  • StorageClass
  • PersistentVolumeClaim
  • ServiceAccount
  • Role
  • RoleBinding
  • Namespace

Out of the box, deploying an application on Kubernetes is not as simple as pushing a big red button marked Deploy. Developers need to be able to determine which resources are required to deploy their application and they need to understand those resources at a deep enough level to be able 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 the 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 the '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 local files and apply the changes to synchronize the local state to the live state in an effort to update the source of truth. However, this isn't what usually ends up happening. It is often simpler, in the short term, to modify the live resource in place with kubectl patch or kubectl edit and completely skip over modifying the local files. This results in a 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 create resources to deploy and configure 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 an edit or 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, 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 the changes that have occurred. 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 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 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 configuration between them.

The following figure 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.5: An example of two resources with boilerplate

Figure 1.5 - An example of two resources with boilerplate

Notice, in this example, that each file is 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 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 in units, called packages, which contain metadata around target software and its dependencies.

The process 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 package 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 the 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:

dnf install htop --assumeyes	

This instructs dnf, the Fedora package manager since 2015, to find htop in the Fedora package repository and install it. dnf also takes care of installing the htop package's dependencies, so you would not 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 may potentially ask.

Over time, newer versions of htop may appear in the upstream repository. dnf and other package managers allow users to efficiently upgrade to new versions of the software. The subcommand that allows users to upgrade using dnf is upgrade:

dnf upgrade htop --assumeyes

This instructs dnf to upgrade htop to its latest version. It also upgrades its dependencies to the versions specified in the package's metadata.

While moving forward is often better, package managers also allow users to move backward and revert an application back to a prior version if necessary. dnf does this with the downgrade subcommand:

dnf downgrade htop --assumeyes

This is a powerful process because the package manager allows users to quickly roll back if a critical bug or vulnerability is reported.

If you want to remove an application completely, a package manager can take care of that as well. dnf provides the remove subcommand for this purpose:

dnf remove htop --assumeyes	

In this section, we reviewed how the dnf package manager on Fedora can be used to manage a software package. Helm, as the Kubernetes package manager, is similar to dnf, both in its purpose and functionality. While dnf is used to manage applications on Fedora, Helm is used to manage applications on Kubernetes. We will explore this in greater detail next.

The Kubernetes package manager

Given that Helm was designed to provide an experience similar to that of package managers, experienced users of dnf or similar tools will immediately understand Helm's basic concepts. Things become more complicated, however, when talking about the specific implementation details. dnf operates on RPM packages that provide executables, dependency information, and metadata. Helm, on the other hand, works with charts. A Helm chart can be thought of as a Kubernetes package. Charts contain the declarative Kubernetes resource files required to deploy an application. Similar to an RPM, it can also declare one or more dependencies that the application needs in order to run.

Helm relies on repositories to provide widespread access to charts. Chart developers create declarative YAML files, package them into charts, and publish them to chart repositories. End users then use Helm to search for existing charts to deploy onto Kubernetes, similar to how end users of dnf will search for RPM packages to deploy to Fedora.

Let's go through a basic example. Helm could be used to deploy Redis, an in-memory cache, to Kubernetes by using a chart published to an upstream repository. This could be performed using Helm's install command:

helm install redis bitnami/redis --namespace=redis

This would install the redis chart from the bitnami chart repository to a Kubernetes namespace called redis. This installation would be referred to as the initial revision, or the initial deployment of a Helm chart.

If a new version of the redis chart becomes available, users can upgrade to a new version using the upgrade command:

helm upgrade redis bitnami/redis --namespace=redis

This would upgrade Redis to meet the specification defined by the newer redis-ha chart.

With operating systems, users should be concerned about rollbacks if a bug or vulnerability is found. The same concern exists with applications on Kubernetes, and Helm provides the rollback command to handle this use case:

helm rollback redis 1 --namespace=redis

This command would roll Redis back to its first revision.

Finally, Helm provides the ability to remove Redis altogether with the uninstall command:

helm uninstall redis --namespace=redis

Compare dnf, Helm's subcommands, and the functions they serve in the following table. Notice that dnf and Helm offer similar commands that provide a similar user experience:

With an understanding of how Helm functions as a package manager, let's discuss in greater detail the benefits that Helm brings to Kubernetes.The benefits of Helm

Earlier in this chapter, we reviewed how Kubernetes applications are created by managing Kubernetes resources, and we discussed some of the challenges involved. Here are few ways that Helm can overcome these challenges.

The abstracted complexity of Kubernetes resources

Let's assume that a developer has been given the task of deploying a MySQL database onto Kubernetes. The developer would need to create the resources required to configure its containers, network, and storage. The amount of Kubernetes knowledge required to configure such an application from scratch is high and is a big hurdle for new and even intermediate Kubernetes users to clear.

With Helm, a developer tasked with deploying a MySQL database could simply search for MySQL charts in upstream chart repositories. These charts would have already been written by chart developers in the community and would already contain the declarative configuration required to deploy a MySQL database. In this regard, developers with this kind of task would act as simple end users that use Helm in a similar way to any other package manager.

The ongoing history of revisions

Helm has a concept called release history. When a Helm chart is installed for the first time, Helm adds that initial revision to the history. The history is further modified as revisions increase via upgrades, keeping various snapshots of how the application was configured at varying revisions.

The following diagram depicts an ongoing history of revisions. The squares in blue illustrate resources that have been modified from their previous versions:

Figure 1.6: An example of a revision history

Figure 1.6 - An example of a revision history

The process of tracking each revision provides opportunities for rollback. Rollbacks in Helm are very simple. Users simply point Helm to a previous revision and Helm reverts the live state to that of the selected revision. With Helm, gone are the days of the n-1 backup. Helm allows users to roll back their applications as far back as they desire, even back to the very first installation.

Dynamically configured declarative resources

One of the biggest hassles with creating resources declaratively is that Kubernetes resources are static and cannot be parameterized. As you may recall from earlier, this results in resources becoming boilerplate across applications and similar configurations, making it more difficult for teams to configure their applications as code. Helm alleviates these issues by introducing values and templates.

Values are simply what Helm calls parameters for charts. Templates are dynamically generated files based on a given set of values. These two constructs provide chart developers the ability to write Kubernetes resources that are automatically generated based on values that end users provide. By doing so, applications managed by Helm become more flexible, less boilerplate, and easier to maintain.

Values and templates allow users to do things such as the following:

  • Parameterize common fields, such as the image name in a Deployment and the ports in a Service
  • Generate long pieces of YAML configuration based on user input, such as volume mounts in a Deployment or the data in a ConfigMap
  • Include or exclude resources based on user input

The ability to dynamically generate declarative resource files makes it simpler to create YAML-based resources while still ensuring that applications are created in an easily reproducible fashion.

Consistency between the local and live states

Package managers prevent users from having to manage an application and its dependencies manually. All management can be done through the package manager itself. The same idea holds true with Helm. Because a Helm chart contains a flexible configuration of Kubernetes resources, users shouldn't have to make modifications directly to live Kubernetes resources. Users that want to modify their applications can do so by providing new values to a Helm chart or by upgrading their application to a more recent version of the associated chart. This allows the local state (represented by the Helm chart configuration) and the live state to remain consistent across modifications, giving users the ability to provide a source of truth for their Kubernetes resource configurations.

Intelligent Deployments

Helm simplifies application deployments by determining the order that Kubernetes resources need to be created. Helm analyzes each of a chart's resources and orders them based on their types. This pre-deterministic order exists to ensure that resources that commonly have resources dependent on them are created first. For example, Secrets and ConfigMaps should be created before Deployments, since a Deployment would likely consume those resources as volumes. Helm performs this ordering without any interaction from the user, so this complexity is abstracted and prevents users from needing to worry about the order that these resources are applied.

Automated life cycle hooks

Similar to other package managers, Helm provides the ability to define life cycle hooks. Life cycle hooks are actions that take place automatically at different stages of an application's life cycle. They can be used to do things such as the following:

  • Perform a data backup on an upgrade.
  • Restore data on a rollback.
  • Validate a Kubernetes environment prior to installation.

Life cycle hooks are valuable because they abstract complexities around tasks that may not be Kubernetes-specific. For example, a Kubernetes user may not be familiar with the best practices behind backing up a database or may not know when such a task should be performed. Life cycle hooks allow experts to write automation that performs those best practices when recommended so that users can continue to be productive without needing to worry about those details.

Summary

In this chapter, we began by exploring the change in architectural trends of adopting microservice-based architectures to decompose applications into several smaller applications instead of deploying one large monolith. The creation of applications that are more lightweight and easier to manage has led to utilizing containers as a packaging and runtime format to produce releases more frequently. By adopting containers, additional operational challenges were introduced and solved by using Kubernetes as a container orchestration platform to manage the container life cycle.

Our discussion turned to the various ways that Kubernetes applications can be configured, including Deployments, Services, and PersistentVolumeClaims. These resources can be expressed using two distinct styles of application configuration: imperative and declarative. Each of these configuration styles contributes to a set of challenges involved in deploying Kubernetes applications, including the amount of knowledge required to understand how Kubernetes resources work and the challenge of managing application life cycles.

To better manage each of the assets that comprise an application, Helm was introduced as the package manager for Kubernetes. Through its rich feature set, the full life cycle of applications from install, upgrade, rollback, and removal can be managed with ease.

In the next chapter, we'll walk through the process of configuring a Helm environment. We will also install the tooling required for consuming the Helm ecosystem and following along with the examples provided in this book.

Further reading

For more information about the Kubernetes resources that make up an application, please see the Understanding Kubernetes Objects page from the Kubernetes documentation at https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/.

To reinforce some of the benefits of Helm discussed in this chapter, please refer to the Using Helm page of the Helm documentation at https://helm.sh/docs/intro/using_helm/. (This page also dives into some basic usage around Helm, which will be discussed throughout this book in greater detail.)

Questions

  1. What is the difference between a monolithic and a microservices application?
  2. What is Kubernetes? What problems was it designed to solve?
  3. What are some of the kubectl commands commonly used when deploying applications to Kubernetes?
  4. What challenges are often involved in deploying applications to Kubernetes?
  5. How does Helm function as a package manager for Kubernetes? How does it address the challenges posed by Kubernetes?
  6. Imagine you want to roll back an application deployed on Kubernetes. What Helm command allows you to perform this action? How does Helm keep track of your changes to make this rollback possible?
  7. What are the four primary Helm commands that allow Helm to function as a package manager?
Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Effectively manage applications deployed in Kubernetes using Helm
  • Learn to install, upgrade, share, and manage applications deployed in Kubernetes
  • Get up and running with a package manager for Kubernetes

Description

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 frontrunner in container orchestration. With the help of this book, you’ll explore the efficiency of managing applications running on Kubernetes using Helm. Starting with a short introduction to Helm and how it can benefit the entire container environment, you’ll then delve into the architectural aspects, in addition to learning about Helm charts and its use cases. You’ll understand how to write Helm charts in order to automate application deployment on Kubernetes. Focused on providing enterprise-ready patterns relating to Helm and automation, the book covers best practices for application development, delivery, and lifecycle management with Helm. By the end of this Kubernetes book, you will have learned how to leverage Helm to develop an enterprise pattern for application delivery.

Who is this book for?

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

What you will learn

  • Develop an enterprise automation strategy on Kubernetes using Helm
  • Create easily consumable and configurable Helm charts
  • Use Helm in orchestration tooling and Kubernetes operators
  • Explore best practices for application delivery and life cycle management
  • Leverage Helm in a secure and stable manner that is fit for your enterprise
  • Discover the ins and outs of automation with Helm
Estimated delivery fee Deliver to Argentina

Standard delivery 10 - 13 business days

$12.95

Premium delivery 3 - 6 business days

$40.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Jun 10, 2020
Length: 344 pages
Edition : 1st
Language : English
ISBN-13 : 9781839214295
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Product feature icon AI Assistant (beta) to help accelerate your learning
Estimated delivery fee Deliver to Argentina

Standard delivery 10 - 13 business days

$12.95

Premium delivery 3 - 6 business days

$40.95
(Includes tracking information)

Product Details

Publication date : Jun 10, 2020
Length: 344 pages
Edition : 1st
Language : English
ISBN-13 : 9781839214295
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 178.97
Mastering Kubernetes
$79.99
Kubernetes and Docker - An Enterprise Guide
$54.99
Learn Helm
$43.99
Total $ 178.97 Stars icon

Table of Contents

14 Chapters
Section 1: Introduction and Setup Chevron down icon Chevron up icon
Chapter 1: Understanding Kubernetes and Helm Chevron down icon Chevron up icon
Chapter 2: Preparing a Kubernetes and Helm Environment Chevron down icon Chevron up icon
Chapter 3: Installing your First Helm Chart Chevron down icon Chevron up icon
Section 2: Helm Chart Development Chevron down icon Chevron up icon
Chapter 4: Understanding Helm Charts Chevron down icon Chevron up icon
Chapter 5: Building Your First Helm Chart Chevron down icon Chevron up icon
Chapter 6: Testing Helm Charts Chevron down icon Chevron up icon
Section 3: Adanced Deployment Patterns Chevron down icon Chevron up icon
Chapter 7: Automating Helm Processes Using CI/CD and GitOps Chevron down icon Chevron up icon
Chapter 8: Using Helm with the Operator Framework Chevron down icon Chevron up icon
Chapter 9: Helm Security Considerations Chevron down icon Chevron up icon
ASSESSMENTS Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon

Customer reviews

Rating distribution
Full star icon Full star icon Full star icon Empty star icon Empty star icon 3
(4 Ratings)
5 star 25%
4 star 25%
3 star 0%
2 star 25%
1 star 25%
Balazs Szeti Nov 02, 2020
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Despite Helm 3 getting more and more attention around Kubernetes application management there are still not many related books around. This book is a great choice to start with if you want to learn Helm basics. Obviously you need a basic understanding of containers and Kubernetes - that you probably have if you heard about Helm - but otherwise the book is an easy read for beginners.There a detailed step by step guide how to setup an environment (CLI tools and Minikube) on your own laptop so you don't need a "real" Kubernetes cluster. The chapters are built upon each other, in some way the book feels like workshop or a training guide, you can also find some "knowledge check" questions at the end of each chapter. It's great to have the output of each command included, so even if you don't want to try them yourself you can easily follow what would happen after each step.As being a relatively short read, this book is ideal for starters. It doesn't get lost in the details of edge cases or deployment "theories" nor tries to be a full reference for Helm - we have the documentation for that already.
Amazon Verified review Amazon
Nicolas Gabriel Schenker Oct 15, 2020
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
The authors have written a comprehensive introduction to Helm. The book is easy to read and all instructions are provided as simple and easy to follow step by step guidelines.The first chapter of the book, Understanding Kubernetes and Helm, is easy to read yet very thoughtful introduction into the topic, starting from applications to containers and Kubernetes and finally to Helm, the subject of the book. In the next chapter, Preparing a Kubernetes and Helm Environment, the authors go to great length to describe in detail how to prepare a reader's system for use with helm. I particularly like the fact that they give clear and comprehensive instructions for all 3 major operating systems, namely Windows, MacOS and Linux. The subsequent chapters lead the reader through the details of what a Helm chart is and how one can be authored, debugged and tested. It the touches on more advanced topics such as integrating Helm in your CI/CD pipeline, using Helm with the Operator Framework and last but least provides some useful thoughts about security and Helm.The book targets developers and DevOps engineers with no prior knowledge of Helm and a basic understanding of containers and Kubernetes.I can highly recommend this book.
Amazon Verified review Amazon
Chris F Feb 12, 2021
Full star icon Full star icon Empty star icon Empty star icon Empty star icon 2
I just now received this book and have been reading it for 2 hours, so far so good. I am in Chapter 3, ad doing the exercises, and wanted to just be able to copy/paste the commands, so I went onto the Packt website to download the PDF or other eBook formats - NONE provided for this book! What? I see the code download link, but that does NOT have everything. Come on guys - provide a PDF to be able to cut/paste some of the long commands.Hence 3 stars instead of 5, which the book probably deserves on the content.EDIT: Downgraded from 3 to 2 starsI get to Chapter 7 to learn CI/CD & GitOps. When installing the jenkins helm chart, the Jenkins pod does NOT start because liveliness and readiness probes fail, and just keeps restarting the pod. Where is the code for the Jenkins pipeline? This is probably the MOST important chapter in the book.
Amazon Verified review Amazon
G-Slave Dec 29, 2020
Full star icon Empty star icon Empty star icon Empty star icon Empty star icon 1
You get past chapter 4 and it becomes incomprehensible. Rather than teaching you anything, the book just has you copy/paste snippets of YAML configs while poorly explaining it, if at all.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela