Kubernetes is a platform to orchestrate containers operating in the declarative mode. There are one-thousand-and-one ways to describe how the Kubernetes platform is constructed. This book focuses on programming with the platform.
The entry point of the Kubernetes platform is the API. This chapter explores the Kubernetes architecture by highlighting the central role of the Kubernetes API. It then focuses on the HTTP REST nature of the Kubernetes API, and on the extensions added to organize the many resources managed by it.
Finally, you will learn how to navigate the reference documentation effectively to be able to extract the maximum quantity of useful information daily.
Kubernetes Platform at a Glance
On one side of the chain, the user declares the high-level resources to build applications to deploy: Deployments, Ingresses, and so on.
In the middle, controllers are activated to transform these resources into low-level resources (Pods), and the scheduler distributes these resources into nodes. On the other side of the chain, the node agents deploy the low-level resources onto nodes.
- 1.
The API server – this is the central point on the control-plane; the user and the various pieces of the control-plane contact this API to create, get, delete, update, and watch resources.
- 2.
The etcd database – this is only accessible by the API Server, is used to persist the data relative to resources.
- 3.
The Controller manager – this runs the controllers that transform high-level resources declared by the user into low-level resources to be deployed on nodes. The controllers are connected to the API Server, watching for high-level resources and creating, deleting, and updating low-level resources to satisfy the specifications declared in high-level resources.
- 4.
Scheduler – this distributes the low-level resources on the various nodes. The Scheduler is connected to the API Server to watch for unaffected resources and connect them to nodes.
- 5.
Kubelet – this is an agent running on all nodes of the cluster, and each agent manages the workloads affected to its node. The kubelet is connected to the API Server to watch for Pods resources affected to its node and to deploy the associated containers using the local container runtime.
- 6.
Kube proxy – this is an agent running on all nodes of the cluster, and each agent manages the network configurations affected to its node. The kube proxy is connected to the API Server to watch for Service resources and to configure associated network rules on its node.
OpenAPI Specification
The Kubernetes API is an HTTP REST API. The Kubernetes team provides a specification for this API in the OpenAPI format, either in v2 format at https://github.com/kubernetes/kubernetes/tree/master/api/openapi-spec or in Kubernetes v1.24, in v3 format, at https://github.com/kubernetes/kubernetes/tree/master/api/openapi-spec/v3.
These specifications also are accessible from the API Server at these paths: /openapi/v2 and /openapi/v3.
An OpenAPI specification is made up of various parts and, among these, are a list of paths and a list of definitions. The paths are the URLs you use to request this API, and for each path, the specification gives the distinct operations such as get, delete, or post. Then for each operation, the specification indicates what are the parameters and body format for the request, and what are the possible response codes and associated body format for the response.
The parameters and bodies for requests and responses can be either simple types or, more generally, structures containing data. The list of definitions includes data structures that help build the parameters and bodies for the operations’ requests and responses.
Figure 1-2 is a simplified view of a specification for a User API. This API can accept two different paths: /user/{userId} and /user. The first path, /user/{userId}, can accept two operations, get and delete, respectively, to receive information about a specific user, given its user ID; and to delete information about a specific user, given its user ID. The second path, /user, can accept a single operation, post, to add a new user, given its information.
Verbs and Kinds
The Kubernetes API adds two concepts to this specification: the Kubernetes API Verbs and the Kubernetes Kinds.
Correspondence Between Kubernetes API Verbs and HTTP Verbs
Kubernetes API Verb | HTTP Verb |
---|---|
get | GET |
create | POST |
update | PUT |
patch | PATCH |
delete | DELETE |
list | GET |
watch | GET |
deletecollection | DELETE |
The Kubernetes Kinds are a subset of the definitions in the OpenAPI specification. When requests are made to the Kubernetes API, data structures are exchanged through the bodies of requests and responses. These structures share common fields, apiVersion and kind, to help the participants of the request recognize these structures.
If you wanted to make your User API manage this Kind concept, the User structure would contain two additional fields, apiVersion and kind—for example, with values v1 and User. To determine whether a definition in the Kubernetes OpenAPI specification is a Kubernetes Kind, you can look at the x-kubernetes-group-version-kind field of the definition. If this field is defined, the definition is a kind, and it gives you the values of the apiVersion and kind fields.
Group-Version-Resource
The Kubernetes API is a REST API, and as a result of that it manages Resources, and the paths to manage these resources follow the REST naming conventions—that is, by using a plural name to identify a resource and by grouping these resources.
Because the Kubernetes API manages hundreds of resources, they are grouped together, and because the API evolves, the resources are versioned. For these reasons, each resource belongs to a given Group and Version, and each resource is uniquely identified by a Group-Version-Resource, commonly known as GVR.
To find the various resources in the Kubernetes API, you can browse the OpenAPI specification to extract the distinct paths. Legacy resources (e.g., pods or nodes) will have been introduced early in the Kubernetes API and all belong to the group core and the version v1.
The paths to manage legacy resources cluster-wide follow the format /api/v1/<plural_resource_name>—for example, /api/v1/nodes to manage nodes. Note that the core group is not represented in the path. To manage resources in a given namespace, the path format is /api/v1/namespaces/<namespace_name>/<plural_resource_name>—for example, /api/v1/namespaces/default/pods to manage pods in the default namespace.
Newer resources are accessible through paths following the format /apis/<group>/<version>/<plural_resource_name> or /apis/<group>/<version>/namespaces/<namespace_name>/<plural_resource_name>.
/api/v1/<plural_name> – to access legacy non-namespaced resources
Ex: /api/v1/nodes to access non-namespaced nodes resources
or
To access legacy namespaced resources cluster-wide
Ex: /api/v1/pods to access pods across all namespaces
/api/v1/namespaces/<ns>/<plural_name> – to access legacy namespaced resources in a specific namespace
Ex: /api/v1/namespaces/default/pods to access pods in the default namespace
/apis/<group>/<version>/<plural_name> – to access non-namespaced resources in specific group and version
Ex: /apis/storage.k8s.io/v1/storageclasses to access non-namespaced storageclasses (group storage.k8s.io, version v1)
or
To access namespaced resources cluster-wide
Ex: /apis/apps/v1/deployments to access deployments across all namespaces
/apis/<group>/<version>/namespaces/<ns>/<plural_name> – to access namespaced resources in a specific namespace
Ex: /apis/apps/v1/namespaces/default/deployments to access deployments (group apps, version v1) in the default namespace
Sub-resources
/api/v1/<plural>/<res-name>/<sub-resource>
Ex: /api/v1/nodes/node1/status
/api/v1/namespaces/<ns>/<plural>/<res-name>/<sub-resource>
Ex: /api/v1/namespaces/ns1/pods/pod1/status
/apis/<group>/<version>/<plural>/<res-name>/<sub-resource>
Ex: /apis/storage.k8s.io/v1/volumeattachments/volatt1/status
/apis/<grp>/<v>/namespaces/<ns>/<plural>/<name>/<sub-res>
Ex: /apis/apps/v1/namespaces/ns1/deployments/dep1/status
Most Kubernetes resources have a status sub-resource. You can see, when writing operators, that the operator needs to update the status sub-resource to be able to indicate the state of this resource observed by the operator. The operations that can be executed in the status sub-resource are get, patch, and update. The Pod has more sub-resources, including attach, binding, eviction, exec, log, portforward, and proxy. These sub-resources are useful for getting information about a specific running pod, or executing some specific operation on a running pod, and so on.
The resources that can Scale (i.e., deployments, replicasets, etc.) have a scale sub-resource. The operations that can be executed in the scale sub-resource are get, patch, and update.
Official API Reference Documentation
The official reference documentation of the API can be found at https://kubernetes.io/docs/reference/kubernetes-api/. The resources managed by the API are first grouped together by category (i.e., workloads, storage, etc.), and for each category, you can obtain a list of resource names with a short description (Figure 1-3).
The Deployment Documentation
The apiVersion indicated in the header can help you write a YAML manifest for a Deployment resource because you need to specify, for each resource in a Kubernetes manifest, the apiVersion and kind.
For example, the Deployment kind contains a spec field, of type DeploymentSpec, which is described later. Note that DeploymentSpec is not a structure directly exchanged during HTTP requests, and for that, it is not a kind and does not contain kind or apiVersion fields.
Following the principal kind, and its associated definitions, other kinds associated with the resource are displayed. In this case, the DeploymentList kind.
Operations Documentation
The {namespace} part of the path indicates a path parameter, which is to be replaced by the name of the namespace on which you want to create the deployment. You can specify the query parameters: dryRun, fieldManager, fieldValidation, and pretty. These parameters will follow the path with the format path?dryRun=All.
The body of the request must be a Deployment kind. When using kubectl, you are writing Kubernetes Manifests that contain this body. In Chapter 3, you will see how to build the body in Go. The possible HTTP codes for the responses are: 200, 201, 202, and 401; and for the 2xx codes, the response body will contain a Deployment kind.
The Pod Documentation
Some structures contain many fields. For them, the Kubernetes API documentation categorizes the fields. An example is the documentation of the Pod resource.
The documentation page for the Pod resource first contains the description for the principal kind, Pod, followed by the description of the PodSpec structure. The PodSpec structure contains about 40 fields. To help you understand the relationships between these fields and to simplify their exploration, they are arranged into categories. The PodSpec fields’ categories are the following: Containers, Volumes, Scheduling, Lifecycle, and so on.
Additionally, for fields containing nested fields, descriptions of them are generally displayed inline to avoid a back and forth between structure descriptions. For complex structures, however, the description is reported subsequently on the page, and a link is present next to the field name to be able to access it easily.
This is always the case for the Spec and Status structures because they are very commonly found in almost all the resources. In addition, this is the case for some structures used in the Pod kind—for example, Container, EphemeralContainer, LifecycleHandler, NodeAffinity, and so on.
You also can see that the fields, containers and initContainers, are of the same type as Container, which is described later on the page and is accessible with a link. The imagePullSecrets field is of type LocalObjectReference, which is described in the Common Definitions section and also is accessible through a link.
One-Page Version of the Documentation
Another version of the API Reference documentation exists and is presented on a single page. This version covers all the versions of the resources served by a Kubernretes version (not just the latest one). This version (if you want, change the last part of the path to navigate to another Kubernetes version) can be found at the following URL:
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.24/
Conclusion
In this chapter, you have been able to discover the architecture of the Kubernetes platform, and that the API Server plays a central role. The Kubernetes API is an HTTP REST API, and the resources are categorized into various versioned groups.
Kinds are specific structures used to exchange data between the API server and the clients. You can browse, using the official Kubernetes website, the API specifications in a human-readable form to discover the structure of the various resources and kinds, the different operations available for each resource and sub-resource, and their associated verbs.