Computer scienceSystem administration and DevOpsKubernetes

Running a pod with a simple application

11 minutes read

In this topic, you will acquire knowledge on running a basic application within a Kubernetes pod by creating your own pod manifest. Subsequently, you will deploy that pod to your cluster. This will aid you comprehend the pod structure and also enable you to acquire knowledge on how to deploy a docker image to that pod.

Benefits of manual pod creation

Usually, a pod is created as part of a deployment, where it is internally created and managed as one or more pod replicas based on a configuration. By using a deployment, you can take advantage of Kubernetes' built-in features for managing and scaling pods, such as automatic pod creation, load balancing, rolling updates, and self-healing capabilities. However, this doesn't mean learning how to manually create pods has no use. By writing manifests, a developer can gain insight into the various parameters and configurations necessary to deploy and manage pods effectively.

Manually creating pods helps you understand how a Kubernetes cluster functions. And if something goes wrong during the process, having a solid understanding of the manifest structure and syntax empowers you to identify and resolve problems efficiently. Overall, mastering the art of manual pod creation using manifests equips individuals with a comprehensive skill set to effectively manage and scale Kubernetes deployments.

Creating a pod manifest

So, how can you create a pod? For this, you will need to create a pod manifest file that describes the desired state of the pod. The manifest file for a Kubernetes pod typically follows a YAML format. This manifest file includes information such as the pod's name, labels, and the container image the pod uses. Once you create a manifest file, you can use the kubectl command-line tool to deploy the pod to your cluster.

Let's begin by examining the structure of a manifest file. Familiarize yourself with the key sections: metadata, spec, and containers. Understanding these sections allows you to easily modify the manifest to suit different requirements and scenarios.

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: frontend
    environment: production
  namespace: my-namespacespec
spec:
  initContainers:
    - name: init
      image: busybox:latest
      command: ["sh", "-c", "echo Initializing... && sleep 5"]
  containers:
    - name: frontend
      image: nginx:latest
      args: ["-g", "daemon off;"]
      env:
        - name: ENV_VAR_NAME
          value: "env_variable_value"
      ports:
        - containerPort: 80
      volumeMounts:
        - name: data-volume
          mountPath: /data
    - name: backend
      image: myapp-backend:latest
      ports:
        - containerPort: 8080
      volumeMounts:
        - name: data-volume
          mountPath: /data
  volumes:
    - name: data-volume
      emptyDir: {}

Understanding the metadata of a manifest

In the first line of a manifest, define the Kubernetes API version that should be used to create the pod. To see what version your cluster is operating on, you can use the kubectl api-version command.

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  labels:
    app: frontend
    environment: production
  namespace: my-namespacespec

After that comes the kind of Kubernetes object you wish to create with this manifest. In this topic, it should be "pod" because the objective is to create a pod. But in the future, you might learn how to create a deployment or a service.

In the metadata section, you can provide information about the Pod, such as its name, labels, and namespace, among others. The name field allows you to add a meaningful and descriptive name for the pod you want to create. This will find the pod easier in the future. Labels are key-value pairs that can be used to categorize your pods, and you can add labels like app: frontend or environment: production. The namespace field allows you to specify the namespace in which the Pod will be created. Namespaces provide a way to logically separate resources within a cluster. You can change the namespace value to place the Pod in a different namespace as per your cluster's organization.

Pod specification

The spec section is where you define the desired state of the pod. It includes various subfields, such as containers, initContainers, and volumes. The container's field is used to define the main application container running inside the Pod.

spec:
  initContainers:
    ...
  containers:
    ...
  volumes:
    ...

The initContainers fields allow you to define one or more containers that run before the main containers start. By including an init container in your Pod, you ensure that specific tasks are performed before the main application container runs. This can be useful for tasks such as database migrations, data population, or fetching external configuration files.

In the first manifest file example, an init container named "init" is included before the main containers section. The init container runs a Busy Box image and executes a simple command, which echoes a message and then sleeps for 5 seconds. The init container runs to completion before the main containers start. This ensures that all initialization steps are completed before the application containers begin their execution.

The volumes section is where you define storage volumes that can be shared among containers in the Pod. Volumes provide a way to persist data or share files between containers.

