Your first Pod
The imperative way
A Pod is the smallest deployable unit in Kubernetes. It is not a container, but a wrapper around one or more containers that share network and storage. When Kubernetes runs your application, it always does so inside a Pod.
In this lesson you're going to create your first Pod in two different ways:
- Imperatively, with a single
kubectlcommand (this unit). - Declaratively, describing the Pod in a YAML file (the next unit).
You'll also learn to inspect a Pod with kubectl describe and to read its logs with kubectl logs. All the work happens in a real Kubernetes cluster that is already waiting for you in the dev-machine tab.
💡 You can open the Explorer tab at any time to see visually what is going on inside the cluster.
Step 1: Create a Pod imperatively
The fastest way to create a Pod is the kubectl run command. It's called the imperative way because you give the cluster a direct order: "create this now".
Run the following in the terminal:
kubectl run web --image=ghcr.io/iximiuz/labs/nginx:alpine --port=80
Check the Pod's status:
kubectl get pods
At first it may show up in the ContainerCreating state. Wait a few seconds and run the command again until you see Running.
Step 2: Inspect the Pod with kubectl describe
kubectl get gives you a summary, but kubectl describe tells you the Pod's full story: which node it runs on, which image it uses, which events it has generated and much more.
kubectl describe pod web
Notice these sections of the output:
- Node: the cluster node the Pod has been scheduled on.
- Containers: the list of the Pod's containers, with their image and ports.
- Conditions: the conditions the Pod must meet to be ready.
- Events: the timeline of what has happened to the Pod (image pulled, container created, container started).
To prove you've read the output carefully, answer this question:
Step 3: Read the Pod's logs
Everything the container's main process writes to its standard output (stdout) is recorded and can be read with kubectl logs:
kubectl logs web
You'll see nginx's startup messages. The last line should say something like start worker processes, a sign that the server is ready to serve requests.
💡 If the Pod had more than one container, you would have to say which one you want with kubectl logs web -c <container-name>.
Step 4: Delete the imperative Pod
The imperative way is convenient for experiments, but it has a problem: the Pod's definition exists only in the cluster. If someone deletes it, no trace is left of what web looked like.
Before moving on to the declarative way, delete the Pod:
kubectl delete pod web
Continue with the next unit to create the same Pod the way it's done in the real world: with a YAML file.
The declarative way
The declarative way is the one you'll use in the real world: you describe the desired state in a YAML file and Kubernetes takes care of making it happen. The file can be versioned in git, reviewed in a pull request and applied as many times as you like.
Step 5: Create a Pod declaratively
Create a file called pod.yaml with this content. It pastes as-is into the terminal; if you'd rather type it by hand, the IDE tab is there too:
cat << 'EOF' > pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: web
labels:
app: web
spec:
containers:
- name: nginx
image: ghcr.io/iximiuz/labs/nginx:alpine
ports:
- containerPort: 80
EOF
The YAML, explained in questions and answers
What is apiVersion and why is it v1?
It states the version of the Kubernetes API that knows how to interpret this object. Pods belong to the core group of resources, which is identified simply as v1. Other resources, like Deployments, use versions with a group, for example apps/v1.
What does kind say?
The type of object you're describing. Here it's Pod, but the same file schema works for any Kubernetes resource: Service, Deployment, ConfigMap, etc.
What is metadata.name for?
It's the Pod's unique name within its Namespace. It's the identifier you use in every command: kubectl get pod web, kubectl describe pod web, kubectl logs web.
What are the labels, and why are we adding them already?
They are key-value pairs that let you group and select objects. Right now the label app: web does nothing, but as soon as you create a Service or a Deployment you'll see that everything in Kubernetes connects through labels. Labeling from day one is a good habit.
What does spec define?
The object's desired state. In metadata you say what the Pod is called, and in spec you say what it should be like inside.
Why is containers a list?
Because a Pod can have more than one container. It's a less common case, but there are patterns like sidecars that take advantage of it. In this lesson the list has a single item.
What role does containerPort play?
It's mainly informational: it documents the port the container's process listens on. Traffic would reach port 80 even if you didn't declare it, but declaring it makes the YAML more readable and other tools make use of it.
What's the difference between kubectl run and kubectl apply -f?
With kubectl run you give a one-off order and the configuration lives only in the cluster. With kubectl apply -f the YAML file is the source of truth: you can save it, version it and apply it again on any cluster.
What happens if I apply the same YAML twice?
Nothing bad. kubectl apply is idempotent: if the object already exists and matches the file, nothing changes; if there are differences in mutable fields, it updates them.
Apply the file
Now create the Pod from the file:
kubectl apply -f pod.yaml
And check that it reaches the Running state:
kubectl get pod web
Now repeat the inspection you did in the previous unit, this time on the new Pod:
kubectl describe pod web
kubectl logs web
Summary
In this lesson you have:
- Created a Pod imperatively with
kubectl run. - Inspected a Pod with
kubectl describeand located its node, its image, its conditions and its events. - Read the container's logs with
kubectl logs. - Deleted a Pod with
kubectl delete. - Created the Pod
webdeclaratively with a YAML file andkubectl apply.
The declarative way is the foundation of everything that comes next: Deployments, Services and the rest of the Kubernetes objects are managed exactly the same way, with YAML files applied to the cluster.
- Previous lesson
- Talking to the cluster
- Next lesson
- Challenge: diagnose and fix a broken Pod