Architecture of KID¶
Containers on your machine¶
flowchart LR
subgraph host["Codespace VM or your laptop"]
subgraph docker["Docker"]
DC["<b>devcontainer</b><br/>Ubuntu + kubectl, helm, cilium,<br/>hubble, argocd, kubescape"]
K3S["<b>k3s-server</b> (privileged)<br/>the whole Kubernetes cluster"]
end
BROWSER["Browser"]
end
DC -- "kubectl → k3s-server:6443" --> K3S
BROWSER -- "port 80 (forwarded)" --> K3S
- devcontainer is where you type commands. It has no Kubernetes inside; it talks to the API
server in
k3s-serverusing~/.kube/config. - k3s-server runs the control plane, the kubelet and containerd. All TRE pods run inside this container, which is why it must be privileged. It starts with flannel and the built-in network-policy controller turned off, so that Cilium can own pod networking.
Defined in .devcontainer/docker-compose.yml.
Inside the cluster¶
flowchart TB
B([Browser]) --> T[Traefik ingress<br/>kube-system]
T -- "/" --> PO[portal]
T -- "/auth, /keycloak" --> KC[Keycloak<br/>keycloak]
T -- "/argocd" --> ARGO[Argo CD<br/>argocd]
T -- "/hubble" --> HUI[Hubble UI<br/>kube-system]
T -- "/jupyter" --> PX[proxy<br/>jupyterhub]
HUB[hub<br/>jupyterhub] -- OIDC --> KC
PX --> WA[jupyter-researcher1<br/>project-alpha]
PX --> WB[jupyter-researcher2<br/>project-beta]
HUB -- creates pods --> WA
HUB -- creates pods --> WB
KY[Kyverno<br/>kyverno] -. admits .-> WA
KY -. admits .-> WB
CIL[Cilium + Hubble<br/>kube-system] -. enforces policy .-> WA
CIL -. enforces policy .-> WB
Also in kube-system: CoreDNS, the local-path storage provisioner and metrics-server (all bundled
with k3s).
URL map¶
| Path | Service | Notes |
|---|---|---|
/ |
portal/portal |
Static landing page |
/jupyter/ |
jupyterhub/proxy-public |
JupyterHub and every workspace (/jupyter/user/<name>/) |
/auth/ |
keycloak/keycloak |
OIDC endpoints and account pages |
/keycloak |
redirect | Shortcut to the Keycloak admin console |
/argocd/ |
argocd/argocd-server |
Argo CD UI |
/hubble/ |
kube-system/hubble-ui |
Hubble UI (no login, demo only) |
Namespaces¶
| Namespace | Managed by | Contains |
|---|---|---|
kube-system |
k3s, Cilium CLI, Argo CD (platform) |
Cilium, Hubble, Traefik, CoreDNS, local-path, metrics-server |
argocd |
bootstrap script | Argo CD |
keycloak |
Argo CD (keycloak) |
Keycloak in dev mode |
jupyterhub |
Argo CD (jupyterhub, network-policies) |
Hub, proxy, hub database PVC |
kyverno |
Argo CD (kyverno, kyverno-policies) |
Kyverno controllers |
portal |
Argo CD (portal) |
Landing page |
project-alpha, project-beta |
Argo CD (project-*) + Kyverno |
Workspaces and project storage |
How it is deployed¶
flowchart LR
BS["bootstrap.sh"] -->|kubectl apply| ROOT["Application: root<br/>(gitops/apps chart)"]
ROOT --> PL[platform] & KCA[keycloak] & PO[portal] & JH[jupyterhub] & NP[network-policies] & KY[kyverno] & KP[kyverno-policies] & PA[project-alpha] & PB[project-beta]
PA & PB -.->|render| PC["gitops/projects/chart"]
bootstrap.shinstalls Cilium (with Hubble) and Argo CD imperatively, because everything else depends on them.- It then applies one Argo CD
Applicationcalled root, pointing atgitops/appsin your repository and branch. gitops/appsis a small Helm chart that renders oneApplicationper component and one per research project (from theprojects:list in itsvalues.yaml).- Argo CD syncs each of those, in sync waves: platform/identity first (wave 0), then JupyterHub and policies (wave 1), then projects (wave 2).
The repository layout is described in Repository layout.
Memory budget¶
| Component | Typical RSS |
|---|---|
| k3s (all control-plane processes, containerd, CoreDNS, Traefik, metrics-server) | ~700 MB |
| Cilium agent + operator + Hubble relay/UI | ~450 MB |
| Argo CD (4 components) | ~450 MB |
| Keycloak | ~500–600 MB |
| JupyterHub hub + proxy | ~200 MB |
| Kyverno (3 controllers) | ~300 MB |
| Platform total | ~3 GB |
| Each running workspace | 150–400 MB idle, up to its limit (1–2 GB) |
Check the live numbers with tre usage. See Resource budget for
tips on small laptops.
What a production TRE adds¶
KID leaves these out on purpose. Each is a good discussion topic:
- TLS everywhere (cert-manager) and mTLS between services (Cilium or a service mesh).
- Secrets management: External Secrets + a vault instead of passwords in Git.
- Highly available control plane, multiple nodes, RWX storage, backups and DR.
- Airlock / egress review for data coming in and results going out.
- Private image registry with scanning and signing (the Kyverno policy then verifies signatures).
- Package mirrors (PyPI/CRAN/conda) instead of direct internet allow-lists.
- Central logging and SIEM, Hubble flow export, audit logging of the Kubernetes API.
- Node hardening, encryption at rest, confidential computing where needed.
- Remote desktops (Guacamole) and GPU scheduling.
- A project lifecycle backend (K8TRE's cr8tor) instead of editing YAML by hand.