This lab will walk you through deploying a very simple "Hello World" web app.
Start by starting your local minikube cluster:
minikube startThen clone this repo and cd into this directory:
git clone https://github.com/99/meetup-workshop
cd meetup-workshopWe are now ready to deploy our Hello world web app!
A pre-built Docker image has been pushed to our Image repository. This means that we are ready to use the pods.yaml in this directory to stand up a single Pod:
kubectl create -f pod.yamlBreaking this down, we're using the Kubernetes CLI (kubectl) and we're telling it to create the resource specified in the given file (-f pod.yaml).
From here, you can watch your Pod come up:
kubectl get pods -wIf you run this fast enough, you may see your Pod in a ContainerCreating or Pending state. Finally, you'll eventually see it transition to Running.
Now that your Pod is running, let's look at a few things:
kubectl describe pod hello-worldThis will show you how the Pod has been configured, which image it's running, which port(s) it exposes (if any), any recent events, crashes, or restarts, which node it's running on, and much more.
If we'd like to view the logs from the application running in the Pod:
kubectl logs hello-worldOr perhaps we'd like to attach to a shell within the Pod (sort of like SSH'ing):
kubectl exec -it hello-world /bin/shYou can also find and do all of this the Kubernetes dashboard:
minikube dashboardIf you'd like to reach a specific port on a particular pod, you can port forward it to your local machine by doing something like:
# The port format here is LOCAL_PORT:REMOTE_PORT
kubectl port-forward hello-world 5000:5000However, this is not useful for a production application. Your Pods will be constantly coming and going, and port-forwarding to our machine does nothing for our users.
We'll want to instead create a Kubernetes Service. We've included one in service.yaml. Similar to how we created the Pod, we'll create the Service like this:
kubectl create -f service.yamlAfter the Service is created, you can have minikube point your browser at it:
minikube service hello-worldThis works a bit differently in production, but your traffic was routed through what amounts to a front-facing load balancer for the Pod(s) that matches the Service's selector.
It is rare that we use a stand-alone Pod by itself, primarily due to two attributes:
- A single Pod can't be cloned to scale up.
- If the Node that a Pod is running on dies, it will be marked as Terminated and will not be re-scheduled.
To simulate Node failure, let's delete your single Pod and try to go through our Service again:
kubectl delete pod hello-world
# See the Pod terminate and goes away. Append a -w to watch in realtime.
kubectl get pods
# Try to reach your Service.
minikube service hello-worldYou'll see that we're now failing to connect, as expected. There are no Pods backing the Service. The users are furiously refreshing.
To handle our availability and scaling concerns, we instead use a Deployment object. A Deployment uses a template to create the number of desired Pods (in the replicas field). If a Pod is Terminated, the Deployment will ensure that it gets replaced. It also becomes easy to scale the Pod count up or down.
Let's start by creating the included Deployment:
kubectl create -f deployment.yamlYou should now be able to see a single Pod via:
kubectl get podsUnlike with our bare Pod, you'll notice that the name has a long hash appended to the name. For example hello-world-596fc9fdcf-x9rlz. To break this name down:
hello-world= The value inDeployment.metadata.name596fc9fdcf= The ReplicaSet name. We'll gloss over this for now, but it'll correspond to a distinct "version" managed by the Deployment.x9rlz= A unique hash, to avoid Pod name collisions.
The Pod acts just like our previous bare pod, but has a slightly different name.
Moving on, you should once again be able to reach your app through its service:
minikube service hello-worldIf you recall how we deleted our single bare Pod earlier, let's go on ahead and attempt to do the same with the Pod that our Deployment created:
# Find the name of the Pod to delete, since it's now long and semi-random
kubectl get pods
# Delete the Pod (your name will be different)
kubectl delete pod hello-world-xxxxxxxxx-yyyyy
# Make sure the Pod Terminates and goes away.
kubectl get podsDepending on how quickly you get the updated Pod list, you'll either see a Terminating Pod and a new Pod, or just the new Pod (identifiable by its recent AGE column). The Deployment as a replica count of 1, so Kubernetes knows to replace any Terminated Pods.
However, there was a second or two after you deleted the Pod to where your imaginary users were unable to reach your app.
Let's reduce the likelihood of service disruptions by scaling the Deployment up!
# This will an open an editor. You'll want to edit the 'replicas' field
# from 1 to 3. Save+Quit and your changes will be applied.
kubectl edit deployment hello-world
# Or you can run this shorter command:
kubectl scale --replicas=3 deployment/hello-world
# After doing one or the other:
kubectl get podsYou should now see three Pods, two being newer than the other. You'll notice that the names have some overlap until the last hash.
You can now delete any of the three Pods without taking your app down!
Now it's time to deploy a new version of your smash hit, "Hello world!". Let's pivot a bit and greet this Meetup group instead:
# We'll re-open our editor. Edit the 'image' field's tag from 1.0 to 1.1.
# Save+Quit and your changes will be applied.
kubectl edit deployment hello-world
# Let's re-visit your service:
minikube service hello-worldYou should now see "Hello Meetup Group!" instead of "Hello world!". We'll go into this in more detail later, but what happened:
- The initial state was three pods running version 1.0.
- After you made your changes, the Deployment spun up a fourth Pod running 1.1.
- Once the new Pod passed health checks, one of the 1.0 Pods was terminated.
- New Pods are continuously stood up, replacing the old ones until all Pods are running 1.1.
This completes our Kubernetes Workshop! To review:
- A
Podis the unit of work in Kubernetes. - A Pod's ports can be reached via
kubectl port-forwardor through a Service. - We use a Deployment and its
templateto stamp out a desired number ofreplicaPods. Unhealthy or terminated Pods get replaced for us with a Deployment.