Configuration
The controller reads one YAML file, resolved in this order:
- the first command-line argument
- the
OCTANE_CONFIGenvironment variable /etc/octane/autoscale.yml
A complete file
octane:
mode: custom_resource # recommend | kubernetes | custom_resource
interval_millis: 30000
clusters:
prod:
endpoint: https://opensearch.prod.svc:9200
authorization: "ApiKey <redacted>"
kubernetes:
namespace: search
custom_resource: clusters.lucenia.io/v1/luceniaclusters/prod
replica_paths:
hot: spec.nodePools.hot.replicas
warm: spec.nodePools.warm.replicas
license_path: /etc/octane/license.json
license_issued_to: acme-corp
Reference
| Key | Default | Meaning |
|---|---|---|
octane.mode | recommend | recommend, kubernetes, custom_resource. |
octane.interval_millis | 30000 | How often a cycle runs. |
octane.clusters.<id>.endpoint | — | Required. REST endpoint. At least one cluster. |
octane.clusters.<id>.authorization | — | Verbatim Authorization header value. |
octane.kubernetes.namespace | — | Required for kubernetes and custom_resource. |
octane.kubernetes.statefulsets.<tier> | — | (kubernetes mode) StatefulSet name for a tier. |
octane.kubernetes.custom_resource | — | (custom_resource mode) The resource to patch. |
octane.kubernetes.replica_paths.<tier> | — | (custom_resource mode) Dotted path to that tier's replica count. |
octane.license_path | — | License file. Absent ⇒ recommendation mode only. |
octane.license_issued_to | self-serve | Name the license is checked against. |
Multiple clusters
octane.clusters is a map, and one controller can drive several:
octane:
clusters:
prod: { endpoint: "https://prod:9200", authorization: "ApiKey ..." }
staging: { endpoint: "https://staging:9200", authorization: "ApiKey ..." }
At least one is required; a file with none is refused at startup.
It refuses to start on a configuration it cannot act on
Every one of these is checked when the file is read, not at the first scale:
| Condition | Error |
|---|---|
| no clusters | no clusters configured under octane.clusters |
| a cluster with no endpoint | cluster [id] has no endpoint |
custom_resource with no custom_resource set | octane.mode is custom_resource but octane.kubernetes.custom_resource is not set |
custom_resource with no replica_paths | octane.mode is custom_resource but no octane.kubernetes.replica_paths are configured |
kubernetes or custom_resource with no namespace | octane.mode is <mode> but octane.kubernetes.namespace is not set |
This is deliberate, and the reason is worth stating: a controller that starts happily and then cannot act at the one moment it is needed has hidden the mistake until it costs something. Failing at startup means the mistake surfaces during deployment, when someone is watching.
The replica_paths check has a second reason. Without a path there is nowhere to write the node
count, and guessing one could set a field that means something else entirely.
Secrets
authorization is a header value and belongs in a mounted secret, not in a ConfigMap. The same is
true of license_path. Mount both read-only.
Choosing an interval
interval_millis is the cycle period, not a scaling rate. A cycle that finds nothing to do is cheap
— a few REST calls — so 30 seconds is a reasonable default. A drain in progress is resumed across
cycles rather than restarted, so a short interval does not mean repeating work.