This is What You Need to Know About Kubernetes YAML, Pods, Deployments, and ReplicaSets (2/3)

in Kubernetes

YAML, Pods, Deployments, and ReplicaSets

In this second part, we are going to see how to create a basic way and why it’s not the best way to create managed Pods. We will understand the difference between Pods and Deployments.

Make sure to check part I of this Kubernetes tutorial.


The Basic Way to Create Pods

The Kubectl command line provides several generating commands that can be used to create resources even without writing the YAML definition files for the resources. For instance, creating a pod that is running Nginx can be done simply by executing the following command.

$ kubectl run nginx --image=nginx

Creating Kubernetes resources with the imperative commands, as shown above, is a straightforward task. However, it is not the recommended way for creating resources simply because it is not possible to update and manipulate the created resources using the YAML files.

It is also possible to get the YAML definition file without even creating the pods by specifying the output format to YAML.

$ kubectl run nginx-pod --image=nginx --dry-run=client -o=yaml

The output of the above command will be the complete YAML definition for the Nginx Pod. We can save the output to a YAML file and create the pod using the generated YAML file

$ kubectl run nginx-pod --image=nginx --dry-run=client -o=yaml > nginx.yaml
$ kubectl apply -f nginx.yaml

The structure of YAML files used to create Kubernetes resources is the same for almost all the supported resources, and four sections need to be defined in each resource definition file. These sections are briefly described below:

  • apiVersion: The Kubernetes resource API version is used to create the resource.
  • Kind: The type of the resource to be created. It could be Pod, Secret, Configmap, or Namespace.
  • metadata: The metadata that needs to be attached to the created resource, such as the resource name of the resource labels.
  • Spec: This section defines the resource specifications

To write a Pod definition file for an Nginx service, we need to cover all the above-described sections. The apiVersion for the Pod resource is v1, the kind is Pod, and the metadata should define the name and labels of the pod. Below is an example of how to define these sections for the Nginx pod in YAML

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nginx-pod
  name: nginx-pod

The last section that we need to define is the spec section, but before defining the Nginx Pod specification, let us understand what is exactly a Pod in Kubernetes.

Pods are the smallest deployable units of computing that can be created and managed in Kubernetes. In other words, Kubernetes is not managing containers directly, and instead, the pod resource is used to manage and create application containers.

As a result, the specification of a given Pod should include the needed information for creating the containers that are managed by Pod. In addition, Pods are not restricted to have only one container; in fact, it is a common pattern to deploy multi-container pods for some use cases such as collecting logs. To get more information about the Kubernetes Pods and their use cases, you can visit this link.

Now that we know what needs to be defined in the PodSpec, we can move to define the specs for the Nginx pod. The snippet below is showing the minimal specs for the Nginx Pod. As shown, we need to specify the list of the containers managed by the Pod resource and the name and docker image used to create the container.

spec:
  containers:
  - image: nginx
    name: nginx-pod

The Pod Specification section is not limited to the list of container names and docker images, in fact, there is a wide range of specifications items that can be used to define Pods. This specification can be classified into two groups. The first group is the specification that is applied to the Pod level, such as

  • Volumes: The list of volumes that can be attached to containers inside the pod.
  • initContainers : The List of the init containers that need to be created before creating the Pod containers.
  • restartPolicy: The Restart policy for all containers within the pod. One of Always, OnFailure, Never. Default to Always.
  • imagePullSecrets: The list of secrets used to authenticate and pull images.
  • nodeSelector and nodeName: Specifications used to decide on which node to create the pod.
  • Affinity: Pod scheduling constraints

The second group of the specification is the specifications that are applied to the containers list. Some of these specifications are listed below

  • Command: The Container entrypoint, if this is not provided, the default image entrypoint will be used.
  • Args: The arguments of the container entrypoint.
  • Env: The list of the environment variables attached to the container.
  • envFrom: Load environment variables from different sources such as Configmaps or secrets.
  • Ports: The list of exposed ports.
  • readinessProbe: A health check command that will be used to decide if a container is healthy or not.
  • Resources: Compute resources needed by the container.
  • volumeMounts: The list of the volume mounts attached to the container.

Below is a more sophisticated Pod YAML definition file that is using some of the above-mentioned properties

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nginx-pod
  name: nginx-pod
  namespace: default
