Home Cloud & Networking Kubernetes Design Patterns and Extensions

Kubernetes Design Patterns and Extensions

By Onur Yılmaz
books-svg-icon Book
eBook $21.99 $14.99
Print $26.99
Subscription $15.99 $10 p/m for three months
$10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
BUY NOW $10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
eBook $21.99 $14.99
Print $26.99
Subscription $15.99 $10 p/m for three months
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
About this book
Before plunging into how Kubernetes works, this book introduces you to the world of container orchestration and describes the recent changes in application development. You'll understand problems that Kubernetes solves and get to grips with using Kubernetes resources to deploy applications. In addition to this, you'll learn to apply the security model of Kubernetes clusters. Kubernetes Design Patterns and Extensions describes how services running in Kubernetes can leverage the platform's security features. Once you've grasped all this, you'll explore how to troubleshoot Kubernetes clusters and debug Kubernetes applications. You also discover how to analyze the networking model and its alternatives in Kubernetes, and apply best practices with design patterns. By the end of this book, you'll have studied all about using the power of Kubernetes for managing your containers.
Publication date:
September 2018
Publisher
Packt
Pages
106
ISBN
9781789619270

 

Kubernetes Design Patterns

Design patterns are the formalization of best practices for everyday problems. Using design patterns in everyday, professional life creates a common language and communication platform for you to work on. In real life, seasoned engineers do not explain how to convert one interface into another; instead, they decide to implement an adapter. Design patterns hide the complexity and details of communication and create a common platform. In addition, converting business requirements into code is more comfortable with the accumulated knowledge of design patterns.

Kubernetes is the uprising and prominent open source container orchestration system, designed by Google. Its fundamental features include automation, scaling, and scheduling of containerized applications. To have a scalable and reliable cloud-native application, Kubernetes is a crucial part of your toolset. All levels of companies, from start-ups to large enterprises, are using Kubernetes to install and manage cloud-native applications.

This paradigm shift in software development began by creating microservices instead of chunks of large software systems. The "new" best practices have aligned with the de facto cloud-native orchestration tool, Kubernetes. Throughout this book, Kubernetes design patterns and extension capabilities will be presented. The book starts by explaining best practices to show how to create Kubernetes-native applications. Following that, accessing Kubernetes itself programmatically and enriching the best orchestration tool ever created will be explained. Finally, Kubernetes itself will be extended with a higher level of automation. At the end of the day, you will have the technical knowledge and hands-on experience to not only create applications to run on Kubernetes, but also extend the system itself.

In this first chapter, Kubernetes design patterns will be presented, starting with the fundamentals of design patterns. Following that, you will build Kubernetes solutions using structural patterns, assemble systems with behavioral patterns, and finally, install applications according to the deployment strategies.

By the end of this chapter, you will be able to:

  • Define the fundamentals of design patterns
  • Explain the classification of patterns
  • Use Kubernetes design patterns to solve real-life problems
  • Build solutions using structural patterns
  • Assemble complex systems with behavioral patterns
  • Install applications with deployment strategies
 

Software Design Patterns

In software development, a design pattern is a repeatable solution to a widespread problem, since it is ubiquitous to solve the same problems you have encountered before. There are two main advantages of design patterns. The first advantage is that they are proven solutions, and the second one is that they create a communication platform between developers. With these advantages, templates and specifications have been formalized over the years to create a knowledge and experience pool.


Design patterns are not finished designs that can be transformed directly into code – they are only best practices and set of approaches.

Software development is seen as a relatively young and evolving field of study; however, most of the problems solved in various circumstances are similar. For instance, it is common to create a single instance component in various software systems, such as payment systems, log managers, enterprise resource planning (ERP) systems, or online games. Therefore, making use of past collected knowledge helps development teams to advance rapidly.

