Similar to learning a new coding framework, becoming productive with Kubernetes is mostly about understanding its components and how they’re used. There’s a long list of components and the list is growing daily. However, the 3 foundational pieces that arguably almost everything else builds upon are Pod
, Service
and Deployment
. For someone just learning Kubernetes, I recommend starting with those.
A pod is a collection of containers that run your application. It’s also the component that you scale to handle load and provide redundancy. For example, if you want to run 5 instances of your website, you specify it in the pod. Kubernetes resources that the app requires, such as networking ports or persistent storage volumes, are also specified in the pod.
The Kubernetes Object Specification (object spec) for Pod
defines its characteristics, such as what container to run, how many instances and resources required. Here’s example to run a simple container. Save this YAML in a file named hello-world.yaml
.
apiVersion: v1
kind: Pod
metadata:
name: hello-pod
spec:
containers:
- name: hello-container
image: docker.io/busybox:latest
command: ["/bin/sh"]
args: ["-c", "while true; do echo 'Hello'; sleep 3; done"]
Run the pod in your cluster with the following kubectl
command.
> kubectl apply -f hello-world.yaml
pod/hello-pod created
You can see it’s running
> kubectl get pod hello-pod
NAME READY STATUS RESTARTS AGE
hello-pod 1/1 Running 0 7s
and see its console output.
> kubectl logs hello-pod
Hello
Hello
Hello
Hello
Hello
Hello
You can connect interactively to it with a new shell, as follows.
kubectl exec -it hello-pod /bin/sh
/ # ls
bin dev etc home proc root run sys tmp usr var
/ # ps aux
PID USER TIME COMMAND
1 root 0:00 /bin/sh -c while true; do echo 'Hello'; sleep 3; done
15 root 0:00 /bin/sh
26 root 0:00 sleep 3
27 root 0:00 ps aux
/ # exit
command terminated with exit code 127
Finally, tear down the pod with the kubectl
delete command.
> kubectl delete -f hello-world.yaml
pod "hello-pod" deleted
Usually a pod is built to do more interesting work than echoing a hello string. For example, the pod could run a web server listening on a port to provide a microservice. To do that, add a containerPort
resource to the object spec.
Pods will sometimes also need more than one container to perform different, but related functions. What containers should be grouped together in a pod and which should have their own pod is a design decision and possibly a good topic for a future post.
In the following example, a second container is added to the pod to run nginx listing on port 80.
apiVersion: v1
kind: Pod
metadata:
name: hello-pod
spec:
containers:
- name: hello-container
image: docker.io/busybox:latest
command: ["/bin/sh"]
args: ["-c", "while true; do echo 'Hello'; sleep 3; done"]
- name: web-service
image: docker.io/nginx:latest
ports:
- containerPort: 80
After creating the pod again, we can see there are now 2 of 2 running instances.
> kubectl get pod hello-pod
NAME READY STATUS RESTARTS AGE
hello-pod 2/2 Running 0 22s
We can use the kubectl
port forwarding command to test our nginx web server, as follows.
> kubectl port-forward hello-pod 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
The command tells kubectl
to act as a proxy, listening on local port 8080 and forwarding to port 80 of the hello-pod
pod. We need a proxy because nginx is listening to the container port 80 and it’s not accessible outside the cluster.
After port forwarding starts, you can use your favorite tool or browser to do a HTTP request and see the default nginx response.
> curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
In a more realistic scenario, the nginx container might include with real website code or mount a storage volume with web content. The development process for creating app containers is on the radar for a future post.
To summarize, the Pod
is the unit of deployment in Kubernetes. It’s the bundle of containers that make up a deployable piece of your application. That could be the entire app itself or just one of many microservices. As we’ll see later in Part 3, it’s also the scale unit, or the component that’s instantiated or stopped when there’s a change to the number of instances required. The Pod
is definitely one of the foundational building blocks that everything else in Kubernetes builds upon.