Kubernetes object and definition files

Apr 11, 2023ยท

18 min read

Play this article

Kubernetes Objects are the basic building blocks of any Kubernetes application deployment. They are API resources that represent the state of your cluster. There are several built-in Kubernetes objects, some of which are:

  • Pods: They are the smallest and the simplest Kubernetes Objects that represent a single instance of a running process within the cluster.

  • Services: They provide a stable IP or DNS name to a set of pods, enabling you to access them easily.

  • Deployments: They allow you to define and manage a set of identical pods, ensuring that the desired number of replicas are always running.

  • ConfigMaps: They provide a way to decouple configuration from container images, enabling your applications to be more portable.

  • Secrets: They provide a secure way to store and manage sensitive information such as database passwords, API keys, or TLS certificates.

  • StatefulSets: They represent a set of pods that have a stable hostname and stable network identity, enabling stateful applications to be run on Kubernetes.

These objects can be defined using YAML or JSON configuration files and are managed using the Kubernetes API or command-line tools such as kubectl.

Pods

In Kubernetes, a Pod is the smallest and simplest unit of deployment. It is a logical host for a single container or multiple tightly coupled containers that share the same resources, such as storage and network. A Pod represents a single instance of a running process in a cluster.

Each Pod is allocated its own IP address and can communicate with other Pods in the same cluster using that IP address. Within a Pod, containers share the same network namespace, which means they can communicate using localhost or 127.0.0.1. Containers within a Pod also share the same storage volumes, allowing them to share data easily.

Pods are designed to be ephemeral and disposable. They can be easily created, replicated, and destroyed as needed. They can be created manually using YAML or JSON specification files, or they can be created automatically by a deployment or replication controller.

Overall, Pods provide a simple and powerful way to manage containers within a cluster, making it easier to develop, deploy, and scale containerized applications.

Pod life cycle

A Pod has a lifecycle that goes through several phases, from pending, running, succeeded, failed, to unknown. These phases indicate the current state of the Pod and what is happening to it at any given moment.

Here is a brief explanation of each phase in a Pod's lifecycle:

  1. Pending: this is the initial phase when the Pod is created and the Kubernetes scheduler is looking for available nodes to run the Pod. During this phase, Kubernetes allocates resources for the Pod, such as CPU and memory, and it pulls the required container images.

  2. Running: this phase indicates that the Pod has been scheduled to a node and has started running its containers. At this stage, the container(s) within the Pod are considered "live" and running their intended functionality.

  3. Succeeded: this phase indicates that all the containers in the Pod have exited successfully and no further action is required from the Pod. In other words, the purpose of the Pod has been fulfilled, and it can now be deleted.

  4. Failed: this phase indicates that all containers in the Pod have exited unsuccessfully or with an error, and have not been able to recover. This may require investigation to diagnose and resolve the underlying cause of the failure.

  5. Unknown: this is the phase where the state of the Pod cannot be determined by the Kubernetes control plane, for example, when there is a connection issue between the control plane and the node the Pod is running on.

These lifecycle phases help provide visibility into a Pod's state, making it easier to diagnose and resolve issues. Additionally, Kubernetes provides several mechanisms for automating Pod lifecycle management, such as deployments and replication controllers, to help manage the overall state of a cluster's Pods.

pod definition file

Here's an example of a YAML definition file for a simple Pod that runs a container:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: my-app
spec:
  containers:
  - name: my-container
    image: nginx:1.19
    ports:
    - containerPort: 80

Copy

Let's break down the above YAML file:

  • apiVersion: This specifies the Kubernetes API version to use. In this case, we are using version v1.

  • kind: This specifies the type of object we are creating. In this case, we are creating a Pod.

  • metadata: This section provides metadata about the Pod, such as its name and labels.

  • name: This specifies the name of the Pod.

  • labels: This provides labels for the Pod. Labels are key-value pairs that can be used to select and filter resources. In this case, we are setting the app label to my-app.

  • spec: This section defines the desired state of the Pod.

  • containers: This defines the container(s) to be run as part of the Pod.

  • name: This specifies the name of the container.

  • image: This specifies the Docker image to use for the container.

  • ports: This specifies the network ports to expose on the container.

  • containerPort: This is the port number of the container to expose. In this case, we are exposing port 80 of the Nginx container.

Once you have created this YAML file, you can create the Pod by running the following command:

kubectl apply -f pod-definition.yaml

Labels for kubernetes object

Kubernetes labels are key-value pairs that are used to organize and select resources. Labels are attached to resources like Pods, ReplicaSets, Services, or Deployments as metadata, and can be used to select subsets of resources based on specific criteria.

Labels are essential to Kubernetes, as they are frequently used by other Kubernetes objects to find, organize, and manage resources. For example, a ReplicaSet uses labels to identify the Pods it is responsible for, and a Service uses labels to select the Pods that it directs traffic to.

