How to build a Raspberry Pi Kubernetes cluster using MicroK8s

Key Value
Summary How to deploy a multi-node Kubernetes cluster on your Raspberry Pi 4, 3 or 2. At the end of this tutorial, you will have a production-grade K8s cluster, easy to scale, running on top of MicroK8s.
Categories iot, raspberrypi, kubernetes, microk8s
Difficulty 2
Author Canonical Web Team


Duration: 1:00

This tutorial will be a brief walk through the process of getting MicroK8s up and running on Raspberry Pi, and joining multiple Pis to form a production-grade Kubernetes cluster.

MicroK8s is a lightweight, fast, enterprise-grade Kubernetes. Whether you’re new to K8s or a power user, MicroK8s will help you save time and space on any embedded device or IoT projects.

This setup can be fully headless or using an HDMI screen and USB keyboard to control nodes of your cluster.

What you’ll learn

  • Deploying Kubernetes on Raspberry Pi using MicroK8s
  • Joining multiple deployments to form a cluster
  • Managing the cluster: adding and removing nodes

What you’ll need

  • A 16.04 LTS (or later) Ubuntu desktop
  • A minimum of 2 Raspberry Pis, they need to be Pi 3B or later. (You can use as many as you like, here we use 3)
  • A micro-USB power cable for each Pi (USB-C for Pi4)
  • A USB power-supply with as many ports as you have boards
  • A microSD card per Pi (8GB recommended), flashed with an Ubuntu Server image
  • Some basic command-line knowledge


  • A monitor with an HDMI interface
  • An HDMI cable if you’re using Pis 2 or 3 or a MicroHDMI cable for the Pi 4
  • A Cat5/6 network cable for each board is preferred, but Wi-FI setup is possible as well
  • A USB keyboard
  • A cluster rack (Here we are using the Cluster Case from the PiHut)

You will also need to have all of the boards on the same network, with a terminal window ready to connect to each Pi through SSH.

Building the cluster

Duration: 30:00

If you have gone ahead and purchased a rack for your Pis now is the time to set it up. The time to build will vary depending on which rack you bought and how nimble your fingers are, but it shouldn’t take you longer than 45 minutes. We recommend you do this at the start to have everything nicely organised before you get going.

If you have the PiHut Cluster Case that we used here, the assembly instructions are very straight forward. Here are a couple of in-progress shots for reference:

:warning: Warning
Do not handle nuts over a dark carpet. One (or two) slips and those suckers will be lost forever. Trust me.

Once you’re done it should look something like this:

If you don’t have a rack, just ensure that the Pis can be connected to a power source and be in a location allowing them to connect to the same network (through WiFi or ethernet).

Setting up each Pi

Duration: 10:00

Each Pi is going to need an Ubuntu server image and you’ll need to be able to SSH into them.

This tutorial will teach you how to get to this stage. Follow it all the way until the install a desktop section. Go ahead and do that in another tab. We’ll wait.

:warning: Warning
MicroK8s is only available for 64-bit Ubuntu images.

Afterwards you should be able to log in to your Pis on your network using their IP addresses.

Installing MicroK8s

Duration: 2:00

Follow this section for each of your Pis. Once completed you will have MicroK8s installed and running everywhere.

SSH into your first Pi and there is one thing we need to do before we get cracking. We need to enable c-groups so the kubelet will work out of the box. To do this you need to modify the configuration file /boot/firmware/cmdline.txt:

sudo nano /boot/firmware/cmdline.txt

And add the following options:

cgroup_enable=memory cgroup_memory=1

The full line for this particular raspberry pi looks like this:

cgroup_enable=memory cgroup_memory=1 net.ifnames=0 dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

Now save the file in your editor and reboot:

sudo reboot

Once that’s done we can now Install the MicroK8s snap:

sudo snap install microk8s --classic

What Kubernetes version is this installing?

MicroK8s is a snap and as such it will be automatically updated to newer releases of the package, which is following closely upstream Kubernetes releases.

To follow a specific Kubernetes upstream series it’s possible to select a channel during installation. For example, to follow the v1.17 series:

sudo snap install microk8s --classic --channel=1.17/stable

Channels are made up of a track (or series) and an expected level of stability, based on MicroK8s releases (Stable, Candidate, Beta, Edge). For more information about which releases are available, run:

snap info microk8s

Discovering MicroK8s

Before going further here is a quick intro to the MicroK8s command line:

  • The start command will start all enabled Kubernetes services: microk8s.start
  • The inspect command will give you the status of services: microk8s.inspect
  • The stop command will stop all Kubernetes services: microk8s.stop
  • You can easily enable Kubernetes add-ons, eg. to enable “kubedns”: microk8s.enable dns
  • To get the status of the cluster: microk8s.kubectl cluster-info

MicroK8s is easy to use and comes with plenty of Kubernetes add-ons you can enable or disable.

Master node and leaf nodes

Duration: 2:00

Now that you have MicroK8s installed on all boards, pick one is to be the master node of your cluster.

On the chosen one, run the following command:

sudo microk8s.add-node

This command will generate a connection string in the form of <master_ip>:<port>/<token>.

Adding a node

Now, you need to run the join command from another Pi you want to add to the cluster:

microk8s.join <master_ip>:<port>/<token>

For example:


You should be able to see the new node in a few seconds on the master with the following command:

microk8s.kubectl get node

For each new node, you need to run the microk8s.add-node command on the master, copy the output, then run microk8s.join <master node output> on the leaf.

Removing nodes

Duration: 1:00

To remove a node, run the following command on the master:

sudo microk8s remove-node <node name>

The name of nodes are available on the master by running the microk8s.kubectl get node command.

Alternatively, you can leave the cluster from a leaf node by running:

sudo microk8s.leave

That’s it!

You are now in control of your Kubernetes cluster: once Pis are setup with MicroK8s, adding and removing nodes is easy and you can scale up or down as you go.

What’s next?

The opportunities from here onwards are endless, we can’t wait to see what you come up with with your Pi cluster. For feedback, bug reports or contributing, reach out on GitHub, chat with us on the Kubernetes Slack, in the #microk8s channel, Kubernetes forums or tag us @canonical or @ubuntu, on Twitter (#MicroK8s).

And we of course recommend reviewing the microk8s documentation to get better acquainted with MicroK8s.

1 Like

the command to remove has been updated (checked in micok8s snap version 1.18)

microk8s remove-node

Also, are there plans to change terminology away from master/node? I’ve been asked by several folks lately. Other places have started referring to the relationship as “server/workers”. or maybe “control/workers”

This doesn’t work as in the tutorial…the cgroup memory is disabled by default…not sure how to enable it, just saying it doesn’t work

1 Like

Hey zwhitchcox, thanks for letting us know. Would you mind filling a bug here:

So the right people know and can look into fixing it?

Each node should have a different name before being joined. To change default node name from ubuntu to something like ubuntu1 etc. (sudo vi /etc/hostname …)

1 Like

Update Instructions to join the microk8 group per on each node:

MicroK8s creates a group to enable seamless usage of commands which require admin privilege. To add your current user to the group and gain access to the .kube caching directory, run the following two commands:

sudo usermod -a -G microk8s $USER
sudo chown -f -R $USER ~/.kube

You will also need to re-enter the session for the group update to take place:

su - $USER

Otherwise joining a leaf node to the master node will fail with the following permission erros:
Traceback (most recent call last): File "/snap/microk8s/xxxx/scripts/cluster/", line 967, in <module> join_dqlite(connection_parts) File "/snap/microk8s/xxxx/scripts/cluster/", line 900, in join_dqlite update_dqlite(info["cluster_cert"], info["cluster_key"], info["voters"], hostname_override) File "/snap/microk8s/xxxx/scripts/cluster/", line 818, in update_dqlite with open("{}/info.yaml".format(cluster_backup_dir)) as f: FileNotFoundError: [Errno 2] No such file or directory: '/var/snap/microk8s/xxxx/var/kubernetes/backend.backup/info.yaml'

I would expect an estimate on the resources required.
The article has been created a bit earlier on and I guess 1 GB RAM will not be sufficient.

There is a part missing in “The full line for this particular raspberry pi looks like this:”, the final fixrtc

cgroup_enable=memory cgroup_memory=1 net.ifnames=0 dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=LABEL=writable rootfstype=ext4 elevator=deadline rootwait fixrtc

For newbies this is a key follow on link to include int he article

Great article to get some experience using K8’s. My one question if you have an array of different raspberry pi’s, for an example, 1 x RPI3b, 1x RPI4 with 8GB RAM and 1x RPI4 4GB RAM which is the best to run as the master?

Would it be the 3b? The only reason I suggest this is because it has a lot less RAM than the other two and I’d figure the apps running across the cluster will use more than the master.

1 Like

Great article!! I would inform you that last version 1.22 does not work with Ubuntu 21.10 release (on RPi4 8gb) but very well with LTS 20.04.
Microk8s goes in endless loop with calico-kube-controllers in ContainerCreating state

Thanks for the clear break down for installing a Raspberry PI Kubernetes Cluster, as stated by @alfax1962 there is an issue running it on Ubuntu 21.10. This can be overcome by installing extra kernel modules with this command: “sudo apt install linux-modules-extra-raspi”.

Another step that may also be useful to amend would be the changing of the devices hostname, as the default “ubuntu” seems to effect how nodes are displayed if there are multiple with the same name.

1 Like

Has anyone been successful at getting this to work on a couple of Raspberry Pi 3 Model B Plus Rev 1.3? The instructions indicate that it should work but I’m not able to get the two Pi’s joined in a cluster.

Suggest an extra page with information on how to verify that installation of clustered mikcrok8s was successful.
Info that can be usefull.
What extra IP numbers wiil be active on each node. (example output of ip a)
What IP routes will be active (example output of ip r)

what pods will be running (example output of microk8s.kubectl get pods -A -o wide)

test that all nodes can reach kubernetes service

  • get IP (kubectl get svc)
  • run curl -I -k https://<Above IP#>

If above isn’t OK suggest

Use as template for deploy and test access of containers and services (without extra debug and DNS stuff, image need to be replaced with something that runs on arm64)

microk8s will always fail, if you do not first execute:

sudo apt install linux-modules-extra-raspi

tested on Ubuntu 22.04 LTS and rasp4