Kubernetes Camp

Learn Kubernetes on your Coffee Break

1. Run your first application

Above all else Kubernetes is a platform for running applications. It takes applications in the form of Linux Containers and runs them in a special executable environment called a Pod.

A simple application such as NGINX can deploy to Kubernetes with a simple kubectl command. While this is not how you would deploy software into production, its a nice easy way to start getting familiar with Kubernetes.


Ask Kubernetes to run NGINX

You can use the kubectl create command to create a Deployment which is a Controller that wraps around a Pod to provide functionality.

Note: Kubernetes downloads images from an Image Registry, if a specific registry is not provided it will default to the public Docker Registry. Thus the image referenced below is pulled from https://hub.docker.com/_/nginx.

$ kubectl create deployment first --image=nginx
deployment.apps/first created

Look at what resources are running

Note there are actually three resources deployed as a result of this command. kubectl create deployment created the Deployment, which created the ReplicaSet, which created the Pod in which the application itself is running.

$ kubectl get all
NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/first   1/1     1            1           15h

NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/first-7f77d57ccc   1         1         1       15h

NAME                         READY   STATUS    RESTARTS   AGE
pod/first-7f77d57ccc-8gwkp   1/1     Running   0          15h

Ask Kubernetes to forward a port to your new deployment

The astute observer would notice that there’s no obvious way to access your application in the above output. This is because a Service is needed to wire up external access.

You can access an application by using the kubectl port-forward command which will forward a port from your localhost into the specified Resource.

Note: this process will run until you hit ctrl-c to break it.

$ kubectl port-forward deployment/first 8080:80
Forwarding from -> 80
Handling connection for 8080

Access from a web browser, or another terminal:

$ curl
<!DOCTYPE html>
<title>Welcome to nginx!</title>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
<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>



What you just did was create a Kubernetes resource using the imperative command kubectl create deployment. This creates a Deployment resource which in turn creates a ReplicaSet resource which in turn creates a Pod resource.

Imperative commands are actions that act against the live resources and are used to quickly create, update, and delete resources. While this makes for simple use, they are not great for real workloads.


Controllers are the beating heart of Kubernetes, they’re what take it from being a fairly simple container scheduler to a powerful platform. Controllers are programs that watch resources (by connecting to the API) and reconciles the live object against the desired state.

Most resources in Kubernetes are managed by controllers. Following the UNIX Philosophy of doing one thing and doing it well, controllers will often stack together to create complex workflows.

We saw this controller stacking in action above when we created a Deployment, which managed ReplicaSets which in turn managed sets of Pods.


Kubernetes objects are known as Resources and they can be described by a fairly simple data structure, usually formatted as YAML or JSON. All resources have a kind, apiVersion, metadata, and spec.


A Pod is the basic building block of compute operations in Kubernetes. A Pod is not a container, a Pod is the execution environment in which one or more containers run. Each pod shares a Network IP (and localhost) and Volumes between the Containers hosted in the pod.

Think of the Pod as the minimum scalable unit of your application. If you were running Wordpress you might run an NGINX container and a PHP-FPM container in the same pod sharing a UNIX socket over a shared volume. You would not however put the MySQL database in the same pod as while it is part of your application it is a separate scalable unit of your application.

A Pod however is [purposefully] quite fragile. A Pod is scheduled to a specific worker node (managed via the kubelet process). If the worker node disappears, so does the pod.


The ReplicaSet improves the resiliency of compute workloads on Kubernetes. A ReplicaSet Controller manages multiple copies of the same Pod. When the ReplicaSet controller detects that the number of pods is different to the requested number of Pods it will attempt to create or destroy pods to reconcile the difference.

It is completely normal to see a ReplicaSet with a size of one, as that ensures that if a Pod disappears a new copy of the pod will be started.


A Deployment goes one step further and manages the upgrade lifecycle of a compute workload on Kubernetes. A Deployment Controller manages sets of ReplicaSet resources. When you first request a Deployment the controller will request a single ReplicaSet of the specified size.

When you change the image version, change an environment variable, or other such settings the Deployment Controller goes to work. It will request a new ReplicaSet using the new settings and will slowly increase the new ReplicaSet size while reducing the old ReplicaSet (maintaining the correct max count) until the old ReplicaSet has a size of zero.

You can tweak the specific behaviors of the upgrade process in the Deployment resource manifest.

Next learn how to scale and upgrade your Application.