Running HomeAssistant on Kubernetes Microk8s

Share with:


Home Assistant is a free and open-source software solution for home automation designed to be a central control system for smart home devices with a focus on local control and privacy. It provides a single point for managing the myriad IoT and home automation devices sold by several manafucturers. Normally you would need to install and learn each manufacturer’s 3rd party software and this eventually becomes overwhelming. With Home Assistant you can aggregate and enhance the capabilites of the devices running in your home, regardless of the manufacturer. Not every manufacture is fully supported, but the beauty of open source is that you can make enhancements and contribute to the open source projects if needed.

This article assumes you already have a working MicroK8s cluster, and that you have setup load balancing with metallb, if not please see linked articles for reference.

First we need to customize the Home-Assist config, use this as a starting point to make adjustments.

homeassistant:
  # Name of the location where Home Assistant is running
  name: Home
  # Location required to calculate the time the sun rises and sets
  latitude: 0
  longitude: 0
  # Impacts weather/sunrise data (altitude above sea level in meters)
  elevation: 0
  # metric for Metric, imperial for Imperial
  unit_system: metric
  # Pick yours from here: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones
  time_zone: America/Phoenix

  auth_providers:
    - type: homeassistant

default_config:

http:
  ip_ban_enabled: false
  login_attempts_threshold: 5
  use_x_forwarded_for: true
  trusted_proxies:
    - 10.1.0.0/16

Next we need to convert the configuration.yaml into base64 format, this will be utilized in the next step. Run the following terminal command to print the base64 string for your config file: base64 -w 0 configuration.yaml

To Install HomeAssistant on your MicroK8s cluster, copy the following yaml to a file called homeassist.yaml, and replace PASTE_BASE64_CONFIG_HERE with the base64 string from the previous step. Then run this terminal command from one of your microK8s nodes: microk8s.kubektl create -f homeassist.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: homeassist-pv
spec:
  capacity:
    storage: 30Gi
  accessModes:
    - ReadWriteOnce
  local:
    path: /data/homeassist
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - app1.local
          - app2.local
          - app3.local
          - app4.local
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: homeassist-pv-claim
  labels:
    app: homeassist
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: "" # Empty string must be explicitly set otherwise default StorageClass will be set
  volumeName: homeassist-pv
---
apiVersion: v1
kind: Secret
metadata:
  name: homeassist-config
type: Opaque
data:
  configuration.yaml: PASTE_BASE64_CONFIG_HERE

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: homeassist-deployment
  labels:
    app: homeassist
spec:
  replicas: 1
  selector:
    matchLabels:
      app: homeassist
  template:
    metadata:
      labels:
        app: homeassist
    spec:
      containers:
        - name: homeassist
          image: homeassistant/home-assistant
          ports:
            - containerPort: 8123
          volumeMounts:
            - mountPath: "/config"
              name: homeassist-persistent-storage
            - mountPath: "/config/configuration.yaml"
              subPath: "configuration.yaml"
              name: homeassist-config
      volumes:
        - name: homeassist-config
          secret:
            secretName: homeassist-config
            defaultMode: 0777
        - name: homeassist-persistent-storage
          persistentVolumeClaim:
            claimName: homeassist-pv-claim
---
apiVersion: v1
kind: Service
metadata:
  name: homeassist
spec:
  type: ClusterIP
  selector:
    app: homeassist
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 8123
    - name: https
      protocol: TCP
      port: 443
      targetPort: 8123

---
apiVersion: v1
kind: Service
metadata:
  name: homeassist-ingress-tcp
  namespace: ingress
  annotations:
    metallb.universe.tf/allow-shared-ip: "homeassist-shared-ip"
spec:
  selector:
    name: nginx-ingress-microk8s
  type: LoadBalancer
  # loadBalancerIP is optional. MetalLB will automatically allocate an IP
  # from its pool if not specified. You can also specify one manually.
  # loadBalancerIP: x.y.z.a
  loadBalancerIP: 192.168.1.10
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
    - name: https
      protocol: TCP
      port: 443
      targetPort: 443
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: homeassist-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  tls:
    - hosts:
        - homeassist.local
      secretName: star-app-tls
  rules:
    - host: homeassist.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: homeassist
                port:
                  number: 443

Home Assistant should now be running on your Kubernetes cluster. To confirm, browse to the host provided in the Ingress definition (eg. https://homeassist.local).

If you enjoyed this post, please see my next post on enabling auto discovery for Home Assistant

Share with:


6 Replies to “Running HomeAssistant on Kubernetes Microk8s”

  1. Matt,
    Thanks for putting this together.
    My home assistant has been running on microk8s for over a year without major issues with a similar configuration like above.
    One slightly annoying topic is that HomeKit won’t connect to my home assistant to open up a whole new world for Siri. I suppose this is because of some weird networking stuff going on which prevents mDNS from functioning correctly.
    Do you happen to have any experience with that?

  2. in the manifest, persistent volume – node affinity, I assume we need to put our hostnames in rather than app1-4.local?

    • Yeah the app1-4.local values should be replaced by the names of the hosts in your cluster. I’m running a local DNS server to ensure the hosts can be resolved from anywhere on the network. I think you could also use the IP addresses if you want to rule out DNS related issues.

Leave a Reply

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

*


The reCAPTCHA verification period has expired. Please reload the page.