fbpx
Get Started Free

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

Kubernetes YAML

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 1 of this 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: and nodeName: Specifications used to decide on which node to create the pod.
  • nodeSelector: This section defines the resource specifications.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: Pod scheduling constraints
    • 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: 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

    In software development, orchestration refers to the integration of multiple applications or services, allowing them to automate a process or synchronize their data in real-time. If an application runs on multiple microservices that are placed in separate containers, orchestration helps the services communicate seamlessly to achieve the goal.

    • 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.

    Asad Faizi

    Founder CEO

    CloudPlex.io, Inc

    asad@cloudplex.io

Start building app

Start building your cloud native application

132160cookie-checkThis is What You Need to Know About Kubernetes YAML, Pods, Deployments, and ReplicaSets (2/3)