This is a short tutorial showing how to build a small, single node, Kubernetes cluster that runs on a virtual private server (VPS). Perfect for small projects!
Kubernetes is great, it’s the standardized way to deploy containers into a production environment and has great tools to manage and control your entire application. However, getting a cluster from AWS, Azure or DigitalOcean can be expensive for small projects.
The cheapest solution now (08/08/2020) is KubeSail (https://kubesail.com/), they provide a free cluster with several interesting features (like automatically generate services and expose your application)
KubeSail perfect for very small projects or even if you want to study how to play with K8s, but if you have larger projects you may need more computational resources and this article shows a solution!
VPS, or a virtual dedicate server, is basically a virtual machine that you can buy as a service from hosting companies. There are several and here you can see a nice comparison table (https://www.comparevps.com/).
A nice suggestion is Contabo, they have a great deal for 5.0 eur/mo with 4vCPUs, 8 Gb RAM, 300 Gb of SSD and unlimited data transfer. But feel free to choose your preferred VPS 😊
***This tutorial uses Ubuntu version 18.04***
***This tutorial uses Docker version 19.03.12***
***This tutorial uses Kubernetes version 1.18.6***
How install a Kubernetes single node cluster
For this part I used Raimund Rittnauer great tutorial (https://raaaimund.github.io/tech/2018/10/23/create-single-node-k8s-cluster/)
1- Install Docker
First we have to download and add the GPG public keys (to ensure we are getting the right official package)
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Now you have to verify if the added key has the correct fingerprint
sudo apt-key fingerprint 0EBFCD88
You should get an output like this:
Now we have to add the Docker repository into our sources, we will use
add-apt-repository to that, then, first you might have to install
apt install software-properties-common
And now we can add and update the repository and install Docker:
sudo add-apt-repository "deb [arch=amd64]
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"sudo apt update && sudo apt install docker-ce
We must disable the swap memory as Kubernetes as it does not support it:
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
Now we will install Kubernetes in a similar fashion as we did with Docker:
sudo apt-get update && sudo apt-get install -y apt-transport-https && curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list && sudo apt-get update
sudo apt install -y kubeadm kubelet kubernetes-cni
Now we will initialize Kubernetes control-plane node. But, before that we must check our server IP, this can be done by:
ip addr show
Your server IP address can be found on the main network adapter (generally
inet like this:
Or you can check your IP address by your provider too.
So now we can initialize K8s:
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=<YOUR_SERVER_IP_ADDRESS>
Then, after some time, you will receive an output like this:
So you must follow the instructions to create the
.kube folder with the configuration file:
mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/config
Now we must install the networking model for kubernetes:
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
And finally we must allow our master note to run and manage pods:
kubectl taint nodes --all node-role.kubernetes.io/master-
If you want to control your Kubernetes cluster from your local computer, just copy the
conf file content and paste to your local machine:
Then it will show the configuration file, copy it and then in another terminal in your local machine environment:
sudo gedit ~/.kube/config
Now paste the content from
conf of your server and save it. Now (if you have kubectl installed on your computer) you will be able to manage your Kubernetes cluster from your local environment.
Enabling LoadBalancer to application exposure
This Tutorial was based on another tutorial (https://www.youtube.com/watch?v=xYiYIjlAgHY&t=423s) made by the Just me and Opensource YouTube channel
Congrats! Now you have your own Kubernetes cluster! However, one of the most important features is allow your applications be accessed from internet. You can do it with NodePort (I know, for a single node configuration maybe this is a good solution), but I think for practice and simulate a real world production environment is good to use LoadBalancer.
If you use some in cloud Kubernetes service (such the ones in AWS and Azure) the provider will take care of the Load Balancer instances. On the other hand, with a VPS you don’t have this feature, so you must use MetalLB and this tutorial will show you how:
First, just to test, we will create a simple NGINX server:
kubectl run nginx --image nginx
The command above will create a pod with the NGINX server, you can check it with:
kubectl get pods
You will receive something like:
Now we will try to expose this service to the internet, we can do it by simply:
kubectl expose pod nginx --port 80 --type LoadBalancer
Check now your service created (with additional information):
kubectl get service -o wide
This will output the following:
EXTERNAL-IP will hang on
<pending> forever as you don’t have a LoadBalancer service set.
To create a LoadBalancer service in our cluster, lets use MetalLB (https://metallb.universe.tf/) and make the installation by Manifest (https://metallb.universe.tf/installation/), following their steps:
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/namespace.yamlkubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.9.3/manifests/metallb.yamlkubectl create secret generic -n metallb-system memberlist --from-literal=secretkey="$(openssl rand -base64 128)"
Now you have to create a
ConfigMap for the MetalLB namespace, in orther to do that, first modify the file below and replace the address by your cluster IP (yes two times with a trace between them).
- name: default
Then, go to the terminal and create the ConfigMap by typing the following:
cat <<EOF | kubectl create -f -
- name: default
This will create a ConfigMap for your MetalLB LoadBalancer and, hopefully, your NGINX server will be able to be exposed in your IP address, then check again with:
kubectl get service -o wide
EXTERNAL-IP has your IP address, congratulations! You exposed your service through internet using LoadBalancer. Check it by accessing your IP address in the browser, you should get a default NGINX page.
In case your server was not correctly exposed, try to delete and recreate the exposure service by:
kubectl delete service nginxkubectl expose pod nginx --port 80 --type LoadBalancer
And that’s all for now! I hope you liked the tutorial and this helped you to create your own (cheap) Kubernetes cluster!