A Kubernetes cluster is made up of masters and nodes. These are L beinux hosts running on anything from VMs, bare metal servers, all the way up to private and public cloud instances.
Masters (control plane)
A Kubernetes master is a collection of small services that make up the control plane of the cluster.
The simplest (and most common) setups run all the master services on a single host. However, multi-master HA is becoming more and more popular, and is a must have for production environments. Looking further into the future, we might see the individual services comprise the control plane split-out and distributed across the cluster – a distributed control plane.
It’s also considered a good practice not to run application workloads on the master. This allows the master to concentrate entirely on looking after the state of the cluster.
Let’s take a quick look at the major pieces that make up the Kubernetes master.
The API server
The API Server (apiserver) is the frontend into the Kubernetes control plane. It exposes a RESTful API that preferentially consumes JSON. We POST manifest files to it, these get validated, and the work they define gets deployed to the cluster.
You can think of the API server as the brains of the cluster.
The cluster store
If the API Server is the brains of the cluster, the cluster store is its memory. The config and state of the cluster gets persistently stored in the cluster store, which is the only stateful component of the cluster and is vital to its operation – no cluster store, no cluster!
The cluster store is based on etcd, the popular distributed, consistent and watchable key-value store. As it is the single source of truth for the cluster, you should take care to protect it and provide adequate ways to recover it if things go wrong.
The controller manager
The controller manager (kube-controller-manager) is currently a bit of a monolith – it implements a few features and functions that’ll probably get split out and made pluggable in the future. Things like the node controller, endpoints controller, namespace controller etc. They tend to sit in loops and watch for changes – the aim of the game is to make sure the current state of the cluster matches the desired state (more on this shortly).
At a high level, the scheduler (kube-scheduler) watches for new workloads and assigns them to nodes. Behind the scenes, it does a lot of related tasks such as evaluating affinity and anti-affinity, constraints, and resource management.
Control Plane summary
Kubernetes masters run all of the cluster’s control plane services. This is the brains of the cluster where all the control and scheduling decisions are made. Behind the scenes, a master is made up of lots of small specialized services. These include the API server, the cluster store, the controller manager, and the scheduler.
The API Server is the front-end into the master and the only component in the control plane that we interact with directly. By default, it exposes a RESTful endpoint on port 443.
First up, nodes used to be called minions. So, when some of the older docs and blogs talk about minions, they’re talking about nodes.
As we can see from Figure, nodes are a bit simpler than masters. The only things that we care about are the kubelet, the container runtime, and the kube-proxy.
First and foremost is the kubelet. This is the main Kubernetes agent that runs on all cluster nodes. In fact, it’s fair to say that the kubelet is the node. You install the kubelet on a Linux host and it registers the host with the cluster as a node. It then watches the API server for new work assignments. Any time it sees one, it carries out the task and maintains a reporting channel back to the master.
If the kubelet can’t run a particular work task, it reports back to the master and lets the control plane decide what actions to take. For example, if a Pod fails on a node, the kubelet is not responsible for restarting it or finding another node to run it on. It simply reports back to the master. The master then decides what to do.
On the topic of reporting back, the kubelet exposes an endpoint on port 10255 where you can inspect it. We’re not going to spend time on this in the book, but it is worth knowing that port 10255 on your nodes lets you inspect aspects of the kubelet.
The Kubelet needs to work with a container runtime to do all the container management stuff – things like pulling images and starting and stopping containers. More often than not, the container runtime that Kubernetes uses is Docker. In the case of Docker, Kubernetes talks natively to the Docker Remote API.
More recently, Kubernetes has released the Container Runtime Interface (CRI). This is an abstraction layer for external (3rd-party) container runtimes to plug in to. Basically, the CRI masks the internal machinery of Kubernetes and exposes a clean documented container runtime interface.
The CRI is now the default method for container runtimes to plug-in to Kubernetes. The containerd CRI project is a community-based open-source project porting the CNCF containerd runtime to the CRI interface. It has a lot of support and will probably replace Docker as the default, and most popular, container runtime used by Kubernetes.
Note: containerd is the container supervisor and runtime logic stripped out of the Docker Engine. It was donated to the CNCF by Docker, Inc. and has a lot of community support.
At the time of writing, Docker is still the most common container runtime used by Kubernetes.
The last piece of the puzzle is the kube-proxy. This is like the network brains of the node. For one thing, it makes sure that every Pod gets its own unique IP address. It also does lightweight load-balancing on the node.