Design patterns and corresponding business requirements could seem artificial and only software-related. However, both problems and solutions have roots in real life. For instance, the singleton pattern is proposed as a best practice for implementing a configuration manager. With the same approach in mind, the adapter pattern is proposed as a best practice to work with both versions of the APIs. As its name implies, it is a similar approach in real-life to using electrical adapters to work with the different plug and socket types in various countries. As these examples indicate, software design patterns and the ideas behind them all come from real-life experiences.

Uses of Software Design Patterns

There are two main uses of design patterns. First, design patterns create a common platform for developers with their terminology. For example, during a technical discussion, let's assume that a design decision is made to use a single instance of a component. All other developers, at least the ones that are aware of design patterns, will not need any further information considering the properties of the singleton pattern. Although this looks trivial, it is an enrichment of communication, with the best practices of technical expertise. Secondly, knowing and leveraging best practices in engineering makes it easier to advance rapidly. Let's imagine that you are designing a car – you should always start by inventing the best wheel possible first. This makes the process faster and eliminates the gains of learning from past
mistakes.

Classification of Software Design Patterns

Design patterns are classified in three ways. With new technologies and programming languages always emerging, new groups are proposed, but the main idea of classification remains the same – the interaction between their controllers
and other applications:

To sum this section up, design patterns are formalized best practices that have roots in both real-life and software design. They create a common communication platform for developers, and they are a valuable source of knowledge as a collection.
In the following chapter, design patterns for Kubernetes are presented as best practices for creating, managing, and deploying modern cloud-native applications.

 

Kubernetes Design Patterns

The evolution of microservices and container technologies has changed the way software applications are designed, developed, and deployed. Nowadays, modern cloud-native applications focus on scalability, flexibility, and reliability in order to meet business requirements. For instance, the scalability of an application with thousands of instances running in a reliable manner was not a concern 10 years ago. Similarly, self-awareness and self-healing features were out of scope when there was no orchestrator for these issues, such as Kubernetes.

New requirements and cloud-native characteristics unveil their own best practices and design patterns. Extensive use and the adoption of Kubernetes by all sorts of companies, including start-ups and large enterprises, made it possible to formalize and collect best practices. In this section, widely known and essential design patterns and deployment strategies in Kubernetes will be described. With the help of these patterns, you'll be able to make use of the best practices that have been formalized by Kubernetes itself.

Structural Patterns

Structural patterns are focused on the composition of building blocks to create higher-level complex resources. In microservice architecture, applications are packaged and deployed as containers. This approach makes it easier to scale applications with less overhead and more isolation. However, this makes it difficult to schedule and run related containers side-by-side, or sequentially in a cluster with thousands of nodes. For instance, if you want to run your frontend and backend containers together in a cluster, you need to find a mechanism so that you can always schedule them to the same nodes. Likewise, if you need to fill in configuration file templates before starting your application, there is a need to ensure that configuration handler containers are running before the application is.

In Kubernetes, containers are the building blocks that are encapsulated in pods. As a container orchestrator, Kubernetes provides built-in functionalities for organizing containers within pods. In this section, the sidecar and initialization structural design patterns for Kubernetes will be explained.

Pods are the smallest deployable resources in Kubernetes, and they consist of one or more containers sharing resources. Pod containers are always scheduled to the same node so that they can share resources such as networking and storage.
Further information about the pod concept is available in the official documentation of Kubernetes: https://kubernetes.io/docs/concepts/workloads/pods/pod.

Sidecar Pattern

Modern software applications often require external functionalities such as monitoring, logging, configuration, and networking. When these functionalities are tightly integrated into the application, they can run as a single process. However,
this violates the isolation principle and creates an opportunity for a single point of failure. With this idea, containers in cloud-native applications are expected to follow the Unix philosophy:

  • Containers should have one task
  • Containers should work together
  • Containers should handle text streams
The single point of failure (SPOF) is a component within a system where its failure can cause all systems to fail. To have reliable and scalable cloud-native applications, SPOFs are undesirable, and system designs should be checked for their existence.

