And what does it have to do with data? Developers worldwide are building cloud-native applications using microservices, containers, orchestration and automation. Let's look at how you can combine these approaches with flexible data access through storage, streams, and APIs to build powerful applications that are elastic, scalable, and resilient.
Cloud-native applications are designed for the cloud to take advantage of its unique possibilities for scaling out and scaling in, and typically consist of collections of loosely coupled services running in containers. Cloud-native applications leverage cloud computing technologies including those listed above to increase the speed, flexibility and innovation in the development cycle, while providing predictable iterations towards delivering new digital user experiences.
According to the Cloud Native Computing Foundation (CNCF), “Cloud-native technologies empower organizations to build and run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify this approach.” The benefits include, “loosely coupled systems that are resilient, manageable, and observable. Combined with robust automation, they allow engineers to make high-impact changes frequently and predictably with minimal toil.”
Applications can survive hardware, network and software flaws
Applications are easy to configure and quickly adapt to changing operating conditions and environments
Applications are instrumented to collect metrics and logs in order to provide actionable insight
Applications are modular allowing rapid incremental changes to individual units
Applications and configurations are source controlled to ensure auditability and repeatability of deployments and configuration changes
Application deployment and management is automated, reducing busywork and enabling operators to manage systems holistically
Building cloud-native applications requires a mindset shift that reaches into the culture and processes of organizations, architecture of the system as a whole, and technology choices throughout the stack. Whether you're delivering that first app for your startup or modernizing a traditional monolith, adopting cloud-native applications enables you to bring tailored, personalized experiences to delight and empower your consumer and enterprise customers to leverage their data in ways they may not have even considered.
There are some key elements that are commonly found in cloud-native applications:
Small, loosely coupled services which promote agility and independence in the development lifecycle. Multiple instances of stateless microservices support resilience and elastic scalability, and low-risk system evolution.
Development teams have the freedom to choose the tools that best fit the functionality of their application. When accessing data sources, options range from low-level drivers, to frameworks that abstract drivers and query languages, to higher level data APIs.
Business logic can be expressed as simple functions that don’t require a full operating system can be deployed and scaled with greater ease than microservices using serverless frameworks or cloud providers.
Databases, Data services, streaming and messaging platforms enable the flow of data between microservices and persistence in systems of record, as you’ll read more about below.
Microservices are frequently packaged and deployed as Docker images for portability and optimized resource consumption.
Containers are then managed by an orchestration framework such as Kubernetes for automated deployment, operation, scaling, and resilience of applications at scale.
Distributed applications expose new fault domains and teams turn to central monitoring systems such as Prometheus to provide a single view over the system.
TLS, OAuth, OIDC, JWTs, identity providers, API gateways, and automatic container patching provide new mechanisms to cover attack surface areas.
Application code and required infrastructure expressed as “infrastructure as code” are checked into source control systems such as Git, enabling rapid iteration through automated dev, test, and prod pipelines.
Given the variety of design options and data stores available, there are any number of ways to approach data. We’ve observed several common patterns.
Microservices typically delegate responsibility for storing state to a persistence mechanism such as a dedicated block storage volume, a distributed database cluster, or a data service. Regardless of the store used, each service should control access to its own data.
When interacting with a distributed database such as Cassandra, the simplest way to access data is through data service APIs described in GraphQL, REST, or gRPC. This mode of interaction is useful for frontend applications, serverless functions, or microservices. Microservices that need more control over their interactions with the backend database can code directly using a driver, or use a framework such as Spring, Quarkus, Django, Vue.js to aid in data interactions.
Cloud-native architectures also need to address the flow of data between services and APIs. Data can flow from streaming and messaging systems such as Kafka into Cassandra as a system of record for access by microservices. Change Data Capture (CDC) enables data flows out of Cassandra to other services or to a data lake to enable further analysis.