docs.fermihdi.io — helm.md

/ › hd › 2.0.3 › md › install

Download helm.mdView raw

install/helm/fermihdi

The chart the installer deploys to Kubernetes. install/fermihdi-k8s renders its values from the same cluster.yaml everything else in install/ reads, so a Kubernetes install and a bare-metal one are described by one file:

install/fermihdi-k8s cluster.yaml -o values.yaml
helm install fermihdi install/helm/fermihdi -f values.yaml

It began as docs/examples/k8s_example, which is still there and still a reference. This copy is the one that is kept current; where the two disagree, this is the one to trust.

What it deploys

Namespace Runs
fermihdi-dms DMS-CA, DMS-Core, the OPA engine, the WebUX, the OTEL collector
fermihdi-sc the SCC, and the Storage Nodes as a StatefulSet
fermihdi-edge the Ingester and the HD Proxy
fermihdi-extra hd_mcp, hd_graphql, the data explorer

Each group is reached from the others through ExternalName Services rather than by fully-qualified names spread through the templates — which is what makes a DMS outside the cluster a value rather than an edit:

dms:
  externalHost: dms.corp.example.com   # already installed, or on bare metal
  core: { enabled: false }             # ... and nothing here deploys one

What differs from the bare-metal install

A Pod is not a host, and four things do not survive the trip. The generator says so per cluster file rather than leaving it to be discovered:

IPC_LOCK is granted to the SCC, the SNs and the Ingester: the HD engine and DPDK pin their arenas, and a container's default RLIMIT_MEMLOCK of 64 KB stops them at startup. hd_mcp and hd_graphql get a medium: Memory emptyDir at /dev/shm instead — they allocate from shared memory rather than hugepages, and the 64 MiB a container gets by default is not enough to start with.

Secrets

The chart reads everything from three Secret objects — fermihdi-dms-secrets, fermihdi-sc-secrets, fermihdi-edge-secrets — so anything that creates them with the right keys will do: External Secrets, Sealed Secrets, or your own pipeline. secrets.create=true renders them from values instead, which is what fermihdi-k8s --secrets writes and which is for development.

Keeping it honest

The services' environments are checked against tests/sandbox_dms/compose.yml, which is the deployment as it is actually run. When something moves there, it moves here. The last sweep (2026-08-20) closed these:

To check it yourself:

helm lint install/helm/fermihdi
helm template hd install/helm/fermihdi -f values.yaml | kubectl apply --dry-run=server -f -

The OPA adapter is a sidecar

dms.opaAdapter.enabled=true adds it to the OPA engine's Pod rather than deploying it separately, because the handover between the two is a directory: the adapter polls an OPA control plane that cannot reach into the deployment and writes bundles into dms.opaEngine.bundleDir; the engine, which reaches nothing outward, validates and serves what appears there. Two Pods would need a ReadWriteMany volume for what an emptyDir does inside one.

Three things follow from sharing a Pod, and each is a value rather than a surprise:

Without styraApiUrl and a STYRA_TOKEN it registers and then idles: there is nothing for it to poll.

Not deployed here

The public front door — the Traefik that terminates TLS for the Proxy and the WebUX, and the forward-auth service behind it — and hd_ipflow_graphql. docs/examples/k8s_example is no further ahead on either; they are genuinely not written yet.

Download helm.mdView raw