Kubernetes exposes a robust API that lets you control every aspect of the cluster.
Most of the time, it's hidden behind kubectl, but no one stops you from using it directly.
In this article, you will learn how to navigate and issue requests to the Kubernetes API with curl
or your favourite programming language.
But first, let's recap how the Kubernetes API works.
When you type a command, kubectl:
- Validates the request client-side.
- Generate YAML on the file (e.g.
kubectl run
). - Construct the runtime object.
At this point, kubectl just acted locally without issuing any request to the cluster.
As the next step, it queries the current API server and discovers all available API endpoints.
Finally, kubectl uses the runtime objected and endpoints to negotiate the correct API call.
If your resource is a Pod, kubectl reads the apiVersion
and kind
fields and ensures those are available and supported in the cluster.
Then it sends the request.
It's important to understand that APIs in Kubernetes are grouped.
To further segregate multiple versions, resources are versioned.
Now that you mastered the basics, let's look at an example.
You can start a local tunnel to the API server with kubectl proxy
.
But how can you retrieve all deployments?
Deployments belong to the "app" group and have a v1
version.
You can list them with: curl localhost:8001/apis/apps/v1/namespaces/{namespace}/deployments
.
What about listing all running pods?
Pods belong to the ""
(empty) group and have a v1
version.
You can list them with: curl localhost:8001/api/v1/namespaces/{namespace}/pods
.
The empty group is… weird — are there more exceptions?
Well, the reality is that there's an easier way to construct URLs.
I usually use the Kubernetes API reference as the paths are all neatly listed.
Let's look at another example but this time with the help of the API reference.
What if you want to be notified of changes to the pod?
That's called "watch" in the API, and the command is: GET /api/v1/watch/namespaces/{namespace}/pods/{name}
.
Great, but what's the point of all of this?
Accessing the API directly allows you to build scripts to automate tasks.
Or you can build your own kubernetes extensions.
Let me show you.
This is a small kubernetes dashboard in ~130 lines of Javascript.
It uses 2 API calls:
- List all pods.
- Watch for changes to pods.
The remaining code is used to group and display the nodes.
In Kubernetes, combining the listing and updating resources is so common that it's a pattern called shared informer.
The Javascript/Typescript API has an excellent example of the shared informer in action.
But it's just a fancy name for 2 GET requests (and some caching).
The API doesn't stop at reading resources.
You can also create new resources and amend existing ones.
For example, you can amend the replicas for a deployment with: PATCH /apis/apps/v1/namespaces/{namespace}/deployments/{name}
.
To experiment, I built something… unconventional.
xlskubectl is my attempt at controlling a kubernetes cluster using Excel/Google Sheets.
The code is remarkably similar to the Javascript dashboard:
- It uses the shared informer (almost).
- It polls for updates from google sheets.
- It renders everything as cells.
Is it a good idea? Probably not.
Hopefully, it helps you realize the potential of using the Kubernetes API directly.
None of this code was written in Go — you can use any programming language.
And finally, if you've enjoyed this thread, you might also like:
- The Kubernetes workshops that we run at Learnk8s https://learnk8s.io/training
- This collection of past threads https://twitter.com/danielepolencic/status/1298543151901155330
- The Kubernetes newsletter I publish every week https://learnk8s.io/learn-kubernetes-weekly
Top comments (1)
Like all your posts, another piece of art in information! Thank you! 🙏