DEV Community

Cover image for Discover Cyphernetes: a Query Language for Kubernetes
Aurélie Vache
Aurélie Vache

Posted on

Discover Cyphernetes: a Query Language for Kubernetes

Kubernetes have 10 years now so to manipulate our Kubernetes resources we have our daily habits. We can use daily the kubectl command, with or without JSON Path, aliases, but also k9s, kubectl plugins with krew...
But do you know that a Query language for Kubernetes exists?

Cyphernetes

Cyphernetes

Cyphernetes, written in Go, is a query language for Kubernetes based on Cypher.

Cyphernetes extends Cypher, that allows you to express graph operations, with Kubernetes-specific syntax and features. It allows you to query and mutate Kubernetes resources in a natural way, works out-of-the-box with your CRDs, supports multi-cluster queries, and more.

Concretely, you can do CRUD (Create, Read, Update, Delete) operations on Kubernetes clusters with a Cypher based query language.

Cyphernetes have a CLI (that we will install in the coming seconds ^^), but also a web interface to visualize the resources of our Kubernetes cluster and a also a Kubernetes operator.

Cypher query language for Kubernetes

Cyphernetes is based on Cypher query language to query our Kubernetes clusters.

In order to understand how to do Cyphernetes queries, read the documentation about the language.

In a nutshell:

(k:Kind)
Enter fullscreen mode Exit fullscreen mode

k is the variable and Kind is the type of the resource you want to handle.

To query the Kubernetes resource graph, use MATCH/RETURN expressions.

So if we want the list of Deployments and display their metadata name, the query will be:

MATCH (d:Deployment) RETURN d.metadata.name
Enter fullscreen mode Exit fullscreen mode

Like in SQL, you can also use the WHERE clause.

Example:

MATCH (d:Deployment {app: "nginx"})
WHERE d.spec.replicas=4
RETURN d.metadata.name,
       d.spec.replicas
Enter fullscreen mode Exit fullscreen mode

This tool allows us to do some CRUD operations so let's see different examples:

Create

Create a Service that exposes the Deployment nginx:

MATCH (d:Deployment {name: "nginx"})
CREATE (d)->(s:Service)
Enter fullscreen mode Exit fullscreen mode

Read

List the Deployments and Services:

MATCH (d:Deployment), (svc:Service)
RETURN d.name, svc.name
Enter fullscreen mode Exit fullscreen mode

Update

Update the number of replicas to 5 for the nginx Deployment:

MATCH (d:Deployment {name: "nginx"})
SET d.spec.replicas=5
RETURN d.name, d.spec.replicas
Enter fullscreen mode Exit fullscreen mode

Delete

Delete the nginx Deployment but also his Service and his Ingress:

MATCH (d:Deployment {name: "nginx"})->(s:Service)->(i:Ingress)
DELETE s, i
Enter fullscreen mode Exit fullscreen mode

Cyphernetes CLI installation

In this guide we will install it with brew but you can install in several others ways, follow the installation guide.

$ brew install cyphernetes
Enter fullscreen mode Exit fullscreen mode

Check the CLI is correctly installed locally:

$ cyphernetes
Cyphernetes allows you to query Kubernetes resources using a Cypher-like query language.

Usage:
  cyphernetes [command]

Available Commands:
  completion  Generate the autocompletion script for the specified shell
  help        Help about any command
  operator    Manage the Cyphernetes operator
  query       Execute a Cypher-inspired query against Kubernetes
  shell       Launch an interactive shell
  web         Start the Cyphernetes web interface

Flags:
  -A, --all-namespaces     Query all namespaces
  -h, --help               help for cyphernetes
  -l, --loglevel string    The log level to use (debug, info, warn, error, fatal, panic) (default "info")
  -n, --namespace string   The namespace to query against (default "default")
      --no-color           Disable colored output in shell and query results

Use "cyphernetes [command] --help" for more information about a command.
Enter fullscreen mode Exit fullscreen mode

Note that the CLI don't have a -v or version command to know the version of the CLI. I've created an issue about it because it's a common behavior and usage in CLIs.

Queries

We can execute query by query with the cyphernetes query command.

