Skip to content

Manual installation of a Single Node Kubernetes Cluster managed with Muppy

This document describes how to configure a secured single node microk8s Cluster managed with Muppy Pack8s (Multi Cloud HA), by running the installation commands yourself.

For the same cluster installed by Muppy Tasks instead of by hand, see SingleNode Cluster - Tasks.

A single node cluster is a k8s cluster with only one node, which runs:

  • the Control Plane
  • Kubelet (worker)
  • PostgreSQL (see the options)

Info

There are three options for PostgreSQL:

  • do not install it
  • install it on the Node
  • install it on a separate host.

Prerequisites

The Host must have at least one Private interface.

The following options are possible:

  • Public IP + Mesh VPN (Tailscale, Nebula, Wireguard, …)
  • Public IP + Private IP
  • Private IP + SSH Gateway

In the rest of this document, NODE_PRIVATE_IP denotes the host's private IP.

Provision a host with a Private IP, or install a mesh VPN; write down the value of NODE_PRIVATE_IP and enrol it in Muppy.

Install microk8s

sudo snap info microk8s

# Careful: the Firewall must be changed before installing microk8s
sudo ufw default allow routed

sudo apt install -y snapd 

# Do not apply the following rules yet
# sudo ufw allow in on cni0 && sudo ufw allow out on cni0
# sudo ufw default allow routed

sudo snap install microk8s --classic --channel=latest/stable \
&& sudo usermod -a -G microk8s $USER \
&& newgrp microk8s

microk8s status --wait-ready

microk8s kubectl get -A all
microk8s status
microk8s inspect

Reconfiguring the interfaces k8s uses

# stop microk8s
sudo microk8s stop

kube-proxy

The Kubernetes network proxy runs on each node. This reflects services as defined in the Kubernetes API on each node and can do simple TCP, UDP, and SCTP stream forwarding or round robin TCP, UDP, and SCTP forwarding across a set of backends.

We force k8s to publish the Nodeports on the internal interface.

export MPY_K8S_NODE_PRIVATE_IP=10.0.4.1
sudo grep -q '^--nodeport-addresses=' /var/snap/microk8s/current/args/kube-proxy && sudo -E sed -i "s/^--nodeport-addresses=.*/--nodeport-addresses=${MPY_K8S_NODE_PRIVATE_IP}\/32/" /var/snap/microk8s/current/args/kube-proxy || echo "--nodeport-addresses=${MPY_K8S_NODE_PRIVATE_IP}/32" | sudo tee -a /var/snap/microk8s/current/args/kube-proxy
# cat /var/snap/microk8s/current/args/kube-proxy

kubelet

The kubelet is the primary "node agent" that runs on each node. It can register the node with the apiserver using one of: the hostname; a flag to override the hostname; or specific logic for a cloud provider.

We force the node's IP.

sudo grep -q '^--node-ip=' /var/snap/microk8s/current/args/kubelet && sudo -E sed -i "s/^--node-ip=.*/--node-ip=${MPY_K8S_NODE_PRIVATE_IP}/" /var/snap/microk8s/current/args/kubelet || echo "--node-ip=${MPY_K8S_NODE_PRIVATE_IP}" | sudo tee -a /var/snap/microk8s/current/args/kubelet
# cat /var/snap/microk8s/current/args/kubelet

kube-apiserver

The Kubernetes API server validates and configures data for the api objects which include pods, services, replicationcontrollers, and others. The API Server services REST operations and provides the frontend to the cluster's shared state through which all other components interact.

We advertise the services on the private IP.

sudo grep -q '^--advertise-address=' /var/snap/microk8s/current/args/kube-apiserver && sudo -E sed -i "s/^--advertise-address=.*/--advertise-address=${MPY_K8S_NODE_PRIVATE_IP}/" /var/snap/microk8s/current/args/kube-apiserver || echo "--advertise-address=${MPY_K8S_NODE_PRIVATE_IP}" | sudo tee -a /var/snap/microk8s/current/args/kube-apiserver
# cat /var/snap/microk8s/current/args/kube-apiserver
# Reboot the host
sudo reboot
microk8s start
microk8s status
microk8s kubectl get -A all
microk8s kubectl get nodes -o wide  # check node Internal IP is private

# Generate a Kubeconfig
microk8s config > $HOSTNAME-kubeconfig.yaml

Enabling hostpath-storage

If you need PersistentVolume, you must install hostpath-storage.

Ref: https://microk8s.io/docs/addon-hostpath-storage

microk8s enable hostpath-storage

Registering the k8s cluster in Muppy

  • Use Muppy / K8s / K8s Clusters to create a Cluster.
  • Upload the config file through the Kubeconfig field, or copy/paste its content into the "Kubeconfig" and "Kubeconfig" filename fields.
  • Fill in the Qualifier and Provider fields.

Click "Update Info". If the Namespaces are retrieved, the cluster is ready to be used with Muppy.

Installing PostgreSQL

Follow the Muppy documentation.

The only specific point is the UFW configuration. You must:

  • allow traffic from the private network, or from the cluster if PostgreSQL is on a dedicated server
  • allow traffic from the Pods if the database is on the kubernetes worker.

Info

To find the Pods' CIDR, run this command on the node: sudo grep -R 'cluster-cidr=' /var/snap/microk8s/current/args/. Unless it has been changed, the Pods' CIDR is 10.1.0.0/16 on microk8s (the default Calico Pods Range) and 10.244.0.0/24 on K0s.

  • allow traffic from a Replica, if there is one

Conclusion

Kubernetes is installed. The next step is installing the Infrastructure Packages, which is documented here: Infrastructure Packages

Note the following specifics of SingleNode Kubernetes clusters:

  • Cert-Manager is deployed in the cluster
  • Traefik is configured as an Ingress and connected to a second Traefik acting as the LoadBalancer.
  • Certificates can be verified over HTTP or over DNS.

Using UFW logging

sudo ufw logging on
sudo tail -f /var/log/ufw.log
sudo ufw logging off