In the example manifest, a volume named "data-volume" is defined using the emptyDir volume type. The emptyDir volume is a temporary storage volume that is created during pod creation. The volume is deleted when the pod terminates. It is suitable for storing non-persistent data that is shared between containers in the pod.

To mount the volume into containers, you can use the volumeMounts field within each container's specification. In this manifest example, both the frontend and backend containers have a volumeMount defined with the name "data-volume" and the mountPath set to "/data". This means that both containers will have access to the same shared volume at the specified mount path.

Properties of a container

The specs section contains the definitions for the containers that run on a pod. Here, you can specify the image, configuration, and behavior of each container. You can define multiple containers in a pod, allowing them to run together and share the same network namespace, IPC namespace, and storage volumes. Each container operates independently and can have its own unique configuration, responsibilities, and lifecycle. This flexibility allows you to deploy complex applications that require multiple components or services to work together.

containers:
  - name: frontend
    image: nginx:latest
    args: ["-g", "daemon off;"]
    env:
      - name: ENV_VAR_NAME
        value: "env_variable_value"
    ports:
      - containerPort: 80
    volumeMounts:
      - name: data-volume
        mountPath: /data
  - name: backend
    image: myapp-backend:latest
    ports:
      - containerPort: 8080
    volumeMounts:
      - name: data-volume
        mountPath: /data

Each container is identified by a name and an image specified using the name and image fields respectively. The image field specifies the container image to be used. In this example, the frontend container uses the nginx:latest image, while the backend container uses the myapp-backend:latest image. You can change the image name and tag to match the specific image you want to use for your application. The nginx:latest image pulls the latest version of the NGINX container image from Docker Hub (hub.docker.com). The NGINX community provides and maintains this image and you can use it for hosting front-end applications.

The command field in a container specification allows you to specify the main command to be executed when the container starts running. It overrides the default command defined in the container image. In the example line — command: ["nginx"], the command is set to "nginx". This means that when the container starts, it will execute the nginx command. By specifying a custom command, you have the flexibility to run specific processes or scripts inside the container. This is useful for performing initialization tasks, starting a specific application, or customizing the container's behavior.

It is important to note that the command specified in the command field will be the only process running in the container. If the command exits or terminates, the container will also stop. If you need to run multiple processes within a container, you can use an init system or a process manager like supervisord to manage them.

The args field in a container specification allows you to provide additional arguments or parameters to the command specified in the command field. It is used to pass runtime parameters to the command when the container starts.

In the example line — args: ["-g", "daemon off;"], the args field is set to ["-g", "daemon off;"]. This means that when the nginx command specified in the command field is executed, the -g and daemon off; arguments are passed to it.

By using the args field, you can modify how a command behaves or configure it according to your specific requirements. It provides flexibility and allows you to adapt the command's behavior without modifying the container image itself.

You can configure ports for each container to enable communication with other containers or external services. The ports field in a container specification defines which ports should be opened and accessible within the container. It specifies the network ports on which the container is listening and is ready to accept incoming network traffic.

In the example line — ports: containerPort: 80, the port's field is set to an array with a single element. Inside that element, the containerPort field is set to 80. This means that the container is listening on port 80 for incoming connections.

Deploying the pod

To deploy a pod, you first have to create a file named my-pod.yaml where you can copy the above-mentioned example manifest. Once the pod manifest is ready, you can use the kubectl command to deploy it to your Kubernetes cluster. Open your terminal and navigate to the directory where you saved the my-pod.yaml file and run the following command:

kubectl apply -f my-pod.yaml

This command creates the pod based on the specifications defined in the manifest file.

After deploying the pod, you can check its status using the kubectl command. Run the following command to see the status of your pod:

kubectl get pods

You should see the name of your pod along with its current status. If the pod is running, it means that your application is successfully deployed inside the pod.

Conclusion

Congratulations! You can successfully run a simple application inside a Kubernetes pod using existing example images. By understanding the necessary commands and syntax for creating pod manifests, you are now equipped to deploy your applications in a Kubernetes cluster. Remember to keep exploring and experimenting with Kubernetes to further enhance your skills in container orchestration.

4 learners liked this piece of theory. 0 didn't like it. What about you?
Report a typo