Every platform needs a demo stack: something that looks alive on a projector and quietly exercises every layer underneath. Ours is seven apps on a vSphere Kubernetes Service (VKS) cluster that VCF Automation provisioned, in a tenant VPC, each behind its own load-balancer VIP.

kubedoom       192.168.144.20:5900   (VNC — yes, it kills pods)
kubeinvaders   192.168.144.21
kube-ops-view  192.168.144.22
pacman         192.168.144.23        (+ MongoDB on a PVC — persistent high scores)
podinfo        192.168.144.24
goldpinger     192.168.144.25        (DaemonSet incl. control plane)
prometheus     (in-cluster: KSM + node-exporter, 11/11 targets up)

Three of the seven live on their VIPs — KubeInvaders, kube-ops-view, Pac-Man — and the whole set as VCF Operations sees it Captured from the VIPs the platform handed out. KubeDoom is VNC-only and podinfo is an API, so they sit this one out; the Ops topology tile shows all seven by name.

The path that matters: tenanted, not shortcut

I deployed the first version of this stack against the supervisor: an admin kubeconfig, a vSphere namespace, kubectl apply. It worked, and it was wrong, for the reason the previous post spells out. Nothing about it was provided to anyone.

So I tore it down: seven apps, cluster, VPC and VIPs, gone in about seven minutes. Demolition, as ever, was the quick part. Then I rebuilt it the proper way:

dev-01 org → default-project → SupervisorNamespace (class large, region f06, VPC default-f06)
          → VKS cluster vks-demo01 → seven apps

Everything went in through VCF Automation: the Cloud Consumption Interface (CCI) API for the namespace and cluster, then the apps through the cluster’s own kubeconfig. Two auth facts are worth writing down; each cost me a cycle:

  • A provider service account reaches the cloud API only. CCI (/cci/kubernetes/apis/...) rejects provider tokens with a 401. It needs an org-scoped service account.
  • Device-flow login uses the service account’s own UUID as the client_id (not its software ID), against the tenant endpoint /oauth/tenant/<org>/device_authorization.

VCF Operations topology: the cluster with its apps named

What the platform does for free

Each app is an ordinary Deployment plus a Service of type LoadBalancer. The supervisor turns each service into an NSX VPC load-balancer virtual server, and hands back a VIP from the org’s external block. No ingress controller, no MetalLB, no port-forwarding. Seven services, seven VIPs, done.

Pac-Man’s MongoDB asks for a persistent volume and gets one on vSAN, through the CSI driver the supervisor already installed. The high scores are on enterprise storage. Priorities.

Goldpinger runs as a DaemonSet on every node, the control plane included, and draws the node-to-node mesh live.

That’s three platform services (load balancing, storage and networking) exercised by apps that know nothing about VCF.

The traps

The supervisor refuses cluster-scoped RBAC, even to admin. Demo apps that need ClusterRoles (kube-ops-view, Goldpinger, KubeDoom) must live on a guest cluster. You can’t run them as vSphere Pods on the supervisor.

PodSecurity restricted is the VKS 1.35 default. Half the demo set runs as root. The symptom: the Deployment shows 0 UP-TO-DATE, the ReplicaSet exists, zero pods, and the events say FailedCreate. The fix: label the namespace pod-security.kubernetes.io/enforce=privileged. Then say so in the demo, because it’s a teaching moment.

node-exporter without hostNetwork. The VPC fabric blocks scrapes from a pod to a node IP, so the stock DaemonSet’s hostNetwork: true doesn’t help. Run it as a normal pod and let Prometheus scrape it in-cluster.

Docker Hub is flaky from behind a proxy. TLS handshake timeouts put pods into kubelet’s image-pull backoff, where they sit and sulk. Deleting the stuck pods gets round the backoff. A Harbor proxy-cache project fixes it properly.

Pod CIDR shadowing. The stock 192.168.0.0/16 pod range hid the org’s 192.168.144.0/21 external block from inside the cluster, so apps couldn’t reach their neighbours’ VIPs. The pod CIDR is now 172.16.0.0/16.

Automation notes

The whole stack is one checkbox on the lab’s catalog item that deploys a supervisor. installDemoApps creates the cluster, with the newest compatible Kubernetes release and the newest built-in ClusterClass, both auto-detected. Then it applies the seven apps and reports their URLs in the deployment summary.

On a fresh environment, an integrated run takes 16.7 minutes to CREATE_SUCCESSFUL. An immediate re-run takes 3.3 minutes, every step idempotent. That’s the number I actually care about: it makes a broken demo a re-run, not a rebuild. Demos have an uncanny sense of when they’re being watched.

Why this matters outside the lab

A demo stack sounds like a toy. To be fair, one of the apps is Pac-Man. But it’s actually the fastest way to make a platform legible to people who don’t read YAML. A customer watches a request become a cluster, watches seven services get their own addresses, then opens one and plays it.

Everything underneath gets exercised (self-service Kubernetes, load balancing, persistent storage, isolation), and a non-technical stakeholder can see it working. The same stack is what we put in front of a new team on day one. And the same idempotent deploy is what makes it safe to demonstrate live: if it breaks on stage, it re-runs in three minutes.

Rules learned

  • Demo apps that need cluster-scoped RBAC must run on a guest cluster. The supervisor won’t grant it, even to admin.
  • Build the stack through the tenanted path: org service account, then CCI, then namespace, then cluster, then apps. Same apps, but now they’re provided, quota’d and visible in Ops.
  • VKS 1.35 has restricted PodSecurity by default. Label the namespace and say why.
  • One LoadBalancer per app means one NSX VIP per app. No ingress needed for a demo.
  • Pick a pod CIDR that doesn’t overlap the VPC external block.
  • Make the deploy idempotent. A demo that re-runs in 3 minutes is one you can afford to break on stage.

Broadcom documentation

Previously: one VKS cluster, two ways. The Pac-Man instance here is the one from What’s a VPC?.


Lab environment; opinions my own.