Kubernetes Home Server Using Monokle

Apr 29, 2022
7 min
Erdi Köse
Software Engineer

Learn how to create your own Kubernetes home server and expose it to the internet with the help of Monokle, a Kubernetes manifest IDE.

Share on Twitter
Share on LinkedIn
Share on Reddit
Share on HackerNews
Copy URL

Table of Contents

No items found.

Try Monokle Desktop Today

Like many developers out there I too have applications ready to be tested in a production-like environment and for this purpose I was using cloud providers like GCP or AWS. Even though cloud providers are easy to set up and use, I realized they are not that great especially for testing purposes. Because even if I don’t use the servers, I am still charged and I just didn’t want to pay for something I rarely use. So I decided to install my own k8s server and expose it to the internet.

I will walk through my experiences while doing this and will try to explain every step. Before we start we need to have some prerequisites such as,

* At least 1 server that has at least 2GB of ram (I use Raspberry Pi 4B but you can use whatever you want.)
* Static IP (You can buy it from your internet service provider)

* A valid domain (Yeah you know you need to buy it)

* Monokle, Kubectl, Helm installed
* Some Linux and Kubernetes knowledge

## Preparing the servers
I assume that you have Raspberry Pi servers and will explain everything keeping that in mind.First, we need to install a Linux operating system on the machines. I prefer Ubuntu server 21.10.

Then we will continue by installing microk8s on the machines. To install microk8s we need to ssh to servers and run:

-- CODE language-bash --
sudo snap install microk8s --classic

After this command is successfully completed. We can check microk8s status by running this command;

-- CODE language-bash --
microk8s status --wait-ready

If everything is OK, you can install microk8s on the other servers. You can install as many as the nodes you would like to have by repeating the same steps.

Then we need to pick one server as our master server. You can decide on how handsome it looks, I picked it this way 😁 So SSH to our new master server and run: 

-- CODE language-bash --
microk8s enable dashboard dns

This command will enable dashboard and DNS on our k8s node. And now we are able to visit and see the k8s dashboard by running:

-- CODE language-bash --
microk8s dashboard-proxy

That is all now we have a master node installed. Let’s add other nodes as slave nodes to the master. First, we need to run this command on the master node:

-- CODE language-bash --
microk8s add-node

This command will output some instructions that you need to run on your slave nodes, such as

-- CODE language-bash --
microk8s join

Run this command on all slaves and we will have a fully running k8s cluster with N many nodes. You can confirm that by running the command below on your personal PC.

-- CODE language-bash --
kubectl get nodes

## Deploying a sample application

Let's deploy our first application. I have created a simple application and dockerized it for this purpose. I will use this image but you can use the one you have too.

Now when we open Monokle we will see a screen like this:

deployment templates for home servers

We need to create a project to deploy our application to our k8s cluster. To do that, we have 3 options (above). I will go with the **Start from a template** option since I don’t want to spend a lot of time with resource creation. I gave the *Calculation App* name to my project and selected the **Basic Service Deployment** template.

When I select the template, the modal below will pop up. I filled the form as follows:

cluster deployment settings

-- CODE language-bash --
Name: calculation-api
Namespace: calculation-app
Image: erdkse/calculation-api:v1.0.0
Service port: 8080
Target port: 8080

After you click the **Create** button, your project will be created by Monokle and you will see the generated resources. I want to make some additional changes to generated resources.

Let’s select the `calculation-api` deployment resource in the Navigator pane and select the `Form` section in the Editor pane. And please find the Image Pull Policy section and pick Always.  And also I want to change the type of our service to ClusterIP. Let’s select our service resource and again select the `Form` section in the Editor pane. And please find the Type section and pick ClusterIP.

We can now save our 2 resources.

And yes!! We are ready to serve our application without writing any line of YAML 😁

YAML file with no code

All we need to do is click the **Deploy** button (at the top right of the **Editor** pane) And we are ready! We can now test our service and deployment by port-forwarding.

Let’s run this command and navigate to localhost:8080 to view our application:

-- CODE language-bash --
kubectl port-forward service/calculation-api 8080:8080

## Configuring Ingress and MetalLB

We served our application, but this is not a good approach for the real world. We have also not published our application to the world yet. To do it, we need to configure our Load Balancers.

Let’s start by installing ingress-nginx. You need to run these commands:

-- CODE language-bash --
helm upgrade
--install ingress-nginx ingress-nginx
--repo https://kubernetes.github.io/ingress-nginx
--namespace ingress-nginx

After you install ingress-nginx to our cluster, you will be able to serve our application through a domain address.

Now we need to create a resource. Please right-click on the project root folder in the **File Explorer** pane and select **New Resource**. You will see a modal like below – I filled the form with these values:

resource form control

Now we created our Ingress resource after some additions to my Ingress resource, which will look like this:

After deploying this resource, Voila! Now we are able to see the application when we visit: 

-- CODE language-bash --

Now we need to install MetalLB as our external LoadBalancer to listen for traffic from our router to our host machine. We are close to exposing our cluster to the world!  🎉

Let’s install MetalLB with the help of Helm and Monokle. First, add MetalLB to Helm repos by running this command:

-- CODE language-bash --
helm repo add metallb https://metallb.github.io/metallb

And pull metallb into our directory by running this command:

-- CODE language-bash --
helm pull metallb/metallb --untar

<strong>Now</strong>, open Monokle again and on the left menu, we will see the Helm section. Let’s modify the *values.yaml* file to handle incoming traffic from our router:

Monokle Helm Chart Control

Change configInline section in values.yaml file as follows:

Please change CLUSTER_IP with your host machine's private IP that is received from the router. Install metallb to your cluster.

Now, we are all set and you should be able to receive traffic from the router. We have only a few additional steps left.

* Direct your domain name that you purchased from a provider to your public IP address that you purchased from your ISP.
* Direct 80 and 443 ports of your router to 80 and 443 ports of your host machine that the cluster is installed.
* Update domain address of ingress to your valid domain. And deploy again.

And MAGIC! You exposed your k8s server to the world. Congratulations!

## Applying Encrypt SSL certificate to domain (Optional)

Now we exposed our server to the world, but wouldn’t it be nice if we have a valid SSL too? It is pretty easy and straightforward to do.

First we need to create and issuer, You can create your resource by Monokle and edit the resource as follows:

And update your Ingress resource as follows:

And after deploying these updated resources you will be able to issue an SSL certificate for your domain/domains.

I hope you enjoyed reading this blog post. If you have any questions please don’t hesitate to ask!

Related Content