otel-k8s-graph
Health Uyari
- License — License: Apache-2.0
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 9 GitHub stars
Code Gecti
- Code scan — Scanned 9 files during light audit, no dangerous patterns found
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
A service graph that overlays structure derived from opentelemetry spanmetrics onto kubernetes entities for a more detailed service graph and exposes apis and an mcp server on top of it
otel-k8s-graph
A live Kubernetes service dependency graph (service map) built from OpenTelemetry traces. See what runs where and which service calls what — then query it over REST or from any LLM / MCP client (Claude, etc.).
Keywords: Kubernetes service map · service dependency graph · service topology · OpenTelemetry · distributed tracing · observability · trace-based service map · MCP server for Kubernetes.
A live relationship graph — a service map / service topology — of a Kubernetes
cluster: what runs where, and which service talks to what. Built from two sources,
queryable by humans, scripts, and LLM agents.
- Cluster structure — namespaces, nodes, zones, regions, workloads
(deployments, statefulsets, daemonsets, jobs, rollouts, …), autoscalers
(HPA, KEDA), pods and containers, and how they contain/manage/scale each
other — from the Kubernetes API. - Service relationships — which service calls which HTTP endpoint, queries
which database, publishes to which topic — derived from OpenTelemetry (OTel)
trace spans, with no spanmetrics connector or metrics pipeline required.
What you can ask
One graph answers questions that normally need a service mesh, a tracing UI, and a
cluster inspector at once — over REST or from Claude / any MCP client:
- Safe deprecation — "what pods call
/v1/checkoutvs/v2/checkout— can I safely retire v1?" - Blast radius — "how many upstream dependencies does this deployment have — what's impacted if it changes?"
- Dead-code / unused APIs — "which exposed endpoints have no callers?"
- Data-store reach — "which services talk to the
mysqldatabase at10.0.0.0?" - Cross-zone traffic — "which services call
auth-servicefrom another zone?"
How it compares
Unlike a service mesh (Istio/Linkerd) or eBPF agent, otel-k8s-graph needs no
sidecars and no kernel access — it derives the service map straight from the
OpenTelemetry spans your apps already emit. Unlike a tracing UI (Jaeger, Tempo,
Kiali) it stores the distilled relationship graph, not raw traces, so it stays
small and is directly queryable by scripts and LLMs.
Architecture
Kubernetes API ──watch──────> graph-k8s ──┐
(pods, nodes, ...) (structure) │
├──> Redis <──reads── graph-read ──> REST API
OTel Collector ──OTLP/gRPC──> graph-otel ──┘ (graph) └─> MCP server
(trace spans) (relationships) (graph-read mcp)
Three small Go binaries, each with one job, coordinating only through Redis:
| Component | Source | Role | Docs |
|---|---|---|---|
| graph-k8s | Kubernetes API | Writes structural entities + containment/management edges. Single writer. | cmd/graph-k8s |
| graph-otel | OTel trace spans | Writes relationship entities + CALLS/QUERIES/PUBLISHES/EXPOSES edges. | cmd/graph-otel |
| graph-read | Redis | Serves the read/query HTTP API; also the MCP server (graph-read mcp). |
cmd/graph-read |
Quickstart
The Helm chart bundles a single-replica Redis by default, so a fresh install
is self-contained:
# 1. Build + push the three images (versioned + latest) and install the chart:
REGISTRY=<your-registry> ./deploy.sh # add a registry here that your k8s cluster can access,
# the script will build and push the image,
# update the helm chart and run the helm install command
# 2. Add an otlp exporter to your OTel Collector's traces pipeline, pointing at graph-otel:
# endpoint: graph-otel-otlp:4317
Already have Redis? --set redis.internal.enabled=false --set redis.host=....
See the chart README for every value, includingexistingSecret for credentials and persistence for the bundled Redis.
Sample values: self-contained install
The chart needs only a registry; everything else has working defaults
(bundled Redis included):
# graph-values.yaml
image:
registry: <your-registry> # e.g. ghcr.io/<you>
# Optional: keep the graph across Redis restarts (default: rebuilt from
# the K8s API and OTel metrics, so persistence is off).
# redis:
# internal:
# persistence:
# enabled: true
# size: 1Gi
helm upgrade --install graph helm/graph -f graph-values.yaml
Sample values: OTel Collector feeding trace spans
graph-otel consumes trace spans directly — no spanmetrics connector or
metrics pipeline required. Just fan the trace spans your apps already emit to
graph-otel alongside your existing trace backend. Sample values for the upstream
opentelemetry-collector chart:
# otel-collector-values.yaml
mode: deployment
image:
repository: ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-contrib
# Adds the k8sattributes processor (+ RBAC) to every pipeline, so spans carry
# k8s.namespace.name / k8s.pod.name / k8s.container.name. graph-otel needs
# these to attach relationships to the right container.
presets:
kubernetesAttributes:
enabled: true
config:
exporters:
otlp/graph:
# <service>.<namespace>: adjust if you installed the chart elsewhere
endpoint: graph-otel-otlp.default.svc.cluster.local:4317
tls:
insecure: true
service:
pipelines:
# Trace spans in (apps send OTLP to this collector) -> fanned out to
# graph-otel, which derives the relationship graph from span.kind,
# span.name and the span attributes (http.route, db.system,
# server.address, peer.service, ...). Add your own trace backend to the
# exporters list alongside otlp/graph.
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlp/graph]
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm upgrade --install otel-collector open-telemetry/opentelemetry-collector \
-f otel-collector-values.yaml
Already exporting traces from a collector? Just add the otlp/graph exporter
to your existing traces pipeline.
The graph
Entity kinds: namespace, node, zone, region, deployment, statefulset, daemonset, job, cronjob, rollout, pod, container, hpa, scaledobject (K8s derived); endpoint, topic, database (span derived).
Edge kinds: CONTAINS/RUNS_IN, MANAGES/MANAGED_BY, SCALES/SCALED_BY (K8s derived);EXPOSES/EXPOSED_BY, CALLS/CALLED_BY, PUBLISHES/PUBLISHED_BY,CONSUMES/CONSUMED_BY, QUERIES/QUERIED_BY (span derived). Edges
are single-directional but have a counterpart edge in the store, and QUERIES
edges carry an action (the SQL/command).
Entity IDs are namespace-qualified where applicable: pod:<ns>/<name>,container:<ns>/<pod>/<name>, endpoint:<service>/<METHOD>/<route>,database:<system>/<host>[:<port>], topic:<name>.
Zones & regions. Nodes carrying the well-known topology.kubernetes.io/zone / region labels (or their legacy failure-domain.beta.kubernetes.io forms) produce zone and region entities: region CONTAINS zone CONTAINS node. Cross-zone questions — "which services call auth-service from another zone?" — become short graph walks: pod → node → zone on each side of a CALLS edge.
Workloads & autoscalers. Beyond deployments, graph-k8s models statefulset, daemonset, job/cronjob, and Argo rollout (each MANAGES its pods), plus hpa and KEDA scaledobject autoscalers that SCALES a target workload. HPA replica bounds, KEDA triggers/scaling policy, and cron schedules are captured as metadata. The Argo and KEDA resources are CRDs — graph-k8s detects their absence and skips them, so it runs anywhere.
Redis schema (prefix configurable, default graph)
<prefix>:entity:<id> HASH id, kind, name, last_seen_at_ms
<prefix>:entity:<id>:metadata HASH arbitrary string key/values
<prefix>:entity:<id>:edges SET JSON-encoded Edge objects
<prefix>:by_kind:<kind> SET entity IDs of the given kind
<prefix>:ids SET all entity IDs
Querying
- REST (graph-read):
GET /search,/entities,/entity/{id},/subgraph/{id},POST /prune,GET /healthz. - MCP (
graph-read mcp): the toolssearch,get_entity,list_entities,get_subgraphfor LLM clients (Claude Code, Claude
Desktop, …). See cmd/graph-read.
Repository layout
cmd/graph-k8s/ K8s watcher binary
cmd/graph-otel/ OTLP ingest binary
cmd/graph-read/ read API + MCP binary
internal/k8swatch/ informer wiring + object->entity mapping + diff/apply
internal/otlpreceiver/ OTLP TracesService server
internal/builder/ span record -> relationship entities/edges
internal/graph/ Redis read (RedisGraph) + write (RedisWriter, BatchWriteSet) + keys/schema
internal/api/ HTTP query handlers
internal/mcp/ MCP server + tools
helm/graph/ Helm chart (+ generated README)
Development
go build ./...
go test ./...
go test -race ./internal/graph/ ./internal/k8swatch/
Requires Go 1.25+. Tests use miniredis
and the client-go fake clientset, so no real Redis or cluster is needed.
See CONTRIBUTING.md for how to contribute.
License
Apache License 2.0 — see LICENSE.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi