Kubernetes is an open source container management tool. It is a Go-Lang based (https://golang.org), lightweight, and portable application. You can set up a Kubernetes cluster on a Linux-based OS to deploy, manage, and scale the Docker container applications on multiple hosts.
Kubernetes is constructed using several components, as follows:
These components are connected via network, as shown in the following screenshot:
The preceding image can be summarized as follows:
In this section, we are going to explain the features of Kubernetes master and nodes; both of them realize the main functions of the Kubernetes system.
Kubernetes master is the main component of Kubernetes cluster. It serves several functionalities, such as the following items:
The next image shows how master daemons worked together to fulfill the mentioned functionalities:
There are several daemon processes that make the Kubernetes master's functionality, such as kube-apiserver, kube-scheduler, and kube-controller-manager. Hypercube wrapper launched all of them.
In addition, the Kubernetes Command Line Interface kubectl can control the Kubernetes master functionality.
The API server provides an HTTP- or HTTPS-based RESTful API, which is the hub between Kubernetes components, such as kubectl, scheduler, replication controller, etcd datastore, and kubelet and kube-proxy, which runs on Kubernetes nodes and so on.
Scheduler helps to choose which container runs by which nodes. It is a simple algorithm that defines the priority to dispatch and bind containers to nodes, for example:
Controller manager performs cluster operations. For example:
After you install Kubernetes master, you can use the Kubernetes Command Line Interface kubectl to control the Kubernetes cluster. For example, kubectl get cs
returns the status of each component. Also, kubectl get nodes
returns a list of Kubernetes nodes:
//see the ComponentStatuses # kubectl get cs NAME STATUS MESSAGE ERROR controller-manager Healthy ok nil scheduler Healthy ok nil etcd-0 Healthy {"health": "true"} nil //see the nodes # kubectl get nodes NAME LABELS STATUS AGE kub-node1 kubernetes.io/hostname=kub-node1 Ready 26d kub-node2 kubernetes.io/hostname=kub-node2 Ready 26d
Kubernetes node is a slave node in the Kubernetes cluster. It is controlled by Kubernetes master to run the container application using Docker (http://docker.com) or rkt (http://coreos.com/rkt/docs/latest/) in this book; we will use the Docker container runtime as the default engine.
The following image displays the role and tasks of daemon processes in node:
Node also has multiple daemon processes, named kubelet and kube-proxy, to support its functionalities.
kubelet is the main process on Kubernetes node that communicates with Kubernetes master to handle the following operations:
Proxy handles the network proxy and load balancer for each container. It performs to change the Linux iptables rules (nat table) to control TCP and UDP packets across the containers.
After starting the kube-proxy
daemon, it will configure iptables rules; you can see iptables -t nat -L
or iptables -t nat -S
to check the nat table rules, as follows:
//the result will be vary and dynamically changed by kube-proxy # sudo iptables -t nat -S -P PREROUTING ACCEPT -P INPUT ACCEPT -P OUTPUT ACCEPT -P POSTROUTING ACCEPT -N DOCKER -N FLANNEL -N KUBE-NODEPORT-CONTAINER -N KUBE-NODEPORT-HOST -N KUBE-PORTALS-CONTAINER -N KUBE-PORTALS-HOST -A PREROUTING -m comment --comment "handle ClusterIPs; NOTE: this must be before the NodePort rules" -j KUBE-PORTALS-CONTAINER -A PREROUTING -m addrtype --dst-type LOCAL -m comment --comment "handle service NodePorts; NOTE: this must be the last rule in the chain" -j KUBE-NODEPORT-CONTAINER -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER -A OUTPUT -m comment --comment "handle ClusterIPs; NOTE: this must be before the NodePort rules" -j KUBE-PORTALS-HOST -A OUTPUT -m addrtype --dst-type LOCAL -m comment --comment "handle service NodePorts; NOTE: this must be the last rule in the chain" -j KUBE-NODEPORT-HOST -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER -A POSTROUTING -s 192.168.90.0/24 ! -o docker0 -j MASQUERADE -A POSTROUTING -s 192.168.0.0/16 -j FLANNEL -A FLANNEL -d 192.168.0.0/16 -j ACCEPT -A FLANNEL ! -d 224.0.0.0/4 -j MASQUERADE
There are two more components to complement the Kubernetes nodes' functionalities, the datastore etcd and the overlay network flannel. You can learn how they support the Kubernetes system in the following paragraphs.
The etcd (https://coreos.com/etcd/) is the distributed key-value datastore. It can be accessed via the RESTful API to perform the CRUD operation over the network. Kubernetes uses etcd as the main datastore.
You can explore the Kubernetes configuration and status in etcd (/registry
) using the curl
command as follows:
//example: etcd server is 10.0.0.1 and default port is 2379 # curl -L "http://10.0.0.1:2379/v2/keys/registry" {"action":"get","node":{"key":"/registry","dir":true,"nodes":[{"key":"/registry/namespaces","dir":true,"modifiedIndex":15,"createdIndex":15},{"key":"/registry/serviceaccounts","dir":true,"modifiedIndex":16,"createdIndex":16},{"key":"/registry/services","dir":true,"modifiedIndex":17,"createdIndex":17},{"key":"/registry/ranges","dir":true,"modifiedIndex":76,"createdIndex":76},{"key":"/registry/nodes","dir":true,"modifiedIndex":740,"createdIndex":740},{"key":"/registry/pods","dir":true,"modifiedIndex":794,"createdIndex":794},{"key":"/registry/controllers","dir":true,"modifiedIndex":810,"createdIndex":810},{"key":"/registry/events","dir":true,"modifiedIndex":6,"createdIndex":6}],"modifiedIndex":6,"createdIndex":6}}
Network communication between containers is the most difficult part. Because when you start to run the Docker, an IP address will be assigned dynamically; the container application needs to know the peer's IP address and port number.
If the container's network communication is only within the single host, you can use the Docker link to generate the environment variable to discover the peer. However, Kubernetes usually works as a cluster and ambassador pattern or overlay network could help to connect every node. Kubernetes uses overlay network to manage multiple containers' communication.
For overlay network, Kubernetes has several options, but using flannel is the easier solution.
Flannel also uses etcd to configure the settings and store the status. You can also perform the curl
command to explore the configuration (/coreos.com/network
) and status, as follows:
//overlay network CIDR is 192.168.0.0/16 # curl -L "http://10.0.0.1:2379/v2/keys/coreos.com/network/config" {"action":"get","node":{"key":"/coreos.com/network/config","value":"{ "Network": "192.168.0.0/16" }","modifiedIndex":144913,"createdIndex":144913}} //Kubernetes assigns some subnets to containers # curl -L "http://10.0.0.1:2379/v2/keys/coreos.com/network/subnets" {"action":"get","node":{"key":"/coreos.com/network/subnets","dir":true,"nodes":[{"key":"/coreos.com/network/subnets/192.168.90.0-24","value":"{"PublicIP":"10.97.217.158"}","expiration":"2015-11-05T08:16:21.995749971Z","ttl":38993,"modifiedIndex":388599,"createdIndex":388599},{"key":"/coreos.com/network/subnets/192.168.76.0-24","value":"{"PublicIP":"10.97.217.148"}","expiration":"2015-11-05T04:32:45.528111606Z","ttl":25576,"modifiedIndex":385909,"createdIndex":385909},{"key":"/coreos.com/network/subnets/192.168.40.0-24","value":"{"PublicIP":"10.97.217.51"}","expiration":"2015-11-05T15:18:27.335916533Z","ttl":64318,"modifiedIndex":393675,"createdIndex":393675}],"modifiedIndex":79,"createdIndex":79}}
This section describes the basic architecture and methodology of Kubernetes and related components. Understanding Kubernetes is not easy, but a step-by-step lesson on how to setup, configure, and manage Kubernetes is really fun.
The following recipes describe how to install and configure related components: