Kubernetes, now with 70% less jargon!
Kubernetes tutorials told me what to do, but always left me wondering:
- why am I doing this?
- what is happening?
I dug deeper, looked under the covers, and what I found has helped me better understand, describe and apply my kubernetes knowledge.
The jargon and magic may seem intimidating, but read on and we’ll break down the kubernetes API into simple, familiar building blocks.
Hello Kubernetes
kubernetes
at its very simplest is a standard set of extensible APIs to start, track, and stop the execution of containers running on a set of computers.
All of your basic interactions with kubernetes do nothing more than send JSON with HTTP requests to these apis.
kubectl apply
kubectl apply
provides a “declarative” method for managing kubernetes resources
.
Behind the scenes, it’s really just a convenience wrapper for simple HTTP Apis.
a
resource
is an http endpoint in the Kubernetes API that represents a collection of API “objects” of a certain type.
Let’s look at what happens when you call kubectl apply
on this Deployment
from the Hello Minikube tutorial.
# deployment.yaml
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: hello-node
labels:
app: hello-node
spec:
replicas: 1
selector:
matchLabels:
app: hello-node
template:
metadata:
labels:
app: hello-node
spec:
containers:
- name: hello-node
image: k8s.gcr.io/echoserver:1.4
We’ll be adding --v=8
to let us see what requests it sends. This will enable
tracing/debug logging.
$ kubectl --v=8 apply -f deployment.yaml
...
HTTP GET /apis/apps/v1/namespaces/default/deployments/hello-node
Response HTTP 404 Not Found in 3 millisecondss
...
HTTP POST /apis/apps/v1/namespaces/default/deployments?fieldManager=kubectl-client-side-apply
Request Body: {"apiVersion": "apps/v1", "kind": "Deployment","metadata": {...}, "labels": { "app": "hello-node" }, "name": "hello-node", "namespace": "default" }, "spec": { "replicas": 1, "selector": { "matchLabels": { "app": "hello-node" }}, "template": { "metadata": { "labels": { "app": "hello-node" }}, "spec": { "containers": [ { "image": "k8s.gcr.io/echoserver:1.4", "name": "hello-node" }]}}}}
Let’s review
Put more simply, with the help of kubectl apply
we just:
- checked for an existing
Deployment
- called
POST .../deployments
to create a newDeployment
???
Wait, what is a deployment?
In kubernetes usage, a Deployment
is a resource that describes at least:
- an identifier (
name
) - instructions for how to start a single container (
template
) - a number of containers to start (
replicas
) - rules to follow when updating the deployment.
- for example,
StrategyType: RollingUpdate
(docs)
- for example,
For an example, let’s look at the results of our command above:
$ kubectl get deployment hello-node -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
hello-node 1/1 1 1 10m hello-node k8s.gcr.io/echoserver:1.4 app=hello-node
Looking at our deployment, we can see that it is named hello-world
and has 1 running container, corresponding to the 1 replica
requested when we created it.
Breaking down deployments
A lot has just happened in the background. We’ve used the api create a deployment,
lets explore how controllers
took that request and started the containers
we wanted.
controllers
are autonomous computer programs that leverage the kubernetes APIs to add custom behaviors to it. They might:
- Add addional APIs
- Handle new custom types
- Send ☹️ in slack when things break
The posssibilities are truly endless
DeploymentController (code)
The DeploymentController
is the software that provides/configures the
deployment resource.
*If you want to learn more about how kubernetes does what I describe, just click the (code) links to be taken to the code that performs it!
The DeploymentController
is the first stop our request takes on its way
to becoming a container.
When the DeploymentController
sees a new deployment, it creates a new
ReplicaSet
using the information from the template.
(code)
ReplicaSetController (code)
The ReplicaSetController
is the software responsible for providing and configuring
the replicaset resource. (code) (startup code)
Once a new ReplicaSet
is added, the ReplicaSetController
is notified and
creates a new Pod
to run the containers
Scheduler (code)
The Scheduler
has traditionally been a special controller in the kubernetes
ecosystem, but now can be configured and replaced just like other controllers.
It does not create any new resources. It is responsible for binding pods to
individual servers, and It interacts with the kubernetes API in largely the same
way as the other controllers.
Once a new Pod
is created, the Scheduler
is notified (code)
and binds it to a Node
during the next scheduler loop.
(loop code)
(bind code)
Finally, the kubelet
listens for updates to Pods that match its node name
(code), starts the containers, and then updates
the pods status to running (code)
the
kubelet
is the software that runs on each server (also called aNode
) that starts, stops and monitors containers.
Putting it all together
kubectl create deployment
is just one way to run software in kubernetes.
The extenisble api allows any number of off-the-shelf or custom controllers to help you
rapidly build and \terate on complex software. The power of kubernetes
emerges from the interactions of these simple parts.
Web Sites/Databases/Game Servers/Resta APIs and more can all be managed by kubernetes as long as there is controller software to help orchestrate them.
But Dan…
What good is my Web Site/Database/Game Server…, if noone can access it!?
Stay tuned for a follow up post, we’ll break down kubernetes networking, explore cluster DNS and discuss how it can help make your software configuration more repeatable.