x

Menu

Lab with Kubernetes and Traefik on Raspberry

Learn how you can build your own Kubernetes cluster at home on a simple Raspberry Pi

published in: Cloud Native

Install then base OS

install the flash tool GitHub - hypriot/flash: Command line script to flash SD card images of any kind

curl -O https://raw.githubusercontent.com/hypriot/flash/master/$(uname -s)/flash
chmod +x flash
sudo mv flash /usr/local/bin/flash

if you want a progress bar install pv and for downloading it is good to have wget

brew install pv wget

get a version from Releases hypriot/image-builder-rpi GitHub

wget https://github.com/hypriot/image-builder-rpi/releases/download/v1.2.1/hypriotos-rpi-v1.2.1.img.zip
flash --hostname node01 hypriotos-rpi-v1.2.1.img.zip
flash --hostname node02 hypriotos-rpi-v1.2.1.img.zip
flash --hostname node03 hypriotos-rpi-v1.2.1.img.zip
ssh pirate@black-pearl.local # password "hypriot"

You should ensure that the IP address of your devices do not change. Either configure DHCP to give out the same IP all the time, or edit /etc/network/interfaces.d/eth0, and change it from DHCP:

iface eth0 inet dhcp

To a static IP config:

iface eth0 inet static
address your-static-ip
gateway your-gateway-ip
#google dns servers
domain_name_servers=8.8.8.8, 8.8.4.4

Upgrade OS

Releases · hypriot/image-builder-rpi · GitHub

$ sudo apt-get update
$ sudo apt-get upgrade -y
$ sudo reboot

Fix machine-id

/etc/machine-id the same on every installation · Issue #167 · hypriot/image-builder-rpi · GitHub

Run

dbus-uuidgen > /etc/machine-id

Change Init

If you want to change e.g. hostname or do other things on init. The device-init tool reads the file /boot/device-init.yaml to initialize several settings while booting your device. GitHub - hypriot/device-init: Initialize a device on boot with user defined configuration

Install Kubernetes

Follow Installing Kubernetes on Linux with kubeadm Kubernetes

Basically (April/2017) do:

Become root on all your machines and run:

apt-get update && apt-get install -y apt-transport-https
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt-get update
# Install docker if you don't have it already.
apt-get install -y docker-engine
apt-get install -y kubelet kubeadm kubectl kubernetes-cni

Initialize the master:

kubeadm init

Which should finish with something like:

Your Kubernetes master has initialized successfully!

To start using your cluster, you need to run (as a regular user):

  sudo cp /etc/kubernetes/admin.conf $HOME/
  sudo chown $(id -u):$(id -g) $HOME/admin.conf
  export KUBECONFIG=$HOME/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  http://kubernetes.io/docs/admin/addons/

You can now join any number of machines by running the following on each node
as root:

  kubeadm join --token <token> <master-ip>:<master-port>

install a pod network. You have to choose a plugin for that. Integrating Kubernetes via the Addon - Weaveworks

export KUBECONFIG=$HOME/admin.conf
kubectl apply -f https://git.io/weave-kube-1.6

now join the remaining nodes

$node2: kubeadm join --token <token> <master-ip>:<master-port>
$node3: kubeadm join --token <token> <master-ip>:<master-port>

Test the cluster

Install a tiny service

kubectl run hypriot --image=hypriot/rpi-busybox-httpd --replicas=3 --port=80

Expose the port to access it from now of your nodes

kubectl expose deployment hypriot --port 80

Access the endpoints

$ kubectl get endpoints hypriot
NAME      ENDPOINTS                                AGE
hypriot   10.32.0.3:80,10.32.0.4:80,10.40.0.1:80   1h

And test it with curl

HypriotOS/armv7: pirate@raspi-01 in ~
$ curl 10.32.0.3
<html>
<head><title>Pi armed with Docker by Hypriot</title>
  <body style="width: 100%; background-color: black;">
    <div id="main" style="margin: 100px auto 0 auto; width: 800px;">
      <img src="pi_armed_with_docker.jpg" alt="pi armed with docker" style="width: 800px">
    </div>
  </body>
</html>

Access it from the Outside - Ingress with Traefik

A good explanation on Kubernetes Ingress can be found here: Kubernetes Ingress – Jay Gorrell – Medium Since we use Kubernetes >= 1.6 with RBAC we need to do a little bit more then in the past. A starting point can be found here: https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-with-rbac.yaml

Since we run Træfik on Kubernetes we must change the example to use a arm image.

wget https://raw.githubusercontent.com/containous/traefik/master/examples/k8s/traefik-with-rbac.yaml

Find the line

   - image: traefik

And change it to

   - image: hypriot/rpi-traefik

apply the config

kubectl apply -f traefik-with-rbac.yaml

And add an Ingress object:

$ cat > hypriot-ingress.yaml <<EOF
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: hypriot
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: hypriot
          servicePort: 80
EOF

Now you should be able to access the hypriot deployment on the node were the loadbalancer got deployed

Deploy Kuberentes UI

Super simple:

curl -sSL https://rawgit.com/kubernetes/dashboard/master/src/deploy/kubernetes-dashboard.yaml | sed "s/amd64/arm/g" | kubectl create -f -

Wait a little bit and run

kubectl -n kube-system get service kubernetes-dashboard -o template --template="{{ (index .spec.ports 0).nodePort }}" | xargs echo

This will output the port were you can reach the k8s dashboard

Using Hostname Ingress with Traefik

A good writeup can be found here: Kubernetes - Træfɪk

$ cat > traefic-ui.yml <<EOF
apiVersion: v1
kind: Service
metadata:
  name: traefik-web-ui
  namespace: kube-system
spec:
  selector:
    k8s-app: traefik-ingress-lb
  ports:
  - port: 80
    targetPort: 8081
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: traefik-web-ui
  namespace: kube-system
spec:
  rules:
  - host: traefik-ui.example.com
    http:
      paths:
      - backend:
          serviceName: traefik-web-ui
          servicePort: 80
EOF
kubectl apply -f traefic-ui.yml

Now either use your DNS server settings or an /etc/hosts setting to access the traffic UI

echo "10.20.0.5 traefik-ui.example.com" | sudo tee -a /etc/hosts
$ kubectl --namespace=kube-system get ingress
NAME             HOSTS                               ADDRESS   PORTS     AGE
traefik-web-ui   traefik-ui.example.com             80        1h