The Unix philosophy focuses on designing a small operating system with a clean service interface. To have such a system, simple, precise, clear, and modular software development should be undertaken, taking into consideration the developers and maintainers. Besides, the philosophy emphasizes that you should compose subsystems instead of creating a big, monolithic design.

With this idea, it is a conventional approach to separate the main application and run a couple of sidecars attached, which are provided for extra functionality. The main advantages of using a sidecar are as follows:

  • They have independent programming languages and runtime dependencies
  • They monitor the main application closely and minimize latency
  • They extend black box applications

In the following activity, a web-based game will be installed in Kubernetes. As expected, there should be at least one container running the web server. However, there is an additional requirement of continuous source code synchronization.
With the Unix philosophy, it is expected to make containers with only one primary task. They should also work independently and together to achieve the necessary requirements. Finally, these containers should update their statuses, informing the console as log lines. All three of these points are covered in the following activity.

Activity: Running a Web Server with Synchronization

Scenario

You are assigned the task of making a Kubernetes installation for a web-based 2048 game. However, the game is still in development and developers push frequent changes throughout the day. In this installation, the game should be frequently
updated to include the recent changes.

Aim

With the successful deployment, there should be a pod running in Kubernetes with two containers. One of the containers should serve the game and the other container, namely the sidecar container, should continuously update the source code of the game. Using Kubernetes, you need to create a cloud-native solution where the server and synchronization tasks are working together, but not depending on each other.

Prerequisites

Use a git Docker image for continuous synchronization in the sidecar container and an open source code repository for the 2048 game.

Steps for Completion

  1. Create a pod definition.
  2. Include two containers:
    • httpd for game serving.
    • git for source code synchronization.
  1. Deploy the pod.
  2. Show the logs of the synchronization.
  3. Check whether the game has started.

All of the code files for the activities in this chapter are provided on GitHub in the Lesson-1 folder at https://goo.gl/gM8W3p.

You are expected to create a 2048 game, like the one shown in the following screenshot:

Initialization Pattern

Initialization is a widespread pattern in every part of software engineering, including programming languages and operating systems. In order to handle the initialization of an application in Kubernetes, initialization containers are proposed. Initialization containers, namely initContainers, are part of a pod's definition. Separation of concerns is handled by separating the life cycles of containers:

  • Init containers
  • Main containers

Containers that are defined as initContainers are executed for completion one by one, and they are all expected to exit successfully. After successful completion, the main containers are started. Some of the example uses of startup containers are as follows:

  • To create configuration files
  • To wait and ensure dependency services are available
  • To create volumes and prepare files
  • To register services to discovery systems

In the following activity, a web server will be installed in Kubernetes. As expected, there should be at least one container running the web server. However, there is an additional requirement of changing the served files before the web server starts. The life cycle of these operations is separated into the initialization container and the main container. These containers could have different container images and executables; however, they are expected to work on a shared resource. Life cycle separation and working together issues are handled in the following activity, and the initialization pattern is implemented in Kubernetes.

Activity: Running a Web Server after Content Preparation

Scenario

You are assigned the task of making a Kubernetes installation for a web server. However, there are some manual tasks to be carried out to change the files before serving them. You need to ensure that changes are always applied before the content is served. Besides this, show the status of the initialization and check the final output of the web server.

Aim

With the successful deployment, there should be a pod running in Kubernetes with one main container and one initialization container. In the initialization container, write Welcome from Packt to the main index file. This file should be served by the main container when started.

Prerequisites

  • Use a basic Docker image for the initialization container, such as busybox.
  • For the main container, a web server capable image should be used, such as nginx.

Steps for Completion

  1. Create a pod definition.
  2. Include one initialization container:
    • Change the content of the files.
  3. Include one main container:
    • Create a web server.
  4. Deploy the pod.
  5. Check the status of the initialization container.
  6. Check the output of the web server.

You should see the following output:


All of the code files for the activities in this chapter are provided on GitHub in the Lesson-1 folder at https://goo.gl/gM8W3p.

Behavioral Patterns

In software development, behavioral design patterns focus on the communication and interaction between objects. Interaction and communication includes responsibility assignment, the encapsulation of behaviors, and the delegation of requests. With the microservice architecture, behavioral patterns focus on the communication between microservices and the interaction of services with orchestration tools.

For instance, let's consider the execution of a microservice that checks a user's quota daily. It can be implemented by an infinite loop that includes 24 hours of sleep and the execution of the quota check. Although it works, it consumes additional resources during sleep and creates an inefficient architecture. With the behavioral pattern of the "scheduled job pattern," orchestration tools could handle the scheduling of the microservice and ensure that it runs every 24 hours.

In Kubernetes, containers are encapsulated inside pods, which are the primary interest of behavioral patterns. Behavioral patterns are focused on the interaction and communication of the Kubernetes resources, namely pods, with the Kubernetes services. Communication and interaction within the controller system could include the distribution of pods to nodes, the scheduling of pods, or metadata distribution by the Kubernetes master and node components.
The following behavioral patterns are covered in the following sections:

  • The job pattern
  • The scheduled job pattern
  • The daemon service pattern
  • The singleton service pattern
  • The introspective pattern

Job Pattern

The general use case of pods in Kubernetes is that they are used for long-running processes that are always up. To this aim, Kubernetes provides higher-level resources such as replication sets or deployments. These high-level resources manage the life cycles of pods by creating replicas, checking for health statuses, and controlling update mechanisms. On the other hand, there is a need for microservices that do one job and successfully exit upon completion. For instance, database initializations, backups, or converting a video should run once and exit without consuming any extra resources. For this requirement, Kubernetes provides a higher-level resource named Job. Kubernetes jobs represent an isolated work run until completion and are ideal for use cases that are required to only run once.

The most important difference between jobs and replication-controlled pods is the restartPolicy field:
  • For always running pods, the restartPolicy is set to Always
  • For jobs, the restartPolicy could be set as OnFailure or Never

Scheduled Job Pattern

Distributed systems and the microservices architecture do not rely on temporal events for running services; instead, they focus on triggers such as HTTP requests, new database entries, or messaging queues. However, scheduling a task and expecting it to run at specified intervals are common approaches that are part of the "Scheduled Job Pattern". Microservices for maintenance operations, sending daily emails, or checking for old files should be scheduled at fixed intervals and must run to meet business needs. Kubernetes provides the CronJob resource for creating scheduled tasks, and it ensures that these jobs are running.

Daemon Service Pattern

Daemon applications are commonly used in operating systems and programming languages as long-running applications or threads that run as background processes. The names of the daemon applications are httpd, sshd, and containerd; the trailing letter indicates that the services are daemons. Within the microservice architecture, some services should run and scale without any relation to consumer usage. These applications should run on every node in the cluster to ensure the daemon application's requirements, such as:

  • Cluster storage daemons: glusterd, ceph.
  • Log collection daemons: fluentd, logstash.
  • Node monitoring daemons: collectd, Datadog agent, New Relic agent.

In Kubernetes, DaemonSets are designed for deploying ongoing background tasks that need to run on all or certain nodes. Without any further management considerations, Kubernetes handles running these daemon pods on the newly joined nodes in the cluster.

Singleton Service Pattern

Running one – and only one – instance is a requirement for applications, since multiple instances could create instability. Although it seems to be against the scalable microservice architecture, there are some applications that are required to follow the singleton pattern:

  • Database instances and connectors
  • Configuration managers
  • Applications that do not scale yet

Kubernetes StatefulSet with a replica count of 1 ensures that only instances of the pod are running in the cluster. With this small configuration, singleton services can be created and used in a cloud-native environment. However, having only one instance of an application in the cluster comes with its drawbacks. For instance, handling the downtime of singleton applications should be handled with care. The primary concern for this issue is how to handle downtime due to the automatic
update of Statefulset. There are two possible solutions in Kubernetes:

  • Tolerate occasional downtime during updates
  • Set PodDistruptionBudget with minAvailable=1:
    • Eliminate the automatic update since PodDistruptionBudget is set
    • Prepare for disruption by operational steps
    • Delete the PodDistruptionBudget resource and let the update continue
    • Recreate PodDistruptionBudget for the next disruption

