Configs for my Raspberry Pi Kubernetes Cluster (named "rstack") running k3s.
Glamour shots of the cluster:
This is the second iteration of my cluster setup (I wrote a blog post about my first iteration). Previously I was using full K8s with MetalLB for load balancing, now I'm using k3s with Traefik.
The ansible
folder contains playbooks for provisioning and standing up the cluster, as well
as for admin tasks such as bulk upgrading system packages.
- Install
ansible
andansible-playbook
. - Download and
dd
rasbian onto the Raspberry Pi SD cards. - Mount the
boot
partition of each SD card andtouch
the file<bootpart>/ssh
. - Put SD cards into Raspberry Pis and boot them.
- Accept SSH signatures and enable password-less SSH by running
ssh-copy-id pi@pi-address
on each of the Pis (will help ansible). - SSH into each pi and change the password for the
pi
user. - Add static IP assignments to your router for each of the Pis (grab their MAC addresses while you are SSH'd in).
- Add each pi as a host in
/etc/hosts
(for ansible) - Update
ansible/hosts
with each host name. - Reboot the Pis so they pick up their static IPs. Double check the IPs have been leased properly by SSHing into each at their static IP/hostname.
To perform system updates (which you should to ensure security patches etc are installed), run:
ansible-playbook -i ansible/hosts ansible/update-all.yml
Simply run the ansible playbook and wait:
ansible-playbook -i ansible/hosts ansible/provision-k3s.yml
The master node will have a kubectl config folder at /root/.kube
. Copy this folder from the master node
over to your computer somewhere (e.g. with rsync
) so you can run kubectl
commands from your computer.
To set this kubectl
config as your default config, export the KUBECONFIG
variable in your .bashrc
file:
export KUBECONFIG=/path/to/.kube/config
Test kubectl
to check everything is working (don't forget to source ~/.bashrc
):
kubectl get nodes
NAME STATUS ROLES AGE VERSION
rstack-node0 Ready master 91d v1.15.4-k3s.1
rstack-node2 Ready worker 91d v1.15.4-k3s.1
rstack-node1 Ready worker 91d v1.15.4-k3s.1
rstack-node3 Ready worker 91d v1.15.4-k3s.1
Traefik works great as an Ingress controller with k3s (I couldn't get ingress-nginx to work).
The LetsEncrypt setup uses DNS validation via Cloudflare, so your domain's DNS needs to hosted with Cloudflare (although other providers do work - see Traefik's Provider Docs).
Traefik is installed via helm, so we need to install helm first. Use the helper script:
bash ./install-helm.sh
LetsEncrypt needs your Cloudflare API key (the 'Global' one, not an API 'token') to validate DNS challenges. Add it as a k8s secret:
kubectl -n kube-system create secret generic cloudflare-api-key \
--from-literal=CLOUDFLARE_EMAIL=youremail@incloudflareaccount \
--from-literal=CLOUDFLARE_API_KEY=cloudflareapikey
Update the values in config/traefik/values.yml
- notably acme.email
to match your CloudFlare email.
You may also want to enable the dashboard with authentication, example yaml:
dashboard:
enabled: true
domain: customdomain.name
auth:
basic:
customusername: password-generated-with-htpasswd
See Traefik's BasicAuth Docs for more info.
Finally we can install Traefik:
helm install stable/traefik --name traefik --namespace kube-system --values config/traefik/values.yml
There is a test nginx deployment/service/ingress at config/traefik/test-ingress.yml
. Update the domains/host values and apply:
kubectl apply -f config/traefik/test-ingress.yml
Delete it with:
kubectl delete -f config/traefik/test-ingress.yml
In case you need to rollback the traefik install, run:
helm delete traefik && helm del --purge traefik
kubectl delete secret -n kube-system cloudflare-api-key
kubectl delete -f config/traefik/test-ingress.yml
The config
folder contains a number of K8s deployments/services.
config/dashboard
- (not in use) Kubernetes Dashboard deployment files for monitoring the Cluster.config/dnscrypt
- DNSCrypt service for encrypted DNS (for home network).config/sensor-monitoring
- Contains all the microservices for my IoT Home Monitoring setup, which monitors the temperature around my house using MQTT, Influxdb, and Grafana, and my computer stats using Prometheus.config/docker-cloudflare-ddns.yml
- Dynamic DNS service if you do not have a static IP (uses same Cloudflare API key as traefik).config/hue-im-home.yml
- Hue-Im-Home service to automatically turn off/on house lights when leaving for/coming home from work.
I hope this repo is of help to anyone else setting up k3s on a Raspberry Pi Cluster.
MIT - see LICENSE.md