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, 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)
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
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
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)
Read
List the Deployments and Services:
MATCH (d:Deployment), (svc:Service)
RETURN d.name, svc.name
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
Delete
Delete the nginx Deployment but also his Service and his Ingress:
MATCH (d:Deployment {name: "nginx"})->(s:Service)->(i:Ingress)
DELETE s, i
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
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.
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
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"
}
}
]
}
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"
]
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
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
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:
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
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
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
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>;
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;
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
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)