Skip to main content
Welcome. This site supports keyboard navigation and screen readers. Press ? at any time for keyboard shortcuts. Press [ to focus the sidebar, ] to focus the content. High-contrast themes are available via the toolbar.
serard@dev00:~/cv

Part 26: Meet Acme and Globex

"Two clients. Different stacks. Different release cadences. Same workstation. Zero overlap."


Why

The remaining acts of this series ground the abstractions in two concrete examples. Rather than parade a fictional "DocHub" or "TodoApp" as the demo project, we use two realistic client environments — one a .NET shop, one a Spring Boot shop — and walk both of them end-to-end through GitLab, Postgres, MinIO, observability, ArgoCD, and a real workload deployment.

The thesis: Acme Corp and Globex are the demo. They are not toys. Their stacks are the kind a real freelancer or contractor encounters in week one of an engagement. The K8s.Dsl plugin makes both achievable on the same workstation, isolated from each other, in parallel.


Acme Corp — the .NET shop

Tech stack:

  • Language: C# / .NET 10
  • API style: ASP.NET Core minimal APIs + SignalR for real-time
  • Database: Postgres 16 (managed by CloudNativePG)
  • Cache: Redis (Bitnami chart)
  • Object storage: MinIO (operator)
  • Frontend: Blazor Server, served by the same ASP.NET process behind Traefik
  • Authentication: Keycloak (Bitnami chart)
  • Build: GitLab CI with the .NET SDK image
  • Deployment: ArgoCD with App-of-Apps + Helm charts
  • Observability: kube-prometheus-stack + Grafana dashboards specific to ASP.NET (Microsoft.Extensions.Diagnostics)
  • Backup: Velero, daily snapshots of Postgres + MinIO

Release cadence: One release every two weeks. Strict change control. Every deploy goes through dev → stage → prod, with manual approval at each transition.

HomeLab K8s topology: k8s-multi (1 control plane + 3 workers). Acme's production runs four-node clusters; matching that in dev is the right call.

Acme's namespaces:

acme-dev          ← active development
acme-stage        ← integration testing
acme-prod         ← production simulation (also where Velero restore tests run)
acme-platform     ← shared infra (cert-manager, ingress, observability, ArgoCD)
acme-monitoring   ← Prometheus, Grafana, Loki

The freelancer (you) has a kubeconfig context named acme and a HomeLab instance named acme on subnet 192.168.60.0/24.


Globex — the Spring Boot shop

Tech stack:

  • Language: Java 21
  • API style: Spring Boot 3.4 microservices (a gateway + three services)
  • Database: Postgres 16 (also managed by CloudNativePG; same operator, different Cluster CRD instance)
  • Message bus: Apache Kafka via the Strimzi operator
  • Object storage: MinIO (same operator as Acme; different MinIO Tenant)
  • Frontend: React SPA built by a separate CI job, served by an nginx pod behind Traefik
  • Authentication: Keycloak
  • Build: GitLab CI with the Maven image
  • Deployment: ArgoCD with App-of-Apps + Helm charts
  • Observability: kube-prometheus-stack + Grafana dashboards specific to Spring Actuator and JMX
  • Backup: Velero, twice-daily snapshots, plus Kafka topic mirroring to a backup cluster (not in HomeLab K8s scope; we just back up the Kafka volumes)

Release cadence: Two deploys per day on the main branches, blue-green via ArgoCD's Rollouts. Loose change control with strong test automation.

HomeLab K8s topology: k8s-ha (3 control planes + 3 workers). Globex's production is HA, and they want every Reference Architecture quirk validated in dev.

Globex's namespaces:

globex-dev
globex-stage
globex-prod
globex-platform
globex-monitoring
globex-kafka      ← Strimzi-managed Kafka cluster

The freelancer has a globex kubeconfig context and a HomeLab instance named globex on subnet 192.168.61.0/24.


What both share

  • The same K8s.Dsl plugin code
  • The same IClusterDistribution, IK8sManifestContributor, IHelmReleaseContributor, IGitOpsRepoGenerator
  • The same Helm charts (CloudNativePG, kube-prometheus-stack, ArgoCD, cert-manager, external-dns, ingress-nginx, MinIO operator)
  • The same FrenchExDev toolbelt
  • The same multi-instance isolation primitives (subnet allocator, kubeconfig context, cert namespace)

The differences are configurational: a few [VerbGroup]-decorated values, a few Helm chart Values overrides, two different application repositories.


The Mermaid view

Diagram
Two clients, two clusters, two GitLabs, two Postgreses, two MinIOs — one workstation, zero overlap, because every instance owns its own subnet and namespace.

Two clusters. Two GitLabs. Two Postgreses. Two MinIOs. One workstation. Zero overlap.


The freelancer's day

08:30 — coffee. homelab k8s use-context acme. Browse https://gitlab.acme.lab, see the overnight CI runs. Switch to a feature branch.

09:00 — write code on Acme's API. dotnet test locally. Push. Watch CI run inside the acme cluster (the runner is in acme-platform). The deployment manifests in acme-dev get reconciled by ArgoCD.

10:30 — switch contexts. homelab k8s use-context globex. The Grafana dashboard for Globex shows that one of the Spring Boot services is OOMing in globex-stage. Pull up the logs via homelab k8s logs gateway --namespace globex-stage. Find the bug. Fix it. Push.

11:30 — back to Acme. homelab k8s use-context acme. Continue the morning's work.

13:00 — lunch.

14:00 — Globex paged. homelab k8s use-context globex. The Velero restore-test job that runs every Tuesday afternoon failed because the new chart version of Strimzi changed a CRD field name. Fix the chart values, push, reconciliation happens, restore-test re-runs and passes.

15:30 — Acme. The day's PR is ready. Deploy to acme-stage via ArgoCD by clicking sync in the ArgoCD UI (or homelab k8s argocd sync acme-api --target-namespace acme-stage). Watch the rolling deploy. Hit the staged endpoint with curl. It works. Mark the PR as ready.

17:00 — done. Both clusters are still running. The freelancer never had to spin one down to start the other. Tomorrow morning the same eight commands resume work.

This is what the multi-client workflow actually looks like.


What this gives you that "spin up a kind cluster" doesn't

A kind create cluster for each client takes minutes per switch and produces a non-realistic cluster. A pair of HomeLab K8s instances takes seconds to switch (one use-context verb) and produces real clusters that match production.

The bargain pays back the first day you have to context-switch between two clients three times before lunch.


⬇ Download