Awesome
Kubeiql
A GraphQL interface for Kubernetes.
The goal of this project is to provide an alternative GraphQL interface to a Kubernetes cluster. It is not intended to entirely replace the ReST APIs as some of them (particularly the watch APIs) don't map well onto GraphQL.
Yipee.io is a CA, Inc. Accelerator project.
Current Status
pre-alpha
- Queries are currently supported against Pods, Deployments, ReplicaSets, StatefulSets, and DaemonSets.
- No mutations are yet implemented.
- The retrieval of data from the cluster is accomplished via watchers
on the kubernetes API. By default, we expect to access the API at
localhost port 8080 (run "kubectl proxy --port=8080")
- to access a kubernetes API without using the proxy, you can set
environment variables:
- API_HOST: host/port of API, e.g., https://kubernetes.default.svc from inside a cluster
- API_SECRET_PATH: directory containing files 'ca.crt' and 'token', e.g. /var/run/secrets/kubernetes.io/serviceaccount from a pod inside a cluster
- to access a kubernetes API without using the proxy, you can set
environment variables:
- Tests are lacking
- See https://hub.docker.com/r/yipeeio/kubeiql/ for a docker image
Getting Started
To experiment with the API:
- Download the code
- Type <code>sh gobuild.sh</code>
- Start a proxy for the kubernetes API on port 8080 (e.g., kubectl proxy --port=8080)
- Run ./kubeiql
The server runs at port 8128. You can use curl to play with it as shown in the examples below via the /query endpoint, or point your browser at 'localhost:8128/' and experiment with the GraphiQL tool (much more user-friendly).
Build an image
If you're running on a non-linux machine, use the elf-build.sh script to build an image suitable for use in a docker container. Then just build in the usual way:
docker build -t your-image-name .
Running inside a Kubernetes cluster
To run kubeiql inside a cluster, simply apply the k8sdeploy.yaml file:
kubectl apply -f k8sdeploy.yaml
Examples
The query:
{
daemonSetByName(namespace: "kube-system", name: "kube-proxy") {
metadata {name namespace labels {name value}}
}
}
<code>
curl -X POST -H"Content-Type: application/json"
http://localhost:8128/query -d
'{ "query": "{daemonSetByName(namespace: \"kube-system\", name: \"kube-proxy\") { metadata {name namespace labels {name value}} pods {metadata {name}}}}"}'
</code>
returns:
{
"data": {
"daemonSetByName": {
"metadata": {
"name": "kube-proxy",
"namespace": "kube-system",
"labels": [
{
"name": "k8s-app",
"value": "kube-proxy"
}
]
},
"pods": [
{
"metadata": {
"name": "kube-proxy-7vhx5"
}
}
]
}
}
}
and the query:
{
allPods() {
owner {kind metadata {name}}
rootOwner { kind metadata { name namespace }
... on StatefulSet {
metadata { name }
}
... on Deployment {
replicaSets {
metadata { name }
pods { metadata { name } } }
}
}
}
}
<code>
curl -X POST -H"Content-Type: application/json"
http://localhost:8128/query -d '{"query": "{allPods() {owner {kind
metadata {name}} rootOwner { kind metadata { name namespace } ... on
StatefulSet { metadata { name } } ... on Deployment { replicaSets {
metadata { name } pods { metadata { name } } } } } } }" }'
</code>
returns:
{
"data": {
"allPods": [
{
"owner": {
"kind": "ReplicaSet",
"metadata": {
"name": "backend-549447ccf"
}
},
"rootOwner": {
"kind": "Deployment",
"metadata": {
"name": "backend",
"namespace": "default"
},
"replicaSets": [
{
"metadata": {
"name": "backend-549447ccf"
},
"pods": [
{
"metadata": {
"name": "backend-549447ccf-4zphf"
}
},
{
"metadata": {
"name": "clunky-sabertooth-joomla-5d4ddc985d-fpddz"
}
},
{
"metadata": {
"name": "clunky-sabertooth-mariadb-0"
}
}
// ...
]
}
]
}
},
{
"owner": {
"kind": "ReplicaSet",
"metadata": {
"name": "clunky-sabertooth-joomla-5d4ddc985d"
}
},
"rootOwner": {
"kind": "Deployment",
"metadata": {
"name": "clunky-sabertooth-joomla",
"namespace": "default"
},
"replicaSets": [
{
"metadata": {
"name": "backend-549447ccf"
},
"pods": [
{
"metadata": {
"name": "backend-549447ccf-4zphf"
}
},
{
"metadata": {
"name": "clunky-sabertooth-joomla-5d4ddc985d-fpddz"
}
}
//...
]
}
]
}
},
{
"owner": {
"kind": "StatefulSet",
"metadata": {
"name": "clunky-sabertooth-mariadb"
}
},
"rootOwner": {
"kind": "StatefulSet",
"metadata": {
"name": "clunky-sabertooth-mariadb",
"namespace": "default"
}
}
},
{
"owner": {
"kind": "ReplicaSet",
"metadata": {
"name": "ui-9c6c8d79"
}
},
"rootOwner": {
"kind": "Deployment",
"metadata": {
"name": "ui",
"namespace": "default"
},
"replicaSets": [
{
"metadata": {
"name": "backend-549447ccf"
},
"pods": [
{
"metadata": {
"name": "backend-549447ccf-4zphf"
}
},
{
"metadata": {
"name": "clunky-sabertooth-joomla-5d4ddc985d-fpddz"
}
}
// ...
]
}
]
}
},
{
"owner": {
"kind": "ReplicaSet",
"metadata": {
"name": "ui-9c6c8d79"
}
},
"rootOwner": {
"kind": "Deployment",
"metadata": {
"name": "ui",
"namespace": "default"
},
"replicaSets": [
{
"metadata": {
"name": "backend-549447ccf"
},
"pods": [
{
"metadata": {
"name": "backend-549447ccf-4zphf"
}
},
{
"metadata": {
"name": "clunky-sabertooth-joomla-5d4ddc985d-fpddz"
}
}
// ...
]
}
]
}
},
{
"owner": {
"kind": "Pod",
"metadata": {
"name": "etcd-minikube"
}
},
"rootOwner": {
"kind": "Pod",
"metadata": {
"name": "etcd-minikube",
"namespace": "kube-system"
}
}
},
{
"owner": {
"kind": "Pod",
"metadata": {
"name": "kube-addon-manager-minikube"
}
},
"rootOwner": {
"kind": "Pod",
"metadata": {
"name": "kube-addon-manager-minikube",
"namespace": "kube-system"
}
}
},
{
"owner": {
"kind": "Pod",
"metadata": {
"name": "kube-apiserver-minikube"
}
},
"rootOwner": {
"kind": "Pod",
"metadata": {
"name": "kube-apiserver-minikube",
"namespace": "kube-system"
}
}
},
{
"owner": {
"kind": "Pod",
"metadata": {
"name": "kube-controller-manager-minikube"
}
},
"rootOwner": {
"kind": "Pod",
"metadata": {
"name": "kube-controller-manager-minikube",
"namespace": "kube-system"
}
}
},
{
"owner": {
"kind": "ReplicaSet",
"metadata": {
"name": "kube-dns-86f4d74b45"
}
},
"rootOwner": {
"kind": "Deployment",
"metadata": {
"name": "kube-dns",
"namespace": "kube-system"
},
"replicaSets": [
{
"metadata": {
"name": "backend-549447ccf"
},
"pods": [
{
"metadata": {
"name": "backend-549447ccf-4zphf"
}
},
{
"metadata": {
"name": "clunky-sabertooth-joomla-5d4ddc985d-fpddz"
}
}
// ...
]
}
]
}
},
{
"owner": {
"kind": "DaemonSet",
"metadata": {
"name": "kube-proxy"
}
},
"rootOwner": {
"kind": "DaemonSet",
"metadata": {
"name": "kube-proxy",
"namespace": "kube-system"
}
}
},
{
"owner": {
"kind": "Pod",
"metadata": {
"name": "kube-scheduler-minikube"
}
},
"rootOwner": {
"kind": "Pod",
"metadata": {
"name": "kube-scheduler-minikube",
"namespace": "kube-system"
}
}
}
// ...
]
}
}
License
The work done has been licensed under Apache License 2.0. The license file can be found here. You can find out more about the license at www.apache.org/licenses/LICENSE-2.0.
Questions?
Feel free to contact us.