Administrator guide
Documentation home · User guide · API reference
Runtime and prerequisites
The backend is FastAPI served by Uvicorn. It uses the Python Kubernetes client
directly and serves the static Cytoscape.js UI from the same process. The
container listens on TCP port 8080 and runs from /app.
You need a reachable Kubernetes API and a Kubernetes identity with the list
permissions below. Local container use requires Docker; the deployment examples
use kubectl configured for the intended cluster. The browser needs access to
unpkg.com for Cytoscape 3.26.0, Dagre 0.8.5, and cytoscape-dagre 2.3.2. The
backend itself does not fetch those scripts.
Kubernetes authentication
Clients are initialized on the first API request and reused by the process.
| Runtime condition | Configuration loaded |
|---|---|
KUBERNETES_PORT is non-empty |
In-cluster configuration using the Pod's service account credentials. |
KUBERNETES_PORT is absent or empty |
Local kubeconfig through config.load_kube_config(), including its current context. |
Outside Kubernetes, the Kubernetes client honors KUBECONFIG; otherwise its
normal default is ~/.kube/config. KUBERNETES_PORT is a mode switch, not an
application HTTP port setting. In a Pod, ensure service account token mounting
and the usual Kubernetes service environment are available. Restart the process
after changing kubeconfig context or credential configuration.
Run locally
Run commands from the tak-os-cluster-map repository root.
Container
Create a kubeconfig with embedded certificate data for the current context so the container does not depend on certificate paths on the host:
docker build -t tak-os-cluster-map:latest .
install -d -m 700 "$HOME/.kube"
(umask 077; kubectl config view --raw --minify --flatten > "$HOME/.kube/cluster-map.config")
docker run --rm \
-p 127.0.0.1:8080:8080 \
-v "$HOME/.kube/cluster-map.config:/root/.kube/config:ro" \
tak-os-cluster-map:latest
Open http://localhost:8080. The generated file contains credentials; keep it
private and remove it when it is no longer needed. Flattening embeds referenced
certificates but does not install kubeconfig exec authentication plugins or
their credentials in the image. If your context uses such a plugin, provide it
and its required environment or use another appropriate Kubernetes identity.
The API server address must be reachable from inside the container. A kubeconfig
pointing to 127.0.0.1 refers to the container itself, not the host.
Local Python
Use Python 3.10 or newer for the application's union type annotations:
python3 -m venv .venv
. .venv/bin/activate
python -m pip install fastapi uvicorn kubernetes
python -m uvicorn app.app:app --host 127.0.0.1 --port 8080
Keep the working directory at the repository root: app/static is resolved
relative to that directory. The container installs Alpine-packaged dependencies
from alpine:latest; the repository does not pin Python dependency versions.
Minikube helper
test.sh builds the local image and runs it interactively. It first
removes any container named tak-os-cluster-map and publishes port 8080 on
Docker's default host interfaces. For a normal reachable kubeconfig:
bash test.sh
For the Minikube Docker driver, when the Docker network is named minikube
and its API is reachable as https://minikube:8443:
USE_MINIKUBE_DOCKER_NETWORK=1 bash test.sh
In this mode the script rewrites an IPv4 API server address from
~/.kube/config into ~/.kube/config.orbit-minikube-docker (or the path set by
KUBECONFIG_ORBIT) and attaches the container to the minikube network. It
overwrites the destination file; review the script before use. Outside this
mode, KUBECONFIG chooses the source file. The helper does not flatten
certificate paths or install authentication plugins, so those requirements
still apply. It is a manual run helper, not an automated test suite.
Required RBAC
The current backend uses list operations only. It does not need Kubernetes
write access, Secret access, or watch permission.
| API group | Resources | Purpose |
|---|---|---|
Core ("") |
namespaces |
Populate the namespace dropdown. |
Core ("") |
services, pods |
Service selectors and Pod state. |
apps |
deployments, statefulsets, daemonsets, replicasets |
Workload nodes and Pod ownership. |
networking.k8s.io |
ingresses |
HTTP backend relationships. |
k8s.tlspu.com |
orbit-deployments |
Optional Orbit Deploy integration, requested on every graph build. |
The default UI starts with an all-namespace graph and lists namespaces, so the
example uses a ClusterRole and ClusterRoleBinding. Namespace selection is not
an authorization boundary. A deployment limited to namespace Roles would also
need UI/backend changes to avoid the all-namespace and namespace-list requests;
Orbit integration additionally queries kube-system in namespace views.
The Orbit resource is queried at group k8s.tlspu.com, version v1, plural
orbit-deployments. The backend suppresses only HTTP 404 from this lookup.
Other errors, including 403, fail the graph request. Include the Orbit list
rule even when the CRD is absent to avoid an authorization denial preventing
the optional lookup from reaching a 404 response.
Deploy to Kubernetes
Standalone example
examples/deployment.yaml creates a dedicated
tak-os-cluster-map namespace, a ServiceAccount, list-only RBAC, one replica,
and an internal ClusterIP Service. It intentionally contains a placeholder
image. Build and push the image to a registry your cluster can access, then
replace YOUR_REGISTRY/tak-os-cluster-map:YOUR_TAG in a local copy with that
image reference. Configure image pull credentials if your registry needs them.
cp docs/examples/deployment.yaml /tmp/tak-os-cluster-map-deployment.yaml
# Edit /tmp/tak-os-cluster-map-deployment.yaml to set your image and local settings.
kubectl apply -f /tmp/tak-os-cluster-map-deployment.yaml
kubectl -n tak-os-cluster-map rollout status deployment/tak-os-cluster-map
kubectl -n tak-os-cluster-map port-forward service/tak-os-cluster-map 8080:8080
Open http://localhost:8080. The manifest's CPU/memory requests and limits are starting values; adjust them after measuring your cluster's graph size and load. ClusterRole and ClusterRoleBinding creation requires appropriate administrative permissions. Review names before applying if another installation exists.
The / readiness and liveness probes only check static page serving. They do
not validate Kubernetes credentials, RBAC, API availability, or graph generation.
Existing Orbit Deploy packaging
In the wider TAK-OS workspace, the companion deployment repository is
tak-os-orbit-deployments/tak-os-cluster-map. Its default/ directory contains
RBAC, Deployment, Service, Ingress, and deployment.json image configuration.
It deploys into kube-system, exposes Service port 8080, and uses the hostname
template cluster-map.<!domain!>. Resolve its Orbit placeholders through that
deployment workflow; those files are not plain standalone manifests.
Choose the standalone example or the Orbit-managed installation according to your environment. The example does not install an Ingress or Orbit Deploy.
Control access
All HTTP clients see data through the backend's Kubernetes identity. The application has no built-in login, per-user Kubernetes impersonation, or per-namespace authorization. It exposes names, namespace membership, selectors, container images, Ingress hosts, and topology.
Keep access limited to the intended audience. For a shared installation, configure your ingress or proxy for TLS and authentication/authorization on both the UI and JSON endpoints. The companion Orbit Ingress has authentication annotations commented out; deploying it does not enable authentication by itself.
Serve the UI at the hostname root. Its requests use absolute paths
/graph.json and /namespaces.json; placing it under a URL subpath requires
additional routing or application changes. For an offline environment, vendor
the three JavaScript libraries and update the script references; the shipped UI
depends on the public CDN.
Verify and operate
After deployment, check all three paths through a port-forward or your gateway:
curl --fail http://localhost:8080/ > /dev/null
curl --fail http://localhost:8080/namespaces.json
curl --fail --get --data-urlencode ns=default http://localhost:8080/graph.json
curl --fail http://localhost:8080/graph.json
Successful JSON calls verify more than the static page probe. Check the browser
as well to verify CDN access, namespace switching, legend toggles, and tooltips.
An empty nodes array can be valid for an empty namespace.
Each graph request lists the supported resource types again. There is no graph cache, Kubernetes watch, automatic browser polling, or dedicated metrics/health endpoint. Large all-namespace graphs and frequent manual refreshes increase API and rendering load; use namespace views when practical.
View application errors with:
kubectl -n tak-os-cluster-map logs deployment/tak-os-cluster-map --tail=100
kubectl -n tak-os-cluster-map get pods -l app=tak-os-cluster-map
Use kube-system in these commands for the companion Orbit installation. To
update a standalone installation, change the image in your maintained manifest,
apply it, wait for the rollout, and repeat the endpoint checks. The application
has no persistent data store to back up; retain deployment configuration and
access-control settings in your normal configuration workflow.
Troubleshoot
Static page works, JSON endpoints fail
Kubernetes clients load lazily, so a successful / response does not prove
cluster access. Inspect the application logs for authentication, TLS, network,
or Kubernetes API errors. Unhandled backend errors normally appear to the
browser as HTTP 500; the Kubernetes cause is in the server logs.
Check the intended identity's permissions, for example:
kubectl auth can-i list namespaces --as=system:serviceaccount:tak-os-cluster-map:tak-os-cluster-map
kubectl auth can-i list pods --all-namespaces --as=system:serviceaccount:tak-os-cluster-map:tak-os-cluster-map
kubectl auth can-i list ingresses.networking.k8s.io --all-namespaces --as=system:serviceaccount:tak-os-cluster-map:tak-os-cluster-map
kubectl auth can-i list orbit-deployments.k8s.tlspu.com --all-namespaces --as=system:serviceaccount:tak-os-cluster-map:tak-os-cluster-map
Repeat for all resources in the RBAC table. These checks require permission to
impersonate that service account. For local execution, omit --as to check the
current kubeconfig identity. For namespace-specific failures, also check Orbit
list permission in kube-system.
Container cannot reach the API
Check that the kubeconfig API address is reachable from the container, its
certificate paths exist there or are embedded, and any authentication plugin
exists in the image. For Minikube, use the helper's network option where
applicable. On Linux, host networking is another option for a loopback API
address; omit Docker's -p option and account for the application's default
0.0.0.0:8080 binding. Preserve TLS verification and use a hostname covered by
the API server certificate.
OrbitDeployment nodes or links are missing
Verify the k8s.tlspu.com/v1 resource is served and readable. Management links
come from keys in status.managedObjects formatted as
apiVersion|kind|namespace|name; malformed keys are skipped. Empty status does
not prevent an OrbitDeployment node from appearing. Links require the target
to exist among the displayed resource kinds. In a namespace view, only local
OrbitDeployments and qualifying managers from kube-system are loaded.
JSON works, but the graph is blank
Check the browser network panel and console for failed CDN scripts, CSP errors,
or proxy routing errors. Confirm /graph.json and /namespaces.json reach the
backend at the hostname root. Restore hidden resource kinds in the legend.
Map differs from traffic or health observations
Review the user guide's interpretation limits.
The backend uses selectors and owner references, not live traffic or
EndpointSlices. Its Pod ready field means any regular container is ready.
Refresh the graph and verify Kubernetes state directly before drawing an
operational conclusion.