Introspective Pattern

Applications that run on bare-metal clusters know precisely where they are running, the specification of the system, and their network information. This information helps them to work in a self-aware environment. For instance, these applications can align their resource usage, enhance their logs with more data, or send their node-related metric data. In the microservice architecture, applications are considered ephemeral with less dependency than the environment they are running on. However, self-awareness about runtime information, namely the introspective pattern, could increase the utility and discoverability of applications in distributed systems.

In Kubernetes, the Downward API ensures that the following environment and runtime data is provided for the pods:

  • Environment: Node name, namespace, CPU, and memory limitations.
  • Networking: Pod IP.
  • Authorization: Service account.

In the following activity, a simple but self-aware Kubernetes application will be created and installed. The application has all of the runtime information, which is provided by Kubernetes as environment variables. Being a single application, it logs all of these variables to the console. However, the pod definition that's developed throughout this activity shows you how to use the Downward API inside containers to implement an introspective pattern in Kubernetes.

Activity: Injecting Data into Applications

Scenario

You are assigned the task of making a Kubernetes installation for a simple application with self-awareness. In this installation, the application should collect all the runtime information from Kubernetes and write to its logs.

Aim

With the successful deployment, there should be a pod running in Kubernetes with only one container. In this container, all available runtime information should be injected as environment variables. Also, the application should log runtime information.

Prerequisites

Use the Kubernetes Downward API to collect runtime information.

Steps for Completion

  1. Create a pod definition with one container:
    • Define the environment variables from the Downward API.
    • Create a shell script to write the environment variables.
  2. Deploy the pod.
  3. Check the status of the pod.
  4. Check the logs of the container.

All of the code files for the activities in this chapter are provided on GitHub in the Lesson-1 folder at https://goo.gl/gM8W3p.

Deployment Strategies

Designing and developing cloud-native applications with the microservice architecture is essential for reliable and scalable applications of the future. Likewise, deploying and updating applications in the cloud is as critical as design and development. There are various techniques for delivering applications, and therefore choosing the right setup is essential to leverage the impact of change on the consumers. Using the right subset of Kubernetes resources and choosing an appropriate deployment strategy, scalable and reliable cloud-native applications are feasible.

In this section, the following deployment strategies are presented, and you are expected to complete these exercises so that they can see the Kubernetes resources in action:

  • Recreate strategy
  • Rolling update strategy
  • Blue/green strategy
  • A/B testing strategy

Recreate Strategy

The recreate strategy is based on the idea of closing old version instances and then creating the next version's. With this strategy, it is inevitable to have downtime, depending on both the shutdown and start duration of applications. In Kubernetes, the recreate strategy can be used for creating deployment resources with the strategy of recreate.

The rest of the operations are handled by Kubernetes. Under the hood, the steps of the recreate strategy are as follows:

  1. Requests from users are routed to V1 instances by using a load balancer:
  1. V1 instances are closed, and downtime has started since there is no available instance:
  1. V2 instances are created; however, they are not serving to the requests until they are ready:
  1. Requests from users are routed to V2 instances:

The primary benefits of the recreate strategy are that it's straightforward and not doesn't have any overhead processes. Besides this, the instances are completely renewed with every update, and there is not a time where two versions are running together. However, the downside of this strategy is an inevitable downtime during the update.

Deploying the Application Using the Recreate Strategy

You are running a high-available application on Kubernetes that needs a deployment strategy to handle updates. This application can resist the short span of downtimes; however, there should not be any moment where two versions are running together. This application consumes services that cannot handle working with two different versions at the same time. We want to run an application with the recreate deployment strategy so that updates will be handled by Kubernetes by deleting old instances and creating new ones.


You can find the recreate.yaml file at: https://goo.gl/2woHbx.

Let's begin by following these steps:

  1. Create the deployment with the following command:
 kubectl apply -f recreate.yaml
  1. In a separate terminal, watch for the deployment changes and wait until all three are available:
kubectl get deployment recreate -w 
  1. Update the version of the deployment:
kubectl patch deployment recreate -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx", "image":"nginx:1.11"}]}}}}'

  1. In the terminal that we opened in Step 2, it is expected that you should see the deletion of the pods and the downtime, where Available reaches zero. Afterward, the creation of new instances can be tracked, where Available increases from 0 to 3:
  1. You can run the following command for cleanup:
 kubectl delete -f recreate.yaml

Rolling Update Strategy

The rolling update strategy, which is also known as incremental or ramped, is based on the idea of slowly rolling out a version by replacing the previous ones. In this strategy, firstly, a pool of applications is running behind a load balancer. Then, new version instances are started, and when they are up and running, the load balancer redirects requests to the new instances. At the same time, instances from the previous versions are shut down. In Kubernetes, the rolling update strategy is the default strategy in deployments, so any update on the deployment is already implementing the rolling update strategy.

While Kubernetes handles this, the steps of the rolling strategy can be tracked as follows:

  1. Requests from users are routed to V1 instances by using a load balancer:
  1. V2 instances are created, and users are directed to them. At the same time, V1 instances are deleted. During this stage, both versions are running and serving requests:

  1. Creating V2 instances and the deletion of V1 instances is done one at a time until there are no V1 instances left:
  1. Finally, all requests from all users are routed to V2 instances:

The main advantage of the rolling update strategy is that it is easy and is the default approach of Kubernetes. It is also beneficial for a slow release of new versions by balancing the load during the startup of new instances. On the other hand, Kubernetes automatically handles rollout and rollback, and the duration of these operations are not known. One of the most complicated problems in rolling updates is that two versions are running at the same time in the cluster, and the traffic is not under control.

Deploying an Application Using the Rolling Update Strategy

You are running a high-available application on Kubernetes that needs a deployment strategy to handle updates. This application, let's say, the frontend of your client's company, should always be available so that downtime is out of the question. Multiple versions of the applications could be working together at any time; however, the client does not want to cover the cost of extra resources during the update. We'll run an application with the rolling update deployment strategy so that updates will be handled by Kubernetes by incrementally creating new instances and deleting old instances, one after another. Let's begin by following these steps:

  1. Create the deployment with the following command:
kubectl apply -f rolling.yaml
  1. In a separate terminal, start a cURL instance in the Kubernetes cluster:
kubectl run curl --image=tutum/curl --rm -it
  1. When the Command Prompt is ready, watch for the version of the deployment by using an HTTP request:
while sleep 0.5; do curl -s http://rolling/version | grep nginx; done
  1. Update the version of the deployment with the following command:
kubectl patch deployment rolling -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx", "image":"nginx:1.11"}]}}}}'

  1. In the terminal that we opened in Step 2, it is expected that we should see Kubernetes handle an incremental change of versions. During the update, there is no interruption of the service. However, both versions are alive and serving requests as 1.10.3 and 1.11.13, and are used interchangeably:
  1. For cleanup, stop the cURL command with Ctrl + C and exit from the pod by writing exit. The pod will be deleted by Kubernetes upon exit. Run the following command:
kubectl delete -f rolling.yaml

You can find the rolling.yaml file at: https://goo.gl/eo8cJw.

Blue/Green Strategy

The blue/green strategy is the idea of having two active production environments, namely blue and green. The blue environment is active and serving requests. The green environment has the new version, and it is being tested for the update. When the tests are completed successfully, the load balancer is switched from blue to green instances. In Kubernetes, blue/green deployment is handled by installing both versions and then changing the configuration of a service or resource.

  1. The main steps of the blue/green strategy can be defined as follows:Both the V1 and V2 instances are deployed, and the load balancer is configured for V1 instances:

  1. After testing, the load balancer is configured for route V2 instances:

