Relacionado con –> Kubernetes. k0s – Instalación de homeassistant
Hace tiempo instalé un homeassistant en el clúster de kubernetes. Ahora le ha tocado el turno a un compañero inseparable como es esphome, y así poder configurar mis esp8266 también desde kubernetes.
Una de las necesidades de esphome es que va a necesitar un acceso físico al puerto usb del NAS, que es donde voy a pinchar un adaptador USB <–> Serial TTL. La verdad es que es un poco extraño mezclar un POD con un puerto físico, pero es la necesidad existente y como siempre lo importante es lo aprendido por el camino.
El esquema a alto nivel sería como el de la imagen siguiente:
El primer lugar, tenemos la comunicación física entre el NAS y el puerto USB, donde he pinchado el conversor TTL Serial <–> USB. Después tenemos que entregar este dispositivo a una Máquina Virtual (VM). Finalmente esta VM tiene que compartir el dispositivo al contenedor que corre esphome.
La primera y segunda parte se hace desde el NAS. En el caso de QNAP, en la aplicación “VirtualizationStation” basta con decirle que conectamos un dispositivo USB a la VM en concreto. Yo elijo un nodo del cluster en concreto (k0s-node-1). El dispositivo lo reconoce como “HL-340 USB-Serial adapter”.
No es posible conectar el USB a todos los nodos del cluster por lo que tenemos que indicarle a kubernetes que siempre levante el POD de esphome en el nodo k0s-node-1. Sí, está claro que esto va en contra de la filosofía de k8s, donde los nodos son ganado. Para conseguirlo, basta con etiquetar al nodo en concreto, para después en el despliegue hacer referencia a esta etiqueta. En este caso le he puesto la etiqueta tipo=hardware.
$ kubectl get nodes k0s-node-1 --show-labels
NAME STATUS ROLES AGE VERSION LABELS
k0s-node-1 Ready 675d v1.27.3+k0s beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k0s-node-1,kubernetes.io/os=linux,tipo=hardware
$
$ cat esphome.yaml | grep -A3 -i nodeselector
nodeSelector:
# Busca el nodo que tenga la etiqueta tipo=hardware.
# Así el POD va a caer en un nodo con el hardware requerido.
tipo: "hardware"
Otro aspecto importante es como le decimos a kubernetes el mapeo necesario para que el puerto usb llegue hasta el POD. Si vemos como lo ve cada elemento de la cadena; NAS – VM – POD.
EL NAS
[~] # lsusb | grep -i qinheng
Bus 001 Device 125: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
[~] #
[~] # ls -l /dev/bus/usb/001/125
crw------- 1 admin administrators 189, 124 2024-01-02 22:28 /dev/bus/usb/001/125
LA VM
root@k0s-node-1:~# lsusb | grep -i QinHeng
Bus 001 Device 004: ID 1a86:7523 QinHeng Electronics CH340 serial converter
root@k0s-node-1:~#
root@k0s-node-1:~# ls -l /dev/bus/usb/001/004
crw-rw-r-- 1 root root 189, 3 Jan 2 22:28 /dev/bus/usb/001/004
EL POD
root@esphome-849c7f6bc4-kqgm7:/config# ls -l /dev/bus/usb/001/004
crw-rw-r-- 1 root root 189, 3 Jan 2 21:28 /dev/bus/usb/001/004
root@esphome-849c7f6bc4-kqgm7:/config# dmesg -T | grep -i usb
[Tue Jan 2 21:28:19 2024] usb 1-2: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[Tue Jan 2 21:28:19 2024] usb 1-2: Product: USB2.0-Serial
[Tue Jan 2 21:28:20 2024] usbcore: registered new interface driver usbserial_generic
[Tue Jan 2 21:28:20 2024] usbserial: USB Serial support registered for generic
[Tue Jan 2 21:28:20 2024] usbcore: registered new interface driver ch341
[Tue Jan 2 21:28:20 2024] usbserial: USB Serial support registered for ch341-uart
[Tue Jan 2 21:28:20 2024] usb 1-2: ch341-uart converter now attached to ttyUSB0
El deploy completo de esphome sería (estate pendiente de los comentarios, especialmente al hostPath):
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
labels:
app: esphome
name: esphome
namespace: homeassistant
spec:
replicas: 1
selector:
matchLabels:
app: esphome
template:
metadata:
labels:
app: esphome
spec:
containers:
- image: esphome/esphome
imagePullPolicy: Always
name: esphome
securityContext:
# Requiere privilegio para montar el usb
privileged: true
volumeMounts:
- mountPath: /config
name: esphome-storage
- mountPath: /dev/bus/usb/001/004
name: usb-device
nodeSelector:
# Busca el nodo que tenga la etiqueta tipo=hardware.
# Así el POD va a caer en un nodo con el hardware requerido.
tipo: "hardware"
volumes:
- name: esphome-storage
nfs:
path: /ruta
server: tu_servidor_nfs
- name: usb-device
hostPath:
# Este path depende de donde esté pinchado el usb en el hierro
# y donde lo esté registrando la máquina virtual
path: /dev/bus/usb/001/004
---
apiVersion: v1
kind: Service
metadata:
labels:
app: esphome
name: esphome
namespace: homeassistant
spec:
ports:
- port: 6052
protocol: TCP
targetPort: 6052
selector:
app: esphome
type: ClusterIP