Photo by Growtika / Unsplash

Understanding the Kubernetes API Objects and How They Work

Ehis Iribhogbe
Ehis Iribhogbe

Table of Contents

Kubernetes is an open-source container orchestration platform that allows developers to automate containerized applications' deployment, scaling, and management. One of the key features of Kubernetes is its API, which provides a uniform way to interact with the platform and perform tasks such as deploying and managing applications, monitoring the status of the cluster, and updating configuration settings.

This article will teach you about the Kubernetes API and its various objects, such as Pod, Service, Controller, Deployment, and Storage. You will also learn what each object does and see examples that will help you understand their functionality.

What is the Kubernetes API?

The Kubernetes API (Application Programming Interface) is a set of rules and protocols that allows developers to interact with a Kubernetes cluster. The Kubernetes API server exposes the Kubernetes API. The API server is the primary interface for managing and orchestrating containerized applications within a Kubernetes environment.

The Kubernetes API provides a way to perform various operations, such as creating and managing pods, services, deployments, replica sets, namespaces, and other Kubernetes resources. The API is designed to be RESTful and runs over HTTP and HTTPS using JSON.

The Kubernetes API consists of a set of basic API objects that represent the system’s current state. These API objects enable the configuration of the system’s state, which can be done either declaratively or imperatively. Declarative configuration involves describing the desired implementation, such as specifying the deployment and how we want the system to appear. On the other hand, imperative configuration involves executing a sequence of commands on the command line to achieve the desired system state.

Some of the Kubernetes API Objects

In this section, you will explore some of the essential Kubernetes API objects and their functionalities. Understanding these objects is crucial for effectively harnessing the power of Kubernetes and maximizing the efficiency of your containerized infrastructure. Let's dive in and discover the key Kubernetes API objects that form the backbone of this powerful platform.

Pods

“Pods are the smallest deployable units of computing that you can create and manage in Kubernetes” — The Kubernetes documentation. To create a Pod, create a manifest (YAML or JSON) file with a specification. The specification will contain the Pod name and the Pod's container(s) image. When you apply the manifest, Kubernetes schedules the Pod on a worker node in the cluster.

Below is an example YAML manifest that defines a Pod object:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    env: dev
spec:
  containers:
    - name: nginx
      image: nginx

The above YAML file describes a Kubernetes Pod running a single container of the nginx image. Let's break down the different fields:

  • apiVersion: v1: This specifies the Kubernetes API version used for this Pod, in this case, v1.
  • kind: Pod: This specifies the type of Kubernetes resource being described, in this case, a Pod.
  • metadata: This section contains metadata about the Pod, such as its name and labels.
  • name: nginx-pod: This is the name of the Pod.
  • labels: This is a set of key-value pairs that can be used to identify and group related resources. In this case, the label env: dev is applied to the Pod.
  • spec: This section describes the specification for the Pod.
  • containers: This is an array of containers to be run in the Pod. In this case, there is a single container.
  • name: nginx: This is the name of the container.
  • image: nginx: This specifies the Docker image to use for the container. In this case, it will use the official nginx image from Docker Hub.

Pods are considered ephemeral, meaning they are not redeployed if they die. For instance, if we deploy an application as a Pod based on a container image and that Pod dies, Kubernetes will automatically deploy another pod based on the same container image. There is no state maintained between these two pods, and they are considered independent of each other.

Pods are also considered atomic, meaning they either exist or do not exist. For example, in a single container Pod, if the application running inside that Pod dies, the Pod also dies. Similarly, in a multi-container Pod where multiple applications run, the entire Pod becomes unavailable if one of those applications dies. Therefore, having only one container-based application inside a Pod is recommended to avoid any unwanted dependencies between applications.

Note: When deploying and managing applications in Kubernetes, it is recommended you use the Deployment object rather than "naked" Pods (Pods that are not managed by a higher-level resource, such as a Deployment). You will learn about Deployment later in this article.

Controllers

Controllers are responsible for defining and maintaining the desired state of a cluster. The controller managers ensure that the system remains in the desired state. For controllers to define and manage the desired state of deployed applications, they monitor and respond to the state and health of the Pods, ensuring that the desired number of pods are up and running and healthy. If the state or health changes, the controller will respond accordingly, ensuring the system stays in the desired state.

