# kubectl-graph turns cluster resources into a relationship graph

> kubectl-graph is a kubectl plugin that resolves the relationships between Kubernetes resources and emits them as DOT, Cypher or AQL so you can pipe them into Graphviz, Neo4j or ArangoDB. It is genuinely useful for understanding a cluster, and its release line stopped in 2023 even though the code moved on in 2026.

**steveteuber/kubectl-graph** — A kubectl plugin to visualize Kubernetes resources and relationships.

- Repository: https://github.com/steveteuber/kubectl-graph
- Stars: 696 · Forks: 33
- Language: Go
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/steveteuber-kubectl-graph

## The plugin works like kubectl get, then draws the answer

The README describes the behaviour in one sentence that is worth repeating, because it is the whole design. The plugin works like kubectl get but it tries to resolve relationships between the Kubernetes resources before it prints a graph in AQL, CQL or DOT format, and DOT is the default. So the resource selection syntax you already know still applies, and what the plugin adds is the edge information that plain kubectl get never shows you. The usage line shows the shape of the interface.

```bash
kubectl graph [(-o|--output=)aql|arangodb|cql|cypher|dot|graphviz|mermaid] (TYPE[.VERSION][.GROUP] ...) [flags]
```

The resource argument follows the familiar TYPE[.VERSION][.GROUP] form, so you can ask for a specific group or version when the kind name is ambiguous. The output list is longer than the three formats the prose mentions, and includes aql, arangodb, cql, cypher, dot, graphviz and mermaid, which means the same relationship set can be rendered as an image, loaded into a graph database or pasted into documentation as a diagram. The plugin is written in Go, and the module dependencies show it leaning on the Kubernetes client libraries rather than shelling out to kubectl, with k8s.io/api, apimachinery, cli-runtime, client-go and kubectl all at 0.37.1, plus cobra for the command line and openshift/api at 3.9.0, which suggests the resource resolution reaches into OpenShift specific types as well as core Kubernetes ones.

## Installing through krew and the external tools you still need

Distribution is through krew, the kubectl plugin manager, and the install is a single command.

```bash
kubectl krew install graph
```

That is the easy part. The plugin does not draw anything by itself, and the prerequisites section is explicit that it requires Graphviz, Neo4j or ArangoDB to visualize the dependency graph, with the choice determined by the output format you pick. The default DOT format needs the dot command to convert the output into something useful, and the README suggests the macOS install.

```bash
brew install graphviz
```

The CQL output format needs cypher-shell to talk to a Neo4j database, installed the same way.

```bash
brew install cypher-shell
```

The AQL output format needs curl and jq to send API requests to an ArangoDB server.

```bash
brew install curl jq
```

This is the design decision that shapes the workflow. The plugin is not a self-contained visualizer, it is a relationship extractor that hands you a text format and lets a specialist tool do the rendering. That is why the quickstart is written in terms of pipes, and it is also why the plugin needs credentials for a graph database if you want persistence.

## The Graphviz path needs no database at all

The simplest use needs nothing but the dot binary, and it is worth starting here. With the dot command line tool installed, you fetch all running Pods in the kube-system namespace and pipe the output straight into dot.

```bash
kubectl graph pods --field-selector status.phase=Running -n kube-system | dot -T svg -o pods.svg
```

The result is a pods.svg file in the current working directory that you can open in any web browser.

```bash
open pods.svg
```

Two things are worth noting about this example. The field selector, status.phase=Running, is passed through, so you can narrow the graph with the same selectors kubectl understands, and the namespace is selected with -n. The second is that the DOT output goes to stdout, which is what makes the pipe work. Nothing is written to the cluster and nothing is stored, so this is a read-only operation and as safe as any other kubectl read. If SVG is not the output you want, the README points to the Graphviz documentation for the list of output formats that dot can produce, which means the plugin's DOT output is a normal Graphviz graph and the whole dot toolchain applies to it.

## Loading the graph into Neo4j for real queries

The database path is where this tool starts to pay for itself, because a graph you can query beats a picture. You need a Neo4j instance with an empty database first, and the README offers two routes. Docker is the easiest way to get a server and an empty database.

```bash
docker run --rm -p 7474:7474 -p 7687:7687 -e NEO4J_AUTH=neo4j/secret neo4j
```

With the container running, the Neo4j Browser is at http://localhost:7474/. The alternative is the Neo4j Desktop application, which the README says lets you create any number of local databases.

```bash
brew install --cask neo4j
```

From there you fetch all resources in the namespace and pipe the Cypher output into cypher-shell.

```bash
kubectl graph all -n kube-system -o cypher | cypher-shell -u neo4j -p secret
```

Once the data is in, the graph is yours to query. The README gives two example statements for the Neo4j Browser command line.

```bash
MATCH (n) RETURN n         // Render all nodes as a visual graph
MATCH (n) DETACH DELETE n  // Delete all nodes and relationships
```

The second one is the reset button, and it is a good reminder of what this tool is. The plugin populates a graph, and the graph is a scratch space you can wipe and rebuild as often as you like.

## ArangoDB needs its collections created by hand first

The ArangoDB path is the fiddliest of the three, and the reason is that the database needs a shape before it can hold anything. Docker again gets you a server.

