In this tutorial, we will use kubeadm to configure Kubernetes cluster on CentOS 7.4.

IMPORTANT NOTE: Ensure swap is disabled on both master and worker nodes. Kubernetes requires swap to be disabled in order for it to successfully configure Kubernetes Cluster.

Before you start setting up Kubernetes cluster, it is recommended that you update your system to ensure all security updates are up-to-date.

Execute below command:

sudo yum update -y

Install Docker

In order to configure kubernetes cluster, it is require to install Docker. Execure below command to install Docker on your system.

sudo yum install -y docker

Enable & start Docker service.

sudo systemctl enable docker && sudo systemctl start docker

Verify docker version is 1.12 and greater.

sudo docker version
[rahil@k8s-master ~]$ sudo docker version
Client:
 Version:         1.12.6
 API version:     1.24
 Package version: docker-1.12.6-71.git3e8e77d.el7.centos.1.x86_64
 Go version:      go1.8.3
 Git commit:      3e8e77d/1.12.6
 Built:           Tue Jan 30 09:17:00 2018
 OS/Arch:         linux/amd64

Server:
 Version:         1.12.6
 API version:     1.24
 Package version: docker-1.12.6-71.git3e8e77d.el7.centos.1.x86_64
 Go version:      go1.8.3
 Git commit:      3e8e77d/1.12.6
 Built:           Tue Jan 30 09:17:00 2018
 OS/Arch:         linux/amd64

Install Kubernetes packages

Configure yum to install kubeadm, kubectl, and kubelet.

Copy below content and execute on your centos.

sudo bash -c 'cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF'

Disable SELinux:

sudo setenforce 0

In order for Kubernetes cluster to communicate internally, we have to disable SELinux. Currently SELinux is not fully supported. In future this may change when support for SELinux is improved.

Installing packages for Kubernetes:

On Master node:

sudo yum install -y kubelet kubeadm kubectl

Enable & start kubelet service:

sudo systemctl enable kubelet && sudo systemctl start kubelet

On worker nodes:

sudo yum install -y kubelet kubeadm kubectl

Copy below content and excute on centos master and worker nodes. There has been an issue reported that traffic in iptable is been routed incorrectly. Below settings will make sure IPTable is configured correctly.

sudo bash -c 'cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF'

Execute below command to apply above changes.

sudo sysctl --system

Once you have completed above steps on all your centos nodes including master & worker nodes. Let's go ahead and configure Master node.

Disable Firewall on Master node

Kubernets Cluster uses IPTables to manage inbound and outbound traffic. In order to avoid conflict, we will disable firewalld on centos 7 system. If you prefer to keep firewall enabled. I recommend allowing port 6443 to allow communication from worker node to master node.

Disable:

sudo systemctl disable firewalld

Stop:

sudo systemctl stop firewalld

Check status:

sudo systemctl status firewalld

Configuring Kubernetes Master node

On your CentOS master node execute below commands:

sudo kubeadm init --pod-network-cidr 10.244.0.0/16

NOTE: Ensure SWAP is disabled on all your Centos system. Kubernetes cluster configuration will fail if swap is not disabled.

Once above command is completed, it will output Kubernetes cluster information. Please make sure that you have the token information somewhere safe. It will be needed to join worker nodes to Kubernetes cluster.

Output from kubeadm init:

Your Kubernetes master has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

You can now join any number of machines by running the following on each node
as root:

  kubeadm join --token a2dc82.7e936a7ba007f01e 10.0.0.7:6443 --discovery-token-ca-cert-hash sha256:30aca9f9c04f829a13c925224b34c47df0a784e9ba94e132a983658a70ee2914

On Master node apply below changes after kubeadm init successful configuration:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

Configuring Pod Networking

Before we setup worker nodes, we need to ensure pod networking is functional. Pod networking is also a dependency for kube-dns pod to manage pod dns.

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/k8s-manifests/kube-flannel-rbac.yml

Ensure all pods are in running status by executing below command:

kubectl get pods --all-namespaces

It may take sometime depending on your system configuration and network speed. It pulls all the images from online to run required pods in system namespace.

Once all the pods are in running status, let's configure worker nodes.

Configure Kubernetes Worker nodes

To configure worker nodes to be part of Kubernetes cluster. We need to use kubeadm join command with token received from master node.

Execute below command to join worker node to Kubernetes Cluster.

sudo kubeadm join --token a2dc82.7e936a7ba007f01e 10.0.0.7:6443 --discovery-token-ca-cert-hash sha256:30aca9f9c04f829a13c925224b34c47df0a784e9ba94e132a983658a70ee2914

Once the node has joined the cluster, you will see similar output on your console.

[preflight] Running pre-flight checks.
        [WARNING Service-Kubelet]: kubelet service is not enabled, please run 'systemctl enable kubelet.service'
        [WARNING FileExisting-crictl]: crictl not found in system path
[preflight] Starting the kubelet service
[discovery] Trying to connect to API Server "10.0.0.8:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://10.0.0.8:6443"
[discovery] Requesting info from "https://10.0.0.8:6443" again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "10.0.0.8:6443"
[discovery] Successfully established connection with API Server "10.0.0.8:6443"

This node has joined the cluster:
* Certificate signing request was sent to master and a response
  was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the master to see this node join the cluster.

On kubernetes master node execute below command to see node status. If you see node status ready, that means your worker node is ready to host pods.

kubectl get nodes

Output for above command

[rahil@k8s-master-node ~]$  kubectl get nodes
NAME                STATUS    ROLES     AGE       VERSION
k8s-master-node     Ready     master    28m       v1.9.3
k8s-worker-node-1   Ready     <none>    3m        v1.9.3

If you see worker node status ready, then you are ready to deploy pods on your worker nodes.