Kubernetes utilizes controller managers to monitor the state of a pod and ensure that it remains operational. There are different types of controller managers, the following are some of them:

  • ReplicaSet Controller Manager: It allows you to define the number of replicas for a particular Pod you want up and running at all times. Suppose one of those Pods becomes unhealthy and unavailable for any reason. In that case, it's the job of the ReplicaSet controller to delete that unhealthy Pod and deploy a new Pod to return the system to its desired healthy state.
  • Deployment set Controller Manager: When deploying applications in Kubernetes, you do not create ReplicaSet(s) directly. Instead, you create a deployment, which then creates a ReplicaSet based on what is specified in the Deployment manifest file. The Deployment manages the state of the replica set, such as the number of Pods to create and which container image to run. Additionally, the Deployment set manages the transition between two ReplicaSets, such as when updating an application with new changes or transitioning from one version of an application to another.

To learn about other Controllers, check out this Kubernetes documentation on controllers.

Services

Services in Kubernetes provide a persistent access point to the applications deployed as Pods. They add persistence to the ephemeral nature of Pods. A Service is an abstraction that defines a set of Pods and a policy for accessing them. It offers reliable and stable network connections to the Pods, allowing you to expose your application to the outside world or other parts of your cluster.

Services can automatically distribute incoming traffic among the Pods in a Deployment, providing load-balancing features and allowing you to scale your application as needed.

There are different types of Services in Kubernetes, each with its own set of features and use cases. Some of the most common types are:

  • ClusterIP: This is a type of service that exposes the pods within the cluster only. It creates a virtual IP address that is accessible only within the cluster.
  • NodePort: This type of service exposes the pods to the network by opening a port on each node in the cluster. The port can be used to access the service from outside the cluster.
  • LoadBalancer: This service is similar to NodePort but also creates an external load balancer to distribute incoming traffic to the pods. LoadBalancers are typically used in cloud-hosted clusters where the cloud provider can create and manage the load balancer for you.

The following is a YAML manifest defines a NodePort service:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30008
  selector:
    env: dev

The above YAML file describes a NodePort Service that will expose the Pod running the nginx image on port 80. Let's break down the different fields:

  • apiVersion: v1: This specifies the Kubernetes API version used for this Service, in this case, v1.
  • kind: Service: This specifies the type of Kubernetes resource being described, in this case a Service.
  • metadata: This section contains metadata about the Service, such as its name.
  • name: nginx-service: This is the name of the Service.
  • spec: This section describes the specification for the Service.
  • type: NodePort: This specifies the type of the Service, in this case NodePort. This type exposes the Service on a static port on each Node in the cluster.
  • ports: This is an array of ports to be exposed by the Service.
  • port: 80: This is the port number on which the Service will listen.
  • targetPort: 80: This is the port number of the Pod to which the traffic will be forwarded.
  • nodePort: 30008: This is the static port number on each Node in the cluster on which the Service will be exposed.
  • selector: This is a set of key-value pairs that will be used to match the Service to the Pod to which it will forward traffic.
  • env: dev: This specifies the label to use for matching the Service to the Pod. In this case, the Service will match any Pod with the label env: dev.

In Kubernetes clusters, services provide network connectivity, load balancing, and service discovery for your applications. They help you build scalable and highly available applications that can run on a cluster of machines.

Storage

In Kubernetes, there are storage options that provide persistent storage for your applications. Storage refers to the different storage solutions used to store data for our applications. These storage solutions can be local to a single node or distributed across multiple nodes. They can be used to store application data, configuration data, or log data.

In Kubernetes, Persistent Volume (PV), Persistent Volume Claim (PVC), and StorageClass are Kubernetes resources used for managing storage in a cluster.

  • Persistent Volume (PV) is a Kubernetes resource that represents a piece of storage that can be dynamically provisioned when a claim for storage is made, or they can be manually created and managed by an administrator.

Below is a yaml template that defines a PV object.

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  accessModes:
  - ReadWriteOnce
  capacity:
    storage: 500Mi  

The above YAML manifest describes a Kubernetes PV that can be used to store data persistently in the cluster. Let's break down the different fields:

  • apiVersion: v1: This specifies the Kubernetes API version used for this PV, in this case v1.
  • kind: PersistentVolume: This specifies the type of Kubernetes resource being described, in this case a Persistent Volume.
  • metadata: This section contains metadata about the PV, such as its name.
  • name: my-pv: This is the name of the PV.
  • spec: This section describes the specification for the PV.
  • accessModes: This is an array of access modes that the PV supports.
  • - ReadWriteOnce: This access mode specifies that the PV can be mounted as read-write by a single node.
  • capacity: This section specifies the capacity of the PV.
  • storage: 500Mi: This specifies the storage capacity of the PV, in this case 500MiB.