```bash
docker run --rm -p 8529:8529 -e ARANGO_NO_AUTH=1 arangodb
```

The browser is at http://localhost:8529/. With an empty database you have to create two collections, one for resources and one for relationships, using the HTTP API.

```bash
curl http://localhost:8529/_api/collection -d '{"type": 2, "name": "resources"}'
curl http://localhost:8529/_api/collection -d '{"type": 3, "name": "relationships"}'
```

Then you need a graph, which requires a name and a definition of its edges.

```bash
curl http://localhost:8529/_api/gharial -d @- <<EOF
  {"name": "quickstart", "edgeDefinitions": [
    {"collection": "relationships", "from": ["resources"], "to": ["resources"]}
  ]}
EOF
```

Only after that does the import work, and the import is a three stage pipe that turns the plugin's AQL output into a cursor request.

```bash
kubectl graph all -n kube-system -o aql \
  | eval 'jq -n --arg stdin "$(cat)" "{query:\$stdin}"' \
  | curl http://localhost:8529/_api/cursor -d @-
```

The jq step wraps the query in the JSON the cursor endpoint expects, and the whole chain assumes curl and jq are on the path. This is the part of the quickstart where a beginner will lose an hour, because an ArangoDB instance without the graph definition accepts nothing without saying much about why.

## Mermaid and Graphviz output for documentation

The output list includes mermaid, which is worth calling out because it changes where the tool fits. Mermaid diagrams are text, and text can live in a Markdown file in a repository, in a pull request description or in a wiki page. The plugin also ships a style.grass file at the repository root, which is a Graphviz stylesheet, so the DOT output can carry a consistent look rather than the default node and edge styling. There is also an assets/ directory holding the Graphviz, Neo4j and ArangoDB logos that appear in the documentation. The Loki example at the end of the README shows the intended pattern for a real log aggregation deployment, fetching everything in the loki namespace and feeding it to cypher-shell. The last line of that example is cut off in the documentation, so the exact invocation is worth reading from the repository rather than guessing. The practical read of the whole output story is that the plugin can serve three distinct audiences: a person who wants an SVG, a team that wants to query relationships in a database, and a documentation workflow that wants a diagram committed next to the code.

## A release line frozen in 2023 and a codebase that moved on

The maintenance record needs two numbers side by side. The tagged releases are v0.7.0 on 2023-10-23, v0.6.0 on 2022-12-20 and v0.5.0 on 2022-04-19, so the published versions stopped nearly three years ago. The last push to the repository was on 2026-09-28, and the module now requires Go 1.26.0 with the Kubernetes libraries at 0.37.1, which is a dependency set that could not have existed in 2023. In other words the code is being maintained while the releases are not being cut. The repository has the pieces a release process needs, with a .goreleaser.yml for building and publishing binaries, a .krew.yml for the krew plugin manifest and a ci.yml workflow, so what is missing is a maintainer publishing tags. The practical consequence for you is that the krew install gets you the last tagged build, not the current code, and there is a real chance that a 0.37 client library meets a 0.7 plugin in a cluster where something behaves differently. The licence is Apache-2.0 with the LICENSE file in the repository root, which is permissive and lets you build and redistribute it yourself, so reading the source and compiling it is a legitimate path when the published binary is behind.

## Conclusion

Adopt kubectl-graph if you need to see how the objects in a namespace relate to each other and you already have Graphviz, Neo4j or ArangoDB available, or you are willing to install one of them. Skip it if you want a maintained plugin with a release trail, because the last tagged release is v0.7.0 from 2023-10-23 while the last push was on 2026-09-28, and skip it if you only need a one-off picture of a namespace, since kubectl describe and the API itself may answer the question. Before you pipe anything into a database, check which output format your graph store expects and remember that the plugin writes the graph, it does not decide what the graph means.

## FAQ

### How do I install the kubectl-graph plugin?

The plugin is distributed through krew, and the install command is kubectl krew install graph. You also need Graphviz, Neo4j or ArangoDB depending on the output format you intend to use.

### Which output formats does kubectl-graph support?

The usage line lists aql, arangodb, cql, cypher, dot, graphviz and mermaid, and DOT is the default. The DOT format needs the dot tool, the CQL format needs cypher-shell for Neo4j, and the AQL format needs curl and jq for ArangoDB.

### Does kubectl-graph need a database to produce a graph?

No. With the Graphviz route you pipe the output straight into dot, for example kubectl graph pods --field-selector status.phase=Running -n kube-system | dot -T svg -o pods.svg, and open the resulting SVG in a browser.

### Is kubectl-graph still being worked on?

The last push to the repository was on 2026-09-28 and the module targets Go 1.26.0 with Kubernetes libraries at 0.37.1, but the last tagged release is v0.7.0 from 2023-10-23, so the published krew plugin is older than the source.

## Sources

- [Issues](https://github.com/steveteuber/kubectl-graph/issues)
- [License: Apache-2.0](https://github.com/steveteuber/kubectl-graph/blob/main/LICENSE)
- [README](https://github.com/steveteuber/kubectl-graph/blob/main/README.md)
- [Releases](https://github.com/steveteuber/kubectl-graph/releases)
- [steveteuber/kubectl-graph on GitHub](https://github.com/steveteuber/kubectl-graph)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/steveteuber-kubectl-graph
