Installing Kubernetes on Ubuntu 20.10


As a developer we are confronted with cloud platforms of multiple vendors. Most of these platforms provide a way to deploy and run our developed applications in containers. Most of these platforms use Kubernete under the hood. To get more insight in Kubernete, which components are part of it and how things work together I decided to install Kubernete as basic as possible.

The first I tried was to install Kubernetes using the snap packages provided by Ubuntu itself.
The kubeadm and kubelet packages should be the minimal packages which are needed to setup a single node Kubernetes cluster.
However, I did not manage to get this working in the end.

The second try was using MicroK8s and I was pleasantly surprised about the ease to install and the fact that it just works.
However, there is one side note: because MicroK8s installs all the stuff for you with sensible defaults, it is not directly visible what is installed, how it is configured and how all the moving parts work together.

In the upcoming weeks I will try to investigate more about MicroK8s and Kubernetes in general and write some additional blog posts about my journey.

This is the first of this series and just describes how to install MicroK8s.

What does MicroK8s install?

MicroK8s is a all-in-one Kubernetes installation.
It contains all the necessary bits and pieces to get a working Kubernetes setup. MicroK8s is available on:

  • Linux (as a snap package)
  • MacOS (as a brew package)
  • Windows (as a installable exe)

Here we will use the snap package on an Ubuntu 20.10 system.
Snaps are installed in a predefined structure.
The following directory locations on your system might be of interest to you if you want to know a bit more on what is installed.


After the installation the following services are active (on my machine at least):

  • snap.microk8s.daemon-apiserver-kicker
  • snap.microk8s.daemon-apiserver
  • snap.microk8s.daemon-cluster-agent
  • snap.microk8s.daemon-containerd
  • snap.microk8s.daemon-control-plane-kicker
  • snap.microk8s.daemon-controller-mananer
  • snap.microk8s.daemon-kubelet
  • snap.microk8s.daemon-proxy
  • snap.microk8s.daemon-scheduler

Mentioned in the documentation, but not running on my machine with a default installation:

  • snap.microk8s.daemon-etcd
  • snap.microk8s.daemon-flanneld


There are no specific things which need to be installed or configured before installed MicroK8s (as far as I know).

I do already have kubectl installed on my machine because I also used it before to manage other Kubernetes clusters but this is not required.
If you have kubectl installed, see the Post installation paragraph to configure your local kubectl to control the MicroK8s installation.

Install MicroK8s

This is (should be, you never know for sure with computers!) the easy part.
If you want you can first obtain information about the versions and the to be installed package:

 sudo snap info microk8s

The following command installs the microk8s snap.

 sudo snap install microk8s --classic

The –classic parameter is needed because of the way snap works.
Snaps are typically installed in a what they call ‘a tightly controlled space’.
This restricts access to a vast majority of system resources.
MicroK8s however needs extensive access to your system resources and with the –classic parameter a different confinement is used in which the snap has full access to all the system resources.

The last thing you need to do is to add your username to the newly created microk8s user group.
this group is used to control the access to MicroK8s commands and files.

 sudo usermod -a -G microk8s <<YOUR USERNAME>> <-- Needs a restart

After these commands the Kubernetes cluster should be up and running.

Verify the installation

Verifying MicroK8s itself

The first thing to do is to check the status of the MicroK8s services:


This will list the status of MicroK8s and which addons are enabled and disabled:

microk8s is running
high-availability: no
  datastore master nodes:
  datastore standby nodes: none
    ha-cluster           # Configure high availability on the current node
    ambassador           # Ambassador API Gateway and Ingress
    cilium               # SDN, fast with full network policy
    dashboard            # The Kubernetes dashboard
    dns                  # CoreDNS
    fluentd              # Elasticsearch-Fluentd-Kibana logging and monitoring
    gpu                  # Automatic enablement of Nvidia CUDA
    helm                 # Helm 2 - the package manager for Kubernetes
    helm3                # Helm 3 - Kubernetes package manager
    host-access          # Allow Pods connecting to Host services smoothly
    ingress              # Ingress controller for external access
    istio                # Core Istio service mesh services
    jaeger               # Kubernetes Jaeger operator with its simple config
    keda                 # Kubernetes-based Event Driven Autoscaling
    knative              # The Knative framework on Kubernetes.
    kubeflow             # Kubeflow for easy ML deployments
    linkerd              # Linkerd is a service mesh for Kubernetes and other frameworks
    metallb              # Loadbalancer for your Kubernetes cluster
    metrics-server       # K8s Metrics Server for API access to service metrics
    multus               # Multus CNI enables attaching multiple network interfaces to pods
    portainer            # Portainer UI for your Kubernetes cluster
    prometheus           # Prometheus operator for monitoring and logging
    rbac                 # Role-Based Access Control for authorisation
    registry             # Private image registry exposed on localhost:32000
    storage              # Storage class; allocates storage from host directory
    traefik              # traefik Ingress controller for external access

Another command which is helpful to ‘inspect’ your MicroK8s installation is:


This command will ask for your password to get elevated privileges to be able to obtain all relevant data.

The result is information on which services are running and produces an additional report which can be accessed as mentioned on the last line of the inspection output with much more details.

Inspecting Certificates
Inspecting services
  Service snap.microk8s.daemon-cluster-agent is running
  Service snap.microk8s.daemon-containerd is running
  Service snap.microk8s.daemon-apiserver is running
  Service snap.microk8s.daemon-apiserver-kicker is running
  Service snap.microk8s.daemon-control-plane-kicker is running
  Service snap.microk8s.daemon-proxy is running
  Service snap.microk8s.daemon-kubelet is running
  Service snap.microk8s.daemon-scheduler is running
  Service snap.microk8s.daemon-controller-manager is running
  Copy service arguments to the final report tarball
Inspecting AppArmor configuration
Gathering system information
  Copy processes list to the final report tarball
  Copy snap list to the final report tarball
  Copy VM name (or none) to the final report tarball
  Copy disk usage information to the final report tarball
  Copy memory usage information to the final report tarball
  Copy server uptime to the final report tarball
  Copy current linux distribution to the final report tarball
  Copy openSSL information to the final report tarball
  Copy network configuration to the final report tarball
Inspecting kubernetes cluster
  Inspect kubernetes cluster
Inspecting juju
  Inspect Juju
Inspecting kubeflow
  Inspect Kubeflow

# Warning: iptables-legacy tables present, use iptables-legacy to see them
WARNING:  Docker is installed. 
Add the following lines to /etc/docker/daemon.json: 
    "insecure-registries" : ["localhost:32000"] 
and then restart docker with: sudo systemctl restart docker
Building the report tarball
  Report tarball is at /var/snap/microk8s/2094/inspection-report-20210416_155317.tar.gz

As you can see there are also some warnings in this inspection report. The microk8s.inspect command is actually a script which is located in the /snap/microk8s/current/script directory. After investigation the following can be concluded:

# Warning: iptables-legacy tables present

This is actually not a warning generated by the inspect script itself, but it is a warning generated by the iptables command used in the inspect script.

This warning indicates legacy iptables exist on the system while the prefered way is to use the netfilter tables.

The complete iptables-legacy tables are actually generated by MicroK8s so somehow the installation adds these tables itself but it should have used iptables-nft.

This is at least what I understand. I have created an issue in the MicroK8s github space:

WARNING: Docker is installed

This warning is a bit strange because:

  1. It only checks if docker is installed based on a check if the /etc/docker directory exists on your system
  2. It does NOT check if you actually have the ‘registry’ addon activated for microk8s.

The first point might be confusing if you previously had docker installed but removed it and still get this warning. Now you know that only the presence of /etc/docker directory is enough to show this warning message.

The second point is in my opinion more tricky because the default installation as described here does not enable the registry (see microk8s.status). The message however does point out to add configuration to the /etc/docker/daemon.json file, adding the registry listening port.

So if you would add the lines described above to your /etc/docker/daemon.json it actually will point to a non existent docker registry!

Verifying Kubernetes

The previous commands are part of MicroK8s and are not part of Kubernetes itself.
The following command is the first command directly executed on the Kubernetes cluster itself and should return the status of the cluster:

 microk8s.kubectl cluster-info

Which will result in output similar to:

Kubernetes control plane is running at

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

The following command lists all available namespaces (virtual clusters):

 $ microk8s.kubectl get namespace

 NAME              STATUS   AGE
 kube-system       Active   24h
 kube-public       Active   24h
 kube-node-lease   Active   24h
 default           Active   24h

Now you have verified MicroK8s is up and running we can continue to really start using it.
However, to facilitate and ease the use of Kubernetes, I also did some post installation stuff.

Post installation stuff

Configure your local kubectl to work with the cluster

If you already installed the kubectl tool and want to use this tool to access the cluster, continue reading.

MicroK8s aims to provide you with all the necessary tools to start working with the cluster.
This includes its own kubectl command (microk8s.kubectl) which we used in the previous examples.

Although the documentation shows how to add an alias for this command, I think this is not transparant because of the fact that the entire configuration is hidden.

So to better understand how the cluster can be managed, I prefer to use the default kubectl command and just configure it to use the MicroK8s cluster.
To do this, it is easy to extract the configuration into the normal kubectl configuration location:

microk8s.kubectl config view --raw > $HOME/.kube/config

Now the configuration is stored in the normal location and you can just use the standard kubectl command. For example:

kubectl get namespaces

Add bash completion

If you are using the kubectl command line tool it is also easy to have bash auto completion.
This is all made easy for us as users, just use the following command:

echo "source <(kubectl completion bash)" >> ~/.bashrc

This will permanently add the required bash autocompletion configuration to your .bashrc file so it will be available in your bash shells.
Note that this will require you to restart your bash shell.


MicroK8s makes it really easy to setup a Kubernetes cluster on an Ubuntu machine.
It contains tools to verify its own installation, services and add-ons, and also provides the tools to access the Kubernetes cluster itself.

We have also configured our own kubectl command to use the MicroK8s cluster and are now ready to start using the Kubernetes single node cluster.

NOTE: Although MicroK8s installs a Kubernetes cluster, this cluster currently only consists of a single node and therefor is not really a cluster yet with high availability and resilience to failure.




Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s