replicaCount | 1 | Must stay 1 until the Kubernetes watcher has leader election. |
image.repository | 941017932298.dkr.ecr.eu-west-2.amazonaws.com/expanse-daemon | Expanse release registry with signed multi-arch images per daemon release. Point at your registry mirror on air-gapped clusters. |
image.tag | unset | Empty runs the chart’s appVersion, pinned per chart version, so a new chart version is the upgrade. Set a daemon-v* semver only to run another release than the chart names. |
image.digest | unset | Empty with an empty tag uses the release digest the published chart carries; with a tag, set it from that release’s manifest so a re-pushed tag can never change what the cluster runs. |
image.pullPolicy | IfNotPresent | Standard Kubernetes field, passed through. |
imagePullSecrets | unset | Pull secrets for every chart pod. registryPull adds its refreshed Secret itself; list others here, e.g. your mirror’s, or a console Platform > Registry Secret without registryPull. |
registryPull | | Refresher Deployment (daemon role “registry-pull”): keeps the Expanse registry pull Secret holding a fresh token minted with the compute key. |
registryPull.enabled | false | Render the refresher Deployment, its ServiceAccount, Role and RoleBinding. |
registryPull.secretName | expanse-registry | The existing docker-registry Secret the refresher updates; the chart never creates it. |
registryPull.secretNamespace | unset | Namespace of the Secret, where the Role and RoleBinding render; empty is the release namespace. |
registryPull.refreshInterval | 4h | Go duration between refreshes, at most 6h (half a token’s 12 hours); the refresher refuses longer. |
registryPull.useAsImagePullSecret | true | Add secretName to the imagePullSecrets of every chart pod, the refresher’s own included. |
registryPull.serviceAccount.name | unset | Refresher ServiceAccount name; empty derives it from the release name. Required with serviceAccount.create=false; never the observer’s, which would gain the Secret grant. |
registryPull.resources | | The refresher holds one Secret between refreshes. No cpu limit, as in the umbrella chart. |
registryPull.resources.requests.cpu | 10m | CPU request of the refresher container. |
registryPull.resources.requests.memory | 32Mi | Memory request of the refresher container. |
registryPull.resources.limits.memory | 128Mi | Memory limit of the refresher container. |
registryPull.podAnnotations | unset | Annotations added to the refresher pod. |
registryPull.podLabels | unset | Labels added to the refresher pod. |
registryPull.nodeSelector | unset | Refresher node selector, passed through unchanged. |
registryPull.tolerations | unset | Refresher tolerations, passed through unchanged. |
registryPull.affinity | unset | Refresher affinity, passed through unchanged. |
registryPull.priorityClassName | unset | Pre-existing PriorityClass for the refresher; the chart creates none. |
nameOverride | unset | Replaces the chart name in resource names. |
fullnameOverride | unset | Replaces the whole release-qualified resource name. |
serviceAccount.create | true | Create the observer ServiceAccount; false reuses serviceAccount.name. |
serviceAccount.annotations | unset | Observer SA annotations for a cloud identity (IRSA role ARN, Workload Identity). |
serviceAccount.name | unset | Observer ServiceAccount name; empty derives it from the release name. |
serviceAccount.automountToken | true | Mount the observer’s API token; the watcher needs it to list and watch pods. |
rbac.create | true | Create the watcher’s (Cluster)Role and binding; false expects them to exist. |
rbac.clusterWide | true | true watches every namespace with cluster-wide list/watch permissions. false creates Role/RoleBinding objects only for watch.namespaces. |
rbac.listNodes | null | Cluster-scoped list nodes for queue and topology snapshots. Unset follows rbac.clusterWide; scoped installs set true to un-degrade the queue view. |
config.existingSecret | expanse-daemon-config | Installer-created Secret containing the exchanged daemon config. |
config.rolloutRevision | unset | Change on every Secret update. For staging-key rotation, set this to the new source-upload key ID so both workloads restart onto the new config. |
config.key | config.json | Secret key that holds the exchanged config. |
config.mountPath | /expanse-home/.expanse | Directory the config Secret is projected into; the daemon reads HOME/.expanse. |
config.fileName | config.json | File name of the projected config inside mountPath. |
config.defaultMode | 416 | 0640 (decimal 416): fsGroup below makes the root-owned Secret file readable by the nonroot daemon; the daemon refuses anything broader than 0640. |
home | /expanse-home | HOME of the daemon process; the config mount lives under it. |
state.mountPath | /expanse-state | Writable state mount: queued source uploads, the ingest queue, caches and health markers. |
state.persistence.enabled | false | emptyDir suits KIND and local dev. Enterprise installs set true (values-enterprise.yaml) so queued source uploads and the ingest queue survive Pod replacement and node drain; the observer’s Recreate keeps one RWO claim safe. |
state.persistence.existingClaim | unset | Bring your own PersistentVolumeClaim instead of the chart-created one. |
state.persistence.storageClassName | unset | StorageClass for the chart-created claim; empty uses the cluster default. |
state.persistence.size | 1Gi | Size of the chart-created claim; queued source uploads are small. |
state.persistence.annotations | unset | Standard Kubernetes field, passed through. |
state.persistence.labels | unset | Standard Kubernetes field, passed through. |
watch.namespaces | unset | Empty means all namespaces. Set a namespace list for scoped installs. |
limits.namespacePolicyCaptureEnabled | false | Read ResourceQuota and LimitRange per watched namespace; true also renders the observer’s get, list and watch on both, false renders neither. Off is a proposal; a denied read is reported. |
limits.admissionConfigCaptureEnabled | false | List mutating and validating webhook configurations; true also renders a dedicated observer ClusterRole with get, list and watch on both, in either RBAC mode. Off records capture_disabled. |
podAnnotations | unset | Standard Kubernetes field, passed through. |
podLabels | unset | Standard Kubernetes field, passed through. |
podSecurityContext | | The release image runs as uid 65532; without fsGroup the projected Secret is root-owned 0600 and the observer exits at “load config”. |
podSecurityContext.fsGroup | 65532 | Only the group: the uid comes from the image. Under an OpenShift SCC or a mustRunAsRange policy set podSecurityContext=null and let the range apply. |
podSecurityContext.fsGroupChangePolicy | OnRootMismatch | Skip the kubelet’s ownership pass once the state PVC root carries the group; the pass ORs group rw onto files and the daemon’s 0600 config cache must stay tight. |
podSecurityContext.seccompProfile.type | RuntimeDefault | Standard Kubernetes field, passed through. |
securityContext | | Every Expanse container but the sampler’s; with the pod context above it meets the Pod Security restricted profile. runAsNonRoot is never rendered at pod level, so the kubelet runs an injector’s root init container (chart 1.2.1, #1315). |
securityContext.runAsNonRoot | true | Standard Kubernetes field, passed through. |
securityContext.allowPrivilegeEscalation | false | Standard Kubernetes field, passed through. |
securityContext.readOnlyRootFilesystem | true | Standard Kubernetes field, passed through. |
securityContext.capabilities.drop | ["ALL"] | Standard Kubernetes field, passed through. |
resources | | Observer memory scales with the pod informer cache; 1Gi covers a few thousand pods. Raise on very large clusters. No cpu limit, as in the umbrella chart. |
resources.requests.cpu | 100m | Standard Kubernetes field, passed through. |
resources.requests.memory | 256Mi | Standard Kubernetes field, passed through. |
resources.limits.memory | 1Gi | Standard Kubernetes field, passed through. |
nodeSelector | unset | Standard Kubernetes field, passed through. |
tolerations | unset | Standard Kubernetes field, passed through. |
affinity | unset | Standard Kubernetes field, passed through. |
priorityClassName | unset | Standard Kubernetes field, passed through. |
runtimeClassName | unset | Standard Kubernetes field, passed through. |
trust | | The customer’s internal CA, trusted by every role beside the image’s public roots: the chart mounts the PEM and sets SSL_CERT_DIR. |
trust.customCA.existingSecret | unset | Existing Secret holding the PEM; set this or existingConfigMap. Empty trusts the public roots only. |
trust.customCA.existingConfigMap | unset | Existing ConfigMap holding the PEM, the alternative to existingSecret. |
trust.customCA.key | ca.crt | Key of the PEM in the Secret or ConfigMap; one key may hold several certificates. |
extraEnv | unset | Extra env for every workload, e.g. HTTPS_PROXY and NO_PROXY; a customer CA belongs in trust.customCA. A name the observer and sampler both render (HOME, the config and spool paths, the primary container) is refused. |
extraVolumes | unset | Appended after the chart’s fixed volumes/mounts in every workload. |
extraVolumeMounts | unset | Standard Kubernetes field, passed through. |
controller | | Gates the cluster-wide workload-observer Deployment. Disable for a GPU-sampler-only install on a cluster whose workloads are observed elsewhere. |
controller.enabled | true | Render the cluster-wide observer Deployment. |
observer.liveTail.enabled | true | Mid-run log tails of Running pods every 30s. false renders EXPANSE_KUBERNETES_LIVETAIL_POLL=0, so the observer reads pod logs only at termination. |
observer.featureSchema | | Typed custom features from pod labels, annotations and image digests. |
observer.featureSchema.configMap | unset | Existing ConfigMap holding the organisation’s protobuf-JSON FeatureSchema; empty captures nothing. |
observer.featureSchema.key | schema.json | Key of the schema inside the ConfigMap. |
observer.featureSchema.checksum | unset | Content hash of the schema; a change rolls the observer pod even where lookup cannot read the ConfigMap. |
observer.platformEvents | | Platform events about watched pods and their Jobs: one events.k8s.io watch per watched namespace and list,watch RBAC on events. A proposal, off until enabled. |
observer.platformEvents.enabled | false | Renders EXPANSE_KUBERNETES_PLATFORM_EVENTS and the events grant on the observer. |
probes | | Exec probes on both workloads via expanse-daemon healthcheck, which reads marker files the heartbeat loop touches. |
probes.enabled | true | Needs image.tag v0.5.0 or newer (the healthcheck subcommand); on an older image every probe fails and the kubelet restart-loops the pods, so set false. |
probes.liveness | | Liveness follows the loop marker, not heartbeat success, so a plane outage never restarts pods. The heartbeat interval clamps at 5m; stay above it. |
probes.liveness.maxAge | 20m | Go duration, e.g. 20m; oldest acceptable loop marker, passed as healthcheck —max-age. |
probes.readiness | | Readiness follows the last accepted heartbeat. Off by default so DaemonSet rollouts stay independent of plane availability; on, helm —wait proves a heartbeat. |
probes.readiness.enabled | false | Add a readiness probe on the heartbeat marker; needs probes.enabled. |
probes.readiness.maxAge | 15m | Go duration, e.g. 15m; oldest acceptable accepted-heartbeat marker. |
networkPolicy | | Opt-in NetworkPolicy per workload: ingress denied, egress limited to DNS, the planes, the API server and (sampler) the DCGM host engine. Off: many CNIs do not enforce. |
networkPolicy.enabled | false | Render one NetworkPolicy per workload. |
networkPolicy.dns.kubeSystemOnly | false | Restrict port 53 to kube-system instead of any destination. |
networkPolicy.egress.planes | | Control and data plane destinations; narrow the CIDRs to your plane addresses. |
networkPolicy.egress.apiServer | | API server endpoint. kind and k3s serve 6443, managed clusters mostly 443. |
networkPolicy.egress.dcgmPort | 5555 | DCGM host engine port and the node ranges it is reached on, used only when nodeSampler.dcgm.hostEngine is set. |
networkPolicy.extraEgress | unset | Extra NetworkPolicyEgressRule items appended to every workload’s policy, e.g. EKS Pod Identity: [{to: [{ipBlock: {cidr: 169.254.170.23/32}}], ports: [{protocol: TCP, port: 80}]}]. |
nodeSampler | | Per-node GPU metric sampler DaemonSet. The observer Deployment does NOT sample GPUs. |
nodeSampler.enabled | false | Render the per-node GPU sampler DaemonSet. |
nodeSampler.serviceAccount | | Dedicated SA bound to NO RBAC. On serviceAccount.create=false you must name an SA that also carries no RBAC; the render fails loudly if it is unset. |
nodeSampler.serviceAccount.name | unset | Sampler ServiceAccount name; empty derives it from the release name. |
nodeSampler.serviceAccount.annotations | unset | Node-sampler SA only, never inherited from serviceAccount.annotations, so the sampler cannot pick up the observer’s IRSA or Workload Identity role. |
nodeSampler.podSecurityContext | | fsGroup lets the nonroot daemon read the root-owned config Secret at 0640. Only the root-forcing features in securityContextOverridden below change the uid. |
nodeSampler.podSecurityContext.runAsUser | 65532 | Standard Kubernetes field, passed through. |
nodeSampler.podSecurityContext.runAsGroup | 65532 | Standard Kubernetes field, passed through. |
nodeSampler.podSecurityContext.fsGroup | 65532 | Standard Kubernetes field, passed through. |
nodeSampler.podSecurityContext.runAsNonRoot | true | Standard Kubernetes field, passed through. |
nodeSampler.podSecurityContext.seccompProfile.type | RuntimeDefault | Standard Kubernetes field, passed through. |
nodeSampler.securityContext | | Node-sampler container only, never inherited. On top of drop ALL adds SYS_PTRACE (codeAttribution, observedProcess or storageClient), DAC_READ_SEARCH (observedProcess or storageClient), PERFMON (perfCounters) and the CUPTI grant. |
nodeSampler.securityContext.allowPrivilegeEscalation | false | Standard Kubernetes field, passed through. |
nodeSampler.securityContext.readOnlyRootFilesystem | false | false until verified on a GPU node with the release image: the NVIDIA hook bind-mounts driver libraries into the rootfs. |
nodeSampler.securityContext.capabilities.drop | ["ALL"] | Standard Kubernetes field, passed through. |
nodeSampler.securityContextOverridden | false | Set true to keep full control of nodeSampler.podSecurityContext instead of the chart forcing root for the pod-resources source, codeAttribution, observedProcess, runHop, cupti.mode=sysadmin, perfCounters, hostPower or storageClient. |
nodeSampler.config.defaultMode | 416 | Projected config Secret mode for the node sampler. 0640 (decimal 416) so the fsGroup can read it; the daemon refuses anything broader than 0640. |
nodeSampler.state.hostPath | /var/lib/expanse-daemon | Node directory under which each release’s sampler keeps its state (ingest queue, run records, caches) at <hostPath>/<release> while state.persistence.enabled is true. |
nodeSampler.state.sizeLimit | 512Mi | Size limit of the emptyDir the sampler’s state uses while state.persistence.enabled is false; the ingest queue caps itself at 256 MiB plus a 32 MiB lifecycle reserve, and the rest is small. |
nodeSampler.hostMetrics.enabled | true | Per-pod host CPU and memory series from each pod’s cgroup. false stands the reader down while GPU and code attribution keep the pod informer; it forces no root. |
nodeSampler.containerStats.enabled | false | Pod ephemeral storage and container writable-layer and log usage from the kubelet summary over verified HTTPS; adds get nodes/stats and egress to port 10250. Needs hostMetrics and pod reads. Off until enabled. |
nodeSampler.containerStats.caSecretName | unset | Optional Secret holding the kubelet serving CA; empty uses the service-account CA. |
nodeSampler.containerStats.caSecretKey | ca.crt | PEM key within caSecretName. Certificate verification always remains enabled. |
nodeSampler.primaryContainer | unset | The workload container’s name, for pods matching primaryContainerSelector that carry no default-container annotation. Both workloads read it. |
nodeSampler.primaryContainerSelector | unset | Labels every pod the primaryContainer override applies to must carry; required with it, so a foreign pod with a container of that name keeps its own choice. |
nodeSampler.podResources | | Per-pod GPU attribution: each card’s owner joins the pod’s execution timeline. Disabled ships node-scope metrics only, with no RBAC or token. |
nodeSampler.podResources.enabled | true | Grant read-only pods access and resolve each GPU’s owning pod. |
nodeSampler.podResources.source | cgroup | cgroup (default) joins the processes nvidia-smi lists on each card to their pod through the host /proc, non-root with hostPID. podresources reads the root-owned kubelet socket, exact for idle cards, as uid 0. |
nodeSampler.podResources.hostPath | /var/lib/kubelet/pod-resources | Host directory containing kubelet.sock, mounted only with source=podresources. Override only on clusters that relocate the kubelet root; k3s uses this stock path. |
nodeSampler.nvidia | | All GPUs visible read-only, so the sampler sees every GPU on the node without taking a schedulable GPU slot. |
nodeSampler.nvidia.visibleDevices | "all" | NVIDIA_VISIBLE_DEVICES / NVIDIA_DRIVER_CAPABILITIES for the sampler container: all GPUs, utility libraries only (nvidia-smi, no CUDA). |
nodeSampler.nvidia.driverCapabilities | "utility" | NVIDIA_DRIVER_CAPABILITIES; cupti.enabled appends compute when missing. |
nodeSampler.cupti | | GPU performance-counter sampling (CUPTI) from the sampler pod; needs an r580 or newer NVIDIA driver. |
nodeSampler.cupti.enabled | false | Starts CUPTI sampling and adds the compute driver capability. Needs a daemon image v0.5.0 or newer. |
nodeSampler.cupti.mode | perfmon | perfmon keeps counters restricted without forcing root (Linux 5.8+, R565+). sysadmin explicitly uses SYS_ADMIN/root for older hosts; none adds no capability. |
nodeSampler.profiling | | Adaptive profiling on each GPU node: rule engine plus Phase A CUPTI widening when cupti.enabled is on. false pins Light-only sampling. |
nodeSampler.profiling.enabled | true | Sets EXPANSE_PROFILING_ENABLE; false pins Light-only sampling. |
nodeSampler.dcgm | | DCGM enrichment from a host engine you already run, passed as dcgmi —host. ”$(NODE_IP):5555” reaches a GPU Operator nvidia-dcgm or a host nvidia-dcgm.service. |
nodeSampler.dcgm.hostEngine | unset | Host engine address (dcgmi —host); empty leaves the DCGM chip disabled. Needs daemon v0.5.0 or newer. |
nodeSampler.codeAttribution | | Python stack attribution for the pods on this node. Needs hostPID, SYS_PTRACE, root and read-only pod access, so off by default. |
nodeSampler.codeAttribution.enabled | false | Needs daemon v0.5.0 or newer. |
nodeSampler.codeAttribution.readsPerSecond | 10 | Stack reads a second across every pod on the node, shared fairly per pod; 0 removes the bound. |
nodeSampler.codeAttribution.namespaces | unset | Namespaces whose pods are sampled without the expanse.sh/code-attribution=enabled annotation; every other pod must carry it. |
nodeSampler.codeAttribution.mode | dump | dump reads one stack per pid per tick; record runs bounded py-spy recording windows whose timestamps are reconstructed. |
nodeSampler.observedProcess | | Capture the primary container’s observed commands, effective configs and runtime libraries; needs root, SYS_PTRACE, DAC_READ_SEARCH and pod reads, never hostPID. |
nodeSampler.observedProcess.enabled | false | Sets EXPANSE_OBSERVED_PROCESS_CAPTURE on the node sampler; false grants nothing extra. |
nodeSampler.platformEvents | | Platform events about this node, ridden on its host row: one node-scoped events.k8s.io watch, pod reads and list,watch on events. A proposal, off until enabled. |
nodeSampler.platformEvents.enabled | false | Renders EXPANSE_KUBERNETES_PLATFORM_EVENTS and the events grant on the node sampler. |
nodeSampler.hostSeries | | Node host series readers, listed in EXPANSE_HOST_SERIES (none while hostMetrics.enabled is false). No root or capability, so cpufreq’s root-only cpuinfo_cur_freq record reads permission_denied. |
nodeSampler.hostSeries.cpufreq | true | CPU frequency per CPUFreq policy from sysfs. |
nodeSampler.hostSeries.steal | true | Node CPU steal seconds from /proc/stat, never attributed to a job. |
nodeSampler.hostSeries.smt | true | SMT state and the sibling map from sysfs. |
nodeSampler.hostSeries.vmstat | true | Kernel memory counters from /proc/vmstat and /proc/buddyinfo. |
nodeSampler.hostSeries.hwerr | true | Hardware error counters. |
nodeSampler.perfCounters | | CPU hardware counters through perf_event: adds PERFMON only and runs the sampler as uid 0, since Kubernetes sets no ambient capabilities. Never SYS_ADMIN, never a perf_event_paranoid write. |
nodeSampler.perfCounters.enabled | false | Sets EXPANSE_PERF_COUNTERS_ENABLE=1. |
nodeSampler.perfCounters.fdBudget | 0 | EXPANSE_PERF_EVENT_FD_BUDGET: the most perf_event file descriptors the reader holds open. |
nodeSampler.hostPower | | RAPL and ACPI power meter energy: uid 0 owns the 0400 energy_uj file and reads it without a capability, so this runs the sampler as root and adds none. |
nodeSampler.hostPower.enabled | false | Sets EXPANSE_HOST_POWER_ENABLE=1. |
nodeSampler.storageClient | | Per-mount storage client statistics (/proc/<pid>/mountstats, statfs through /proc/<pid>/root); takes the observedProcess grant (root, SYS_PTRACE, DAC_READ_SEARCH) and, at the default cgroup source, its hostPID. |
nodeSampler.storageClient.enabled | false | Sets EXPANSE_STORAGE_CLIENT_STATS=1. |
nodeSampler.storageClient.statfsWorkers | 2 | EXPANSE_STATFS_WORKERS: statfs calls in flight at once. |
nodeSampler.storageClient.statfsTimeoutSeconds | 2 | EXPANSE_STATFS_TIMEOUT in seconds: the bound on one statfs call. |
nodeSampler.storageClient.excludeMounts | unset | EXPANSE_STORAGE_EXCLUDE_MOUNTS: mount points never read. |
nodeSampler.storageClient.excludeFstypes | unset | EXPANSE_STORAGE_EXCLUDE_FSTYPES: filesystem types never read. |
nodeSampler.kubeletConfig | | The kubelet’s CPU manager policy and exclusive CPUs: two host files mounted read-only, as type File, so a missing file keeps the pod from starting. No directory mount, no RBAC, uid 65532 kept. |
nodeSampler.kubeletConfig.enabled | false | Mounts both files and sets EXPANSE_KUBELET_CONFIG_PATH and EXPANSE_KUBELET_CPU_MANAGER_STATE_PATH. |
nodeSampler.kubeletConfig.configPath | /var/lib/kubelet/config.yaml | The kubelet configuration file on the node, mounted at /host/kubelet/config.yaml. |
nodeSampler.kubeletConfig.statePath | /var/lib/kubelet/cpu_manager_state | The CPU manager checkpoint on the node, mounted at /host/kubelet/cpu_manager_state. |
nodeSampler.runHop | | Run transports for a runner that reuses one pod for several runs; both off by default. |
nodeSampler.runHop.enabled | false | Serve the local hop: a Unix socket under hostPath that runner pods mount and report run start and finish on. Needs hostPID, which the chart sets. |
nodeSampler.runHop.hostPath | /run/expanse | Node directory holding run-hop.sock; mount the same path into runner pods. |
nodeSampler.runHop.annotations | false | Follow expanse.sh/run-id, run-started and run-metadata pod annotations as run edges. |
nodeSampler.runHop.observationBacklog | 4096 | Progress observations the node holds awaiting a seal; one past it is refused ResourceExhausted and counted on the run_hop row. Unmeasured: the edge backlog’s figure until the kwok run. |
nodeSampler.runtimeClassName | unset | Set to “nvidia” only if the cluster needs an explicit RuntimeClass. Most GPU AMIs already default the container runtime to nvidia. |
nodeSampler.nodeSelector | unset | Restrict to GPU nodes, e.g. {“nvidia.com/gpu.present”: “true”}. Empty runs everywhere: CPU-only nodes ship host and per-pod usage without GPU chips. Required when runtimeClassName is set. |
nodeSampler.tolerations | | Tolerates the conventional GPU node taint (eksctl and the GPU operator both apply nvidia.com/gpu=present:NoSchedule). |
nodeSampler.affinity | unset | Node-sampler placement and pod metadata, passed through unchanged. |
nodeSampler.resources | | The CUPTI helper holds ~165MB per node on the bundled cuda1300 build plus a ~16MiB ring per GPU; 2Gi covers 8 GPUs. Raise for denser nodes. |
nodeSampler.resources.requests.cpu | 100m | Standard Kubernetes field, passed through. |
nodeSampler.resources.requests.memory | 256Mi | Standard Kubernetes field, passed through. |
nodeSampler.resources.limits.memory | 2Gi | Standard Kubernetes field, passed through. |
nodeSampler.priorityClassName | unset | Pre-existing PriorityClass so the sampler survives node pressure. The chart creates none: PriorityClass is cluster-scoped and scoped installs avoid those. |
nodeSampler.podAnnotations | unset | Standard Kubernetes field, passed through. |
nodeSampler.podLabels | unset | Standard Kubernetes field, passed through. |
agentInjection | | Phase B CUPTI agent for GPU pods that opt in by label: the observer’s webhook injects it at admission, the sampler stages and arms it. Needs both roles. |
agentInjection.service.annotations | unset | Annotations for the agent injection webhook Service, such as DNS registration settings. |
agentInjection.service.labels | unset | Labels for the agent injection webhook Service; chart-owned identity labels take precedence. |
agentInjection.enabled | false | Render the webhook, its Service and the sampler’s profiling root. |
agentInjection.podLabel | expanse.sh/profiling-agent | Label whose value “true” opts a namespace in and, inside it, a GPU pod. The mutation adds a hostPath volume, so the namespace must admit one; Pod Security baseline or restricted never is. |
agentInjection.hostPath | /var/lib/expanse/profiling | Node directory holding the staged agent library and the per-pod control tree, mounted read-write by the sampler and by every mutated pod. |
agentInjection.webhook.port | 9443 | Observer container port the API server reaches through the Service on 443. |
agentInjection.webhook.timeoutSeconds | 5 | Seconds the API server waits before admitting the pod unprofiled (failurePolicy Ignore). |
agentInjection.tls.certManager.enabled | true | cert-manager issues and rotates the serving certificate and injects the CA. Point issuerRef at an existing issuer, or disable and bring your own Secret. |
agentInjection.tls.certManager.issuerRef | | The existing cert-manager issuer that signs the webhook’s serving certificate. |
agentInjection.tls.certManager.issuerRef.kind | ClusterIssuer | ClusterIssuer or Issuer. |
agentInjection.tls.certManager.issuerRef.name | unset | Issuer name; the render fails without one while certManager.enabled is true. |
agentInjection.tls.existingSecret | unset | Used when certManager.enabled is false: a pre-created tls.crt/tls.key Secret and the base64 CA bundle for the webhook clientConfig. |
agentInjection.tls.caBundle | unset | Base64 PEM of the CA that signed existingSecret, placed in the webhook’s caBundle. |
integration | | In-network adapter Deployment (daemon role “integration”): reads the customer’s own run events and metric rows through an adapter mapping file. |
integration.podAnnotations | unset | Annotations shared by the adapter and history-import Pods; generated rollout annotations take precedence. |
integration.podLabels | unset | Labels shared by the adapter and history-import Pods; chart-owned identity labels take precedence. |
integration.enabled | false | Render the adapter Deployment; independent of controller.enabled and nodeSampler.enabled. |
integration.dryRun | true | Map and count but write and commit nothing, so the dry-run report is reviewed first. The default until the organisation’s delivered collector.integration_dry_run setting says otherwise (DAEMON-INTEGRATION.md “Going Live”). |
integration.resumeFrom | unset | Previous checkpoint of a reset replay, a file name under the state directory; see TELEMETRY-ADAPTER.md. |
integration.checkpointInterval | 10s | Floor of the spacing of checkpoints and offset commits, the adapter’s own default; a slow checkpoint stretches the spacing by itself (TELEMETRY-ADAPTER-CHECKPOINT.md “The Guard”), so no install raises it for one. |
integration.runRetention | unset | How long a settled run waits for the lifecycle row correcting its outcome, past the batch lag plus one backfill (a daily batch needs about 72h; taking every outcome from it refuses under 36h); empty is 26h. The claim holds it (72h: 18Gi). |
integration.expectedRunsPerDay | 2500000 | Runs a day the source settles; with runRetention it sizes the retained-run bound. Retained runs past 10,000,000 (about 1.5 GB of the 3Gi limit at 146 B a run) refuse to start; see TELEMETRY-ADAPTER-STATE.md “Bounds And Sizing”. |
integration.heldRowsMax | 0 | Bound on the metric, device and pod window rows held for their run or siblings; 0 is the adapter’s 500,000 (about 320 MB at 640 B a row). Raise it when held_row_overflow counts; see TELEMETRY-ADAPTER-STATE.md “Bounds And Sizing”. |
integration.scopedWaitMaxRows | 0 | Bound on the run event rows waiting for a scoped run; 0 is the adapter’s 1,000,000. Raise it, with the memory limit, when scoped_run_wait_overflow counts; see TELEMETRY-ADAPTER-WAITING.md “Rows Waiting For A Scoped Run”. |
integration.scopedWaitMaxBytes | 0 | Bound on the waiting rows’ raw column bytes, at least 1048576; 0 is the adapter’s 536870912 (512 MiB, about 470 MiB of memory). Raise it with scopedWaitMaxRows and the memory limit. |
integration.maxJobFacts | 0 | Bound on the jobs whose per-job facts are kept; 0 is the adapter’s 100,000. Raise it, with the memory limit, when job_facts_evicted_before_run counts; see TELEMETRY-ADAPTER-IDENTITY.md “Per-Job Tables”. |
integration.writes | | Bounds all writer tasks across independent runs. The batch depth remains two. |
integration.writes.concurrency | 24 | Concurrent delivery calls, from 1 to 256; each run’s declarations, samples and repeats stay ordered. |
integration.writes.maxBytes | 268435456 | Maximum admitted encoded payload and bookkeeping bytes, from 1048576 to 1073741824; includes repeats. |
integration.maxJobFactBytes | 0 | Packed fact bytes, at least 1048576; 0 is 1 GiB. The state claim also reserves two bounded log generations. Size with maxJobFacts for the all-cluster distinct rate and batch reach; TELEMETRY-ADAPTER-JOB-FACTS.md. |
integration.maxCounterSeries | 0 | Bound on the cumulative counter series whose last readings are kept; 0 is the adapter’s 200,000. Raise it, with the memory limit, when counter_series_evicted_by_count grows; see TELEMETRY-ADAPTER-COUNTERS-CUMULATIVE.md. |
integration.maxCounterSeriesBytes | 0 | Bound on the counter series’ memory, at least 1048576; 0 is the adapter’s 100663296 (96 MiB, about 260,000 series at a container’s shape). Raise it with maxCounterSeries when counter_series_evicted_by_bytes grows. |
integration.deployment | unset | The deployment this adapter serves; the mapping’s mandatory deployment filter admits exactly it, and a writing adapter refuses to start without it. |
integration.cluster | unset | The cluster this adapter serves; the mapping’s mandatory cluster filter must admit it, required to write. |
integration.advisoryUrl | unset | Intelligence plane URL the admission records go to under the compute key; empty keeps them in memory, read not delivered on the health row. |
integration.nccl | | The NCCL log tail path: the mapping’s tail column read through the NCCL loop. |
integration.nccl.enabled | false | Runs the loop and its segment station under the state directory; collect_nccl_events still decides whether anything is read, and the uploads leave through the data plane’s segment grants. |
integration.mapping | | Administrator-owned mapping file in an existing ConfigMap; it carries no credential. |
integration.mapping.configMap | unset | Name of the ConfigMap holding the mapping file. |
integration.mapping.key | mapping.yaml | Key of the mapping file inside the ConfigMap. |
integration.mapping.checksum | unset | Content hash of the mapping, filled by the install bundle; a change rolls the adapter pod even where lookup cannot read the ConfigMap. |
integration.mapping.pinConfigMap | false | Run this ConfigMap’s mapping and never fetch the organisation’s active mapping from the control plane, which otherwise wins when one is active (air gap, or file control; DAEMON-INTEGRATION.md “The Active Mapping”). |
integration.mapping.trustKey | | The published install-bundle key (releases.expanse.sh/keys/expanse-install-bundle-signing.pub) a delivered mapping’s signature must verify against; with neither source set the adapter runs the ConfigMap alone. |
integration.mapping.trustKey.existingSecret | unset | Existing Secret holding the PEM; it wins over existingConfigMap. |
integration.mapping.trustKey.existingConfigMap | unset | Existing ConfigMap holding the PEM. |
integration.mapping.trustKey.key | expanse-install-bundle-signing.pub | Key of the PEM inside the Secret or ConfigMap. |
integration.kafka | | The customer’s own Kafka, read in place; offsets in the group are the watermark. |
integration.kafka.brokers | unset | Bootstrap brokers inside the customer’s network, e.g. [“kafka-1:9093”]. |
integration.kafka.group | expanse-integration | Consumer group; one adapter per group. |
integration.kafka.topicTemplate | unset | The topic of every mapping table read from Kafka, holding {table} once for its name, e.g. “telemetry.{table}”. |
integration.kafka.topics | unset | Explicit topic to mapping table bindings, e.g. {“jobs.pilot”: “JobEvent”}; each wins over the template for its table. |
integration.kafka.format | json | Message format of the topics: json or avro (Confluent-framed, schemas from the registry below). |
integration.kafka.startFrom | earliest | Where the group starts a partition it has no committed offset for: earliest (the default), latest or “timestamp:<RFC 3339>”; a group with commits ignores it (DAEMON-INTEGRATION.md “Where A Group Starts”). |
integration.kafka.schemaRegistry | | Confluent-compatible schema registry; required with the avro format, unused with json. |
integration.kafka.schemaRegistry.url | unset | Base URL, e.g. https://schema-registry.internal:8081; several comma-separated are tried in order. |
integration.kafka.schemaRegistry.existingSecret | unset | Existing Secret with username and password for basic authentication; empty sends none. |
integration.kafka.maxPoll | 20000 | Records one poll may return; a batch is checkpointed and committed as one, so small polls cap throughput. |
integration.kafka.fetchMaxPartitionBytes | 4194304 | Bytes one fetch may carry of one partition, at most 32 MiB; a fetch carries twice this. The 1 MiB franz-go default capped a busy single-partition topic near its production rate. |
integration.kafka.sourceRetention | 3h | Fallback retention, a Go duration of at least 10m in whole hours, minutes and seconds (1h30m), for a topic whose own retention.ms the principal may not describe; each topic’s lag past a third of its retention logs a WARN, past two thirds an ERROR and degrades. |
integration.kafka.saslMechanism | unset | SASL mechanism: empty, PLAIN, SCRAM-SHA-256 or SCRAM-SHA-512. |
integration.kafka.existingSecret | unset | Existing Secret: username and password with SASL, or ca.crt, tls.crt and tls.key for mutual TLS. |
integration.kafka.tls | | TLS to the brokers, alone or under SASL (SASL_SSL). |
integration.kafka.tls.existingSecret | unset | Existing Secret with ca.crt, plus tls.crt and tls.key when clientCertificate is on. |
integration.kafka.tls.clientCertificate | null | Present a client certificate (tls.crt, tls.key) for mutual TLS, or false to verify the brokers only; unset refuses to render with existingSecret, so an upgrade states which the broker needs. |
integration.kafka.receivedSchema | | ConfigMap holding the received schema the topics publish; without it the adapter stays in dry run. Not needed with the avro format, whose received schema is the registry’s latest per topic. |
integration.kafka.receivedSchema.configMap | unset | Name of the ConfigMap; empty leaves the mapping unverified. |
integration.kafka.receivedSchema.key | received-schema.jsonl | Key of the schema file inside the ConfigMap. |
integration.kafka.receivedSchema.checksum | unset | Hash of the schema file; a change rolls the adapter pod even where lookup cannot read the ConfigMap. |
integration.pull | | A pull source in place of Kafka: the mapped tables read by a timestamp cursor. The mapping’s connection transport must name the same source; empty reads Kafka. |
integration.pull.source | unset | clickhouse or dremio; empty reads the kafka block above. |
integration.pull.cursors | unset | Mapping table to its cursor column, a declared transport_metadata timestamp, e.g. {“PodCpuMetrics”: “kafka_timestamp”}. |
integration.pull.lateness | unset | How far behind the newest delivered row a late row may still land, e.g. 10m; required. |
integration.pull.settle | unset | Rows newer than now minus this are left for the next sweep, e.g. 30s; required, 0s allowed. |
integration.pull.batchSize | 10000 | Rows one query may return; a page that cannot pass one cursor value is refused, so exceed the rows sharing one. |
integration.pull.pollInterval | 30s | Wait between sweeps once every table reached the settled edge. |
integration.pull.existingSecret | unset | Existing Secret: key dsn (a clickhouse:// DSN naming the database) or key token (the Dremio bearer token). |
integration.pull.dremioUrl | unset | Dremio’s https base URL, e.g. https://dremio.internal:9047; required with dremio. |
integration.pull.tlsCA | false | Read ca.crt from the same Secret as the service’s only trust root. |
integration.prometheus | | Point-scrape tables read from a Prometheus HTTP API beside Kafka, such as dcgm-exporter’s series; under networkPolicy.enabled its host belongs in integration.egress.destinations. |
integration.prometheus.url | unset | Base URL of the API without /api/v1, e.g. http://prometheus.monitoring:9090; empty reads no table from Prometheus. |
integration.prometheus.tables | unset | Override, for one release, of the tables marked transport: prometheus, e.g. [DcgmExporterMetrics]; none on a topic. |
integration.prometheus.lateness | unset | How far behind the newest delivered sample a late one may still land, e.g. 10m; required with a url. |
integration.prometheus.settle | unset | Samples newer than now minus this wait for the next sweep, covering a remote-write store’s ingest lag; required, 0s allowed. |
integration.prometheus.page | 2m | The span one query reads; shorten it for a large fleet or a fast scrape. |
integration.prometheus.pollInterval | 30s | Wait between sweeps once every table reached the settled edge. |
integration.prometheus.externalLabels | unset | The server’s global.external_labels, which fill a label a series lacks, e.g. {k8sContext: cluster-a}. |
integration.prometheus.tenant | unset | Cortex or Mimir tenant sent as X-Scope-OrgID on every request, e.g. chjc01; a federated read joins several with |. |
integration.prometheus.existingSecret | unset | Existing Secret with key token (sent as a bearer token, https only) and, with tlsCA, key ca.crt. |
integration.prometheus.token | false | Send the Secret’s token; the url must be https. |
integration.prometheus.tlsCA | false | Read ca.crt from the same Secret as the server’s only trust root. |
integration.objectStore | | The customer’s S3-compatible object store holding root-job source files. |
integration.objectStore.endpoint | unset | Endpoint of the store or its gateway; empty uses the regional AWS endpoint. |
integration.objectStore.bucket | unset | Bucket of the source files; empty disables source capture. |
integration.objectStore.pathStyle | false | Path-style addressing, which most on-premises gateways need. |
integration.objectStore.region | unset | Region the client signs and routes with; required with a bucket. A gateway accepts any, us-east-1 by convention. |
integration.objectStore.existingSecret | unset | Existing Secret with AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY; empty uses the default credential chain. |
integration.sourceDownload | | In place of objectStore, the one in-network endpoint serving the runner’s upload for a run’s user; under networkPolicy.enabled its host also belongs in integration.egress.destinations. |
integration.sourceDownload.url | unset | Endpoint URL, read as GET <url>?<fileParam>=<object key>&<userParam>=<run user>; empty leaves it off. Not with objectStore.bucket. |
integration.sourceDownload.fileParam | file | Query parameter carrying the object key the mapping’s template renders. |
integration.sourceDownload.userParam | user | Query parameter carrying the run’s user, from the mapping’s user role. |
integration.sourceDownload.existingSecret | unset | Existing Secret holding an optional bearer token, mounted as a file; it needs the url. |
integration.sourceDownload.secretKey | token | Key of the token inside the Secret. |
integration.logDownload | | The one in-network log endpoint each completed run’s work log is read from, its tail declared on the run; under networkPolicy.enabled its host also belongs in integration.egress.destinations. |
integration.logDownload.url | unset | Endpoint URL the job path is appended under, read as GET <url>/<job path>?<attemptParam>=<pod>&<jobOnlyParam>=true; empty leaves it off. |
integration.logDownload.attemptParam | unset | Query parameter carrying the run’s pod name, the attempt the endpoint keys a log by; required with the url. |
integration.logDownload.jobOnlyParam | unset | Query parameter sent true so a reused pod’s log keeps the job’s own output alone; required with the url. |
integration.logDownload.window | 30m | How long after a run’s end a log not uploaded yet is read again: a Go duration from 1m to 24h. |
integration.logDownload.existingSecret | unset | Existing Secret holding an optional bearer token, mounted as a file; it needs the url. |
integration.logDownload.secretKey | token | Key of the token inside the Secret. |
integration.codeHost | | The one in-perimeter code host the adapter may fetch a root job’s source from; under networkPolicy.enabled its address and port also belong in integration.egress.destinations. |
integration.codeHost.url | unset | Base URL of the code host, its only allow-listed host; empty leaves the fetch off. |
integration.codeHost.protocol | raw | raw (one HTTP read per file) or git (a shallow, blob-less fetch with the image’s git). |
integration.codeHost.existingSecret | unset | Existing Secret holding the read token, mounted as a file; it needs the url. |
integration.codeHost.secretKey | token | Key of the token inside the Secret. |
integration.codeHost.scratchSizeLimit | 1Gi | Size of the writable /tmp the git protocol’s scratch repository uses under the read-only root. |
integration.sourceReads | | The bounded pool that reads a run’s source off the batch path, so a slow endpoint never holds the Kafka read; a retryable failure waits 1, 2, 4 and 8 minutes, then 15. |
integration.sourceReads.workers | 4 | Concurrent source reads; also the rate limiter’s burst. |
integration.sourceReads.requestsPerSecond | 10 | Requests a second across every route read (object store, download endpoint, code host); may be fractional. |
integration.sourceReads.queueMax | 10000 | Bound on each of the source and log read queues; a full queue holds due reads back and drops only a read it cannot hold back, counted source_read_dropped (SOURCE-RESOLUTION-READS.md “Bounds”). |
integration.sourceReads.endWindow | 30m | How long after a run’s end a source not kept yet is read again, from its COMPLETED on the same backoff; a Go duration from 1m to 24h. |
integration.sourceReads.sourceWeight | 3 | Rate tokens source reads take to every log read’s while both classes wait, 1 to 100; 1 serves them in turn. |
integration.history | | One history import as a Job: the customer’s extract mapped through the adapter mapping and submitted once; rolled back by its import id. Independent of integration.enabled. |
integration.history.enabled | false | Render the Job; it needs the mapping ConfigMap, the config Secret and every value below. |
integration.history.importId | unset | The import id every row is stamped with; also the Job’s name suffix. Lower-case DNS label characters. |
integration.history.existingClaim | unset | Existing PersistentVolumeClaim holding the extract, mounted read-only at /imports. |
integration.history.file | unset | The extract’s path inside the claim (JSON Lines, under 2,000,000 lines). |
integration.history.fleetBaselineFile | unset | Optional fleet baseline extract inside the claim, imported in the same run. |
integration.history.windowStart | unset | RFC 3339 start of the import window, on a run’s end. |
integration.history.windowEnd | unset | RFC 3339 end of the import window, on a run’s end. |
integration.history.liveSince | unset | RFC 3339 time of this compute’s first live observation; runs ending at or after it are left to the live sources. |
integration.history.dryRun | true | Map and count, write nothing; read the pod’s log, then re-render with it off. |
integration.history.attempt | unset | Free text that names a re-run of the same import (after a stop, under the same id); each distinct value is a new Job, since a Job’s pod template is immutable. |
integration.history.resources | | The index costs about 170 B a line; 2,000,000 lines fit in the default. |
integration.history.resources.requests.cpu | "1" | Standard Kubernetes field, passed through. |
integration.history.resources.requests.memory | 1Gi | Standard Kubernetes field, passed through. |
integration.history.resources.limits.memory | 2Gi | Standard Kubernetes field, passed through. |
integration.persistence | | Durable state for the checkpoint written before every offset commit and the dry-run report. |
integration.persistence.enabled | true | A PersistentVolumeClaim; off uses an emptyDir, which the chart refuses unless integration.dryRun is on. |
integration.persistence.existingClaim | unset | Bring your own PersistentVolumeClaim instead of the chart-created one. |
integration.persistence.storageClassName | unset | StorageClass for the chart-created claim; empty uses the cluster default. |
integration.persistence.size | 12Gi | State capacity includes retained runs, two generations each of job and waiting facts, and checkpoint publication. Fresh defaults need 11.6 GiB; 72h needs 17.9 GiB. Expand during a held reset, also allowing for its kept old state. |
integration.egress | | NetworkPolicy egress to the brokers, the store or download endpoint, the code host and Prometheus, used when networkPolicy.enabled is on. |
integration.egress.destinations | unset | Broker, store, download endpoint, code host and Prometheus destinations as CIDR plus TCP port (a Service’s pods, not its ClusterIP). |
integration.resources | | Sized for eight decode workers: the cpu limit gives each a core, the requests the measured rate and resident set. |
integration.resources.requests.cpu | "2" | Standard Kubernetes field, passed through. |
integration.resources.requests.memory | 2Gi | Standard Kubernetes field, passed through. |
integration.resources.limits.cpu | "8" | Standard Kubernetes field, passed through. |
integration.resources.limits.memory | 3Gi | Standard Kubernetes field, passed through. |
integration.nodeSelector | unset | Adapter placement, passed through unchanged. |
integration.tolerations | unset | Standard Kubernetes field, passed through. |
integration.affinity | unset | Standard Kubernetes field, passed through. |