Newb-ernetes: Playing with Pods

Come on Hal, I’m trying to get this service up, jeez.

This is Part 2 in multipart series. Read Part 1 for Kubernetes terminology and setting up minikube.

Pods are the base unit of containerized workloads in Kubernetes. A pod is a set of 1 or more docker containers that form a logical host. This could be something as simple as a single NodeJS server or NGiNX/Rails/Memcached.

In general, you won’t create pods manually, you’ll use a controllers (ReplicaSets, Deployments, etc) to create them, but we’ll start with pods since they are what all controllers control and to get an understand of how and why what controllers due is important.

In this tutorial we will:

  • Create and explore pods
  • View their logs
  • Expose a pod via a service endpoint

First, let’s set up a namespace and get the pod specs for this tutorial. Feel free to blindly paste this into your terminal.

curl -L | sh;
kubectl get namespaces && ls -1 /tmp/newbernetes;
# You should see output similar to:
NAME                  STATUS    AGE
default Active 1h
kube-public Active 1h
kube-system Active 1h
pods-playground-NNN Active 12m

Let’s create a pod that prints “Hello world” to its logs. Kubernetes resources are created using YAML files.

kubectl create -f /tmp/newbernetes/hello-world-og.yaml
# Check the log output, you should see "Hello World"
kubectl logs hello-world-pod-og -f
# Lets get our pods status. Try hitting TAB after "get pod"
kubectl get pod hello-world-pod-og
# We can also see the full kube spec with 'describe'
# This command will be visited in more detail in the next tutorial
kubectl describe pod hello-world-pod-og
# The --watch flag will continually poll
kubectl get pods --watch

If you keep that watch running for about 15 seconds, you’ll see that pod crash and restart. Lets look at YAML pod spec that created this pod:

Ah the ol’ “exit 1”

As you can see in the containers command is an exit 1 that is causing the container to shutdown after 15 seconds. But you’ll also notice, that kubernetes will continue to bring it back up. Cool, huh?

Let’s create another pod:

kubectl create -f /tmp/newbernetes/hello-world-2.yaml;
# Check in on our pods using a label selector
# both specs tagged our pods with app: hello-world
kubectl get pods -l app=hello-world
# You should see output similar to:
NAME                 READY     STATUS             RESTARTS   AGE
hello-world-pod-2 2/2 Running 3 2m
hello-world-pod-og 0/1 CrashLoopBackOff 4 3m

Looks like our new pod is running fine. That og pod is getting noisy. Let’s nuke it.

kubectl delete pod hello-world-pod-og

And lets check in on our logs from our new pod:

kubectl logs hello-world-pod-2

You probably got an error message, huh? When a pod has a single container it will allow this ‘short hand’ but when it has multiple you have to specific which container you want the logs from. Let’s try that again:

kubectl logs hello-world-pod-2 hello-world-sh -f
# You should see:
Hello world
Hello world
Hello world ...

Nice! Lets check out that pod spec:

You’ll notice that we have 2 containers in our pod and also a Service. You can join multiple specs into one YAML file using the --- notation above.

Services are used to expose pods. The three most common ways to expose a pod are:

  • NodePort — exposes the service via a port on the kubernetes master node
  • ClusterIP — exposes the service on an internal IP address
  • LoadBalancer — exposes the service on a load balancer

In this example we are using the first one because minikube doesnt support load balancers.

Lets check out our service:

kubectl get svc 
# or kubectl get svc hello-world-svc
# You should see output similar to:
NAME              CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
hello-world-svc <nodes> 80:30769/TCP 2m

Nice, now how do we reach it? Minikube has a command to get the IP and port number for an exposed service:

# You'll need to give minikube the name of the service. 
# If you --url minikube will print the URL instead of opening it
minikube service hello-world-svc --namespace YOUR_NAMESPACE

Make sure you put your namespace where it says YOUR_NAMESPACE. If you don’t remember it run:

kubectl get namespaces | grep playground

You should see “Hello World” in your browser! Woohoo, you’re gonna be rich!

Run minikube dashboard if you want to check out the Kubernetes dashboard. You’ll need to use the namespace dropdown on the left to select your namespace.

That’s it! To recap we:

  • Created two pods, one with a single container & one with two containers
  • Viewed and tailed logs
  • Deleted a bad pod
  • Exposed a pod via a NodePort service.

To delete the resources you created you can simply run:

kubectl delete namespace YOUR_NAMESPACE