Kubernetes: The Exception Pathway
Last reviewed · content updated
AdvancedWhat 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:
- 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.”
- 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.”
- 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:
| Object | What it is | Why you care here |
|---|---|---|
| Deployment | Desired state for stateless replicas | For stateless apps; wrong for Oracle |
| StatefulSet | Replicas with stable identity + storage | Databases live here: stable network name, ordered startup, per-replica volume |
| Service | Stable virtual IP/DNS in front of pods | How the API reaches Oracle without chasing pod IPs |
| PersistentVolumeClaim | A request for durable storage | Your data survives pod rescheduling because of this object |
| ConfigMap | Non-secret configuration | Init parameters, tnsnames — never credentials |
| Secret | Credential storage (base64, access-controlled) | Where the passwords go — Lesson 2.5 shows what happens when they don’t |
| Namespace | Scoping + policy boundary | oracle-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
apiVersion: apps/v1kind: StatefulSetmetadata: name: oracle namespace: oracle-prodspec: 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 obligation | Cadence | Notes |
|---|---|---|
| Cluster version upgrades | ~3 releases/year, limited support window | Plan, test, execute — every year, forever |
| Node image patching | Ongoing | Automatable, but you own the automation and its failures |
| Capacity management | Continuous | Node pools sized by you; overprovision = waste, under = incidents |
| etcd/state care, cluster DR | Ongoing | The control plane is managed on AKS; your workload state is not |
| Database backup/restore drills | Scheduled | Volume snapshots + Oracle-level backup; tested restores or it is not backup |
| Cluster security posture | Continuous | Network 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.
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.