Advantages of the blue/green strategy include instant rollout and rollback, and no version mismatch during the update. On the other hand, a drawback of this strategy is that you are using double the resources since two environments are maintained. It should be noted that exhaustive end-to-end testing of applications should be handled before using this strategy.

Deploying an Application Using the Blue/Green Strategy

You are running a high-available application on Kubernetes that needs a deployment strategy to handle updates. This application, for example, a mortgage calculation engine API, has different versions, which result in different calculation results. Therefore, the client requires extensive testing before release and instant switches between the versions. We'll run an application with blue/green strategy so that both versions are running, and Kubernetes service handles instant switch of version. We'll run an application with blue/green strategy so that both versions are running, and Kubernetes service handles instant switch of version. Let's begin by performing the following steps:

  1. Create both versions of the deployment and the common service with the following command:
kubectl apply -f blue-green.yaml

  1. Check that both versions are deployed on the cluster with the following command:
kubectl get pods

You should see the following output:

  1. In a separate terminal, start a cURL instance in the Kubernetes cluster:
kubectl run curl --image=tutum/curl --rm -it
  1. When the command prompt is ready, watch for the version of the deployment by using an HTTP request:
while sleep 0.5; do curl -s http://blue-green/version | grep nginx; done
  1. Update the service to route traffic to the new version with the following command:
kubectl patch service blue-green -p '{"spec":{"selector":{"version":"1.11"}}}'

  1. In the terminal that we opened in Step 3, we should see the Kubernetes service handling an instant change of versions without any interruption:
  1. For cleanup, stop the cURL command with Ctrl + C and exit from the pod by writing exit. The pod will be deleted by Kubernetes upon exit. Run the following command:
kubectl delete -f blue-green.yaml

A/B Testing Strategy

The A/B testing strategy is based on the idea of consumer separation and providing different subsets of functionalities. A/B testing allows you to run multiple variants of functionality in parallel. With the analytics of user behavior, users can be routed to a more appropriate version. The following is a sample list of conditions that can be used in order to scatter traffic:

  • Cookies
  • Location
  • Technology, such as the browser, screen size, and mobility
  • Language

In the following image, both versions are installed, and users are routed based on their technology characteristics, that is, mobile or desktop:

The main advantage of the A/B testing strategy is that you have full control over traffic. However, distributing the traffic requires an intelligent load balancer other than the regular Kubernetes services. Some of the popular applications for this are as follows:

  • Linkerd
  • Traefik
  • NGINX
  • HAProxy
  • Istio

Linkerd, Traefik, NGINX, and HAProxy are data plane applications that focus on forwarding and observing network packages between service instances. On the other hand, Istio is a control plane application that focuses on the configuration and
management of proxies that route traffic.

Deployment Strategies Summary

Before choosing a deployment strategy, it should be taken into consideration that there is no silver bullet to solve all production environment requirements. Therefore, it is crucial to check and compare the advantages and disadvantages of strategies and choose the most appropriate one:

 

Summary

In this chapter, Kubernetes design patterns, which are the best practices for cloud-native applications, were presented. Firstly, the idea of design patterns was explained by their usage and classification. Following that, Kubernetes design patterns were presented, followed by some in-class activities. Kubernetes, being the prominent framework for cloud-native applications, has the flexibility and coverage to meet every business requirement. However, knowing how to use Kubernetes resources compellingly is crucial. This is exactly what we covered in this chapter.

About the Author
  • Onur Yılmaz

    Onur Ylmaz is a senior software engineer in a multinational enterprise software company. He is a certified Kubernetes administrator (CKA) and works on Kubernetes and cloud management systems. He is a keen supporter of cutting-edge technologies including Docker, Kubernetes, and cloud-native applications. He has one master's and two bachelor's degrees in the engineering field.

    Browse publications by this author
Kubernetes Design Patterns and Extensions
Unlock this book and the full library FREE for 7 days
Start now