Kubeql, pronounced "cubicle", is a SQL-like query language for Kubernetes resources.
It might be handy for simple queries, but at the moment, it is very much a toy project for me to learn about parsers, lexers and evaluators.
Things you can do:
->
is currently used over dot-notation, as dot notation is commonly used in
JSONPath and "jq" like expressions. In contrast, ->
access is simple, and only
supports direct->path->access. It supports map and array access (array->0->item
).
$ ./kubeql -execute "select pods->metadata->labels as labels from pods"
labels
------
{"app":"redmine-test-2-mariadb","pod-template-hash":"384399387"}
{"app":"redmine-test-2-redmine","pod-template-hash":"411540601"}
{"app":"redmine-test-2-redmine","pod-template-hash":"411540601"}
{"k8s-app":"event-exporter","pod-template-hash":"1421584133","version":"v0.1.5"}
...
The same ->
path expressions can be used for filtering.
$ ./kubeql -execute "select pods->metadata->labels as labels from pods where pods->metadata->labels->app"
labels
------
{"app":"redmine-test-2-mariadb","pod-template-hash":"384399387"}
{"app":"redmine-test-2-redmine","pod-template-hash":"411540601"}
{"app":"redmine-test-2-redmine","pod-template-hash":"411540601"}
{"app":"helm","name":"tiller","pod-template-hash":"1936853538"}
$ ./kubeql -execute "select pods->metadata->labels as labels from pods where pods->metadata->labels->app = 'helm'"
labels
------
{"app":"helm","name":"tiller","pod-template-hash":"1936853538"}
$ ./kubeql -execute "select pods->spec->containers->0->name as names from pods"
names
-----
"redmine-test-2-mariadb"
"redmine-test-2-redmine"
"redmine-test-2-redmine"
"event-exporter"
...
Kubeql can access non-core v1 resources by a fully qualified name
(eg: apps/v1beta1/deployments
), and core v1 resources by their short-name
(pods, endpoints, services, configmaps, secrets, persistentvolumeclaims, events
etc).
$ ./kubeql -execute "select deployments->metadata->name as deployment_name FROM apps/v1beta1/deployments"
deployment_name
---------------
"redmine-test-2-mariadb"
"redmine-test-2-redmine"
"event-exporter"
"heapster-v1.4.2"
...
Kubeql does not yet fetch efficiently from the backend. In the future, I hope I can use the label/field selector to fetch fewer results than required so that there's less to be processed by the client.
Using the NAMESPACE
keyword will only fetch resources from the specified namespace.
select deployments FROM apps/v1beta1/deployments NAMESPACE default
Kubectl at the moment only supports SQL ANSI-89 JOIN functionality, by selecting from multiple tables.
$ ./kubeql -execute "select deployments->metadata->name as deployment_name, pods->metadata->name as pod_name FROM apps/v1beta1/deployments, pods where pods->metadata->labels->app = deployments->metadata->labels->app"
deployment_name pod_name
--------------- --------
"redmine-test-2-mariadb" "redmine-test-2-mariadb-384399387-dz3xq"
"redmine-test-2-redmine" "redmine-test-2-redmine-411540601-320ws"
"redmine-test-2-redmine" "redmine-test-2-redmine-411540601-938tq"
"tiller-deploy" "tiller-deploy-1936853538-hvjnm"
Kubeql supports kubernetes' implementation of JSONPath templating.
$ ./kubeql -execute "select jsonpath(pods->metadata, '{.labels}') as labels from pods"
labels
------
[{"app":"redmine-test-2-mariadb","pod-template-hash":"384399387"}]
[{"app":"redmine-test-2-redmine","pod-template-hash":"411540601"}]
[{"app":"redmine-test-2-redmine","pod-template-hash":"411540601"}]
[{"k8s-app":"event-exporter","pod-template-hash":"1421584133","version":"v0.1.5"}]
[{"controller-revision-hash":"1419153066","k8s-app":"fluentd-gcp","kubernetes.io/cluster-service":"true","pod-template-generation":"1","version":"v2.0"}]
...
Kubeql supports JQ-style selecting/filtering.
$ ./kubeql -execute "select jq(deployments->metadata, '.labels.app') as deployment_name FROM apps/v1beta1/deployments"
deployment_name
---------------
["redmine-test-2-mariadb"]
["redmine-test-2-redmine"]
[null]
[null]
["helm"]
Because jsonpath
and jq
return arrays, you can always combine this with
Kubeql's ->
path expressions to return a single result:
$ ./kubeql -execute "select jq(deployments->metadata, '.labels.app')->0 as deployment_name FROM apps/v1beta1/deployments"
deployment_name
---------------
"redmine-test-2-mariadb"
"redmine-test-2-redmine"
null
null
"helm"