Virtualization Technology News and Information
Achieving Application Portability with Kubernetes and Cloud Native Design
Article Written by Oleg Chunikhin, CTO, Kublr

Containers and Kubernetes can create code that is portable across on premise VMs, bare metal, and multiple cloud provider environments. Despite this portability promise, developers may include configuration and application definitions that constrain or even eliminate application portability.

Let's look at two Kubernetes clusters, deployed in AWS and Azure correspondingly, to show how a correctly built application may be deployed into different environments with just configuration changes. This is made possible because Kubernetes provides convenient abstractions for application resource requirements and endpoints, namely persistent volumes, ingress rules and ingress controllers.

Why Build Portable Apps?

Portability is one of the core advantages of containers technology. While some companies may be happy with the environment they are working in, other companies may profit from applications that can move between different environments. Here are just some of them:

  • Fast response to traffic from any geographical location by allowing you to spawn containers immediately in another region.
  • Easily migrate applications from one cloud or hosting provider to another, in order to save costs or add an additional point of presence for your applications, using additional regions not available in other cloud providers.
  • Ability to cloud-burst workloads that are generally on premise, but may need cloud capacity at some point.
  • Split-tier architecture (application tiers may reside in different environments).
  • Disaster recovery strategy may require recovery in a different region or cloud, or you may host your application on a data center and recover into a cloud.

Not only does the environment have to be portability compatible, the application has to be correctly designed too. Your bible for portable apps best practices is the 12-factor app methodology manifest. Particularly, verses 2, 3, 4, 6, 7, and 12.

  • Explicitly declare and isolate dependencies. The application should not assume an existing package or component already available by default in the environment.
  • Store configuration in the environment, avoid keeping configuration in application code. When migrating to another cloud or region, the configuration can change, but the application should not need changes.
  • Treat backing services as attached resources. The application should be able to reinitialize detached and reattached resource (such as Redis cache or MySql database).
  • Execute the application as one or more stateless. Do not store any data in the application container or environment, all persistent data has to be stored in a database or other type of storage (ElasticSearch, Cassandra, dedicated file storage, etc.).

Typical problems that arise when building portable applications

Some of the hardest and most common problems when moving applications across environments are handling Ingress traffic (specifically HTTPS/SSL certificates management), routing and load balancing. Complex routing rules are sometimes required and need to be managed by cluster administrators. State persistence can also be a challenge, while some apps require databases, others may need shared file storage or reliable block storage. Messaging is another area, though we won't focus on this in this article.

Not all environments satisfy the needed requirements. Cloud providers may supply only part of the required services that your applications need (like supporting only a particular type of database, so you have no choice but to deploy your own database manually and maintain it on that cloud provider. Think of Cassandra. You can't easily find it available in an as-a-service in most public clouds).

Platforms have different degrees of capabilities. A "rich" platform satisfies all application needs and dependencies:

It has flexible routing capabilities, load balancing with SSL termination, databases, and both types of block storage we need.

Then, there are some with fewer capabilities.

These platforms can satisfy only part of deployed application needs. To get the missing components you may manually deploy custom open source solutions, like proxies and databases hosted on dedicated instances. But that is error prone and quite frankly a nightmare to manage.

Other hosting providers might supply even fewer services on their platforms. Yet, you still need to be able to deploy your applications on them. That leaves you with no choice but to use the limited functionality of the hosting provider or datacenter.


This is where you can benefit from Kubernetes. You can wrap it around the basic provided resources of the hosting provider, and spawn fail-tolerant services on top of the raw resources, using Helm package manager for example. This way, your application can leverage Kubernetes services, instead of relying on the hosting provider.  As you can move all its dependencies with the application, it becomes portable.

Kubernetes is great because it functions almost like a Lego set where you can connect your component and external services anywhere you like. Here are some features of Kubernetes and its ecosystem that help make your applications, its dependencies, and backing services portable:

  • Component definitions and their connectivity and relation to each other, including routing and access policies, are stored as all other resources in simple YAML format.
  • Templating tools: Helm package manager. You can define and reuse templates (or "blueprints") made of several services with variable settings. Each template can contain as many resources as needed, like pods, volumes, load balancers, security settings, deployments and other Kubernetes resources.
  • Abstraction over ingress traffic processing: Service, Ingress, and Ingress controller. Those components serve as a robust framework that satisfies all routing and balancing needs of your application and its backing services.
  • Abstraction over storage provisioning and management: Volumes and Volume claims. These all were made possible by sophisticated "behind the scenes" controllers and plugins, that integrate with all virtualization, storage, and cloud providers, and expose a unified syntax for provisioning storage to cluster users.

Basic Kubernetes Concepts

There are a variety of Kubernetes components that make application portability possible:

  • Services: one of the basic Kubernetes concepts that allow you to provide a single, stable endpoint to access a set of pods or containers running inside a Kubernetes cluster. This pod/container set is dynamic, can be started, scaled up or down, die, or restarted. Services track these dynamic sets and rearrange routing rules so that clients of this service implemented don't see the change.
  • Ingress: is an abstraction of a higher level than ‘service' with a similar purpose. It's a level 7 routing rule, which tells Kubernetes how HTTP and HTTPS requests should be routed to services inside the cluster.
  • Ingress controllers: Implements routing rules for the ingress. Layer 7 reverse proxy that runs inside Kubernetes watches those ingress rules as they are updated by cluster users and reconfigures itself to ensure proper processing of HTTP and HTTP requests. There are various implementations; some are based on Nginx or HAproxy as an example.
  • Config maps and secrets: allows storing configuration or sensitive information like credentials, inside the Kubernetes cluster and mapping them to pods and containers. This allows for complete portability of all application components including their per-namespace and per-environment credentials and settings.
  • Volumes and volume claims: This type of complete abstraction over storage mechanics, contributes to portability by letting developers and administrators avoid manually configuring low-level storage-related settings and managing folder mounts.

To summarize, a portable application architecture involves not only the usage of the right tools, but also correct planning and best practices, like keeping the app stateless, supporting re-initialization and reconnection to external resources like databases, and so on.

Ready to roll up your sleeves and deploy portable applications? You can find a step-by-step guide in the 2nd section of our portability blog.

For more on application portability, Kubernetes, and other great cloud native topics, attend KubeCon + CloudNativeCon EU, May 2-4, 2018 in Copenhagen, Denmark.


About the Author


Oleg Chunikhin has been working in the field of software architecture and development for nearly 20 years. Oleg joined Kublr as the CTO in 2016 to help define the technology strategy and innovative standards and fulfill the company's plans for growth. Notably, Oleg has championed the standardization of DevOps in all the company does and is a firm believer in driving the adoption of automation and artificial intelligence applications, particularly in industries where new technologies are fast becoming mainstream (genetics, 3D printing, robotics, neural interfaces, mesh technologies, etc.). Oleg holds a Bachelor of Mathematics and a Master of Applied Mathematics and Computer Science from Novosibirsk State University and is an AWS Certified Software Architect.

Published Wednesday, April 18, 2018 7:37 AM by David Marshall
There are no comments for this post.
To post a comment, you must be a registered user. Registration is free and easy! Sign up now!
<April 2018>