The YAML file describes a Persistent Volume that can be used to store data persistently in the cluster, with a storage capacity of 500MiB, and can be mounted by a single node as read-write. However, this PV is not bound to any specific Persistent Volume Claim (PVC) yet. To make it usable by a specific application, a matching PVC should be created that requests storage with the same access mode and capacity as the PV. Then, the PV should be bound to the PVC to make it available for use by the application.

  • Persistent Volume Claims (PVCs) in Kubernetes are requests made by pods in your cluster for storage. When a PVC is created, it will bind to a Persistent Volume (PV) and make the storage available to the pod. In other words, a PVC is a way for pods to request a specific amount of storage without having to know the underlying details of where that storage is coming from.

Below is a YAML template that defines a PVC object :

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-claim
spec:
  accessModes:
  - ReadWriteOnce
  storageClassName: google-storage
  resources:
    requests:
      storage: 300Mi

This is a YAML file that describes a Kubernetes Persistent Volume Claim (PVC) that requests storage from a Persistent Volume (PV) with certain characteristics. Let's break down the different fields:

  • apiVersion: v1: This specifies the Kubernetes API version used for this PVC, in this case v1.
  • kind: PersistentVolumeClaim: This specifies the type of Kubernetes resource being described, in this case a Persistent Volume Claim.
  • metadata: This section contains metadata about the PVC, such as its name.
  • name: my-claim: This is the name of the PVC.
  • spec: This section describes the specification for the PVC.
  • accessModes: This is an array of access modes that the PVC requires.
  • - ReadWriteOnce: This access mode specifies that the PVC requires read-write access to the storage.
  • storageClassName: google-storage: This specifies the name of the StorageClass to use for creating the PV. The StorageClass provides a way to specify the underlying storage provider and its characteristics.
  • resources: This section specifies the resource requirements for the PVC.
  • requests: This section specifies the minimum amount of storage that the PVC requires.
  • storage: 300Mi: This specifies the minimum amount of storage capacity that the PVC requires, in this case 300MiB.

The YAML file describes a Persistent Volume Claim that requests 300MiB of storage with read-write access from a PV with a StorageClass of google-storage. If a PV with matching characteristics is available in the cluster, the PVC will bind to it and make it available for use by the application. If a suitable PV is not available, a new PV will be dynamically provisioned according to the StorageClass definition.

  • Storage Classes are ****used to define the type of storage that will be dynamically provisioned when a Persistent Volume Claim (PVC) is created. A Storage Class defines a set of parameters for dynamic provisioning of Persistent Volumes. These parameters can include the type of storage (e.g. block or file), the performance characteristics (e.g. SSD or HDD), and the location of the storage (e.g. on-premises or in the cloud). When a PVC is created and the StorageClass is specified, the Kubernetes cluster will automatically provision a Persistent Volume that meets the criteria defined in the Storage Class.

Below is a yaml template that defines a StorageClass object :

apiVersion: storage,k8s.io/v1
kind: StorageClass
metadata:
  name: my-google-storage
provisioner: Kubernetes.io/gce-pd 
parameters:
  type: pd-standard
  replication-type: none

This is a YAML file that describes a Kubernetes StorageClass resource, which is used to define different classes of storage with specific characteristics. StorageClasses allow users to request storage resources without having to know the underlying details of the storage infrastructure.

Let's break down the different fields:

  • apiVersion: storage.k8s.io/v1: This specifies the Kubernetes API version used for this StorageClass, in this case storage.k8s.io/v1.
  • kind: StorageClass: This specifies the type of Kubernetes resource being described, in this case a StorageClass.
  • metadata: This section contains metadata about the StorageClass, such as its name.
  • name: my-google-storage: This is the name of the StorageClass.
  • provisioner: Kubernetes.io/gce-pd: This specifies the name of the storage provider that will be used to provision the underlying storage resources. In this case, it's using the GCE-PD provisioner, which provisions Google Compute Engine persistent disks.
  • parameters: This section specifies additional parameters for the storage provider.
  • type: pd-standard:This parameter specifies the type of disk to use for the persistent disk, in this case pd-standard.
  • replication-type: none: This parameter specifies that replication is not required for this storage class.

