Cloud Modernization Patterns Module 2 · Where Should It Run?

Kubernetes: The Exception Pathway

Last reviewed · content updated

Advanced

What you'll learn

~20 min
  • Justify a descent to Kubernetes with a specific failed test, then scope it narrowly
  • Read the core Kubernetes objects (Deployment, StatefulSet, Service, PVC, ConfigMap, Secret) as an operator, not a tourist
  • Price the Day-2 operations a cluster adds: upgrades, node patching, capacity, backup

The one-sentence justification

Meridian’s Oracle 19c database fails the ladder at the fit test. A managed option exists — Oracle Database@Azure, Oracle-operated Exadata and Autonomous Database services sold through Azure — and Lesson 2.1 already named why it fails here: entry scale and cost designed for far larger estates, limited regions, no sovereign-cloud presence. That leaves VMs (rung 5) or a Kubernetes StatefulSet (rung 4). Weighed honestly: the VM path means hand-run OS patching, scripted backups, and pet-server drift forever, and it inherits the batch jobs’ file coupling; AKS brings declarative configuration, automated restart and rescheduling, image-based node patching, and the same IaC toolchain as the rest of the estate. Meridian descends — deliberately, narrowly, for one workload.

Three disciplines make this a controlled descent rather than a platform adoption:

  1. The justification is written down — one sentence in the decisions register (Lesson 4.1 formalizes this): “Oracle on AKS because Oracle Database@Azure fails our scale, cost, and region fit tests; re-run the fit test yearly.”
  2. The cluster’s scope is fenced — it hosts the workloads that failed the ladder test, and nothing else. Lesson 2.1’s quiz already rehearsed the failure mode: convenience workloads drifting onto the cluster “since it’s there.”
  3. The license boundary is pinned — Oracle’s core-based licensing counts every node the database could schedule onto. A dedicated node pool with taints and affinity pins the workload — and therefore the license conversation — to those cores; skip this and an audit can treat the whole cluster as licensable. For many shops this single line item is why Oracle stays on VMs at rung 5, and that is a legitimate ladder outcome too.

The vocabulary you now need

Kubernetes in one table, read through an operator’s eyes:

ObjectWhat it isWhy you care here
DeploymentDesired state for stateless replicasFor stateless apps; wrong for Oracle
StatefulSetReplicas with stable identity + storageDatabases live here: stable network name, ordered startup, per-replica volume
ServiceStable virtual IP/DNS in front of podsHow the API reaches Oracle without chasing pod IPs
PersistentVolumeClaimA request for durable storageYour data survives pod rescheduling because of this object
ConfigMapNon-secret configurationInit parameters, tnsnames — never credentials
SecretCredential storage (base64, access-controlled)Where the passwords go — Lesson 2.5 shows what happens when they don’t
NamespaceScoping + policy boundaryoracle-prod, with quotas and network policy at its edge

The one concept that changes how you read all of them: controllers reconcile desired state. You do not command Kubernetes to restart a pod; you declare “three replicas of this spec exist” and controllers make reality converge. Every manifest in Lesson 2.5 is a desired-state declaration — which is why a wrong declaration is so quietly dangerous: the cluster will faithfully converge on your mistake.

What the StatefulSet buys Oracle

oracle-statefulset.yaml — the shape (abridged)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: oracle
namespace: oracle-prod
spec:
serviceName: oracle
replicas: 1
template:
spec:
containers:
- name: oracle
image: registry.meridian.internal/oracle-db:19.3.0-ee
ports: [{ containerPort: 1521 }]
startupProbe:
exec: { command: ["bash", "-c", "printf 'whenever sqlerror exit failure;\nselect 1 from dual;' | sqlplus -S / as sysdba"] }
periodSeconds: 10
failureThreshold: 30
readinessProbe:
exec: { command: ["bash", "-c", "printf 'whenever sqlerror exit failure;\nselect 1 from dual;' | sqlplus -S / as sysdba"] }
periodSeconds: 15
resources:
requests: { memory: "16Gi", cpu: "4" }
limits: { memory: "16Gi", cpu: "4" }
volumeClaimTemplates:
- metadata: { name: datafiles }
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: managed-premium
resources: { requests: { storage: 1Ti } }

Read it as decisions: a readiness probe that runs SQL (the database answering queries is the fact that matters — not the port being open); requests equal to limits (a database gets guaranteed-QoS, never best-effort — Lesson 2.5 returns to this); a volumeClaimTemplate so storage identity follows the replica through rescheduling; and a startupProbe — the idiom for slow starters: it gives the database up to five minutes to open before ordinary probing begins, because probes that ignore real startup time become a restart loop. Three probe details worth copying: whenever sqlerror exit failure makes sqlplus actually exit nonzero on failure (by default it exits 0 even when the query errors), OS authentication (/ as sysdba) keeps any password out of the process list, and the command runs under bash explicitly rather than assuming what sh points to.

The bill: Day-2 operations you just acquired

The ladder’s whole argument was about this table, so here it is for the cluster you now own:

New obligationCadenceNotes
Cluster version upgrades~3 releases/year, limited support windowPlan, test, execute — every year, forever
Node image patchingOngoingAutomatable, but you own the automation and its failures
Capacity managementContinuousNode pools sized by you; overprovision = waste, under = incidents
etcd/state care, cluster DROngoingThe control plane is managed on AKS; your workload state is not
Database backup/restore drillsScheduledVolume snapshots + Oracle-level backup; tested restores or it is not backup
Cluster security postureContinuousNetwork policies, admission rules, image provenance, RBAC reviews

None of this appeared on Lesson 2.3’s Container Apps inventory — the platform rows there were absorbed. Here they land on Meridian’s calendar. This is not an argument against the descent; the descent was forced. It is the price tag that keeps the cluster fenced to workloads that actually earned it.

🔍Regulated and disconnected environments

There is a second legitimate road to Kubernetes: regulated enclaves. In high-compliance and air-gapped environments, teams choose K8s (or OpenShift) precisely because it can be self-contained: images mirrored into a private registry the cluster trusts, no public endpoints, encryption of cluster state at rest, compliance and file-integrity operators auditing continuously, and every control mapped to a framework like NIST 800-53. The tiering pattern is worth knowing even outside government: a connected-but-restricted tier (managed cloud, hardened) and a disconnected tier (private registry mirror, self-contained everything). If your career touches federal or critical-infrastructure work, this pattern is a training of its own.

KNOWLEDGE CHECK

Six months in, a teammate wants the new reporting dashboard (a stateless web app) deployed to the Oracle AKS cluster to 'get more value from it.' Using this lesson's framework, what is the right response?

Key takeaway

Descend to Kubernetes only behind a written, one-sentence justification; scope the cluster to the workloads that earned it; give stateful workloads StatefulSets with guaranteed resources and probes that test the real service; and put the Day-2 bill on the calendar the day the cluster is born. Next lesson: the manifests themselves — and the ten ways generated ones go wrong.

Search lessons