Kausal is a local-first Kubernetes visualization tool that explains why resources look the way they do by combining ownership, selector, exposure, ingress, scaling, reference, and managedFields data into a single graph.
Kausal is published on GitHub under the MIT License.
apps/server/: Express API in TypeScript. It reads supported Kubernetes resources with a read-only ServiceAccount, derives graph edges, summarizesmanagedFields, and exposes the API.apps/client/: React app with a three-column layout: resource list, graph canvas, detail panel.deploy/dev/k8s/: Development-only Kubernetes manifests for a local Kubernetes cluster.Dockerfile: Multi-stage Node build that serves the built React app from the backend container.
The backend supports:
GET /api/healthzGET /api/resourcesGET /api/graphGET /api/resource/:namespace/:kind/:name
- Namespace
- Deployment
- ReplicaSet
- Pod
- Service
- Ingress
- ConfigMap
- Secret references inferred from workloads
- HorizontalPodAutoscaler
ownsselectsexposesscalesreferencesingress-routes-to
- The primary run mode is inside Kubernetes. The app is intended to run in a local Kubernetes cluster and read the cluster through its ServiceAccount.
- The manifests in
deploy/dev/k8s/are for development only. They are intentionally local-cluster oriented and not a production deployment baseline. - Secret contents and Secret metadata are never returned by the API or rendered in the UI. Secret nodes are inferred from workload references instead of being fetched from the Kubernetes API.
- The initial graph layout is deterministic and simple. It is meant for comprehension, not for perfect graph aesthetics.
- Ingress is optional because local Ingress availability depends on the local cluster setup.
Install dependencies:
npm installRun the backend:
npm run dev:serverRun the frontend:
npm run dev:clientThe Vite frontend proxies /api to http://localhost:8080.
From the repository root:
docker build -t kausal:dev .Pushing a Git tag triggers the GitHub release workflow in .github/workflows/release.yml.
The workflow:
- builds the root
Dockerfile - pushes the image to
ghcr.io/vquie/kausalwith version aliases - creates a GitHub release
- generates release notes from the changes since the previous tag
Supported release tags:
v1.2.31.2.3
For either form, the workflow publishes:
v1.2.3v1.2v11.2.31.21latest
Example:
git tag v0.1.0
git push origin v0.1.0Some local Kubernetes setups expose the local Docker image store directly to the cluster. If your environment uses the same image store, no extra import step is needed after docker build.
If the Pod cannot pull kausal:dev, rebuild and confirm the image exists locally:
docker images | grep kausalApply the manifests:
kubectl apply -f deploy/dev/k8s/namespace.yaml
kubectl apply -f deploy/dev/k8s/serviceaccount.yaml
kubectl apply -f deploy/dev/k8s/clusterrole.yaml
kubectl apply -f deploy/dev/k8s/clusterrolebinding.yaml
kubectl apply -f deploy/dev/k8s/deployment.yaml
kubectl apply -f deploy/dev/k8s/service.yaml
kubectl apply -f deploy/dev/k8s/networkpolicy.yamlOptional Ingress:
kubectl apply -f deploy/dev/k8s/ingress.yamlCheck rollout:
kubectl -n kausal rollout status deployment/kausal
kubectl -n kausal get podsUse port-forwarding:
kubectl -n kausal port-forward svc/kausal 8080:8080Then open:
http://localhost:8080
Check logs:
kubectl -n kausal logs deployment/kausalCheck health:
kubectl -n kausal port-forward svc/kausal 8080:8080
curl http://localhost:8080/api/healthzCheck RBAC:
kubectl auth can-i list pods --as=system:serviceaccount:kausal:kausal --all-namespaces
kubectl auth can-i list deployments.apps --as=system:serviceaccount:kausal:kausal --all-namespaces
kubectl auth can-i list ingresses.networking.k8s.io --as=system:serviceaccount:kausal:kausal --all-namespaces
kubectl auth can-i list horizontalpodautoscalers.autoscaling --as=system:serviceaccount:kausal:kausal --all-namespacesIf /api/healthz returns an error, verify:
- The
kausalServiceAccount is mounted into the Pod. - The ClusterRoleBinding points to
kausal/kausal. - The local cluster actually exposes the Kubernetes API to in-cluster Pods.
- The image tag in
deploy/dev/k8s/deployment.yamlmatches the image you built locally.