For example, if I want the list of the Pods that are not in Running status, I can do it with kubectl:

$ kubectl get po --field-selector status.phase!=Running

NAME    READY   STATUS         RESTARTS   AGE
nginx   0/1     ErrImagePull   0          109s
Enter fullscreen mode Exit fullscreen mode

And also with Cyphernetes:

$ cyphernetes query 'MATCH (po:Pod) WHERE po.status.phase != "Running" RETURN po.status.containerStatuses.state.waiting.reason, po.status.phase'
{
  "po": [
    {
      "name": "nginx",
      "status": {
        "containerStatuses": {
          "state": {
            "waiting": {
              "reason": [
                "ImagePullBackOff"
              ]
            }
          }
        },
        "phase": "Pending"
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

And, imagine I want only the reason whay a Pod is not in Running state, I can execute a query with Cyphernetes and manipulate the output with jq:

$ cyphernetes query 'MATCH (po:Pod) WHERE po.status.phase != "Running" RETURN po.status.containerStatuses.state.waiting.reason, po.status.phase' | jq '.po[].status.containerStatuses.state.waiting.reason'
[
  "ImagePullBackOff"
]
Enter fullscreen mode Exit fullscreen mode

OK ... It's working ... But the command is not tiny comparing to a kubectl command 😉.

If you want to test the power of the queries with Cyphernetes, read the USAGE.md file that is located in the GitHub repository of the tool.

Shell

Instead of executing queries by queries, you can also open a shell and execute all the queries you want:

$ cyphernetes shell

                __                    __
 ______ _____  / /  ___ _______  ___ / /____ ___
/ __/ // / _ \/ _ \/ -_) __/ _ \/ -_) __/ -_|_-<
\__/\_, / .__/_//_/\__/_/ /_//_/\__/\__/\__/___/
   /___/_/ Interactive Shell

🔎 fetching resource specs... done!

Type 'exit' or press Ctrl-D to exit
Type 'help' for information on how to use the shell


(kubernetes-admin@my-cluster) hello-app » MATCH (po:Pod) RETURN po.name.

{
  "po": [
    {
      "name": "hello-kubecon-deployment-c545c8f57-8rthw"
    },
    {
      "name": "hello-kubecon-deployment-c545c8f57-v99m2"
    },
    {
      "name": "hello-kubecon-deployment-c545c8f57-x8kkk"
    },
    {
      "name": "nginx"
    }
  ]
}

Query executed in 64.21025ms


(kubernetes-admin@my-cluster) hello-app » MATCH (po:Pod {name: "nginx"}) DELETE po;

Deleted pods/nginx

Query executed in 86.562792ms
Enter fullscreen mode Exit fullscreen mode

Ok cool, I executed one query to list the Pods and one query to delete my nginx in error state.

The Cyphernetes shell comes with autocompletion, syntax
highlighting and history.

Web interface

As you probably know, I'm a visual learner and lover. So one of the reason I wanted to play and dig into Cyphernetes what the visual approach of the resources.

To launch the web interface, just execute:

$ cyphernetes web
🔎 fetching resource specs... done!
Starting Cyphernetes web interface at http://localhost:8080
Press Ctrl+C to stop
Enter fullscreen mode Exit fullscreen mode

And then access to http://localhost:8080 in your browser.

Unfortunately, I tested in two computers, two clusters and I discovered that the web interface is not working and I'm not the only one person in the same case.

Executing a query don't display resources visually:

cyphernetes web

So I can't test the web interface right now. it was one of the reason I tested the tool 😢.

Macros

An interesting feature is the ability to create and use macros.
It's a kind of aliases for your queries.

List existing Macros

You can list existing macros with the \lm command in the shell:

$ cyphernetes shell

                __                    __
 ______ _____  / /  ___ _______  ___ / /____ ___
/ __/ // / _ \/ _ \/ -_) __/ _ \/ -_) __/ -_|_-<
\__/\_, / .__/_//_/\__/_/ /_//_/\__/\__/\__/___/
   /___/_/ Interactive Shell

🔎 fetching resource specs... done!

Type 'exit' or press Ctrl-D to exit
Type 'help' for information on how to use the shell

(kubernetes-admin@my-cluster) hello-app »
(kubernetes-admin@my-cluster) hello-app » \lm

Registered macros:
:getpo [] - List pods
:getsvc [] - List services
:getns [] - List namespaces
:getpvc [] - List persistent volume claims
:expose [deploymentName] - Expose a deployment as a service
:countreplica [] - Count the number of desired vs available replicas for all deployments
:getpv [] - List persistent volumes
:getevent [] - List warning events
:getcm [] - List config maps
:getsecret [] - List secrets
:getjob [] - List jobs
:getcronjob [] - List cron jobs
:deployexposure [deploymentName] - Examine a deployment and its services and ingress
:getdeploy [] - List deployments
:podmon [] - Monitor pod resources
:scale [kind name count] - Scale a deployment or statefulset
:createdeploy [deploymentName image] - Create a deployment
:getno [] - List nodes
:geting [] - List ingresses
:exposepublic [deploymentName hostname] - Expose a deployment as a service and ingress
Enter fullscreen mode Exit fullscreen mode

As you can see, the tool have several macros by default that allows you to list common resources and also expose a deployment.

You can use a macro by running :<macro-name> in the shell.

Unfortunately I tested several macros and several seems not working (:getns, :getno...):

Current behavior:

(kubernetes-admin@my-cluster) hello-app »:getns
Error getting list of resources:  the server could not find the requested resource
Error getting list of resources:  the server could not find the requested resource
Error marshalling results to JSON:  the server could not find the requested resource
Error >> error executing statement 1: error executing query >> error getting node resources >> the server could not find the requested resource
Enter fullscreen mode Exit fullscreen mode

It's strange, because with kubeclt command is working:

$ kubectl get ns
NAME              STATUS   AGE
cert-manager      Active   40d
hello-app         Active   41d
default           Active   41d
goldilocks        Active   12d
ingress-nginx     Active   40d
kube-node-lease   Active   41d
kube-public       Active   41d
kube-system       Active   41d
prometheus        Active   12d
vpa               Active   12d
Enter fullscreen mode Exit fullscreen mode

I opened another issue 😅.

Create a macro

You can create your own macros.
To do it, create the file ~/.cyphernetes/macros.

The file should follow the following format:

:<macro_name> [<args>]
<query>;

:<macro_name2> [<args>]
<query>;
Enter fullscreen mode Exit fullscreen mode

OK, let's create our first macro

:scale_nginx count
MATCH (d:Deployment {name: "nginx"})
SET d.spec.replicas=$count
RETURN d.name, d.spec.replicas;
Enter fullscreen mode Exit fullscreen mode

And let's use it:

$ cyphernetes shell

                __                    __
 ______ _____  / /  ___ _______  ___ / /____ ___
/ __/ // / _ \/ _ \/ -_) __/ _ \/ -_) __/ -_|_-<
\__/\_, / .__/_//_/\__/_/ /_//_/\__/\__/\__/___/
   /___/_/ Interactive Shell

🔎 fetching resource specs... done!

Type 'exit' or press Ctrl-D to exit
Type 'help' for information on how to use the shell

(kubernetes-admin@my-cluster) hello-app » :scale_nginx 5
{
  "d": [
    {
      "name": "nginx",
      "spec": {
        "replicas": 5
      }
    }
  ]
}

Macro executed in 85.364791ms
Enter fullscreen mode Exit fullscreen mode

Note: The documentation is not up-to-date about the macros creation so it's not obvious to know how to use parameters and how to add the description of the macro 😅.

Conclusion

The 0.1 version of Cyphernetes have been published it one year ago (Nov 22, 2023). It's a young tool with one main contributor, not mature for the moment. Severals bugs exists (sorry I'm a black cat 🐈‍⬛, the bugs likes me), the web interface is not working, we can't have another output format like JSON... but on my side I'll keep watching it and see the next relase and bug fixes.

For Ops or SysAdmin or SRE that execute kubectl commands like a guru I don't think this approach can help them but for Developers it can be interesting 💡.

I'll keep an eye in the next releases.

Top comments (0)