Simple setup for converting Kubernetes API server into GraphQL API.
This sample exposes GraphQL endpoint by using only API management tool GraphQL Mesh.
- GraphQL endpoint of Kubernetes API & Docker; dynamically created by GraphQL Mesh
- Advantage of GraphQL
- Query example (Kubernetes)
- Query example (docker)
- Start up
- Cleanup
- Kubernetes Query
- Original resolvers (
parent/children
,connecting/connected
,mounting
,namespace
andevents
) - Architecture
- Customize
- Reference
-
Unique and readable query format
- In GraphQL world, you edit fields in your query so that response data will include only fields that you need.
-
Completion or validation of query
- When you edit your query with GraphQL playground or Graphiql, they have powerful completion function which enables you to easily construct query without remembering exact field name etc.
kubectl get pods --namespace default -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.startTime}{"\n"}{end}'
{ # pods or pos Pods(namespace: "default") { items { metadata { name namespace } status { startTime } } } }
Resource relation is visualized as tree form. Please refer to graphql-treeview.
kubectl get pods --namespace default -l run=mesh -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.namespace}{"\t"}{.metadata.labels}{"\t"}{.status.startTime}{"\n"}{end}'
{
# pods or pos
Pods(
namespace: "default",
labelSelector: "run=mesh"
) {
items {
metadata {
name
namespace
labels
}
status {
startTime
}
}
}
}
{
# pod or po
pod(
name: "mesh"
namespace: "default",
) {
metadata {
name
namespace
}
}
}
These are original fields. Please refer to Original resolvers.
query q {
Pods(namespace: "default") {
items {
metadata {
name
namespace
}
parent {
# ReplicaSets (Pod's parent)
... on ReplicaSet {
metadata {
name
}
children {
# Pods (ReplicaSet's children)
items {
metadata {
name
}
}
}
}
}
connected {
# Services (Pod's connected resources)
items {
metadata {
name
}
connecting {
# Pods (Service's connecting targets)
items {
metadata {
name
}
}
}
}
}
}
}
}
This is useful for Pod debugging.
kubectl get po; (check...) kubectl get deployment; (check...) kubectl get events ...
This query replaces many operations of kubectl
.
query {
Pods(namespace: "default") { # Pod
items {
metadata {
name
namespace
}
status {
startTime
containerStatuses {
state {
terminated {
message
}
waiting {
message
reason
}
}
}
}
events { # Get events list related to Pod
...eventsContents
}
parent { # ReplicaSet or DaemonSet or StatefulSet (if any exists)
...on ReplicaSet { # Deployment (if any exists)
events { # Get events for the above grandparent resources.
...eventsContents
}
}
}
}
}
}
fragment eventsContents on EventList {
items {
message
reason
}
}
Example: document generated according to OpenAPI
Error case
query q {
volumeList {
volumes {
name
}
}
}
query q {
containerList{
names
ports {
privatePort
publicPort
}
}
}
You have your own Kubernetes cluster or create one. For example, you can create it with the following command after installing kind.
# Create a Kubernetes cluster on Docker
kind create cluster --name kube-graphql --config kind-config.yaml
# Run containers on Kubernetes.
kubectl apply -f k8s -n default
# When you need cluster wide resouce access (e.g. Namespace), you can run this command additionally.
kubectl apply -f k8s/cluster-wide/
If you have ingress controller in your cluster, you will see the service at http://graphql-mesh-k8s.127.0.0.1.xip.io
.
Otherwise, this command allows you to forwarding port to localhost.
# Forward GraphQL Mesh to local machine
kubectl port-forward svc/mesh-svc 4000:4000 -n default
Access http://localhost:4000
.
After installing helm command, you can deploy helm chart.
helm repo add kubernetes-graphql https://onelittlenightmusic.github.io/kubernetes-graphql/helm-chart
helm install my-kubernetes-graphql kubernetes-graphql/kubernetes-graphql
# or with parameter
helm install my-kubernetes-graphql kubernetes-graphql/kubernetes-graphql --set kubernetes-api-proxy.serviceAccount.clusterWide=true
Access a URL which is displayed after running helm install
(e.g. http://graphql-mesh-k8s.127.0.0.1.xip.io
).
Helm chart parameters are as follows,
Name | Description | Default |
---|---|---|
kubernetes-api-proxy.serviceAccount.create |
If true , ServiceAccount will be created for GraphQL API |
true |
kubernetes-api-proxy.serviceAccount.clusterWide |
If true , GraphQL API endpoint will be allowed to call cluster wide API like kubectl get nodes |
false |
graphql-mesh.ingress.enabled |
If true , an Ingress will be created. In this case, you prepare Ingress Controller. |
true |
Install Docker
and docker-compose
and run these commands.
cd docker
docker-compose up -d
kubectl delete -f k8s
The query methods follow Kubernetes Resource Type.
Nodes
Namespaces
Pods(namespace: String!)
Services(namespace: String!)
Ingresses(namespace: String!)
ReplicaSets(namespace: String!)
Deployments(namespace: String!)
DaemonSets(namespace: String!)
StatefulSets(namespace: String!)
ReplicationControllers(namespace: String!)
HorizontalPodAutoscalers(namespace: String!)
ClusterRoleBindings
ClusterRoles
StorageClasses
PodSecurityPolicies
ComponentStatuses
CustomResourceDefinitions
PriorityClasses
CSIDrivers
CSINodes
VolumeAttachments
CronJobs(namespace: String!)
Jobs(namespace: String!)
RoleBindings(namespace: String!)
Roles(namespace: String!)
ServiceAccounts(namespace: String!)
ResourceQuotas(namespace: String!)
Endpoints(namespace: String!)
ControllerRevisions(namespace: String!)
NetworkPolicies(namespace: String!)
PodDisruptionBudgets(namespace: String!)
LimitRanges(namespace: String!)
PodTemplates(namespace: String!)
Events(namespace: String!)
PersistentVolumeClaims(namespace: String!)
PersistentVolumes(namespace: String!)
Secrets(namespace: String!)
ConfigMaps(namespace: String!)
etc.
There are some original resolvers inside some resource types. These are "links" from one resource to another.
Name | Value | Example |
---|---|---|
parent |
Follow a owner link which means dependency in Kubernetes | Pod.parent -> ReplicaSet , ReplicaSet.parent -> Deployment |
children |
Drill down owner links downward. Search for all child resource elements which has owner link to original resource. | Deployment.children -> [ReplicaSet] , ReplicaSet.children -> [Pod] |
connecting |
Search for all resource elements which have the same labels as la belSelector of original resource. |
Service.connecting -> [Pod] |
connected |
Search for resources whose labelSelector includes all labels of original resource |
Pod.conntected -> Service |
mounting |
Search for resources which are mounted as Volumes in the Pod | Pod.mounting -> [Secret or ConfigMap or PersistentVolumeClaim] |
events |
Search for events related to the target resource | Pod(and other resources).events -> [Event] |
namespace |
Direct link to namespace object | Pod(and other resources).namespace --> Namespace |
Pod
- pod: mesh
- container: mesh (#1: GraphQL endpoint. runs GraphQL Mesh to convert #2 API to GraphQL)
- container: proxy (#2: REST API endpoint. runs kubectl proxy to forward request to #4)
Service
- mesh-rc (#3: endpoint of GraphQL Mesh, connected to #1 and #2)
- kubernetes (#4: Automatically generated by Kubernetes. Kubernetes API endpoint)
Containers
- container: proxy (REST API: transfer Docker unix-socket API to http port)
- container: mesh-svc (GraphQL API: runs GraphQL Mesh to convert REST API to GraphQL)
Edit resources in src
directory
src
├── .meshrc.yaml # Configuration file for GraphQL Mesh
├── example-query.graphql # Initial query to be shown in GraphQL Playground
└── mesh-init.sh # Initialization script for OpenAPI specification of Kubernetes
Compile into k8s/meshrc-cm.yaml
with this command.
kubectl create cm meshrc-cm --from-file src/.meshrc.yaml --from-file src/mesh-init.sh --from-file src/example-query.graphql --dry-run -o yaml> k8s/meshrc-cm.yaml
These are some existing orignal tools for the same motivation.