LFCA 111 🐧 Cloud Native Principles
Cloud native is not a product or a single technology. It is an approach to building and running applications that takes advantage of what the cloud makes possible: elasticity, resilience, and rapid change. A cloud-native application is designed for the cloud from the beginning, rather than being a traditional application that has been moved to cloud infrastructure . The distinction matters because a monolith running on a cloud VM is still a monolith; it has the location of a cloud application but not the architecture.
The Cloud Native Computing Foundation (CNCF) defines cloud native as an approach that empowers organizations to build and run scalable applications in dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs are the building blocks of this approach. The goal is loosely coupled systems that are resilient, manageable, and observable, so engineers can make high-impact changes frequently and predictably with minimal toil .
This chapter covers the CNCF definition, the twelve-factor methodology that underpins cloud-native applications, the core architectural components, and the principles that distinguish a cloud-native application from one that merely runs in the cloud.
Key point: Cloud native is an approach to building applications that are designed for cloud environments, not merely hosted in them. The CNCF definition emphasizes containers, microservices, service meshes, immutable infrastructure, and declarative APIs as the building blocks. The twelve-factor methodology provides the operational practices.
Why cloud native exists
The lift-and-shift problem. Moving an existing application to a cloud VM does not make it cloud native. The application still has the same architecture, the same deployment process, and the same scaling limitations. It runs in the cloud but does not take advantage of the cloud.
The scaling problem. Traditional monolithic applications scale by running more copies of the entire application. If only the checkout function is under load, the whole application is duplicated. Cloud-native applications decompose into services that scale independently, so only the part under load is duplicated .
The resilience problem. Distributed systems fail. A cloud-native application assumes failure is inevitable and is designed to tolerate it. Fault isolation, self-healing, and graceful degradation are built into the architecture rather than added later .
The delivery problem. Cloud-native applications are released frequently. The build, release, and run stages are strictly separated, releases are immutable, and deployment is automated. This enables continuous delivery and rapid rollback .
The portability problem. Containers package an application with its dependencies, so it runs the same way in development, staging, and production. The application is not tied to a specific server or operating system configuration .
a. The CNCF definition
The Cloud Native Computing Foundation (CNCF) is the organization that maintains the canonical definition and the ecosystem of cloud-native projects. The definition v1.0 states:
“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. 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.”
The definition names five building blocks:
| Building block | Purpose |
|---|---|
| Containers | Package code and dependencies for portability |
| Service meshes | Manage service-to-service communication |
| Microservices | Decompose the application into independent services |
| Immutable infrastructure | Replace components rather than modify them |
| Declarative APIs | Describe the desired state rather than the steps |
The definition does not require every cloud-native application to use all five. It describes the pattern that most cloud-native applications follow .
b. The twelve-factor methodology
The Twelve-Factor App is a methodology for building software-as-a-service applications that are portable, scalable, and maintainable. It was written by engineers at Heroku and has become the operational guide for cloud-native applications .
| Factor | Principle |
|---|---|
| I. Codebase | One codebase tracked in version control, many deploys |
| II. Dependencies | Explicitly declare and isolate dependencies |
| III. Config | Store configuration in the environment |
| IV. Backing services | Treat backing services as attached resources |
| V. Build, release, run | Strictly separate build and run stages |
| VI. Processes | Execute the app as one or more stateless processes |
| VII. Port binding | Export services via port binding |
| VIII. Concurrency | Scale out via the process model |
| IX. Disposability | Maximize robustness with fast startup and graceful shutdown |
| X. Dev/prod parity | Keep development, staging, and production as similar as possible |
| XI. Logs | Treat logs as event streams |
| XII. Admin processes | Run admin/management tasks as one-off processes |
The factors that most directly define cloud-native behavior are processes, disposability, and port binding. Factor VI requires that applications run as stateless processes and store all persistent data in backing services. Sticky sessions are a violation; session state belongs in a datastore like Redis or Memcached . Factor IX requires fast startup and graceful shutdown on SIGTERM, so processes can be started and stopped at a moment’s notice for elastic scaling and rapid deployment . Factor VII requires the application to bind to a port and listen for requests rather than relying on an external web server .
c. Microservices and loose coupling
A microservices architecture decomposes an application into small, independently deployable services. Each service has a single responsibility and communicates with other services through well-defined APIs .
The benefits of this decomposition are:
| Benefit | Explanation |
|---|---|
| Independent scaling | Scale only the services under load |
| Independent deployment | Deploy one service without redeploying the entire application |
| Fault isolation | A failure in one service does not bring down the others |
| Technology diversity | Each service can use the best tool for its job |
| Team autonomy | Small teams own small services |
The cost of microservices is complexity. Distributed systems introduce network latency, partial failures, and data consistency challenges. The application must handle these explicitly, which is why cloud-native applications invest heavily in observability, resilience patterns, and automation .
d. Containers and immutable infrastructure
A container packages an application with its dependencies, so it runs consistently across environments. Containers are lighter than virtual machines because they share the host kernel, and they start in milliseconds rather than seconds .
Immutable infrastructure is the practice of replacing components rather than modifying them. When a new version is deployed, new containers are started, and old containers are stopped. The running components are never patched in place. This reduces configuration drift and makes rollback predictable: the previous version is always available as a container image .
The combination of containers and immutability is what makes continuous delivery practical. A release is a versioned container image, and deploying it is a matter of starting new containers and routing traffic to them.
e. Orchestration and declarative APIs
A container orchestrator, typically Kubernetes, automates the deployment, scaling, and management of containerized services. The orchestrator handles scheduling, self-healing, and service discovery, so the application does not need to manage these concerns itself .
The orchestrator is controlled through declarative APIs. The operator describes the desired state, and the orchestrator works to make the actual state match it. For example, a deployment manifest says “run three replicas of this container,” and Kubernetes ensures that three replicas are running, restarting any that fail .
Declarative APIs are a core building block in the CNCF definition. They shift the operator’s role from issuing commands to describing outcomes, and they enable GitOps workflows where the desired state is stored in version control .
Complete Example Session
# ============================================
# PART 1: THE TWELVE-FACTOR CHECKLIST
# ============================================
# I. Codebase: one repo, many deploys
# II. Dependencies: declared and isolated
# III. Config: environment variables
# IV. Backing services: attached resources
# V. Build, release, run: separated
# VI. Processes: stateless
# VII. Port binding: self-contained
# VIII.Concurrency: scale via processes
# IX. Disposability: fast start, graceful stop
# X. Dev/prod parity: similar environments
# XI. Logs: event streams
# XII. Admin processes: one-off
# ============================================
# PART 2: CONFIG FROM THE ENVIRONMENT
# ============================================
# Instead of hardcoding:
# DATABASE_URL=postgres://localhost/dev
# Read from environment:
export DATABASE_URL=postgres://prod-host/app
node app.js
# ============================================
# PART 3: STATELESS PROCESS
# ============================================
# Bad: session state in memory
# app.set('trust proxy', 1)
# app.use(session({ secret: '...' }))
# Good: session state in Redis
# app.use(session({
# store: new RedisStore({ url: process.env.REDIS_URL }),
# secret: process.env.SESSION_SECRET,
# }))
# ============================================
# PART 4: CONTAINER IMAGE
# ============================================
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
# ============================================
# PART 5: KUBERNETES DEPLOYMENT (DECLARATIVE)
# ============================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:1.2.3
ports:
- containerPort: 3000
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-secret
key: url
# ============================================
# PART 6: PORT BINDING
# ============================================
# The app binds to a port from config
PORT=8080 node server.js
# Kubernetes Service routes traffic to the port
# ============================================
# PART 7: GRACEFUL SHUTDOWN
# ============================================
# On SIGTERM: stop accepting, finish current, exit
process.on('SIGTERM', () => {
server.close(() => {
process.exit(0);
});
});
# ============================================
# PART 8: LOGS AS EVENT STREAMS
# ============================================
# Write to stdout, not to a file
console.log(JSON.stringify({ level: 'info', msg: 'started' }));
# The platform collects and routes the stream
# ============================================
# PART 9: IMMUTABLE INFRASTRUCTURE
# ============================================
# Deploy new image, stop old containers
kubectl set image deployment/my-app my-app=my-app:1.2.4
# Rollback is another image change
kubectl rollout undo deployment/my-app
# ============================================
# PART 10: OBSERVABILITY
# ============================================
# Metrics, logs, and traces
# - Metrics: Prometheus
# - Logs: centralized aggregation
# - Traces: distributed tracing
These ten parts cover the twelve-factor checklist, config from the environment, stateless processes, a container image, a declarative Kubernetes deployment, port binding, graceful shutdown, logs as event streams, immutable infrastructure, and observability.
Quick Reference
CNCF Building Blocks
| Building block | Purpose |
|---|---|
| Containers | Package code and dependencies |
| Service meshes | Manage service-to-service communication |
| Microservices | Decompose into independent services |
| Immutable infrastructure | Replace rather than modify |
| Declarative APIs | Describe desired state |
The Twelve Factors
| Factor | Principle |
|---|---|
| I. Codebase | One repo, many deploys |
| II. Dependencies | Declared and isolated |
| III. Config | Environment variables |
| IV. Backing services | Attached resources |
| V. Build, release, run | Separated stages |
| VI. Processes | Stateless |
| VII. Port binding | Self-contained |
| VIII. Concurrency | Process model |
| IX. Disposability | Fast start, graceful stop |
| X. Dev/prod parity | Similar environments |
| XI. Logs | Event streams |
| XII. Admin processes | One-off tasks |
Cloud Native vs Cloud Hosted
| Aspect | Cloud hosted | Cloud native |
|---|---|---|
| Architecture | Often monolithic | Microservices |
| Scaling | Whole application | Per service |
| Deployment | Manual or scripted | Automated CI/CD |
| Resilience | Added later | Built in |
| Portability | Tied to environment | Containerized |
Core Principles
| Principle | Meaning |
|---|---|
| Loose coupling | Independent components |
| Resilience | Tolerate failure |
| Observability | Metrics, logs, traces |
| Automation | Reduce manual toil |
| Immutability | Replace, do not modify |
Best Practices
✅ Do This:
# Store config in environment variables
export DATABASE_URL=postgres://prod/app
# Package with dependencies
FROM node:20-alpine
COPY package*.json ./
RUN npm ci --only=production
# Declare desired state
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 3
// Handle SIGTERM gracefully
process.on('SIGTERM', () => server.close(() => process.exit(0)));
// Log to stdout
console.log(JSON.stringify({ level: 'info', msg: 'started' }));
❌ Don’t Do This:
// Hardcode configuration
const db = 'postgres://prod-host/app'; // ❌ use env vars
// Store session state in memory
app.use(session({ secret: '...' })); // ❌ use Redis
# Use sticky sessions
# ❌ violates Factor VI
# Patch running containers in place
# ❌ use immutable infrastructure
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Config in code | Convenience | Environment variables |
| Session state in memory | Default framework behavior | External datastore |
| Sticky sessions | Load balancer default | Stateless processes |
| Slow startup | Large initialization | Lazy loading, fast boot |
| No graceful shutdown | Missing signal handling | Handle SIGTERM |
| Logs to files | Traditional logging | Log to stdout |
| Manual deployment | No automation | CI/CD pipeline |
Real-World Examples
1. Environment Config
export DATABASE_URL=postgres://prod/app
2. Stateless Session
app.use(session({ store: new RedisStore() }));
3. Container Image
FROM node:20-alpine
COPY . .
CMD ["node", "server.js"]
4. Kubernetes Deployment
apiVersion: apps/v1
kind: Deployment
spec:
replicas: 3
5. Port Binding
const port = process.env.PORT || 3000;
app.listen(port);
6. Graceful Shutdown
process.on('SIGTERM', () => server.close(() => process.exit(0)));
7. Logs to Stdout
console.log(JSON.stringify({ level: 'info', msg: 'ready' }));
8. Immutable Deploy
kubectl set image deployment/app app=app:2.0.0
9. Rollback
kubectl rollout undo deployment/app
10. Health Check
livenessProbe:
httpGet:
path: /healthz
port: 3000
Visual
Cloud Native Building Blocks
┌──────────────────────────────────────────────────────────────┐
│ CNCF CLOUD NATIVE BUILDING BLOCKS │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Containers │ │ Service │ │Microservices│ │
│ │ │ │ Meshes │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Immutable │ │ Declarative │ │
│ │Infrastructure│ │ APIs │ │
│ └─────────────┘ └─────────────┘ │
│ │
│ Result: loosely coupled, resilient, manageable, observable │
└──────────────────────────────────────────────────────────────┘
Twelve-Factor App
┌───────────────────────────────────────────────────────────────┐
│ I. Codebase ──▶ one repo, many deploys │
│ II. Dependencies ──▶ declared and isolated │
│ III. Config ──▶ environment variables │
│ IV. Backing services ──▶ attached resources │
│ V. Build, release ──▶ separated stages │
│ VI. Processes ──▶ stateless │
│ VII. Port binding ──▶ self-contained │
│ VIII. Concurrency ──▶ scale via processes │
│ IX. Disposability ──▶ fast start, graceful stop │
│ X. Dev/prod parity ──▶ similar environments │
│ XI. Logs ──▶ event streams │
│ XII. Admin processes ──▶ one-off tasks │
└───────────────────────────────────────────────────────────────┘
Cloud Hosted vs Cloud Native
┌──────────────────────────────────────────────────────────────┐
│ CLOUD HOSTED: │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Monolith on a VM │ │
│ │ Scale: whole application │ │
│ │ Deploy: manual or scripted │ │
│ │ Resilience: added later │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ CLOUD NATIVE: │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Microservices in containers │ │
│ │ Scale: per service │ │
│ │ Deploy: automated CI/CD │ │
│ │ Resilience: built in │ │
│ └────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
Declarative Orchestration
┌──────────────────────────────────────────────────────────────┐
│ DESIRED STATE (declared): │
│ replicas: 3 │
│ image: my-app:1.2.3 │
│ │
│ ORCHESTRATOR (Kubernetes): │
│ └── Ensures 3 replicas are running │
│ └── Restarts failed containers │
│ └── Routes traffic │
│ │
│ ACTUAL STATE matches desired state. │
└──────────────────────────────────────────────────────────────┘
Summary
| Item | Value |
|---|---|
| Cloud native | Approach to building for cloud environments |
| CNCF definition | Containers, service meshes, microservices, immutable infrastructure, declarative APIs |
| Twelve-Factor App | Methodology for scalable, portable applications |
| Factor VI | Stateless processes |
| Factor IX | Fast startup, graceful shutdown |
| Factor VII | Port binding |
| Microservices | Decomposed, independently deployable services |
| Containers | Package code and dependencies |
| Immutable infrastructure | Replace rather than modify |
| Orchestration | Kubernetes automates deployment and scaling |
| Declarative APIs | Describe desired state |
| Observability | Metrics, logs, traces |
Key takeaways:
- Cloud native is an approach, not a location. An application running on a cloud VM is not cloud native unless it is designed for the cloud’s characteristics: elasticity, resilience, and rapid change.
- The CNCF definition names five building blocks. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify the approach. The result is loosely coupled systems that are resilient, manageable, and observable.
- The twelve-factor methodology provides the operational practices. The factors that most define cloud-native behavior are stateless processes (VI), disposability (IX), and port binding (VII). Sticky sessions and in-memory state violate the methodology.
- Microservices enable independent scaling and deployment. Each service can be scaled and deployed without affecting the others. The cost is distributed systems complexity, which must be managed with observability and resilience patterns.
- Containers and immutable infrastructure enable continuous delivery. Containers package the application and its dependencies. Immutable infrastructure means replacing components rather than modifying them, which makes rollback predictable.
- Declarative APIs shift the operator’s role from commands to outcomes. The orchestrator ensures the actual state matches the desired state. GitOps workflows store the desired state in version control.
- Observability is a requirement, not an option. Distributed systems are opaque without centralized logging, metrics, and tracing. The application must be instrumented so its behavior can be understood.
Remember: Cloud native is a set of principles and practices for building applications that take advantage of what the cloud makes possible. It is not a single technology or a product you can buy. The CNCF definition provides the building blocks, and the twelve-factor methodology provides the operational discipline. The core principles are statelessness, disposability, loose coupling, immutability, and observability. An application that follows these principles can scale elastically, tolerate failure, and be delivered continuously. An application that does not may run in the cloud, but it is not cloud native.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!