To learn what Kubernetes APIs are and to do RESTful Operation
The Kubernetes API server is one of the core components of the control plane which helps in exposing the Kubernetes API.
This API server serves different HTTP(REST) API endpoints which allows end-users to do different RESTful operations, to interact with different components of the cluster.
At the bottom level, everything in the Kubernetes cluster is treated as an API object and the Kubernetes API endpoints allows us to perform CRUD operations on these API objects.
Kubernetes API server provides different endpoints to which we can connect through different standard HTTP verbs such as POST, PUT, DELETE, GET, PATCH and kubectl CLI is one of the most common tools which users can use to communicate with the Kubernetes API.
The below command will give you the list of API endpoints to which you can connect to :
kubectl api-versions
API groups:
API groups in Kubernetes are a logical collection of related functionality. Kubernetes divides the endpoints into 2 subgroups: core API group and other API group.
- The core (also called legacy) group is found at the REST path
/api/v1
- The named groups are found at the REST path
/apis/$GROUP_NAME/$VERSION
You can find the full list of supported API groups in Kubernetes API reference.
API request verbs:
As all object resource types support the standard HTTP verbs – GET, POST, PUT, PATCH, and DELETE and so Kubernetes also uses its own verbs, which are used in lowercase to differentiate them from HTTP verbs like get, list, create, update, patch, watch and delete.
Request URIs Format:
As resource types can be used and scoped either by a cluster (/apis/GROUP/VERSION/*
) or by a namespace (/apis/GROUP/VERSION/namespaces/NAMESPACE/*
).
The resource is an identifier that receives and returns its corresponding kind. Resources also expose CRUD actions for that kind.
Cluster-scoped resources
- GET
/apis/GROUP/VERSION/RESOURCETYPE
– return the collection of resources of the resource type - GET
/apis/GROUP/VERSION/RESOURCETYPE/NAME
– return the resource NAME under the resource type
Namespace-scoped resources
- GET
/apis/GROUP/VERSION/RESOURCETYPE
– return the collection of all instances of the resource type across all namespaces - GET
/apis/GROUP/VERSION/namespaces/NAMESPACE/RESOURCETYPE
– return a collection of all resource type instances in NAMESPACE - GET
/apis/GROUP/VERSION/namespaces/NAMESPACE/RESOURCETYPE/NAME
– return the resource type instance with NAME in NAMESPACE
As Kubernetes API resources are divided into different API groups along with different scopes and sometimes it becomes difficult to remember all and to see which ones is supported in your Kubernetes cluster and in which scope.
And to help with these, one can run the following command to check:
kubectl api-resources -o wide
The above command helps in enumerating the resource types available in the cluster along with their respective scope and different HTTP verbs.
A group is simply a collection of kinds. You can have kinds such as ReplicaSets, StatefulSets, and Deployments which are all part of the apps group.
Versions allow Kubernetes to release groups as tagged versions. Here are the versions that Kubernetes has available.
- Alpha: This is usually disabled by default since it should only be used for testing. You may see labeled as v1alpha1
- Beta: Enabled by default. You man see labeled as v1beta1
- Stable: These have reached maturity and will be around for further releases. You may see labeled as v1
One can also list down the API resources for a particular API group
kubectl api-resources --api-group apps -o wide
kubectl api-resources --api-group batch -o wide
Use Cases of using API endpoints:
1. Extract information out of K8s as JSON reply
2. Navigate through the JSON reply and extract information such as pod names, IPs, and many more.
3. Display information on the front end of a web app.
Lab with Kubernetes API
To start using Kubernetes APIs you need to turn on Kubernetes reverse proxy and run it in the background by specifying &
with the following command.
kubectl proxy --port 8040 &
kubectl proxy
is a server that handles certificates for us so that we don’t need to worry about auth tokens with curl.
The following list contains a few Kubernetes API endpoints to use after turning on the reverse proxy and the response value would be in JSON format.
localhost:8040/api
to get the API version.localhost:8040/api/v1/namespaces
to get all the namespaces in the k8s clusterlocalhost:8040/api/v1/pods
to get all the pods in the k8s cluster (pods’ IPs, names, where does it exist, etc…)localhost:8040/api/v1/namespaces/<namespace_name>/pods
to get the pods exists in a given namespacelocalhost:8040/api/services
to get all the services exposed by k8slocalhost:8040/apis/app/namespaces/<name>/deployments
to get the pods exists in a given namespace
As everything in Kubernetes is an object to which you can connect and perform CRUD operations .
Let’s start by creating a test namespace and a few pods inside that namespace.
kubectl create ns test
kubectl run nginx --image nginx -n test
kubectl run redis --image redis -n test
Performing GET and LIST operations
In Kubernetes terminology, the response you get from a LIST is a collection of resources and GET helps in retrieving a single resource.
When you query the API for a particular type, all items returned by that query are of that type. For example, when you list Pods, the collection response has a kind set to PodList; each item in that collection represents a single Pod. For example:
- List all of the pods on a cluster
curl localhost:8040/api/v1/pods
{ "kind": "PodList", "apiVersion": "v1", "metadata": { "resourceVersion": "2947301" }, "items": [ { "metadata": { "name": "nginx", "namespace": "default", ... ... }
- List all of the pods on a cluster on a specific namespace
curl localhost:8040/api/v1/namespaces/test/pods
{ "kind": "PodList", "apiVersion": "v1", "metadata": { "resourceVersion": "2947301" }, "items": [ { "metadata": { "name": "nginx", "namespace": "test", ... "metadata": { "name": "redis", "namespace": "test", ... }
As we have to deal with a lot of data, we can use jq (jq is a Linux command-line utility that is easily used to extract data from JSON documents) to further improve readability.
sudo apt install jq -y
curl localhost:8040/api/v1/namespaces/test/pods/ | jq '.items[].metadata.name'
The /pods
endpoint lists all the pods and if you want to query for a particular pod you can query with /pods/<pod_name>
endpoint .
curl localhost:8040/api/v1/namespaces/test/pods/nginx
Performing POST operation
In the case of post operations, you can send the payload as a JSON object.
A payload in API is the actual data pack that is sent with the methods in HTTP. It is the crucial information that you submit to the server when you are making an API request.
The payload can be sent or received in various formats, including JSON. Usually, the payload is denoted using the “{}”
in a query string.
- Create a specific namespace, let’s say demo namespace
You can send the below payload to /api/v1/namespaces
endpoint with a header of Content-Type = application/json
curl -v -XPOST -H "User-Agent: kubectl/v1.22.2 (linux/amd64) kubernetes/8b5a191" -H "Accept: application/json, */*" -H "Content-Type: application/json" -d '{"kind": "Namespace", "apiVersion": "v1", "metadata": {"name": "demo"}}' 'http://localhost:8040/api/v1/namespaces?fieldManager=kubectl-create'
Similarly, we can create a deployment also inside a specific namespace. Here we are creating a redis deployment inside demo namespace
curl -v -XPOST -H "Accept: application/json, */*" -H "Content-Type: application/json" -H "User-Agent: kubectl/v1.22.2 (linux/amd64) kubernetes/8b5a191" 'http://localhost:8040/apis/apps/v1/namespaces/demo/deployments?fieldManager=kubectl-create' -d '{"kind":"Deployment","apiVersion":"apps/v1","metadata":{"name":"redis","namespace":"demo","creationTimestamp":null,"labels":{"app":"redis"}},"spec":{"replicas":1,"selector":{"matchLabels":{"app":"redis"}},"template":{"metadata":{"creationTimestamp":null,"labels":{"app":"redis"}},"spec":{"containers":[{"name":"redis","image":"redis","resources":{}}]}},"strategy":{}},"status":{}}'
Check for the pods and deployments using :
kubectl get pods -n demo
kubectl get deployments -n demo
Performing DELETE operation :
You can use the HTTP DELETE operation to delete a specific kind of resource. For example, you can delete a kind of pod within a namespace with a fieldselector(Read More) name as pod .
curl -XDELETE localhost:8040/api/v1/namespaces/test/pods/?fieldSelector=metadata.name=nginx
Check if the pod has been deleted or not using
kubectl get pods -n test
Conclusion
In this hands-on lab, we have seen the Kubernetes API model and performed different CRUD operations on API endpoints.