Skip to content

Kubernetes Observation Edge

This page is the architecture view for Kubernetes observation after the Headlamp-first cut. It separates human UI access, automation read access, and the still-live shared edge plane so future work does not accidentally bind a service to one node IP.

C4Context
title FractalOps Kubernetes observation context

Person(operator, "Platform operator", "Human with OIDC admin session")
Person(agent, "AgentSquad agent", "Automated worker using scoped tools")

System_Boundary(fractalops, "FractalOps") {
  System(portal, "Portal and Studio", "AgentSquad control surface")
  System(operationAssets, "Operation asset resolver", "Maps roles to executable endpoints")
  System(headlamp, "Headlamp", "Kubernetes operator UI and read proxy")
  System(cliproxy, "CLIProxy", "Model plane for coding runtimes")
}

System_Ext(keycloak, "Keycloak and Pomerium", "Human SSO and protected routes")
System_Ext(openbao, "OpenBao and ESO", "Secret lifecycle and Kubernetes Secret sync")
System_Ext(k8s, "Kubernetes API", "Cluster workloads, events, logs, metrics")

Rel(operator, keycloak, "Signs in", "OIDC")
Rel(keycloak, headlamp, "Forwards authenticated UI route", "Pomerium")
Rel(agent, operationAssets, "Requests kubernetes_observation")
Rel(operationAssets, headlamp, "Calls service DNS", "HTTP bearer")
Rel(headlamp, k8s, "Reads pods, events, logs, metrics", "Kubernetes API")
Rel(openbao, headlamp, "Supplies observer service-account token", "ESO/OpenBao")
Rel(agent, cliproxy, "Calls model plane", "client-key gated")
Rel(portal, operationAssets, "Projects runtime asset bindings")
C4Container
title Headlamp-first observation container boundary

Person(agent, "AgentSquad agent")
Person(operator, "Platform operator")

System_Boundary(cluster, "Kubernetes cluster") {
  Container(operationAssetCli, "operation-assets CLI", "Python", "Role-based runtime asset client")
  Container(runtimeContract, "Runtime contract resolver", "Python/CUE", "Projects connector inventory and service profiles")
  Container(headlampService, "headlamp.kube-system.svc.cluster.local", "Kubernetes Service", "Stable in-cluster executor endpoint")
  Container(headlampPod, "Headlamp pod", "Headlamp", "UI and API proxy")
  Container(openbaoEso, "OpenBao/ESO sync", "ExternalSecret", "Observer token delivery")
  Container(kubernetesApi, "Kubernetes API", "Control plane", "Read model for workloads")
}

System_Ext(publicRoute, "k3s.yamon.io", "Public OIDC/Pomerium route for humans")
System_Ext(sharedEdge, "10.10.10.47 edge plane", "Legacy hostPort edge for cliproxy and Pomerium JWKS")

Rel(agent, operationAssetCli, "GET /api and /apis paths", "fractalops operation-assets")
Rel(operationAssetCli, runtimeContract, "Resolves kubernetes_observation")
Rel(runtimeContract, headlampService, "Uses executor_internal_url", "Service DNS")
Rel(headlampService, headlampPod, "Routes to ready pod")
Rel(openbaoEso, headlampPod, "Provides observer bearer")
Rel(headlampPod, kubernetesApi, "Reads cluster state")
Rel(operator, publicRoute, "Uses Headlamp UI")
Rel(publicRoute, headlampPod, "OIDC-authenticated UI traffic")
Rel(agent, sharedEdge, "Still uses cliproxy :19005 until separate edge migration")
  • Headlamp automation uses http://headlamp.kube-system.svc.cluster.local.
  • Headlamp automation must not depend on node IP, hostPort, or executor_edge_port_key.
  • k3s.yamon.io remains the human UI route and keeps OIDC/Pomerium semantics.
  • 10.10.10.47 is still load-bearing for other edge services, especially CLIProxy :19005 and Pomerium JWKS :17443; migrate those atomically, not as part of a Headlamp-only change.
  • Argo sync diagnostics must print degraded resource health and conditions, not just return a generic failure.

The docs site renders Mermaid fences through astro-mermaid. C4 syntax is Mermaid’s experimental C4 support, so diagrams should stay simple and avoid unsupported C4-PlantUML features. Image zoom is enabled for Markdown and MDX images through starlight-image-zoom; Mermaid diagrams remain source-controlled code blocks rendered as SVG by Mermaid.