Configure the agent
The agent supports Kubernetes-style configuration through three mechanisms. When the same setting appears in more than one, later sources overwrite earlier ones in this order:
defaults → environment variables → YAML config file → CLI flags
CLI flags win over everything. Defaults apply only when nothing else sets a value.
The one ordering that surprises people: the config file beats environment variables, which is the opposite of the viper/12-factor convention and the same way k3s resolves it. The reasoning is in why the config file outranks the environment; the short version is that a file you can read is easier to debug at 3am than a variable you cannot see.
Using CLI flags
Section titled “Using CLI flags”Best for development and one-off runs.
./bin/agent \ --othela-url=http://othela-server:8080/api/v1 \ --node-id=node-01 \ --poll-interval=5s \ --labels="role=edge-proxy,env=production"Using environment variables
Section titled “Using environment variables”Best for containers and systemd unit files.
export OTHELA_URL=http://othela-server:8080/api/v1export NODE_ID=node-01export POLL_INTERVAL=5sexport AGENT_LABELS=role=edge-proxy,env=production./bin/agentNote that this is the weakest of the three mechanisms. Environment
variables fill in whatever the config file leaves unset, but they will not
override a value the file sets. To override a config file at runtime — in a pod
spec, say — use args:, which are CLI flags.
Using a config file
Section titled “Using a config file”Best for managed fleets — this is the mechanism that “tastes like” kubelet.
othelaURL: "http://othela-server:8080/api/v1"nodeID: "node-01"pollInterval: "5s"workspaceDir: "/tmp/helvilette"labels: role: "edge-proxy" env: "production"Then point the agent at it:
./bin/agent --config=/var/lib/helvilette/agent.yamlKey names are case-sensitive: othelaURL and nodeID, with capitalised URL
and ID. An unrecognised key is rejected at startup, so a typo fails
immediately and visibly rather than leaving the agent running on defaults.
Confirming which mechanism won
Section titled “Confirming which mechanism won”Once more than one mechanism is in play, the useful question is not “what does
the precedence table say?” but “what is this node actually using?”.
--print-config answers it directly — it resolves the configuration, prints
each value with the source that supplied it, and exits without starting the
agent:
$ ./bin/agent --config=/var/lib/helvilette/agent.yaml --print-configothelaURL = http://othela-server:8080/api/v1 source=config-filenodeID = node-01 source=config-filepollInterval = 5s source=defaultworkspaceDir = /var/lib/helvilette/workspace source=config-filelabels.owner = sre source=env(AGENT_LABELS)labels.role = edge-proxy source=config-fileRun it the same way you run the agent — same unit file, same container, same environment — or the answer describes a different situation than the one you are debugging.
If the agent is talking to the wrong Othela, this is the first thing to
check. source=default on othelaURL means nothing you wrote was read at all:
a config file that was never passed with --config, a path that does not
exist, or a variable exported in a different shell than the one that started
the agent. source=env(OTHELA_URL) when you expected the file means the file
does not set that key — check the spelling of othelaURL.
If a node registers under an unexpected identity, look at nodeID. A
source of default(hostname) means nothing configured it and the machine’s
hostname was used; agent-unknown means even the hostname was unavailable.
Either way, set nodeID explicitly.
The agent logs the same resolution at startup under the message effective configuration, so you can also answer the question after the fact from a
node’s logs. See the configuration
reference
for the full vocabulary of source names.
Choosing labels
Section titled “Choosing labels”Labels are the entire targeting mechanism. Othela matches an agent’s labels
against nodeSelector rules in helvilette.yml and hands back only the jobs
that match. An agent whose labels match nothing simply receives no work.
Label along the axes you will actually want to target:
--labels="role=edge-proxy,env=production,region=sgn,arch=arm64"Getting this wrong is the most common reason an agent sits idle while you
expect it to be doing something. If a node is not picking up a job, compare its
labels against the nodeSelector before looking anywhere else — diagnose a
manifest that deploys
nothing walks the full
checklist.
Tuning the poll interval
Section titled “Tuning the poll interval”--poll-interval controls how often the agent asks Othela for work, and
therefore how quickly a Git push propagates to the fleet.
- Short (1–5s) — fast convergence, more requests. Fine for a handful of nodes or during development.
- Longer (30s–5m) — appropriate for large fleets, metered connections, or edge devices where waking the radio costs power.
Since agents poll independently, a large fleet on a short interval produces steady load on Othela proportional to fleet size divided by interval.
Related
Section titled “Related”- Agent configuration reference — every setting in table form.
- Why the config file outranks the environment — the reasoning behind the precedence order above.
- helvilette.yml reference — the other half of the targeting equation.
- Diagnose a manifest that deploys nothing — when the labels look right and the agent still gets no work.