nvcl-operator Deployment runs in the nvcl-system namespace, the Hub sees the executor as online, and you can deploy nodes from the UI.
The Operator is the Kubernetes executor: it runs each node as a StatefulSet of pods and reports status back to the Hub. Choose it when you already run Kubernetes, want pod-level isolation, or plan to scale fleets. For the executor concept and the Agent-vs-Operator choice, see Executors.
Prerequisites
- Kubernetes — a cluster serving
networking.k8s.io/v1(Ingress, NetworkPolicy). The chart declares nokubeVersionfloor. - Cluster-admin at install time — the chart creates a namespaced
Role/RoleBindingand, for cluster telemetry, a small cluster-scopedClusterRolethat reads node capacity. - A storage class suitable for blockchain workloads — typically a CSI provider with
WaitForFirstConsumerbinding, fast NVMe-backed for heavy chains. - Outbound HTTPS from the Operator pod to the Hub (
https://hub.novacula.io). No inbound ports are needed. - An executor API key, created via Connect Executor (Operator kind) — see Connect an executor.
- (Optional) cert-manager with a ClusterIssuer — only if you’ll expose node RPC via proxy with automatic TLS. See RPC exposure.
Steps
1
Run the Helm command
From the Connect Executor screen in the UI, copy the exact Helm command. There’s no
helm repo add — the chart is an OCI ref. It installs the Operator in hub mode (it syncs to the Hub each tick) and renders the Hub token into a Secret. It looks like this:image.tagpins the Operator version;gateway.tagpins the matching gateway image (same version), which runs both as each pool’s own gateway and as the per-node RPC-auth sidecar.hub.urlandhub.tokenare the Hub connection;hub.nameis the executor’s identity in the Hub (defaults to the Helm release name).--set source=crdswitches to standalone/GitOps mode (reconcileNodeCRs in-namespace, no Hub); the default ishub.
- A single-replica
Deploymentnvcl-operator(+ServiceAccount), running the operator withrun --config /etc/nvcl/operator.toml. - A
Secretnvcl-operator-configholdingoperator.toml(with the Hub token) — mounted at/etc/nvcl/operator.toml. - A namespaced
Role+RoleBindingnvcl-operatorcoveringstatefulsets,configmaps/secrets/services/persistentvolumeclaims,ingresses/networkpolicies,deployments(get,list,create,patch,delete— each pool’s gateway runs as aDeploymentof its own),getonreplicasets(to find its ownDeployment), read-onlypods/pods/log,metrics.k8s.iopods(live usage of its own pod and the node pods it manages), andnovacula.ionodes(+/status); with self-update on, it also patches this Deployment (viaresourceNames) and runs the chart-upgradeJobs. - A small cluster-scoped
ClusterRole+ binding that reads node capacity and allocatable for cluster telemetry (disable with--set clusterNodeRead=false) — see Cluster telemetry.
2
Confirm online in the UI
online within seconds.If it stays offline:- Check Operator logs for auth errors.
- Confirm outbound HTTPS to the Hub URL.
- Verify
hub.tokenis theexc_key from the Connect Executor step.
What lives in the cluster
Static (chart-managed, in the release namespace):persistentvolumeclaims).
Dynamic (Operator-managed, per pool — <pool> is nvcl-pool-<pool id>):
Exposing node RPC
Each node’s RPC exposure is set per node (see RPC exposure); the Operator materializes it:- Direct → a
NodePortorLoadBalancerService (your choice). - Proxy → an
Ingressat your domain, with TLS via cert-manager when you set a ClusterIssuer, and optional RPC-key auth through the node’s gateway sidecar. - Closed → internal
ClusterIPonly.
proxy.* values (see below).
Operating
Deployment. A release that needs a newer chart can’t be requested by hand from the console — the upgrade dialog shows the helm upgrade command to run yourself instead. When such an upgrade reaches the Operator another way (an automatic update, for instance), the Operator applies the chart with a Helm Job if selfUpdate.enabled is on (the default; the Job uses selfUpdate.helmImage, alpine/helm:4.2.3). With selfUpdate.enabled: false the Operator doesn’t update itself at all, so run helm upgrade yourself; see Operator chart upgrades. Otherwise, run helm upgrade only for your own changes (resources, values).
Configuration (Helm values)
The chart composesoperator.toml from its values and renders it into the Secret. Common values:
- The namespace the Operator watches and deploys nodes into is the Helm release namespace (
--namespace). - The
gateway.*limits bound every pool gateway and node sidecar; they must be whole numbers, and they can’t be set throughextraConfig. Changing one restarts node pods and recreates every pool gateway — a brief outage per pool. See Gateway limits. - Per-node settings (resources, config/CLI overrides, RPC exposure) aren’t Helm values — set them per node in the UI. See Deploy a node and Edit a running node.
Cluster telemetry
The Operator reports cluster capacity from two reads, and they’re scoped as narrowly as the figures allow:
Setting
clusterNodeRead: false drops the cluster-wide read: node count, CPU capacity, and allocatable memory are then omitted. Workload usage is unaffected — it never leaves the release namespace, so the Operator’s ServiceAccount is never granted a pod list across your cluster.
If you’re moving from an older chart, run helm upgrade to pick up the current RBAC — memory reporting on the executor’s Overview and Monitoring tabs depends on it. See Node monitoring.
Hardening
-
Keep the Hub token secret — it lives in the
nvcl-operator-configSecret; restrict who can read Secrets innvcl-system. -
Let the Hub own the image when self-update is on — pinning
image.tagand thenhelm upgrade --reuse-valuesre-applies the pin and can undo a self-update. Either let self-update own the image, or manage it only via Helm. -
Fence the pool gateways’ admin port to the Operator pod — the port the Operator pushes pool config to. The gateway already refuses a push without the Operator’s credential; for defence in depth (it needs a CNI that enforces NetworkPolicy), add to
extraConfig:The Operator then writes aNetworkPolicyper pool that lets only its own pod reach the admin port, and leaves the pool’s serving port open. It’s off by default. -
Restrict egress from
nvcl-systemto the Hub URL (and per-chain image/binary sources) if you run NetworkPolicies.
Next steps
- Deploy a node onto your fresh executor.