The YAML file describes a StorageClass named my-google-storage that uses the GCE-PD provisioner to dynamically provision persistent disks of type pd-standard without replication. This StorageClass can be used to dynamically provision Persistent Volumes when requested by Persistent Volume Claims that request the same StorageClass.

Kubernetes storage allows your applications to store data persistently, even if the pods or containers that use the data are deleted or recreated. It also enables you to manage the various types of storage available in your cluster and provision new storage dynamically as required. By using Kubernetes storage, you can ensure that your data is safe and available whenever your application needs it.

Deployment

A Deployment manages a ReplicaSet, which in turn manages the deployment and scaling of a set of Pods. By using a Deployment object, you can define a desired state for the ReplicaSet, such as the number of replicas to be created, the container images to be used, and the configuration options to be set. The Deployment object then ensures that the desired state is achieved by updating or rolling back the ReplicaSet as necessary.
Deployments enable you to perform rolling updates and rollbacks, which are done by creating a new ReplicaSet and slowly replacing the old Pods with the new ones. This ensures that there is no downtime and that the new version of the application is rolled out gradually.

The following YAML template defines a deployment object:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app-container
          image: my-app-image:latest
          ports:
            - containerPort: 8080
          volumeMounts:
            - name: my-app-pvc
              mountPath: /data
      volumes:
        - name: my-app-pvc
          persistentVolumeClaim:
            claimName: my-pvc

The above YAML file describes a Kubernetes Deployment resource, which is used to manage the lifecycle of a set of replicated Pods. This Deployment creates and manages a set of replicas of a containerized application, as well as the associated resources such as a Persistent Volume Claim and a Volume to store the application's data. Let's break down the different fields:

  • apiVersion: apps/v1: This specifies the Kubernetes API version used for this Deployment, in this case apps/v1.
  • kind: Deployment: This specifies the type of Kubernetes resource being described, in this case a Deployment.
  • metadata: This section contains metadata about the Deployment, such as its name.
  • name: my-app-deployment: This is the name of the Deployment.
  • spec: This section describes the specification for the Deployment.
  • replicas: 3: This specifies the number of replicas of the application to create.
  • selector: This specifies the labels used to select the Pods managed by the Deployment.
  • matchLabels: This specifies the labels used to match the Pods managed by the Deployment.
  • app: my-app: This label selects the Pods that have the label app set to my-app.
  • template: This specifies the Pod template used to create the replicas.
  • metadata: This section contains metadata about the Pod template.
  • labels: This specifies the labels used to select the Pods created from the template.
  • app: my-app: This label is applied to the Pods created from the template.
  • spec: This section specifies the specification for the Pod template.
  • containers: This specifies the containers to be run in the Pod.
  • name: my-app-container: This specifies the name of the container.
  • image: my-app-image:latest: This specifies the Docker image to use for the container, with a tag of latest.
  • ports: This specifies the ports to be exposed by the container.
  • containerPort: 8080: This specifies that the container will listen on port 8080.
  • volumeMounts: This specifies the volumes to be mounted by the container.
  • name: my-app-pvc: This specifies the name of the volume to be mounted.
  • mountPath: /data: This specifies the mount path for the volume in the container.
  • volumes: This specifies the volumes to be created for the Pod.
  • name: my-app-pvc: This specifies the name of the volume.
  • persistentVolumeClaim: This specifies that the volume is backed by a Persistent Volume Claim.
  • claimName: my-pvc: This specifies the name of the Persistent Volume Claim that the volume is backed by.

The YAML file describes a Deployment named my-app-deployment that manages three replicas of an application containerized in my-app-image:latest. The Pods created by the Deployment have a volume named my-app-pvc mounted at /data, which is backed by a Persistent Volume Claim named my-pvc.

Conclusion

In this article, you learned about the Kubernetes API and some of its various objects. There are other API objects in Kubernetes that can be used to define the desired state of a cluster. To learn more about them, check out the Kubernetes documentation.

Kubernetes

Ehis Iribhogbe Twitter

An experienced software engineer and technical writer. My expertise includes developing, maintaining, and deploying software applications that effectively address real-world problems.