Before we get into the various components of a kubernetes cluster, it is important to understand what a pod is. The kubernetes encapsulates containers into a kubernetes object called pod. A pod is a single instance of a containerised application running on a worker node of the kubernetes cluster. If the demand for a given containerised application increases, kubernetes spins up more pods on the same worker node or other worker nodes in the kubernetes cluster. If a demand for an application goes down, the number of pods can be scaled down to free up resources on the worker nodes. In most cases, there is one to one relationship between a container and a pod i.e. only one container is encapsulated in a pod, except in cases where a sidecar or a helper container is required by an application to perform additional task. So, why does kubernetes encapsulates containers in an object called pod, when a container can be run directly on a host hardware or a worker node? Well, it becomes far more easier for kubernetes to manage and orchestrate containers when they are encapsulated inside a pod. For instance, pods can be easily scaled up, scaled down, deployed, destroyed and assigned storage and network resources based on the requirement. With this high level understanding of a pod, let us now dive deep into the various components of a kubernetes cluster.
The Kubernetes cluster comprises of a Master node and one or more worker nodes. The Master node hosts the various control plane components required to manage and administer the Kubernetes cluster, whereas worker nodes are responsible for hosting pods. Some of the key functions performed by a Master node are listed below.
- The Master node is responsible for the management and administration of the kubernetes cluster.
- It determines which containers need to be scheduled on which of the Worker nodes
- It also stores the complete inventory of the cluster
- It monitors the Worker nodes and the containers running on the Worker nodes.
The Master node does all of these using a set of control plane components detailed below.
Kube-apiserver – The kube-apiserver is responsible for orchestrating all operations within the kubernetes cluster. It exposes kubernetes api, which is used by administrators to perform management operations on the kubernetes cluster. The kubectl is a client utility is used to interact with the kube-apiserver. When a user enters a kubectl command to create a pod, the request to create a pod is first authenticated, validated and subsequently executed by the kube-apiserver. The kube-apiserver also updates the ETCD datastore with the information about the new pod.
If a kubernetes cluster is deployed using the kubeadm tool, it deploys the control plane components including the kube-apiserver as a pod in the kube-system namespace. In such a case, the pod definition file /etc/kubernetes/manifests/kube-apiserver.yaml defines all the options with which the kube-apiserver is invoked. If a kubernetes cluster is deployed the hard way (without using the kubeadm tool) using the binaries from the kubernetes release page, the options used to invoke the kube-apiserver are available in /etc/systemd/system/kube-apiserver.service. While specifying the path of kube-apiserver pod definition file or service definition file maybe too much of a detail for a high level overview, I thought of covering it here as such a detail usually comes handy while troubleshooting cluster relevant issues. Moreover, the given pod definition file path and the service definition file path holds true for other control plane components as well with kubelet being an exception. The kubelet can be installed only using the binaries on the kubernetes release page, it cannot be installed using kubeadm.
ETCD – The ETCD stores the complete cluster inventory in the form of key-value pair. It is a key-value datastore, which stores information such as nodes, pods, configs, secrets, roles, bindings, etc. ETCDCTL is a ETCD client or a command line utility used to interact with the ETCD key value datastore.
Kube-scheduler – As the name suggests, the kube-scheduler determines which pods need to be placed on which Worker nodes based on the pods resource requirements, worker node size and any other policy, constraints such as taints and tolerations or node affinity rules. It is worth noting that kube-scheduler does the job of only determining which pod needs to be scheduled on which node, it does not actually deploys a pod on a node.
Controller Manager – The controller manager internally comprises of two controllers:
- Node controller – The Node controller is meant for onboarding new nodes into the cluster and take care of situation where nodes become unavailable. The node controller monitors the status of the nodes every 5 seconds (Node monitor period). In case there is no heart beat received for 40 seconds (Node monitor grace period) , the node controller marks the node as unreachable. After a node is marked unreachable, the node controller waits for 5 minutes (Pod Eviction timeout) to check if the node has come up. If an affected node does not comes up after 5 minutes, the node controller evicts any pods which are part of the replication group, from the affected node and provisions those pods onto the healthy nodes in the cluster.
- Replication controller – The Replication controller ensures that desired number of pods always run in a given replication group. If a pod within a replication group dies, the replication controller creates another pod.
Kubelet – The kubelet runs on every worker node. It listens for instructions from the kube-apiserver running on the Master node and deploys or destroys a pod on the worker node as required. When the kubelet receives a request from the kube-apiserver to create a pod, it instructs the container runtime engine, which could be docker, to pull a required image and run an instance of the pod. The kube-apiserver periodically fetches reports from the kubelet to monitor the status of the pods running on a node. The kublet service also runs on a Master node to manage control-plane pods (control-plane components that are deployed as pods) and pods running services like networking and DNS. The kubelet also registers a worker node with the kubernetes cluster. Once a worker node is registered, it is monitored by the node-controller on the Master node. Unlike the other components, the kubelet is not installed by the kubeadm tool. In order to install the kubelet, you need to download the kubelet binaries from the kubernetes release page, extract it and run it as a service.
Kube-proxy – The Kube-proxy is responsible for enabling communication between the worker nodes. For instance, an application container hosted on one worker node communicates with a database container on another worker node by leveraging a kube-proxy service. In a kubernetes cluster, the pods running custom applications, databases or web servers are exposed by the means of a service (ClusterIP, NodePort or load balancer service). The service is a kind of logical entity which is created in the memory and is accessible to all the nodes of kubernetes cluster. The kube-proxy component on each node is responsible for forwarding any traffic from the service to the back-end pods.
Networking and DNS services – The services responsible for managing networking and DNS requirements of the cluster are usually deployed as pods on the Master node.