Tuesday, November 5, 2024
HomeKubernetesLearn about Kubernetes Objects - Kubernetes Series

Learn about Kubernetes Objects – Kubernetes Series

If you are following Kubernetes series, you may understand more about Kubernetes and also, we have explained some scenarios, which explains the Kubernetes adoption. As mostly we are adding additional workloads to containers, a container orchestration system is required to automate most of the features/options. In that, Kubernetes, the leading open-source container orchestration system has gained more trust from various organizations.

As per the growth, it is important to understand about Kubernetes objects. If you are just started using Kubernetes, this article may help you to understand the basics.

What Are Kubernetes Objects?

Kubernetes objects are represented in JSON or YAML files and describe the state of your cluster. The state of the cluster defines what workloads should be running in it. You can create these objects, and then Kubernetes makes sure that your desired state is maintained. For example, if you create a deployment in Kubernetes, it makes sure it’s running even if the cluster restarts after a crash. That’s the beauty of Kubernetes.

There are two categories of objects in Kubernetes, which we’ll discuss more later on:

  1. basic objects: Pods, Service, Volumes, Namespace, etc., which are independent and don’t require other objects
  2. high-level objects (controllers): Deployments, Replication Controllers, ReplicaSets, StatefulSets, Jobs, etc., which are built on top of the basic objects

You can get to a desired state by creating an object and pushing it to the Kubernetes API with client-side tools like kubectl.

Object Spec and Status

In Kubernetes, object representation is stored in a manifest, as discussed above. Each kind of object has two specific properties:

  1. spec: This contains the details about the object. For example, for a pod, it would contain which container image it would run, the ports to expose, the labels, and more.
  2. status: This contains your object’s current state and is updated in real time by the Kubernetes control plane. If you delete your pod, the status changes to Terminating, and then the pod is no longer listed as it gets deleted. The status is automatically assigned to each object.

Required Fields

Each YAML configuration for an object contains a selected set of fields for it to be valid. These fields are called required fields, and they include the following:

  1. apiversion: This contains the instruction as to which version of the Kubernetes API should be used to create your object from the manifest.
  2. kind: As noted above, there are two categories of objects—basic and high-level objects. This field contains the details of the type of object; for example, if you want to create a pod in your cluster, the kind would be Pod.
  3. metadata: Metadata is defined as a set of data that gives information about other data. So this property defines parameters like name, UID, or namespace that would help you identify your object amid other objects of the same kind. You’ll read more about UID and namespace later in this article.
  4. spec: This, as discussed above, contains your object’s specifications. For example, it would contain what container image the pod would run, as well as what ports should be available for the object pod.

The manifest below contains all the required fields for a pod object for your reference in a YAML format:

apiVersion: v1
kind: Pod
metadata:
  name: demo
spec:
  containers:
  - name: demo
    image: demo/demo
    ports:
    - containerPort: 8080

Kubernetes Object Management

About we have described the objects, now let’s see how to manage it. Kubernetes objects can be managed either by imperative commands or declarative configuration. Using imperative commands with the kubectl command-line tool, you can create, update, and delete Kubernetes objects directly without needing any manifest. This is very helpful when you’re deploying specific objects like a pod.

Here’s an example of some imperative commands:

# kubectl run demo  --generator=run-pod/v1 --image=demo/demo
# kubectl create service nodeport <myservicename>
# kubectl delete pod pod-name

However, this should be used for testing or practice only, as this is not recommended for production use. In production we should use declarative way only, which will help to move towards GitOps also. Here are some examples of declarative commands:

# kubectl apply -f demo.yaml
# kubectl apply -f <directory>/
# kubectl apply -f https://k8s.io/examples/application/simple_deployment.yaml

Now let’s take a look at a few operations that you can perform with your objects:

Create Objects

Regardless of the type of object, Kubernetes objects can be created with the help of this basic syntax:

# kubectl apply -f object.yaml