spec:
  containers:
  - image: nginx:1.18
    imagePullPolicy: IfNotPresent
    name: nginx-pod
    command:
    - '/docker-entrypoint.sh'
    args:
    - 'nginx'
    - '-g'
    - 'daemon off;'
    env:
    - name: POD_NAMESPACE
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.namespace
    resources:
      requests:
        cpu: 200m
        memory: 120Mi
    livenessProbe:
      failureThreshold: 5
      httpGet:
        path: /
        port: 80
        scheme: HTTP
    readinessProbe:
      failureThreshold: 3
      httpGet:
        path: /
        port: 80
        scheme: HTTP
    ports:
    - containerPort: 80
      name: http
      protocol: TCP
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: node01
  priority: 0
  restartPolicy: Always
  schedulerName: default-scheduler
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30

Use the following command to deploy the Nginx Pod.

$ kubectl apply -f nginx-pod.yaml

It is not mandatory to use and define all the above properties to be able to create Pods, most of these priorities are optional, and they have default values that will be used. To get more info regarding Pod resources' supported properties, you can check the Kubernetes API reference.

A Better Way to Create Pods

Pods in Kubernetes are the smallest deployable artifacts and represent the running instances of the services. The PodSpec covers all the needed specifications and configurations required to deploy and run containers defined by the pods. However, The PodSpec does not include many features and specs related to the deployment process in Kubernetes. Below is a brief description of some of the top needed features for hosting and deploying services in Kubernetes.

  • Scaling and Clustering: PodSpec does not support scaling the defined containers, and in case you need to create more containers for the same service, it can be done only by duplicating the YAML configs and creating new containers. But even with this solution, the pods will act as separate, single pods, and there is no relation to the pods that belong to the same service.
  • Monitoring: No controllers monitor single Pods; therefore, if a Pod crashes, Kubernetes will not act in any way.
  • High Availability: Hosting services on Kubernetes using only Pods means that these services are not highly available in many use cases. For instance, if the host is down, the Pod will be down too, and it will not be recreated anywhere else. Another example of unavailability is when deploying new Pods, there is a need to delete the old ones and recreate the new pods, and between the two actions, the service will be completely down.
  • Support for zero downtime deployment: Upgrading your K8s cluster should not impact the availability of your services.
  • Rollback: You should be able to rollback.
  • Maintain the history of the deployment rollout and rollback performed on the cluster.

Luckily, all the mentioned points can be achieved and managed by Kubernetes Deployments. Kubernetes provides a wide range of resources that can be used to manage, deploy, and run the services.

To follow the recommended method for deploying services in a Kubernetes cluster, we need to use two other Kubernetes resources rather than Pods.

Below is a brief description of how to do it.

  • ReplicaSet: This resource is used to guarantee the availability of a specific number of the same Pod on a Kubernetes cluster at any time. In other words, this resource keeps monitoring the Pods that belong to the same group and keeps them in the defined state all the time. For instance, in case we would like to deploy four Pods of the same service and make sure that all the four pods are up and running all the time, then the Replicaset controller which help us in achieving our goal. The Replicaset will take care of checking the health of the running Pods and recreate them when they are not responding. In addition, in case a node in the cluster is down, the ReplicaSet will reschedule the pods on a different node to maintain the defined state of the service and make sure that four pods are running.
  • Deployment: This resource provides support for all the logic needed to deploy services in Kubernetes. For instance, the Deployment resource supports different rollout strategies for creating Pods and rollout updates, provides an easy interface for scaling up and down services, supports the rollback to older versions, pausing and resuming Service Deployments.

In the third part of this tutorial, we are going to dive deep into Kubernetes Deployments and understand the structure of a YAML Deployment file. You already understood the differences between Pods and Deployments in part I and part II of this tutorial. Next on part 3, you are going to create a managed Pod using Kubernetes Deployments.



Share this story with your friends
cloudplex
Cloudplex

Founder and CEO of Cloudplex - We make Kubernetes easy for developers.

Sponsored


Content Marketing Platform for Cloud Native Companies
Get in touch

Content marketing platform for Cloud Native Companies

DevOps Narrated (Podcast)
Subscribe to The DevOps FaunCast

Listen to the stories behind the stories and learn new things each week