From 818028e484cd89c4ed188f9d112e67afc48da047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Mass=C3=A9?= Date: Fri, 7 Jun 2019 17:27:36 +0200 Subject: [PATCH] 2019-06-07 update --- .../use-qlkube-to-query-the-kubernetes-api.md | 334 ++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 content/blog/use-qlkube-to-query-the-kubernetes-api.md diff --git a/content/blog/use-qlkube-to-query-the-kubernetes-api.md b/content/blog/use-qlkube-to-query-the-kubernetes-api.md new file mode 100644 index 0000000..97e1467 --- /dev/null +++ b/content/blog/use-qlkube-to-query-the-kubernetes-api.md @@ -0,0 +1,334 @@ +--- +title: "Use QLKube to query the Kubernetes API" +date: 2019-06-07T00:00:00+02:00 +opensource: +- OpenShift +topic: +- GraphQL +--- + +[QLKube](https://github.com/qlkube/qlkube) is a project that exposes the Kubernetes API as GraphQL. +[GraphQL](https://en.wikipedia.org/wiki/GraphQL) is a data query and manipulation language for APIs developed initially by Facebook and released as open-source. +It strives to reduce the chattiness clients can experience when querying REST APIs. +It is very useful for mobile application and web development: by reducing the number of roundtrips needed to fetch the relevant data and by fetching only the needed field, the network usage is greatly reduced. + +To install QLKube in OpenShift, use the NodeJS Source-to-Image builder: + +```sh +oc new-project qlkube --display-name=QLKube +oc new-app nodejs~https://github.com/qlkube/qlkube.git --name=qlkube +``` + +Disable TLS certificate validation to accommodate your self-signed certificates: + +```sh +oc set env dc/qlkube NODE_TLS_REJECT_UNAUTHORIZED=0 +``` + +And enable the NodeJS development mode to enable the GraphQL explorer (disabled in production mode): + +```sh +oc set env dc/qlkube NODE_ENV=development +``` + +Give the GLKube's Service Account the right to query the Kubernetes API for its own namespace: + +```sh +oc adm policy add-role-to-user view -z default +``` + +Once deployed, open the QLKube URL in your web browser: + +```sh +open $(oc get route qlkube -o go-template --template="http://{{.spec.host}}") +``` + +You can try the following queries in the GraphQL explorer. + +## Get all pods in the current namespace + +Unless you gave the `cluster-admin` right to the QLKube Service Account, you will have to specify a target namespace in all your queries. The `all` type is a [meta type defined by QLKube](TODO) to ease the use of common types such as `services`, `deployments`, `pods`, `daemonSets`, `replicaSets`, `statefulSets`, `jobs` or `cronJobs`. + +**Query:** + +```graphql +query getAllPodsInCurrentNamespace { + all(namespace: "qlkube") { + pods { + items { + metadata { + name + creationTimestamp + } + status { + phase + } + } + } + } +} +``` + +**Response:** + +```json +{ + "data": { + "all": { + "pods": { + "items": [ + { + "metadata": { + "name": "qlkube-1-build", + "creationTimestamp": "2019-06-07T07:56:53Z" + }, + "status": { + "phase": "Succeeded" + } + }, + { + "metadata": { + "name": "qlkube-3-jplpc", + "creationTimestamp": "2019-06-07T14:03:48Z" + }, + "status": { + "phase": "Running" + } + } + ] + } + } + } +} +``` + +## Get a service by name + +To get an object by name, you can use the `fieldSelector` parameter (in this example, we are filtering on the `name` field in the `metadata` section). + +**Query:** + +```graphql +query getServiceByNameAndNamespace { + all(namespace: "qlkube", fieldSelector: "metadata.name=qlkube") { + services { + items{ + metadata { + name + namespace + } + spec { + clusterIP + } + } + } + } +} +``` + +**Response:** + +```json +{ + "data": { + "all": { + "services": { + "items": [ + { + "metadata": { + "name": "qlkube", + "namespace": "qlkube" + }, + "spec": { + "clusterIP": "172.30.213.61" + } + } + ] + } + } + } +} +``` + +## Type introspection + +Playing with the built-in types of GLKube is nice but you might soon be limited. +To discover all the available types, run this query: + +```graphql +{ + __schema { + types { + name + } + } +} +``` + +This query returns a list of all the available types (truncated here for brevity): + +```json +{ + "data": { + "__schema": { + "types": [ + { + "name": "Query" + }, + { + "name": "String" + }, + { + "name": "Boolean" + }, + { + "name": "Int" + }, + { + "name": "ComGithubOpenshiftApiAppsV1DeploymentConfig" + }, + { + "name": "ComGithubOpenshiftApiRouteV1Route" + }, + { + "name": "ComGithubOpenshiftApiRouteV1RouteList" + } + ] + } + } +} +``` + +## Get a Deployment Config by name and namespace + +Once the desired data type discovered, you can use it directly. + +- If the data type represents an item (such as `ComGithubOpenshiftApiRouteV1Route`) you will need to specify the `name` and `namespace` parameters. +- If the data type is a list (such as `ComGithubOpenshiftApiRouteV1RouteList`) you will need to specify the `namespace` and optionally a `fieldSelector` parameters. + +**Query:** + +```graphql +query getDeploymentConfigByNameAndNamespace { + comGithubOpenshiftApiAppsV1DeploymentConfig(name: "qlkube", namespace: "qlkube") { + metadata { + name + } + status { + replicas + availableReplicas + } + } +} +``` + +**Reponse:** + +```json +{ + "data": { + "comGithubOpenshiftApiAppsV1DeploymentConfig": { + "metadata": { + "name": "qlkube" + }, + "status": { + "replicas": 1, + "availableReplicas": 1 + } + } + } +} +``` + +## Get routes by hostname and namespace + +This query use a `fieldSelector` on the `host` field in the `spec` section and uses aliasing to rename the `status` field. + +**Query:** + +```graphql +query getRouteByHostnameAndNamespace { + routes: comGithubOpenshiftApiRouteV1RouteList(namespace: "qlkube" fieldSelector: "spec.host=qlkube-qlkube.app.itix.fr") { + items { + metadata { + name + } + status { + ingress { + routerName + conditions { + deployed: status + } + } + } + } + } +} +``` + +**Reponse:** + +```json +{ + "data": { + "routes": { + "items": [ + { + "metadata": { + "name": "qlkube" + }, + "status": { + "ingress": [ + { + "routerName": "router", + "conditions": [ + { + "deployed": "True" + } + ] + } + ] + } + } + ] + } + } +} +``` + +## Sending your GraphQL request from curl + +Once your GraphQL queries refined in the GraphQL Explorer, you can send them directly using curl or any HTTP client. + +```sh +export GLKUBE_HOSTNAME=$(oc get route qlkube -o go-template --template="{{.spec.host}}") + +cat <