The Kubernetes API
The Kubernetes API uses JSON over HTTP for its requests and responses. It follows the REST architectural style. You can use the Kubernetes API to read and write Kubernetes resource objects.
Note
For more details about the RESTful API, please refer to https://restfulapi.net/.
Kubernetes API allows clients to create, update, delete, or read a description of an object via standard HTTP methods (or HTTP verbs), such as the examples in the following table:
In the context of Kubernetes API calls, it is helpful to understand how these HTTP methods map to API request verbs. So, let's take a look at which verbs are sent through which methods:
- GET: get, list, and watch
Some example kubectl commands are kubectl get pod, kubectl describe pod <pod-name>, and kubectl get pod -w.
- POST: create
An example kubectl command is kubectl create -f <filename.yaml>.
- PATCH: patch
An example kubectl command is kubectl set image deployment/kubeserve nginx=nginx:1.9.1.
- DELETE: delete
An example kubectl command is kubectl delete pod <pod-name>.
- PUT: update
An example kubectl command is kubectl apply -f <filename.yaml>.
Note
If you have not encountered these commands yet, you will in the upcoming chapters. Feel free to refer back to this chapter or the following Kubernetes documentation to find out how each API request works for any command: https://kubernetes.io/docs/reference/kubernetes-api/.
As mentioned earlier, these API calls carry JSON data, and all of them have a JSON schema identified by the Kind and apiVersion fields. Kind is a string that identifies the type of JSON schema that an object should have, and apiVersion is a string that identifies the version of the JSON schema the object should have. The next exercise should give you a better idea about this.
You can refer to the Kubernetes API reference documentation to see the different HTTP methods in action, at https://kubernetes.io/docs/reference/kubernetes-api/.
For example, if you need to create a Deployment in a specific namespace, under WORKLOADS APIS, you can navigate to Deployment v1 apps > Write Operations > Create. You will see the HTTP request and different examples using kubectl or curl. The following page from the API reference docs should give you an idea of how to use this reference:
You will need to keep the version of your API server in mind when you refer to the previously mentioned documentation. You can find your Kubernetes API server version by running kubectl version --short command and looking for Server Version. For example, if your Kubernetes API server version is running version 1.14, you should navigate to the Kubernetes version 1.14 reference documentation (https://v1-14.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.14/) to look up the relevant API information.
The best way to understand this is by tracing a kubectl command. Let's do exactly that in the following section.
Tracing kubectl HTTP Requests
Let's try tracing the HTTP requests that kubectl sends to the API server to better understand them. Before we begin, let's get all the pods in the kube-system namespace by using the following command:
kubectl get pods -n kube-system
This command should display the output in a table view, as you can see in the following screenshot:
Behind the scenes, since kubectl is a REST client, it invokes an HTTP GET request to the API server endpoint and requests information from /api/v1/namespaces/kube-system/pods.
We can enable verbose output by adding --v=8 to our kubectl command. v indicates the verbosity of the command. The higher the number, the more details we get in the response. This number can range from 0 to 10. Let's see the output with verbosity of 8:
kubectl get pods -n kube-system --v=8
This should give output as follows:
Let's examine the preceding output bit by bit to get a better understanding of it:
- The first part of the output is as follows:
From this, we can see that kubectl loaded the configuration from our kubeconfig file, which has the API server endpoint, port, and credentials, such as the certificate or the authentication token.
- This is the next part of the output:
In this, you can see the HTTP GET request mentioned as GET https://192.168.99.100:8443/api/v1/namespaces/kube-system/pods?limit=500. This line contains the operation that we need to perform against the API server, and /api/v1/namespaces/kube-system/pods is the API path. You can also see limit=500 at the end of the URL path, which is the chunk size; kubectl fetches a large number of resources in chunks to improve latency. We will see some examples relating to retrieving large results sets in chunks later in this chapter.
- The next part of the output is as follows:
As you can see in this part of the output, Request Headers describes the resource to be fetched or the client requesting the resource. In our example, the output has two parts for content negotiation:
a) Accept: This is used by HTTP clients to tell the server what content types they'll accept. In our example, we can see that kubectl informed the API server about the application/json content type. If this does not exist in the request header, the server will return the default preconfigured representation type, which is the same as application/json for the Kubernetes API as it uses the JSON schema. We can also see that it is requesting the output as a table view, which is indicated by as=Table in this line.
b) User-Agent: This header contains information about the client that is requesting this information. In this case, we can see that kubectl is providing information about itself.
- Let's examine the next part:
Here, we can see that the API server returns the 200 OK HTTP status code, which indicates that the request has been processed successfully on the API server. We can also see the time taken to process this request, which is 10 milliseconds.
- Let's look at the next part:
As you can see, this part shows the Response Headers, which include details such as the date and time of the request, in our example.
- Now, let's come to the main response sent by the API server:
The Response Body contains the resource data that was requested by the client. In our case, this is information about the pods in the kube-system namespace. Here, this information is in raw JSON format before kubectl can present it as a neat table. However, the highlighted section at the end of the previous screenshot shows that the response body does not have all the JSON output that we requested; part of the Response Body is truncated. This is because --v=8 displays the HTTP request content with truncation of the response content.
To see the full response body, you can run the same command with --v=10, which does not truncate the output at all. The command would look like as follows:
kubectl get pods -n kube-system --v=10
We will not examine the command with --v=10 verbosity for the sake of brevity.
- Now, we come to the final part of the output that we are examining:
This is the final output as a table, which is what was requested. kubectl has taken the raw JSON data and formatted it as a neat table for us.
Note
You can learn more about kubectl verbosity and debugging flags at https://kubernetes.io/docs/reference/kubectl/cheatsheet/#kubectl-output-verbosity-and-debugging.
API Resource Type
In the previous section, we saw that the HTTP URL was made up of an API resource, API group, and API version. Now, let's learn about the resource type defined in the URL, such as pods, namespaces, and services. In JSON form, this is called Kind:
- Collection of resource: This represents a collection of instances for a resource type, such as all pods in all namespaces. In a URL, this would be as follows:
GET /api/v1/pods
- Single resource: This represents a single instance of a resource type, such as retrieving details of a specific pod in a given namespace. The URL for this case would be as follows:
GET /api/v1/namespaces/{namespace}/pods/{name}
Now that we have learned about various aspects of a request made to the API server, let's learn about the scope of API resources in the next section.