Cloud Native, Helm, and Stateless Design
Understand containers, Kubernetes reconciliation, reusable Helm values, and the 12-factor stateless process model.
“Cloud native” is not a synonym for “hosted somewhere.” It describes software designed for automation: repeatable builds, explicit configuration, observable health, replaceable processes, and infrastructure controlled through versioned declarations.
Download this chapter's files
Use your browser to download either ivia-chapter-02.tar.gz or ivia-chapter-02.zip. The archive is self-contained; you do not need this tutorial repository.
Open a terminal after the browser download:
cd ~/Downloads
tar -xzf ivia-chapter-02.tar.gz
cd ivia-chapter-02
All remaining relative paths in this chapter start from that extracted directory.
The challenge
Challenge: classify application data as disposable process state or durable state, then verify that two rendered Kubernetes replicas would share no local files.
Prerequisites
- Helm and the extracted Chapter 2 package.
- A text editor and terminal.
- Basic familiarity with files and processes; no running cluster is required.
Learning goals
- Explain how containers, Pods, Deployments, Services, and Ingress relate
- Explain why Helm values are safer than duplicated Kubernetes YAML
- Apply the 12-factor rules for configuration and stateless processes
- Recognize when a database or persistent volume is needed
From source to request
A Dockerfile turns source files into an image. A container runtime starts an isolated container from that image. Kubernetes places containers in Pods. A Deployment replaces failed Pods and scales replicas. A Service gives changing Pods one stable cluster address. An Ingress routes HTTP hostnames from outside the cluster to Services.
Helm packages Kubernetes templates as a chart. This tutorial reuses the IVIA generic chart instead of creating a custom chart. Our values.yaml chooses components, images, ports, probes, environment variables, ingress hosts, and volumes. Chart version 4.8.0 converts those values into Kubernetes resources.
The 12-factor connection
Two rules guide the tutorial:
- Config: deployment-specific values belong in environment variables or mounted configuration, not inside the image.
- Processes: application processes are stateless and share nothing. Durable data belongs in a backing service or persistent volume.
Imagine the backend handles a message:
- A parsed request body lasts for one request and belongs in process memory.
- A cached calculation is expendable and belongs in memory or a cache.
- Greeting text varies by deployment and belongs in an environment variable.
- A user message must survive restart and belongs in a database or persistent volume.
- Application code is fixed per release and belongs in the container image.
Render without deploying
After Helm is installed, this exact command renders the static stage locally:
mkdir -p work
helm template simple-app \
oci://harbor.ivia.ch/ivia-generic-helm-chart/ivia-generic-helm-chart \
--version 4.8.0 \
--namespace tutorial \
-f static-app/values.yaml \
> work/simple-app-rendered.yaml
Inspect the desired replica count and image references:
grep -n -E 'kind: Deployment|replicas:|image:' \
work/simple-app-rendered.yaml
Rendering is client-side: it does not require a cluster and creates no Kubernetes resources.
Now consider scaling:
kubectl scale deployment/simple-app-frontend --replicas=2 -n tutorial
Do not run this until Chapter 5 creates the Deployment. The important question is whether either replica expects a file written inside the other replica. The static app does not, so either Pod can answer any request.
Expected validation
The rendered file should contain a Deployment named simple-app-frontend, replicas: 1, and the image simple-static:local. The design review succeeds when every durable datum has an external home and no replica depends on another replica's writable filesystem.
Troubleshooting and common pitfalls
- Helm asks for registry credentials: confirm the OCI URL and chart version exactly match the command.
- Rendered output is empty: check Helm's exit status and ensure the values path is relative to the extracted chapter directory.
- “Containers are stateless”: containers can write files, but those files are ephemeral unless a volume is mounted. Stateless is an application design decision.
- “Helm runs my application”: Helm submits declarations; Kubernetes controllers run and reconcile workloads.
- Scaling SQLite to two writers: a local SQLite file plus a ReadWriteOnce volume is intentionally limited to one backend replica in Chapter 10.
This architecture is small enough to understand and structured enough to grow. That is excellent cloud-native practice.