Yes - you can create a Kubernetes cluster with Raspberry Pis with the default operating system called Raspbian. This means you can carry on using all the tools and packages you're used to with the officially-supported OS.
This is part of a blog post [Serverless Kubernetes home-lab with your Raspberry Pis
](https://blog.alexellis.io/serverless-kubernetes-on-raspberry-pi/) written by [Alex Ellis](https://twitter.com/alexellisuk).
> Copyright disclaimer: Please provide a link to the post and give attribution to the author if you plan to use this content in your own materials.
My current thinking is that [k3s](https://github.com/teamserverless/k8s-on-raspbian#pick-k3s) from Rancher Labs is a better option than `kubeadm` to bootstrap a cluster. Whilst both create a compliant Kubernetes cluster, k3s uses fewer resources, is faster and doesn't run into some of the timing issues we've seen in the community with `kubeadm`.
You should also see my note on [installing Docker on Raspbian Buster](https://github.com/teamserverless/k8s-on-raspbian#fix-docker-for-raspbian-buster-optional)
* I'm assuming you're using wired ethernet (Wi-Fi also works, but it's not recommended)
## Master node setup
You can either follow the steps below, or use my flashing script which automates the below. The automated flashing script must be run on a Linux computer with an SD card writer or an RPi.
### Flash with a Linux host
[Provision a Raspberry Pi SD card](https://gist.github.com/alexellis/a7b6c8499d9e598a285669596e9cdfa2)
Then run:
```
curl -sLSf https://gist.githubusercontent.com/alexellis/fdbc90de7691a1b9edb545c17da2d975/raw/125ad6eae27e40a235412c2b623285a089a08721/prep.sh | sudo sh
```
### Continue to flash manually
* Flash Raspbian to a fresh SD card.
You can use [Etcher.io](https://etcher.io) to burn the SD card.
Before booting set up an empty file called `ssh` in /boot/ on the SD card.
Use Raspbian Stretch Lite
> Update: I previously recommended downloading Raspbian Jessie instead of Stretch. At time of writing (3 Jan 2018) Stretch is now fully compatible.
https://www.raspberrypi.org/downloads/raspbian/
* Change hostname
Use the `raspi-config` utility to change the hostname to k8s-master-1 or similar and then reboot.
* Set a static IP address
It's not fun when your cluster breaks because the IP of your master changed. The master's certificates will be bound to the IP address, so let's fix that problem ahead of time:
```
cat >> /etc/dhcpcd.conf
```
Paste this block:
```
profile static_eth0
static ip_address=192.168.0.100/24
static routers=192.168.0.1
static domain_name_servers=8.8.8.8
```
Hit Control + D.
Change 100 for 101, 102, 103 etc.
You may also need to make a reservation on your router's DHCP table so these addresses don't get given out to other devices on your network.
We pass in `--token-ttl=0` so that the token never expires - do not use this setting in production. The UX for `kubeadm` means it's currently very hard to get a join token later on after the initial token has expired.
> Optionally also pass `--apiserver-advertise-address=192.168.0.27` with the IP of the Pi as found by typing `ifconfig`.
Note: This step can take a long time, even up to 15 minutes.
Sometimes this stage can fail, if it does then you should patch the API Server to allow for a higher failure threshold during initialization around the time you see `[controlplane] wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/manifests/kube-apiserver.yaml"`
You should see the "READY" count showing as 1/1 for all services as above. DNS uses three pods, so you'll see 3/3 for that.
### Setup networking with Weave Net or Flannel
Some users have reported stability issues with Weave Net on ARMHF. These issues do not appear to affect x86_64 (regular PCs/VMs). You may want to try Flannel instead of Weave Net for your RPi cluster.
"https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
```
If you run into any issues with Weaveworks' networking then [flannel](https://github.com/coreos/flannel) is also a popular choice for the ARM platform.
Once the Docker image has been pulled from the hub and the Pod is running you can access it via `curl`:
```
$ curl -4 http://127.0.0.1:31118 -d "# test"
<p><h1>test</h1></p>
```
If you want to call the service from a remote machine such as your laptop then use the IP address of your Kubernetes master node and try the same again.
## Start up the Kubernetes dashboard
The dashboard can be useful for visualising the state and health of your system, but it does require the equivalent of "root" in the cluster. If you want to proceed you should first run in a [ClusterRole from the docs](https://github.com/kubernetes/dashboard/wiki/Access-control#admin-privileges).
You can then find the IP and port via `kubectl get svc -n kube-system`. To access this from your laptop you will need to use `kubectl proxy` and navigate to `http://localhost:8001/` on the master, or tunnel to this address with `ssh`.
See also: [Kubernetes Dashboard](https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/) docs.
## Remove the test deployment
Now on the Kubernetes master remove the test deployment:
```
$ kubectl delete -f function.yml
```
### Wrapping up
You should now have an operational Kubernetes master and several worker nodes ready to accept workloads.
Now let's head back [over to the tutorial and deploy OpenFaaS](https://blog.alexellis.io/serverless-kubernetes-on-raspberry-pi/) to put the cluster through its paces with Serverless functions.
See also: [Kubernetes documentation](https://kubernetes.io/docs/home/?path=users&persona=app-developer&level=foundational)