Design artifact (NOT applied). Per-node pod = host-poller + redis + web sharing pod localhost; only host-poller privileged with hostPath /dev+/sys. No SAS poller (no enclosures). MQTT_NODE_ID from spec.nodeName; MQTT creds via VSO VaultStaticSecret reading secret/home_assistant (mqtt_user/pass -> MQTT_USERNAME/ PASSWORD). nodeSelector jbod-monitor=enabled to pin to pascal/currie/fermi.
105 lines
3.6 KiB
YAML
105 lines
3.6 KiB
YAML
# jbod-monitor on RKE2 nodes — per-node self-contained DaemonSet (Model A).
|
|
#
|
|
# Each scheduled node runs one pod = host-poller + redis + web, sharing the
|
|
# pod's localhost (no hostNetwork needed). Only host-poller is privileged and
|
|
# mounts /dev + /sys to read IPMI / SMART / coretemp. web egresses to the MQTT
|
|
# broker and publishes a per-node HA device (MQTT_NODE_ID = spec.nodeName).
|
|
#
|
|
# No SAS poller (these nodes have no SES enclosures). NOTE: without it there is
|
|
# no zfs_map, so host-drive entities won't carry a ZFS pool label.
|
|
#
|
|
# Target nodes are chosen by label — see k8s/README.md (label only
|
|
# pascal/currie/fermi). Apply order: namespace -> VaultStaticSecret -> this.
|
|
---
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: jbod-monitor
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: DaemonSet
|
|
metadata:
|
|
name: jbod-monitor
|
|
namespace: jbod-monitor
|
|
labels:
|
|
app: jbod-monitor
|
|
spec:
|
|
selector:
|
|
matchLabels:
|
|
app: jbod-monitor
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: jbod-monitor
|
|
spec:
|
|
# Only nodes explicitly opted in (see README: kubectl label node ...).
|
|
nodeSelector:
|
|
jbod-monitor: "enabled"
|
|
# If the registry needs auth, sync a regcred and uncomment:
|
|
# imagePullSecrets:
|
|
# - name: regcred
|
|
containers:
|
|
- name: redis
|
|
image: redis:7-alpine
|
|
args: ["redis-server", "--save", "60", "1", "--loglevel", "warning"]
|
|
volumeMounts:
|
|
- name: redis-data
|
|
mountPath: /data
|
|
resources:
|
|
requests: {cpu: 25m, memory: 32Mi}
|
|
limits: {memory: 128Mi}
|
|
|
|
- name: host-poller
|
|
image: docker.adamksmith.xyz/jbod-host-poller:514502e
|
|
securityContext:
|
|
privileged: true # raw /dev access for ipmitool + smartctl
|
|
env:
|
|
- {name: TZ, value: "America/Denver"}
|
|
- {name: REDIS_HOST, value: "127.0.0.1"}
|
|
- {name: REDIS_PORT, value: "6379"}
|
|
- {name: HOST_ENV_INTERVAL, value: "60"}
|
|
- {name: HOST_DRIVE_INTERVAL, value: "300"}
|
|
- {name: POLL_CONCURRENCY, value: "1"}
|
|
- {name: POLL_DRIVE_GAP, value: "0.5"}
|
|
- {name: POLL_STARTUP_JITTER, value: "10"}
|
|
- {name: POLL_DATA_TTL, value: "900"}
|
|
volumeMounts:
|
|
- {name: dev, mountPath: /dev}
|
|
- {name: sys, mountPath: /sys, readOnly: true}
|
|
- {name: udev, mountPath: /run/udev, readOnly: true}
|
|
resources:
|
|
requests: {cpu: 25m, memory: 64Mi}
|
|
limits: {memory: 256Mi}
|
|
|
|
- name: web
|
|
image: docker.adamksmith.xyz/jbod-web:1839e9d
|
|
env:
|
|
- {name: TZ, value: "America/Denver"}
|
|
- {name: REDIS_HOST, value: "127.0.0.1"}
|
|
- {name: REDIS_PORT, value: "6379"}
|
|
- {name: MQTT_HOST, value: "10.5.30.3"}
|
|
- {name: MQTT_PORT, value: "1883"}
|
|
- {name: MQTT_DISCOVERY_PREFIX, value: "homeassistant"}
|
|
- {name: MQTT_BASE_TOPIC, value: "jbod-monitor"}
|
|
- {name: MQTT_PUBLISH_INTERVAL, value: "60"}
|
|
- name: MQTT_NODE_ID
|
|
valueFrom:
|
|
fieldRef:
|
|
fieldPath: spec.nodeName
|
|
envFrom:
|
|
- secretRef:
|
|
name: jbod-mqtt # MQTT_USERNAME / MQTT_PASSWORD (see VaultStaticSecret)
|
|
resources:
|
|
requests: {cpu: 25m, memory: 64Mi}
|
|
limits: {memory: 256Mi}
|
|
|
|
volumes:
|
|
- name: redis-data
|
|
emptyDir: {}
|
|
- name: dev
|
|
hostPath: {path: /dev}
|
|
- name: sys
|
|
hostPath: {path: /sys}
|
|
- name: udev
|
|
hostPath: {path: /run/udev}
|