Cloud Native
Hajimemashite, mediumers!!!
In this article, I will discuss the basics of Cloud Native, feature as an implementation according to the material presented at the 8th meeting of the eFishery Academy. Here’s the explanation
According to the definition of CNCF (Cloud Native Computing Foundation), Cloud-native technologies is a tech innovations to 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. These techniques enable 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.
Cloud-native is about speed and agility. Business systems are evolving from enabling business capabilities to weapons of strategic transformation that accelerate business velocity and growth. It’s imperative to get new ideas to market immediately.
At the same time, business systems have also become increasingly complex with users demanding more. They expect rapid responsiveness, innovative features, and zero downtime. Performance problems, recurring errors, and the inability to move fast are no longer acceptable. Your users will visit your competitor. Cloud-native systems are designed to embrace rapid change, large scale, and resilience.
The poster above explains the basic implementation of cloud-native which is often used by technology companies who are familiar with data storage via the cloud, both on small and massive scale. In addition to the basic cloud, there are some clues about how the data storage flow is managed by the company by applying the available cloud technology. After knowing the understanding and initial description of cloud-native, here are the components in cloud native such as:
The pillars of Cloud Native
The speed and agility of cloud-native derive from many factors. Foremost is cloud infrastructure. But there’s more: Five other foundational pillars shown in picture 3 also provide the bedrock for cloud-native systems. Let’s take some time to better understand the significance of each pillar.
a. The Cloud
Cloud-native systems take full advantage of the cloud service model. Designed to thrive in a dynamic, virtualized cloud environment, these systems make extensive use of Platform as a Service (PaaS) compute infrastructure and managed services. They treat the underlying infrastructure as disposable — provisioned in minutes and resized, scaled, or destroyed on demand — via automation. Consider the widely accepted DevOps concept of Pets vs. Cattle. In a traditional data center, servers are treated as Pets: physical machines, given a meaningful name, and cared for. You scale by adding more resources to the same machine (scaling up). If the server becomes sick, you nurse it back to health. Should the server become unavailable, everyone notice?
The Cattle service model is different. You provision each instance as a virtual machine or container. They’re identical and assigned a system identifier such as Service-01, Service-02, and so on. You scale by creating more of them (scaling out). When one becomes unavailable, nobody notices. The cattle model embraces immutable infrastructure. Servers aren’t repaired or modified. If one fails or requires updating, it’s destroyed and a new one is provisioned — all done via automation. Cloud-native systems embrace the Cattle service model. They continue to run as the infrastructure scales in or out with no regard to the machines upon which they’re running.
b. Modern Design
How would you design a cloud-native app? What would your architecture look like? To what principles, patterns, and best practices would you adhere? What infrastructure and operational concerns would be important?
c. The Twelve-Factor Application
A widely accepted methodology for constructing cloud-based applications is the Twelve-Factor Application. It describes a set of principles and practices that developers follow to construct applications optimized for modern cloud environments. Special attention is given to portability across environments and declarative automation. While applicable to any web-based application, many practitioners consider Twelve-Factor a solid foundation for building cloud-native apps. Systems built upon these principles can deploy and scale rapidly and add features to react quickly to market changes. The following poster’s highlight the Twelve-Factor methodology:
For details of each base, you can access the reference at the end of this article.
In addition to, in the book, Beyond the Twelve-Factor App, author Kevin Hoffman details each of the original 12 factors (written in 2011). Additionally, he discusses three extra factors that reflect today’s modern cloud application design.
d. Containers
It’s natural to hear the term container mentioned in any cloud native conversation. In the book, Cloud Native Patterns, author Cornelia Davis observes that “Containers are a great enabler of cloud-native software.” The Cloud Native Computing Foundation places microservice containerization as the first step in their Cloud-Native Trail Map — guidance for enterprises beginning their cloud-native journey.
Containerizing a microservice is simple and straightforward. The code, its dependencies, and runtime are packaged into a binary called a container image. Images are stored in a container registry, which acts as a repository or library for images. A registry can be located on your development computer, in your data center, or in a public cloud. Docker itself maintains a public registry via Docker Hub.
When an application starts or scales, you transform the container image into a running container instance. The instance runs on any computer that has a container runtime engine installed. You can have as many instances of the containerized service as needed. Picture 7, shows three different microservices, each in its own container, all running on a single host.
Note how each container maintains its own set of dependencies and runtime, which can be different from one another. Here, we see different versions of the Product microservice running on the same host. Each container shares a slice of the underlying host operating system, memory, and processor, but is isolated from one another. Note how well the container model embraces the Dependencies principle from the Twelve-Factor Application.
Containers support both Linux and Windows workloads. While several container vendors exist, Docker has captured the lion’s share of the market. The company has been driving the software container movement. It has become the de facto standard for packaging, deploying, and running cloud-native applications. For more details about containers, you can access the ref at the end of this article.
e. Microservices
Cloud-native systems embrace microservices, a popular architectural style for constructing modern applications.
Built as a distributed set of small, independent services that interact through a shared fabric, microservices share the following characteristics:
- Each implements a specific business capability within a larger domain context.
- Each is developed autonomously and can be deployed independently.
- Each is self-contained encapsulating its own data storage technology, dependencies, and programming platform.
- Each runs in its own process and communicates with others using standard communication protocols such as HTTP/HTTPS, gRPC, WebSockets, or AMQP.
- They compose together to form an application.
Picture 8 contrasts a monolithic application approach with a microservices approach. Note how the monolith is composed of a layered architecture, which executes in a single process. It typically consumes a relational database. The microservice approach, however, segregates functionality into independent services, each with its own logic, state, and data. Each microservice hosts its own data store.
Earlier in the chapter, we compared an eCommerce application built as a monolith to that with microservices. In the example, we saw some clear benefits:
- Each microservice has an autonomous lifecycle and can evolve independently and deploy frequently. You don’t have to wait for a quarterly release to deploy new features or updates. You can update a small area of a live application with less risk of disrupting the entire system. The update can be made without a full redeployment of the application.
- Each microservice can scale independently. Instead of scaling the entire application as a single unit, you scale out only those services that require more processing power to meet desired performance levels and service-level agreements. Fine-grained scaling provides for greater control of your system and helps reduce overall costs as you scale portions of your system, not everything.
While distributed cloud-native microservices can provide immense agility and speed, they present many challenges:
Communication
How will front-end client applications communicate with backed-end core microservices? Will you allow direct communication? Or, might you abstract the back-end microservices with a gateway facade that provides flexibility, control, and security?
Get Febry Heri Setiyawan’s stories in your inbox
Join Medium for free to get updates from this writer.
How will back-end core microservices communicate with each other? Will you allow direct HTTP calls that can increase coupling and impact performance and agility? Or might you consider decoupled messaging with queue and topic technologies?
Communication is covered in the Cloud-native communication patterns chapter.
Resiliency
A microservices architecture moves your system from in-process to out-of-process network communication. In a distributed architecture, what happens when Service B isn’t responding to a network call from Service A? Or, what happens when Service C becomes temporarily unavailable and other services calling it to become blocked?
Resiliency is covered in the Cloud-native resiliency chapter.
Distributed Data
By design, each microservice encapsulates its own data, exposing operations via its public interface. If so, how do you query data or implement a transaction across multiple services?
Distributed data is covered in the Cloud-native data patterns chapter.
Secrets
How will your microservices securely store and manage secrets and sensitive configuration data?
Secrets are covered in detail Cloud-native security.
Manage Complexity with Dapr
Dapr is a distributed, open-source application runtime. Through an architecture of pluggable components, it dramatically simplifies the plumbing behind distributed applications. It provides a dynamic glue that binds your application with pre-built infrastructure capabilities and components from the Dapr runtime. Picture 9 shows Dapr from 20,000 feet.
In the top row of the figure, note how Dapr provides language-specific SDKs for popular development platforms. Dapr v1 includes support for .NET, Go, Node.js, Python, PHP, Java, and JavaScript.
While language-specific SDKs enhance the developer experience, Dapr is platform agnostic. Under the hood, Dapr’s programming model exposes capabilities through standard HTTP/gRPC communication protocols. Any programming platform can call Dapr via its native HTTP and gRPC APIs.
The blue boxes across the center of the figure represent the Dapr building blocks. Each exposes pre-built plumbing code for a distributed application capability that your application can consume.
The components row represents a large set of pre-defined infrastructure components that your application can consume. Think of components as infrastructure code you don’t have to write.
The bottom row highlights the portability of Dapr and the diverse environments across which it can run.
f. Backing Services
Cloud-native systems depend upon many different ancillary resources, such as data stores, message brokers, monitoring, and identity services. These services are known as backing services. Picture 10 shows many common backing services that cloud-native systems consume.
You could host your own backing services, but then you’d be responsible for licensing, provisioning, and managing those resources.
Cloud providers offer a rich assortment of managed backing services. Instead of owning the service, you simply consume it. The cloud provider operates the resource at scale and bears the responsibility for performance, security, and maintenance. Monitoring, redundancy, and availability are built into the service. Providers guarantee service level performance and fully support their managed services — open a ticket and they fix your issue. Cloud-native systems favor managed backing services from cloud vendors. The savings in time and labor can be significant. The operational risk of hosting your own and experiencing trouble can get expensive fast. A best practice is to treat a backing service as an attached resource, dynamically bound to a microservice with configuration information (a URL and credentials) stored in an external configuration. With this pattern, a backing service can be attached and detached without code changes. You might promote a microservice from QA to a staging environment. You update the microservice configuration to point to the backing services in staging and inject the settings into your container through an environment variable.
Cloud vendors provide APIs for you to communicate with their proprietary backing services. These libraries encapsulate the proprietary plumbing and complexity. However, communicating directly with these APIs will tightly couple your code to that specific backing service. It’s a widely accepted practice to insulate the implementation details of the vendor API. Introduce an intermediation layer, or intermediate API, exposing generic operations to your service code and wrapping the vendor code inside it. This loose coupling enables you to swap out one backing service for another or move your code to a different cloud environment without having to make changes to the mainline service code. Dapr, discussed earlier, follows this model with its set of prebuilt building blocks.
g. Automation
As you’ve seen, cloud-native systems embrace microservices, containers, and modern system design to achieve speed and agility. But, that’s only part of the story. How do you provision the cloud environments upon which these systems run? How do you rapidly deploy app features and updates? How do you round out the full picture?
Enter the widely accepted practice of Infrastructure as Code, or IaC.
With IaC, you automate platform provisioning and application deployment. You essentially apply software engineering practices such as testing and versioning to your DevOps practices. Your infrastructure and deployments are automated, consistent, and repeatable.
Automating infrastructure
Tools like Azure Resource Manager, Azure Bicep, Terraform from HashiCorp, and the Azure CLI, enable you to declaratively script the cloud infrastructure you require. Resource names, locations, capacities, and secrets are parameterized and dynamic. The script is versioned and checked into source control as an artifact of your project. You invoke the script to provision a consistent and repeatable infrastructure across system environments, such as QA, staging, and production.
Under the hood, IaC is idempotent, meaning that you can run the same script over and over without side effects. If the team needs to make a change, they edit and rerun the script. Only the updated resources are affected.
In the article, What is Infrastructure as Code, Author Sam Guckenheimer describes how “Teams who implement IaC can deliver stable environments rapidly and at scale. They avoid manual configuration of environments and enforce consistency by representing the desired state of their environments via code. Infrastructure deployments with IaC are repeatable and prevent runtime issues caused by configuration drift or missing dependencies. DevOps teams can work together with a unified set of practices and tools to deliver applications and their supporting infrastructure rapidly, reliably, and at scale.”
Automating deployments
Modern CI/CD systems help fulfill this principle. They provide separate build and delivery steps that help ensure consistent and quality code that’s readily available to users. Picture 11 shows the separation across the deployment process.
In the previous figure, pay special attention to the separation of tasks:
- The developer constructs a feature in their development environment, iterating through what is called the “inner loop” of code, run, and debug.
- When complete, that code is pushed into a code repository, such as GitHub, Azure DevOps, or BitBucket.
- The push triggers a build stage that transforms the code into a binary artifact. The work is implemented with a Continuous Integration (CI) pipeline. It automatically builds, tests, and packages the application.
- The release stage picks up the binary artifact, applies external application and environment configuration information, and produces an immutable release. The release is deployed to a specified environment. The work is implemented with a Continuous Delivery (CD) pipeline. Each release should be identifiable. You can say, “This deployment is running Release 2.1.1 of the application.”
- Finally, the released feature is run in the target execution environment. Releases are immutable meaning that any change must create a new release.
Applying these practices, organizations have radically evolved how they ship software. Many have moved from quarterly releases to on-demand updates. The goal is to catch problems early in the development cycle when they’re less expensive to fix. The longer the duration between integrations, the more expensive problems become to resolve. With consistency in the integration process, teams can commit code changes more frequently, leading to better collaboration and software quality.
This is a fairly complex discussion about basic Cloud Native and what parts are in it. If there are criticisms and suggestions, you can put them in the comments column in this medium. That is all and thank you.
Ref:
eFishery presentation material, accessed on September 3rd, 2022
https://docs.microsoft.com/en-us/dotnet/architecture/cloud-native/definition, accessed on September 3rd, 2022
https://medium.com/turkcell/12-factor-app-methodology-distributed-computing-microservices-concepts-678d87b608f, accessed on September 3rd, 2022









