Introduction: From Verification to Deployment

In the previous lesson, you verified that kubectl works and can connect to your Kubernetes cluster. You confirmed your environment is ready by checking the client version, cluster information, and available nodes. Now comes the exciting part: actually running something on Kubernetes.

The natural next question is: "How do I deploy my application to this cluster?" In this lesson, you'll learn how to create and manage your first Pod using a declarative configuration file. By the end, you'll understand what Pods are, why we use YAML files to define them, and how to create, verify, update, and delete Pods using kubectl. This is the foundation for everything else you'll do with Kubernetes.

What Is a Pod?

A Pod is the smallest deployable unit in Kubernetes. When you want to run an application in Kubernetes, you don't deploy containers directly — you deploy Pods. While a Pod can technically contain multiple containers, the most common pattern is one container per Pod. Think of a Pod as a wrapper around your container that provides additional capabilities like networking, storage, and lifecycle management.

Why does Kubernetes use this wrapper instead of just running containers directly? The Pod concept allows Kubernetes to group tightly coupled containers together so they share resources and context. Specifically, all containers within a single Pod share:

  1. Networking: They share the same network namespace, meaning they have the same IP address and port space. Containers inside the same Pod can communicate with each other using localhost, just as if they were processes running on the same server.
  2. Storage: They can share storage volumes, allowing them to read and write to the same files.

In real-world terms, a Pod represents one instance of your application running in the cluster. If you're running a web server, one Pod equals one running copy of that web server. If you need to handle more traffic, you'd run multiple Pods (we'll cover that in later lessons).

It is also important to understand that Pods are (temporary). They are designed to be disposable. If a dies or the node it is running on fails, the is not "healed"; instead, it is usually replaced by a brand new . This is why we treat as disposable resources rather than unique, permanent servers.

Two Approaches: Imperative vs Declarative

Before we create our Pod, you need to understand that Kubernetes offers two different approaches for managing resources: imperative and declarative.

The imperative approach means telling Kubernetes exactly what to do, step by step. For example, you might run kubectl run nginx-pod --image=nginx:1.25 to create a Pod. This command directly instructs Kubernetes to create a Pod right now with these specific settings. It's fast and convenient for quick testing or one-off tasks. However, imperative commands have a significant drawback: they're not reproducible or documented. If you create a Pod imperatively and then delete it, you'd need to remember the exact command to recreate it. There's no file you can save, version control, or share with your team.

The declarative approach means telling Kubernetes what state you want and letting Kubernetes figure out how to achieve it. You write a YAML file that describes your desired Pod, then use kubectl apply -f pod.yaml to tell Kubernetes, "make the cluster match this file." This approach is more powerful because the YAML file serves as documentation, can be stored in version control (like Git), and can be easily shared and reproduced. If you need to recreate the Pod later, you just apply the same file again.

We focus on the declarative approach in this course because it's the standard practice for production environments. When you work on real projects, you'll store your Kubernetes manifests in Git repositories alongside your application code. This makes your infrastructure reproducible and auditable. That said, imperative commands are still useful for quick experiments and troubleshooting, so it's good to know both approaches exist.

Anatomy of a Pod Manifest

Now let's look at how to write a Pod manifest. A manifest is simply a YAML file that describes a Kubernetes resource. Every Pod manifest has four essential sections that tell Kubernetes what you want to create.

Let's start with the first two sections:

The apiVersion field tells Kubernetes which version of the API to use for this resource. Different resource types use different API versions. For Pods, we use v1, which is the stable, core API. You'll see other API versions like apps/v1 or batch/v1 for different resource types in later lessons, but for now, just know that Pods use v1.

The kind field specifies what type of resource you're creating. In this case, we're creating a Pod. Kubernetes supports many different kinds of resources (Deployments, Services, ConfigMaps, etc.), and this field tells Kubernetes which one you want. The combination of apiVersion and tells Kubernetes exactly how to interpret the rest of your manifest.

Creating and Managing Your First Pod

Now that you understand the manifest structure, let's use it to create your first Pod. Save the YAML content above into a file called pod.yaml. In the CodeSignal environment, you can create this file in the editor provided.

To create the Pod, run this command:

The kubectl apply command tells Kubernetes to make the cluster match the state described in your file. The -f flag means "from file," and pod.yaml is the filename. When you run this command, kubectl sends the manifest to the control plane, which then schedules the Pod onto an available node and starts the container.

You should see output like this:

This confirms that Kubernetes received your request and created the Pod. However, "created" doesn't necessarily mean "running yet" — it just means Kubernetes accepted your manifest and started the creation process.

To verify that your Pod is actually running, use this command:

This command lists all Pods in your current namespace. You should see output similar to this:

Updating Resources Declaratively

One of the most powerful features of the declarative model is how it handles updates. You don't need a separate command to update a resource; you use the exact same command you used to create it.

Suppose you want to change the image version of your Pod. In the imperative world, you might need a specific "edit" or "patch" command. In the declarative world, you simply:

  1. Edit your local pod.yaml file to reflect the new desired state.
  2. Run kubectl apply -f pod.yaml again.

Kubernetes will compare the state defined in your file against the live state of the cluster. If it detects differences, it will update the live resource to match your file.

However, it's important to know that not all fields in a Kubernetes resource are updatable. Some fields are immutable, meaning they cannot be changed after the resource is created. For Pods, most of the spec is immutable. For example, you cannot change a container's name, its ports, or its restart policy once the Pod is running. The Pod's name in the metadata section is also immutable.

So, what can you update? The most commonly updated field in a Pod's spec is the container's image. You can also add or modify metadata like labels and (which we'll cover later).

Deleting the Pod

When you're done experimenting with your Pod, you should clean it up. Kubernetes will keep running Pods indefinitely until you explicitly delete them. To delete the Pod, use the same manifest file:

Notice that we use the same file for creation, updates, and deletion. This is one of the benefits of the declarative approach — the manifest serves as the source of truth for the entire lifecycle. When you run this command, you should see:

If you run kubectl get pods again, you'll see that nginx-pod is no longer listed. The Pod and its container have been completely removed from the cluster.

This workflow — kubectl apply to create or update, kubectl get to verify, and kubectl delete to clean up — is the fundamental pattern you'll use throughout your Kubernetes journey. The manifest file is your source of truth, and kubectl is your tool for making the cluster match that truth.

Lesson Summary and Next Steps

Congratulations! You've just created and managed your first Pod in Kubernetes. You learned that Pods are the smallest deployable units in Kubernetes, typically wrapping a single container but capable of sharing networking and storage across multiple containers. You understand the difference between imperative commands and declarative manifests, and why we prefer the declarative approach for its reproducibility and documentation benefits.

You can now write a Pod manifest with the four essential sections (apiVersion, kind, metadata, and spec), create and update Pods using kubectl apply -f, verify they're running with kubectl get pods, and clean them up with kubectl delete -f. This declarative workflow is the foundation for everything else in Kubernetes.

Next, you'll get hands-on practice creating and managing Pods yourself, experimenting with different container images and configurations to solidify these concepts.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal