Kubernetes is the cloud’s breakout success story. It’s gone from nothing to the application development equivalent of a superstar in only a few years, a rapid growth that’s left developers looking for better ways to build and manage Kubernetes-hosted applications.
There have been plenty of workarounds and extensions. Tools such as Helm make it easy to deploy resources to clusters, whereas CNAB (Cloud Native Application Bundle) wraps up applications and all their dependencies ready for deployment. At a lower level, services such as Draft help design and build basic services. You can build code and deploy it using familiar containers, and you can quickly assemble elements into Kubernetes applications. You can even automate management with Azure Kubernetes Services.
It’s probably not surprising for a tool that comes from a service infrastructure background (Google’s work on Borg), that Kubernetes and the tools around it fundamentally focus on operations. Distributed systems operations have long been a problem, and the whole data center OS movement, from Borg and Mesos, to Docker Swarm and Kubernetes, is much more the ops side of devops than it is the dev.
How do we go beyond that approach, to put the dev back in Kubernetes? We’ve done a lot of work building an ecosystem, codifying the patterns and practices that go into building a distributed application based on microservice principles. Now it’s time to put it all together and deliver that missing piece of the picture, the piece that’s essential to developers: an application-centric way of looking at Kubernetes.
Introducing OAM, the Open Application Model
Microsoft and Alibaba Cloud recently announced the Open Application Model, focusing on building and managing microservice-based applications, with an understanding of the boundaries between the roles and the different layers that make up a modern distributed application. Although OAM is clear that every Kubernetes-based environment is different, there are still points of commonality that can separate application from supporting services from infrastructure, without walking away from the benefits of a devops culture.
The Open Application Model starts by defining the roles and responsibilities of the teams involved in building and operating a modern application. Instead of the traditional divide between developers and operators, it takes a slightly more fine-grained approach and introduces the concept of application operator and infrastructure operator roles. It’s a model that makes sense; tools such as Kubernetes and the platform services that surround them are, at heart, an abstraction of the underlying data center and of core applications.
With OAM we have application operators who manage and deploy the microservices delivered by the development team. They’re the team who manage and deploy pods and containers, ensuring application reliability and scaling, using monitoring and observability tools. They’re also the team who use service mesh components to define the application network and its behavior, using declarative tools to build service policies.
Infrastructure operators are akin to traditional ops roles, though now responsibility only goes as far as infrastructure services, like Kubernetes itself, or the software-defined network that’s managed by service mesh policies. There’s no need for them to know about the applications that are running, all they need to do is ensure that all the services they offer are available and that their APIs are operating. That’s not to downplay the importance of their role, as the increasing complexity of modern system operations requires specialists and experts at a service level: Managing and deploying multitenant databases, for example, requires considerable knowledge and skill.
Defining applications in OAM
At the heart of the OAM is the concept of an application. This separates the application from how it’s deployed and how it integrates with the underlying infrastructure. It’s a way of understanding that I will deploy an application and manage it differently from how you do it, and the way Azure works with it is different from the way AWS does.
Applications are made up of components, which may or may not be included in any deployment package. An application component could be a hosted database service, or a set of networking rules, or a set of message end points. It’s up to the underlying platform how those are implemented, but an application can’t be deployed until they’re in place. Relationships between the various components of an application are described in manifests that can then be used to build application microservices into deployable modules.
It’s a step beyond that used by tools such as CNAB, which package applications. Here, instead of delivering a package, you’re delivering components that are assembled into a site- or service-specific version of an application, using the available platform resources. The result is a very different approach to application packaging, one that requires more work on the part of the application operator, but less on the part of the infrastructure operator.
Working with infrastructure using Traits
By separating the application package from the platform, the result should be a more agnostic approach to application development that can handle the differences between standardized public clouds, where all components and resources are identical wherever you install your app, and custom on-premises private clouds that mix and match off-the-shelf hardware with tools like GCP’s Anthos. Key to this is OAM’s concept of Traits.
Traits are used to describe how an application environment should work, describing scaling and other key distributed-computing concepts in a way that’s both machine- and human-readable. A Trait has a name and a set of properties. For example, an autoscaling trait would define the minimum and maximum number of replicas allowed, which could then be translated to appropriate YAML for a Kubernetes installation, or to configuration files for a service mesh or for a service like KEDA (Kubernetes-based event-driven autoscaling).
Eventually, if OAM takes off, Traits and trait definitions should be supported directly by networking and security tools, as well as by the rest of the infrastructure automation features we’re using in our clouds. The intent is that Traits and other OAM application concepts should be vendor-neutral, allowing applications to install and run no matter whose infrastructure they’re run on. That approach should work well for edge deployments, where code runs close to the client, and where available equipment can depend on a content delivery network like Cloudflare or a metro-level telecom operator like AT&T.
Rudr: A reference implementation of OAM for Kubernetes
A specification such as OAM needs a reference implementation, and Microsoft has released Rudr, an implementation for use with Kubernetes. Rudr takes your OAM definitions, using custom resource definitions to translate them to Kubernetes components and services. Interestingly it’s written in Rust, taking advantage of its memory-safe features to reduce risk to your applications. You can use its published how-to to create a basic component that hosts a simple Python app container.
Rudr is still very much alpha code, as it’s tracking a specification that itself is changing quickly. However, it does give you a feel for how to manage OAM applications on a private cloud, and how services such as Azure will implement it on their much larger-scale infrastructures.