How to run Home Assistant in Kubernetes

There is almost nothing better than running your smart home on your own server! And it’s hard to find better smart home system than Home Assistant itself.

I used to run my instance of Home Assistan on a QEMU virtual machine inside old rack server (Dell R620 with intel Xenon E5-E2630L, 64GB RAM and 10TB RAID5 storage). However, it turned out to be quite a bad choice of hardware. Power consumption, noise, and waste heat was too much for my liking. So, cluster of 4 Raspberry Pi 5 16GB with 128GB SSD each is slowly replacing my old Dell R620.

My legacy Dell R620 home server

Officially, Home Assitant does not support running on Kubernetes. But it supports Docker. And since Kubernetes is Docker on steroids, it’s fully possible to make it happen.

Modern and faster cluster of 4 Raspberry Pi 5
Zigbee dongle for home assistant

There are a few Helm charts for Home Assistant but I found all of the slightly too complicated for my liking and none met all of my needs:

  • Straight forward setup
  • Config volume based on Rook-Ceph and cephfs
  • Load balancer

This is why, here is my version of it. Bear in mind, there are a few specific things:

  1. Storage is based on Rook-Ceph. If you don’t use Rook-Ceph, change storageClassName: cephfs to storageClassName: microk8s-hostpath and add a Persistent Volume. Example of it at the bottom on the page
  2. I use Zigbee dongle connected to only one of cluster’s Raspberry Pi’s. This means Home Assistant pod has to run on that node. To make that happen mark it with environment: zigbee label. Just run kubectl label node <node-name> environment=zigbee on the node with Zigbee dongle connected.
  3. HA pod needs securityContext privileged to be able to access USB devices connected to host node. Zigbee dongle you know
  4. /etc/localtime needs to be mounted a separate volume

And that’s all. Nothing complicated.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: home-assistant-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 512Mi
  storageClassName: cephfs
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: home-assistant-time-pvc
  labels:
    app: home-assistant
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: microk8s-hostpath
  resources:
    requests:
      storage: 1Mi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: home-assistant-time-pv
spec:
  capacity:
    storage: 1Mi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /etc/localtime
  claimRef:
    name: home-assistant-time-pvc
    namespace: default
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: home-assistant
  labels:
    app: home-assistant
spec:
  replicas: 1
  selector:
    matchLabels:
      app: home-assistant
  template:
    metadata:
      labels:
        app: home-assistant
    spec:
      containers:
        - name: home-assistant
          image: "ghcr.io/home-assistant/home-assistant:stable"
          securityContext:
            privileged: true
          ports:
            - containerPort: 8123
          volumeMounts:
            - mountPath: /config
              name: home-assistant-config-volume
            - mountPath: /etc/localtime
              name: home-assistant-time-volume
              readOnly: true
      nodeSelector:
        environment: zigbee
      hostNetwork: true
      volumes:
        - name: home-assistant-config-volume
          persistentVolumeClaim:
            claimName: home-assistant-pvc
        - name: home-assistant-time-volume
          persistentVolumeClaim:
            claimName: home-assistant-time-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: home-assistant-lb
  labels:
    app: home-assistant
spec:
  ports:
    - port: 8123
      targetPort: 8123
      name: home-assistant-web
  selector:
    app: home-assistant
  type: LoadBalancer

Volume claim for host storage

If you want to use local storage (hostpath) here is a Helm snippet for that. Bear in mind, if Home Assitant pod will be relocated to different node, you will loose config. However, since we already pinned it ot the node with connected Zigbee dongle, that should not happen.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: home-assistant-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 512Mi
  storageClassName: microk8s-hostpath
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: home-assistant-pv
spec:
  capacity:
    storage: 512Mi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  hostPath:
    path: /home-assistant-pv #set you own location
  claimRef:
    name: home-assistant-pvc

Posted

in

by

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *