Eugenio Tampieri's blog

Home Assistant in Kubernetes: a better way

I'm writing this, as always, because I think that somebody can find this useful. With that being said, this is a really rough guide. Don't expect that it will work verbatim. Moreover, it is tailored to my setup, that might differ to yours.

I would like to thank lanefu for their post.

Why?

To make mDNS stuff work without using hacks like running avahi-reflector in each node.

My setup

With relevance to this post, you need to know that:

Prepare the nodes

To do this, I use Ansible with an one-off manual modification to create the bridge (here's a stripped down version of my playbook):

---
  - name: Prepare k8s nodes
    hosts: k8s
    become: yes
    become_user: root
    tasks:
      - name: ensure curl is installed
        ansible.builtin.apt:
          name: curl
          state: latest
      - name: Install CNI plugins
        ansible.builtin.script: k8s/install_cni_plugins.sh
      - name: ensure that bridge-utils is installed
        ansible.builtin.apt:
          name: bridge-utils
          state: latest

This playbook is pretty self-explainatory, but it essentially does two things:

  1. Ensures that bridge-utils is installed (in Debian, this is needed)
  2. Downloads the CNI plugins using a script placed in k8s/install_cni_plugins.sh (I'm using this script, with the addition of the static IPAM plugin)

Then, we need to manually configure the bridge:

allow-hotplug eth0
iface eth0 inet manual

auto br0
iface br0 inet dhcp
   bridge_ports eth0
   bridge_hw eth0

bridge_hw ensures that the bridge always uses the underlying physical interface.

A sudo service networking restart later, everything should be good.

Configure Multus

Here is the Network Attachment Definition I use. Basically, it tells Multus how it should handle the additional interfaces.

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: bridge-lan
  namespace: default
spec:
  config: '{
      "cniVersion": "0.3.1",
      "name": "bridge-lan",
      "type": "bridge",
      "capabilities": { "ips": true },
      "ipam": {
        "type": "static",
        "routes": [] 
      },
      "bridge": "br0",
      "disableContainerInterface": false
    }'

Configure the Home Assistant deployment

This is done by adding the following annotation to the deployment:

        k8s.v1.cni.cncf.io/networks: '[
                { "name": "bridge-lan",
                  "namespace": "default",
                  "ips": [ "192.168.1.50/24" ],
                  "gateway": [ "192.168.1.1" ]
                }]'

Configure Home Assistant

Lastly, you need to tell Home Assistant to use the additional interface too.

To do so, go to Settings>System>Network and disable the automatic network card selection.

Restart Home Assistant and you're done!