Here, the -f flag stands for “file name,” and apply applies the configuration stated in your object.yaml to your cluster.

Edit Objects

Editing objects is as simple as using kubectl and running this command:

# kubectl edit <resource-name> <obj-name>

The above command opens the raw configuration of the object in YAML representation from the Kubernetes API and launches your $EDITOR on the file. You can edit your object configuration and then get a new desired state when you save the changes. For example, you can edit the number of replicas in a deployment without redeploying a manifest from scratch.

Furthermore, updating objects from your manifest is as simple as using the replace command with kubectl. If you have your manifest for the initial deployment, you can use the following:

# kubectl replace -f updatedObject.yaml

Delete Objects

Deleting objects is quite similar to editing them. You can use this command:

# kubectl delete <resource-name> <obj-name>

If you have the object manifest, you can also use the manifest to delete the resource using this command:

# kubectl delete -f object.yaml
# kubectl delete -f object1.yaml -f object2.yaml

You can use either of the above two commands as per your requirements, and kubectl will talk to the Kubernetes API to delete the objects specified.

Object Names and IDs

Kubernetes objects should follow a nomenclature and shouldn’t be duplicated in a
namespace. You don’t want something to be deleted when you don’t intend it to. Each object has two unique specifiers:

  1. Name: This is the unique name for your object, and it has some restrictions. You can read
    more about the specifications in this documentation.
  2. UID: UID is a unique, system-generated string standardized as SO/IEC 9834-8 and as ITU-T X.667 for the whole lifetime of the cluster. It helps you distinguish between historical occurrences of similar entities and simplifies logs. UIDs are more reliable than the name as there might be an object of the same name in the history of the cluster, but the UIDs would be distinct.

Using Namespaces

Namespaces help you to divide your resources into isolation groups for ease and efficient resource management with the help of resource quotas. Creating a new namespace for your resources is simple as using the following command:

# kubectl create namespace <your-namespace-name>

Regardless of how many namespaces you create, there will always be four initial namespaces present:

  1. default: where your resources you create would be deployed
  2. kube-system: where the objects created by the Kubernetes system would be stored
  3. kube-public: where the resources that should be visible and publicly readable should be stored
  4. kube-node-lease: where Node Lease objects are stored.

The namespace helps isolation, but there’s a limit to what objects it can isolate. For example, you can isolate your pods but not your nodes. You can have pods, deployments, service, and other objects in a namespace, but PersistentVolumes can’t be in any namespace. To see the full list, you can run this command:

Object in a namespace

 # kubectl api-resources --namespaced=true

Object not in a namespace

 # kubectl api-resources --namespaced=false

To deploy resources in a specific namespace, you can use the following:

# kubectl apply -f <object.yml> --namespace <your-namespace-name>

Not only do namespaces isolate your objects, but they are also hidden from each other until you configure DNS.

Labels and Selectors

Labels and selectors come in handy when you create a meaningful key-value relationship between your objects for segregation and across namespaces. Their beauty lies in the fact they allow for efficient queries and great organization.

In short, labels help you tag your pods, and selectors help you identify objects tagged with a label. Here, in metadata, we have two labels — environment and app:

apiVersion: v1
kind: Pod
metadata:
  name: demo
  labels:
    environment: dev
    app: demo
spec:
  containers:
    - name: demo
      image: demo
      ports:
        - containerPort: 80

You can have labels for your different environments like dev or testing, and they would help you manage the objects inside the labels together.

Annotations

Apart from labels and selectors, Kubernetes also offers annotations. Annotations are another type of metadata that can’t be used to select objects but are there for the sole purpose of providing additional context to you or your logs and act as pointers to your logging, monitoring, and analytics systems.

Annotations are mapped in a key-value format, like labels, though they don’t have nomenclature limitations. Annotations can be large, small, structured, or unstructured data as there are no restrictions.

apiVersion: v1
kind: Pod
metadata:
  name: annotations-demo
  annotations:
    imageregistry: "https://hub.docker.com/"
spec:
  containers:
  - name: demo
    image: demo
    ports:
    - containerPort: 80

In the above example from the Kubernetes Documentation, you can see how imageregistry is used as an annotation to tell the operator that we are pulling the image from Docker Hub and not some other repository. Annotations provide context for the human operator, and it becomes easier for the operator to find the image from a specific registry if required.

Field Selectors

Kubernetes field selectors can help you select objects based on one or more resource fields. Suppose you want to select all pods that are running in the default namespace. You’d use the following command to do so:

# kubectl get pods --field-selector status.phase=Running

Selecting all objects in a namespace can be achieved by using the -n flag, but what if you want to select all objects in the cluster except the namespace? Field selectors are what can help you:

# kubectl get pods --all-namespaces --field-selector metadata.namespace!=default

You can also use more than one field selector in your command for scenarios where you need a highly specific selection. A good example would be when you need to select all pods that are running and can restart.

Finalizers

Kubernetes has its own way of managing memory and resources so does its own Garbage Collection System. It is a systematic way to remove unused/unutilized space.  Programming Languages like Java/GO and the Servers built on them all have this process to ensure the memory is managed optimally.

kubernetes finalizer

Now, Kubernetes being the modern solution, It does manage its resources and perform Garbage collections when the resources are deleted and in various other contexts too.

Now let’s come back to our Kubectl delete and why we are talking about Garbage Collection now.

Kubernetes adds a special tag or annotation to the resource called Finalizers when it creates resources which have multiple dependencies. Here is the definition able Finalizers.

Finalizers are namespaced keys that tell kubernetes to wait until specific conditions are met before it fully deletes resources marked for deletion. finalizers alert controllers to clean up resources the deleted object owned.

Finalizers are the keys to tell Kubernetes API that, there are few resources to be deleted or taken care of before this particular resource is deleted.

For example. When you are trying to delete a Persistent Volume the associated persistent volume claim and the pods bound to it would be affected so you must follow the proper order.

Same way, when you are trying to delete an Ingress it might be associated with some infrastructure items like Load Balancers and Target Groups which needs to be deleted first before delete the ingress.

You can learn more about them here. You can also create your own finalizers to delete objects, which sometimes get stuck in a terminating state.

Owners and Dependents

Owners and dependents are a parent-child relationship present in Kubernetes. Take a look at the following deployment object manifest:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: demo
  name: demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: demo
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: demo
    spec:
      containers:
      - image: demo
        name: demo
        resources: {}

The deployment object has replicas and pods objects linked to it. Deployment is the owner of replicas and pods, and the pods/replicas are dependents of the deployment object.

If you delete the owner, the dependents get deleted too. So, the owner objects manage the dependents automatically, and any change in them translates to a change in the dependent. The relationship is managed by a metadata field called ownerReference.

Recommended Labels

Kubectl is not the only tool you can use to manage Kubernetes objects. There are dashboards, CLIs, and other tools that help you, and you can use one or a combination of them.

Recommended labels are a collection of labels that enable your tools to communicate with one another by describing items in a way that all of the tools can comprehend.

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: psql
    app.kubernetes.io/instance: psql-prod
    app.kubernetes.io/version: "13"
    app.kubernetes.io/managed-by: sonarqube
    app.kubernetes.io/component: sonarqube
    app.kubernetes.io/part-of: sonarqube

In the above example, you can see how we have added metadata labels that help to identify the required instance from our dashboard. You can select them and find all the objects related to your label.

In a production Kubernetes cluster, where thousands of objects are running, you need to manage them efficiently. Recommended labels are a suggestion from Kubernetes for efficiently standardizing the management of your objects.

Learn more about the recommendations here.

RELATED ARTICLES
- Advertisment -

Most Popular

Recent Comments