Deploy Kubernetes using kubeadm in Ubuntu 18.04 running on VMware Workstation

Following up the series of homelab guides, I will explain how I setup my Kubernetes lab running from my laptop with VMware Workstation using Ubuntu Server 18.04 LTS as base OS.

Details of my environment:

Dell Latitude 7480

  • Intel Core i7-7600U @2.8GHz
  • 32GB RAM
  • Windows 10 Enterprise x64
  • VMware Workstation 14 Pro

I downloaded the latest Ubuntu ISO (ubuntu-18.04.4-live-server-amd64.iso) and started the Virtual Machine creation wizard to create first the master server.

And selected to install from the iso file.

You can use all the defaults, or change them according to your preferences. I used the defaults, but if you want kubeadm to go without complaining you need to configure the Virtual Machine with 2 vCPUs.

The virtual machine will boot and you will need to go through the installation of Ubuntu.

It’s important to setup a static IP address and additional networking configuration. It’s better to do it at this moment.

You will also setup the name of the system, and also create the initial administration account. I named my master “k8s-master”.

You will need to do the same steps to create another virtual machine for the worker(s) nodes, and name and setup the network configuration for each.

When you are ready creating your virtual machines, you can start configuring Kubernetes. The following steps need to be run in ALL the nodes, master and worker nodes:

1. First thing, you MUST disable swap in order for Kubernetes to work properly:

sudo swapoff -a
sudo vi /etc/fstab (Comment # the swap line) 

2. Then, you need to install the container runtime. We will use Docker that is the more popular option:

sudo apt-get install -y docker.io

sudo -i 
cat > /etc/docker/daemon.json <<EOF
{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "100m"
  },
  "storage-driver": "overlay2"
}
EOF

sudo systemctl restart docker
sudo systemctl enable docker

3. Then we need to install kubeadm, kubelet and kubectl

sudo apt-get update && sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <<EOF | sudo tee /etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

After this, we are ready to install and configure our master node. You will use kubeadm init command that will bootstrap all the Kubernetes control plane elements, and at the end you will get the instructions to configure kubectl to work with your newly created cluster as well as the command that you need to run in the workers nodes:

sudo kubeadm init

W0321 22:51:00.188540   12917 validation.go:28] Cannot validate kube-proxy config - no validator is available
W0321 22:51:00.188777   12917 validation.go:28] Cannot validate kubelet config - no validator is available
[init] Using Kubernetes version: v1.17.4
[preflight] Running pre-flight checks
[preflight] Pulling images required for setting up a Kubernetes cluster
[preflight] This might take a minute or two, depending on the speed of your internet connection

.......

Your Kubernetes control-plane 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/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.231.60:6443 --token 4zgqvs.ne34lhz9qp2t8wbv \
    --discovery-token-ca-cert-hash sha256:557448ff3ad340c109bf0755dc412c5132d36e98ebbed21dc878ad80fac51758

You need to setup the enviroment for kubectl to work:

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

And then, install a Container Network Interface (CNI) for the cluster be fully initialized. Until you don’t install one, it will be in NotReady state. You have multiple options (Flannel, Calico.. etc), but I chose Weave Net. Installing the CNI is as easy as running the following command:

kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

After that, you will have your master node in Ready status like this:

jfcoronado@k8s-master:~$ kubectl get nodes
NAME            STATUS     ROLES    AGE   VERSION
k8s-master      Ready      master   76m   v1.17.4

The only pending part is to go to the worker nodes, that you need to setup first using the steps 1, 2 and 3. And then, run the command that was provided from kubeadm init in the master (token and hash will be specific to your environment).

sudo kubeadm join 192.168.231.60:6443 --token 4zgqvs.ne34lhz9qp2t8wbv \
    --discovery-token-ca-cert-hash sha256:557448ff3ad340c109bf0755dc412c5132d36e98ebbed21dc878ad80fac51758

That will join the worker node to your cluster. If you check again, you will see it was added. After a couple of minutes it will be also in Ready status:

jfcoronado@k8s-master:~$ kubectl get nodes
NAME            STATUS     ROLES    AGE   VERSION
k8s-master      Ready      master   76m   v1.17.4
k8s-worker-01   NotReady   <none>   17s   v1.17.4

Well.. that finishes this guide, I hope it was helpful…