Here's an example of using labels to select resources:

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: my-app
    environment: production
spec:
  containers:
  - name: my-container
    image: my-image:latest
    ports:
    - containerPort: 80

In this example, the Pod has two labels with key-value pairs, app: my-app and environment: production. These labels can be used to select this Pod with a label selector.

For example, this label selector will select all Pods with the app: my-app label:

apiVersion: v1
kind: Pod
metadata:
  name: my-selector
spec:
  containers:
  - name: my-container
    image: my-image:latest
  selector:
    matchLabels:
      app: my-app

By using labels, Kubernetes makes it easy to group, organize, and manage resources in a dynamic and flexible way.

commands to get a specific label pod

To get a specific label pod in Kubernetes, you can use the kubectl get command with the --selector flag followed by a label selector. Here is an example command that will display all pods that have the label app=my-app:

kubectl get pods --selector=app=my-app

This command will return a list of all pods that have the label app=my-app. If you want to view more details about a specific pod, you can use kubectl describe followed by the pod name. Here is an example command that will display detailed information about a pod with the name my-pod:

kubectl describe pod my-pod

You can also use the --show-labels flag to display the labels for each pod:

kubectl get pods --show-labels

This will return a list of all pods with their associated labels. You can then filter the output using a tool like grep to search for specific labels.

Replicaset

In Kubernetes, ReplicaSets are responsible for ensuring that a specified number of replicas of a Pod are running at any given time. A ReplicaSet is an API object that defines a desired number of replicas for a set of Pods.

ReplicaSets are used to provide high availability for applications by ensuring that a specified number of replicas of a Pod are running at any given time. If a Pod fails or is deleted, the ReplicaSet automatically replaces it with a new Pod.

ReplicaSets use labels to select the Pods that they manage. When you create a ReplicaSet, you specify a label selector that identifies the Pods that the ReplicaSet should manage. The ReplicaSet ensures that the specified number of replicas of these Pods are running at all times.

ReplicaSets are similar to ReplicationControllers, but they provide more advanced selection mechanisms and can be used with more powerful labels. In general, you should use ReplicaSets instead of ReplicationControllers, unless you have a specific reason to use a ReplicationController.

Here's an example of a ReplicaSet definition file in YAML format:

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: my-image:latest
        ports:
        - containerPort: 80

In this example, the ReplicaSet is named my-app and is defined to have 3 replicas. The selector is used to select the Pods that the ReplicaSet should manage. In this case, it selects Pods with the label app: my-app.

The template section is used to define the Pod template that will be used to create the Pods. In this example, the Pod template includes a container with the name my-app and the image my-image:latest, which listens on port 80.

When this ReplicaSet is created or updated, it will ensure that there are always 3 replicas of the my-app Pods running, each with the app: my-app label. If a Pod fails or is deleted, the ReplicaSet will automatically create a replacement Pod to maintain the desired number of replicas.

Namespace

namespace is a way to divide cluster resources between multiple users, teams, or projects. It provides a scope for names, such as pod names, service names, and resource names. Kubernetes resources are assigned to a specific namespace when they are created, allowing different users or teams to use the same resource name in different namespaces.

When you create a Kubernetes cluster, it has a single namespace called default. You can create additional namespaces to group and manage your resources. For example, you may have multiple teams or projects using the same cluster, each with their own set of resources. By creating a namespace for each team or project, you can isolate their resources from each other and apply different access controls and resource quotas for each namespace.

Types of namespace

There are four types of namespace in Kubernetes:

  1. Default Namespace: This is the default namespace created when Kubernetes is installed. All objects that are created in the cluster without a specified namespace get created in the default namespace.

  2. System Namespace: This namespace is intended for objects that are created by the Kubernetes system. Examples of objects that are created in this namespace include kube-system, kube-public, and kube-node-lease.

  3. User Namespace: This namespace is intended for objects that are created by users. The user namespace is created by administrators, and users have permissions to create objects in this namespace.

  4. Custom Namespace: This namespace is created by users for their own project or application.

To create a namespace, you can use the kubectl create namespace command:

kubectl create namespace my-namespace

You can also specify the namespace for a particular resource by setting the metadata.namespace field in its YAML manifest. For example, to create a deployment in a specific namespace, you would add the following to the deployment YAML:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
  namespace: my-namespace
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx
        ports:
        - containerPort: 80

In this example, we are creating a deployment named my-deployment in the my-namespace namespace, which will run three replicas of a container running the nginx image.

Namespaces are a powerful feature of Kubernetes that enable better organization and isolation of resources in a cluster.

Deployment

Deployment is an object that manages a set of identical pods. It allows you to define a desired state for your application and then deploy and maintain that state in a declarative manner.

A Deployment creates a ReplicaSet, which is responsible for maintaining a specified number of replicas of the pod template. The pod template in the Deployment specifies the container image, resources, and other configuration for each pod. If a pod fails or is terminated for any reason, the ReplicaSet will ensure that a replacement pod is created to maintain the desired number of replicas.

Deployments support rolling updates and rollbacks, which allow you to update or roll back your application to a previous version without downtime. You can also perform rolling updates to deploy new versions of your application without downtime, by gradually replacing older pods with new ones.

In Kubernetes, there are different types of deploy strategies that can be used based on the requirements of your application. These strategies determine how a new version of your application is deployed and how it's rolled back in case of failures. Here are some common deployment strategies:

  1. Recreate Deployment: In this strategy, the entire set of pods is terminated and new ones are created with the updated configuration. This causes downtime during the deployment process, but it's a simple and quick way to update your application.

  2. Rolling Update Deployment: In this strategy, a set number of pods are updated at a time, in a gradual and controlled manner. The old pods are replaced with new ones until all pods are updated. This ensures that there's no downtime during the deployment process and that any issues can be detected early.

  3. Blue/Green Deployment: In this strategy, two identical environments are set up for the same application, with one environment (blue) running the current version and the other (green) running the new version. Traffic is then routed to the green environment after it has been tested and validated. If any issues are detected, traffic can be redirected back to the blue environment.

To create a Deployment in Kubernetes, you need to define a YAML file that describes the desired state of your application. Here's an example YAML file for a simple Deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: my-image:latest
        ports:
        - containerPort: 80

In this example, the Deployment will create three replicas of a pod template that runs a container called my-container with the image my-image:latest. The pod will listen on port 80, and the Deployment will use the app: my-app label selector to identify and manage the pods.

use below link for more detail about deployment

kubernetes deployment doc link

Services

In Kubernetes, a Service is an abstract way to expose a set of pods running in your cluster as a network service. Services enable network connectivity to a specific set of pods, regardless of their physical location within the cluster. Services act as "load balancers" to route incoming network traffic to the healthy pods that are part of a defined set of pods called a "Selector".

Here are some important points about services in Kubernetes:

  • Services can be of different types: ClusterIP(default), NodePort, LoadBalancer, ExternalName. It determines how the service is exposed to the network.

  • ClusterIP is the most common type of service, which exposes the service on a cluster-internal IP only. The service can be accessed only within the Kubernetes cluster.

  • NodePort type exposes the service at a specific port on the worker nodes' IP addresses, which is useful when you want to expose the service on a specific port number.

  • LoadBalancer type creates an external load balancer provisioned by a cloud provider, which is useful when you want to expose the service to the outside network.

  • Services are accessed using the Service name and port number combination. Kubernetes DNS service resolves the service name to its corresponding IP address.

To create a service in Kubernetes, you need to define a manifest file that describes the service's properties, including its selector and port mappings. Here is an example manifest file for creating a ClusterIP type service for an application called "myapp" running on port 8080:

apiVersion: v1
kind: Service
metadata:
  name: myapp-svc
spec:
  selector:
    app: myapp
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 8080

This manifest creates a service named "myapp-svc" that selects all the pods with the label "app: myapp" and exposes them on port 80 within the cluster. Incoming traffic on this port is redirected to the port 8080 of the selected pods.

K8s Resource quota

In Kubernetes, a resource quota is a feature that allows you to limit the overall resource consumption of a namespace. Resource quotas help you prevent unexpected overspending of resources and can help in overall cluster resource management.

Resource quotas can be set on a per-namespace basis within a Kubernetes cluster, and can limit the following resources:

  • Compute resources: CPU and memory.

  • Object count: a limit on the number of objects within a namespace.

Here's an example Kubernetes manifest file for setting a resource quota for a namespace.

apiVersion: v1
kind: ResourceQuota
metadata:
  name: my-quota
spec:
  hard:
    cpu: "2"
    memory: 1Gi
    pods: "10"
    services: "5"
    replicationcontrollers: "3"

In this example, the resource quota named "my-quota" has been set with the following limits:

  • The namespace can create up to 10 pods.

  • The total amount of memory used by all pods cannot exceed 1 GB.

  • The namespace can create up to 5 services.

  • The namespace can store no more than 3 replication controllers.

To check the resource quota values of a namespace, you can use the kubectl describe quota command. Here's an example:

$ kubectl describe quota my-quota --namespace=my-namespace
Name:       my-quota
Namespace:  my-namespace
Resource    Used     Hard
--------    ----     ----
cpu         500m     2
memory      256Mi    1Gi
pods        5        10
services    2        5
replicationcontrollers   2        3

The output of the kubectl describe quota command shows the current usage (in the Used column) and the limit (in the Hard column) for each resource type specified in the resource quota. This can help you identify if there are any resources that are close to hitting their quota limits and need to be managed accordingly.

Pod resources with cpu and memory limits

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: my-image:latest
    resources:
      limits:
        cpu: "1"
        memory: "256Mi"
      requests:
        cpu: "500m"
        memory: "128Mi"

In the spec section of the yaml file, you can see the containers field, which specifies the container(s) running in the pod. In this example, there is only one container named my-container, which uses the my-image:latest container image.

The resources field is where you can specify the CPU and memory limits and requests for the container. The limits field specifies the maximum amount of CPU and memory that the container is allowed to use. In this example, the container is limited to 1 CPU and 256Mi of memory.

The requests field specifies the minimum amount of CPU and memory that the container needs. In this example, the container requests at least 500m of CPU and 128Mi of memory.

Note that the values for CPU and memory limits and requests are specified as strings with a unit of measurement (e.g. "500m" for 500 milliCPUs), and that the resource units are standardized across Kubernetes.

K8s Daemonset

In Kubernetes, a DaemonSet is a type of workload controller that ensures that a copy of a specific pod runs on each node within a cluster. It is ideal for situations where you need a single instance of a pod to be scheduled on every node, such as logging agents, monitoring agents, or networking proxies.

A DaemonSet guarantees that a pod is created and scheduled on every node in the cluster, including new nodes that are added later. When a new node joins the cluster, the DaemonSet controller automatically creates and schedules a pod on the new node.

Here is an example YAML manifest for creating a DaemonSet in Kubernetes:

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: my-daemonset
spec:
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx:latest

Let's break down the components of this DaemonSet manifest:

  • metadata: This section specifies metadata about the DaemonSet, including its name.

  • spec: The spec section defines the desired state of the DaemonSet.

    • selector: The selector field specifies the labels used to identify the nodes where the pods should be scheduled. In this example, pods with the label app: my-app will be targeted.

    • template: The template field defines the template for the pods that the DaemonSet should create.

      • metadata: The metadata section within the template specifies labels for the pods.

      • spec: The spec section within the template defines the pod specification, including containers.

        • containers: The containers field lists the containers to be included in the pod. In this example, there is a single container named my-container using the nginx:latest image.

To create the DaemonSet, save the above YAML manifest to a file (e.g., daemonset.yaml) and apply it using the kubectl apply command:

kubectl apply -f daemonset.yaml

Kubernetes will create a pod for each node in the cluster, ensuring that the specified container (nginx:latest in this case) runs on every node.

K8s HPA

In Kubernetes, Horizontal Pod Autoscaler (HPA) is a resource that automatically adjusts the number of replica pods in a Deployment, ReplicaSet, or StatefulSet based on observed CPU utilization or custom metrics. It helps to ensure that your applications have the appropriate amount of resources to handle varying traffic loads.

The HPA controller continuously monitors the CPU utilization or custom metrics of the target workload and calculates the desired number of replicas based on the defined metrics and target utilization.

To create an HPA in Kubernetes, you need to have the metrics server running in your cluster. The metrics server collects resource usage data from the cluster's nodes and provides the data required for the HPA to make scaling decisions.

Here's an example YAML manifest for creating an HPA for a Deployment:

apiVersion: autoscaling/v2beta
kind: HorizontalPodAutoscaler
metadata:
  name: my-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-deployment
  minReplicas: 2
  maxReplicas: 5
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50

Let's go through the components of this HPA manifest:

  • metadata: This section specifies metadata about the HPA, including its name.

  • spec: The spec section defines the behavior and metrics of the HPA.

    • scaleTargetRef: The scaleTargetRef field specifies the target workload to scale. In this example, it targets a Deployment named my-deployment.

    • minReplicas and maxReplicas: These fields define the minimum and maximum number of replicas the HPA can scale.

    • metrics: The metrics field specifies the metrics used for autoscaling. In this case, it uses resource-based metrics, specifically CPU utilization.

      • type: Resource indicates that resource-based metrics are used.

      • resource specifies the resource metric being utilized, in this case, CPU.

      • target specifies the target utilization of the resource metric. In this example, the target CPU utilization is set to an average of 50%.

To create the HPA, save the YAML manifest to a file (e.g., hpa.yaml) and apply it using the kubectl apply command:

shellCopy codekubectl apply -f hpa.yaml

The HPA controller will then monitor the CPU utilization of the target Deployment and adjust the number of replicas accordingly to maintain the desired CPU utilization target.

You can check the status of the HPA using the kubectl get hpa command and observe how it scales the number of replicas based on the observed metrics.

Did you find this article valuable?

Support Naveen Elwaka by becoming a sponsor. Any amount is appreciated!

ย