Deployment and Configuration Guide#
Use this guide to install Dynamic Power Software (DPS) on
Kubernetes, secure its external connections, verify the deployment with
dpsctl, and plan lifecycle operations.
For a network-isolated cluster, prepare the mirrored artifacts in Air-Gapped Deployment before you continue.
The deployment is ready for configuration when the pinned Helm release is
healthy, the dpsctl client and server versions match, the server, database,
and identity checks pass, and enabled external endpoints are reachable. For a
deployment beyond evaluation, also establish an approved backup and recovery
procedure. Do not enable hardware writes until the topology-specific connection
and BMC health gates also pass.
Choose a Release and Its Artifacts#
Choose one DPS release for the Helm chart, container images,
and dpsctl.
Review Release Notes for release-specific behavior and upgrade notes.
Locate the release in the DPS collection on NGC.
Before adding the Helm repository, obtain an NGC API key that can access the DPS collection. Use a personal key with NGC Catalog access for an interactive installation, or a least-privilege service key for automation. Your NGC organization must also have the required entitlement or approval for the collection. Follow the NGC API key guidance and load the key from your approved secret-management workflow.
Add the NGC Helm repository. This uses standard input so the API key is not passed as a command-line argument:
: "${NGC_API_KEY:?set NGC_API_KEY from your approved secret-management workflow}" printf '%s' "${NGC_API_KEY}" | helm repo add ngc https://helm.ngc.nvidia.com/nvidia \ --username='$oauthtoken' \ --password-stdin unset NGC_API_KEY helm repo update ngc helm search repo ngc/dps --versions
If
helm repo add,helm repo update, orhelm searchreturns401or403, verify the NGC organization selected for the key, its Catalog permission, and access to the DPS collection. Do not work around an access error by disabling TLS verification.This Helm repository credential authenticates the installation workstation or CI runner; it is separate from a Kubernetes image pull Secret configured through
global.imagePullSecrets.Set the selected chart version in your shell. Use the chart version shown by NGC exactly.
export DPS_RELEASE="<release-version>"
Inspect the chart metadata before installation:
helm show chart ngc/dps --version "${DPS_RELEASE}"
Install the matching dpsctl release by using
Installing dpsctl.
Requirements#
DPS 0.9 has the following minimum requirements:
Area |
Requirement |
|---|---|
Kubernetes |
Version 1.31.x or later. |
Helm |
Version 3.7 or later. Power Steering requires version 3.12 or later. |
PostgreSQL |
For a deployment beyond evaluation, use an externally managed service. When Power Steering is enabled, use PostgreSQL 17 or later. The chart’s bundled |
Storage |
Provide storage for the chart-managed persistent volume claims (PVCs). The chart creates a DPS server PVC and, when the bundled dependencies are enabled, separate PostgreSQL and SeaweedFS PVCs. For dynamic provisioning, configure a default |
Managed systems |
Use a topology model implemented by DPS 0.9 and firmware at or later than the validation threshold in Topology Models and Firmware Checks. |
Before installation, ensure that you have:
A Kubernetes context for the target cluster and permission to install the chart and its required resources.
When exposing DPS through Ingress or Gateway API, an Ingress controller or Gateway API implementation, client-resolvable hostnames for the API and enabled UI, and certificates issued by a CA that the clients trust.
Registry access to the chart and every image referenced by the selected release. For private registries, create an image pull Secret and configure
global.imagePullSecrets.Network paths from the cluster to PostgreSQL, the selected LDAP or OIDC identity provider, each managed baseboard management controller (BMC) or the Redfish proxy, and any external object storage, Zapp, Alertmanager, or monitoring endpoints you enable.
Capacity and a backup policy for the external PostgreSQL service. The chart-managed PostgreSQL instance is intended for evaluation only.
Evaluation Quickstart#
After you select DPS_RELEASE, install DPS Core and an Agent
for evaluation or testing:
helm upgrade --install dps ngc/dps \
--namespace dps \
--create-namespace \
--version "${DPS_RELEASE}" \
--set agent.enabled=true \
--wait \
--timeout 15m
kubectl rollout status statefulset/dps-server --namespace dps
kubectl rollout status deployment/dps-server-agent --namespace dps
Note
The quickstart configuration is intended for evaluation only. It uses chart-managed dependencies, permissive authentication, default hostnames, and insecure transport settings. Complete the security preparation before connecting DPS to a management or power-control network.
Inspect the Versioned Configuration#
The selected chart’s values.yaml is authoritative for configuration keys and
defaults. The chart metadata is authoritative for dependency versions. Save a
versioned copy for review rather than copying values from another release:
helm show values ngc/dps \
--version "${DPS_RELEASE}" > dps-values-reference.yaml
Store deployment overrides in a separate values file, and keep Secret values out of it.
Prepare a Secure Deployment#
Select Authentication and Transport Security#
Note: The Quickstart deployment uses default settings suitable for evaluation only:
Built-in PostgreSQL (not production-ready)
No LDAP authentication
Authentication in warning-only mode (accepts any credentials)
Default hostnames:
api.dpsandui.dpsFor production deployments, follow the Prepare a Secure Deployment section.
For deployments beyond evaluation:
Configure
dps.serverTLS.transportSecurityastlsor mutual TLS (mtls) and providedps.serverTLS.existingSecret.Configure HTTPS for both API and UI ingress. Browser authentication requires HTTPS. If an upstream load balancer terminates TLS, document and protect the remaining network path.
Choose one authenticator: LDAP with
dps.auth.authenticatorType: ldap, or OIDC withdps.auth.oidc.enabled: true. LDAP and OIDC cannot be enabled together.For LDAP-issued DPS tokens, provide a persistent RSA private key through
dps.auth.jwt.existingSecret.Restrict
dps.cors.allowedOriginsto the UI and other approved browser origins. The default wildcard is not appropriate when credentials are allowed.Keep certificate verification enabled for PostgreSQL, LDAP or OIDC, BMCs, proxies, and optional integrations. Mount private CA certificates when the container trust store does not contain the issuing CA.
Use least-privilege identity groups and separate human and automation accounts. Refer to User Accounts and Automation Accounts.
Create Secrets Outside Helm#
Create the namespace before external Secret controllers reconcile their objects:
kubectl create namespace dps
Use your approved secret manager, External Secrets operator, sealed-secret workflow, or another auditable process. Create the applicable database, transport, authentication, and BMC Secrets by following Credentials and Secrets Configuration. Do not place passwords, tokens, or private keys on command lines, in shell history, in a Helm release’s values, or in a Git repository.
Prepare PostgreSQL and Object Storage#
For deployments beyond evaluation, set postgresql.enabled: false and point
global.postgresql at an externally managed PostgreSQL service. Pre-create the
database named by global.postgresql.auth.database and grant the configured
role ownership or the required schema and migration privileges.
PostgreSQL 17 is the minimum supported version when Power Steering is enabled; it is not an open-ended compatibility commitment for every later major release. Operate high availability, backup, and recovery outside the chart, and validate the selected external PostgreSQL version with the pinned DPS chart before a production upgrade.
Power Steering has additional database, object-storage, and network requirements. If you enable it, follow Deployment and Configuration.
Create a Values Overlay#
The following overlay is a security-focused starting point for an NGINX Ingress, external PostgreSQL, LDAP, and direct BMC connections. Replace every example hostname, Secret, storage class, and identity value. Complete the credential procedures in Credentials and Secrets Configuration. If PostgreSQL uses TLS, add the values described in Database TLS.
Example secure values overlay
global:
defaultStorageClass: "<storage-class>"
postgresql:
host: "postgres.example.com"
service:
ports:
postgresql: "5432"
auth:
username: "dps"
database: "dps"
existingSecret: "dps-postgresql"
postgresql:
enabled: false
dps:
ingress:
className: "nginx"
hostname: "api.dps.example.com"
tls:
- hosts:
- "api.dps.example.com"
secretName: "dps-api-ingress-tls"
cors:
allowedOrigins: "https://ui.dps.example.com"
serverTLS:
transportSecurity: "tls"
existingSecret: "dps-server-tls"
auth:
authenticatorType: "ldap"
auth_required_groups: "<dps-admin-group>,<dps-automation-group>"
jwt:
existingSecret: "dps-jwt-keys"
ldap:
enabled: true
serverUrl: "ldaps://ldap.example.com:636"
bindDn: "<bind-dn>"
baseDn: "<base-dn>"
defaultRole: ""
groupRoleMapping: "<dps-admin-group>=admin,<dps-automation-group>=automation"
bindPassword:
existingSecret: "dps-ldap-bind"
existingSecretKey: "bind-password"
bmcTLS:
caCertPath: "/secrets/bmc/ca.crt"
redfish:
tls:
insecureSkipVerify: false
secrets:
- name: "dps-bmc-ca"
secretKey: "ca.crt"
mountPath: "/secrets/bmc/ca.crt"
prs:
enabled: false
ui:
ingress:
className: "nginx"
hostname: "ui.dps.example.com"
tls:
- hosts:
- "ui.dps.example.com"
secretName: "dps-ui-ingress-tls"
power-steering:
enabled: false
Complete the LDAP group and Secret configuration in LDAP Credentials.
For OIDC, replace the LDAP configuration with the issuer, JSON Web Key Set (JWKS) URL, audience, scopes, and UI settings from the selected chart’s values.
When the gRPC Ingress class is nginx, the chart selects a GRPCS backend for
server TLS. For another controller, configure its supported secure gRPC
backend or TLS-passthrough mode. TLS passthrough is required when public
dpsctl clients authenticate with mTLS.
Configure DPS Core and an Agent#
DPS Core runs in the dps-server workload and routes device
operations to DPS Agents. An Agent initiates the connection
to Core and performs Redfish operations for its assigned devices, so it needs
network access to those BMCs or the configured Redfish proxy.
Deploy Core and its Agent in the same Helm release for each data hall. Core is enabled by default; enabling the Agent creates one logical Agent. Add the following values to the secure overlay before you install the release:
dps:
agent:
allowHandshakeFallback: false
grpcServiceMTLSCN:
nvidia.dcpower.v1.DPSAgentService:
- "data-hall-a-agent"
agent:
enabled: true
replicas: 1
agentID: "data-hall-a-agent"
tls:
transportSecurity: "mtls"
existingSecret: "dps-agent-data-hall-a-tls"
Create the referenced Agent Secret with ca.crt, tls.crt, and tls.key.
When agent.serverAddr is empty, the Agent connects to the Core service in the
same release. Use a distinct Agent ID for each data hall. The agent.agentID
must match the topology AgentId that routes the Agent’s assigned devices. The
Agent certificate common name must appear in the
dps.grpcServiceMTLSCN allowlist for nvidia.dcpower.v1.DPSAgentService; it
does not need to match the Agent ID. Set that AgentId on each managed device
or an appropriate parent entity; child devices inherit it. The Agent must reach
the assigned BMCs or Redfish proxy and their credential and CA Secrets before
you import the topology. By default, the Agent inherits
dps.credentialsStore; set agent.credentialsStore only when it requires a
different store. Do not scale multiple Agent replicas with the same agentID;
deploy each Agent independently for the devices it manages. Refer to
Managing Topologies for the topology workflow.
Review the Rendered Resources#
Render the chart before changing the cluster. Treat the rendered file as sensitive because it can contain Secret references and deployment metadata.
helm template dps ngc/dps \
--namespace dps \
--version "${DPS_RELEASE}" \
--values values.yaml > dps-rendered.yaml
Review the following settings:
Image tags, dependency versions, resource requests, and persistent volume claims.
Ingress or Gateway hosts, TLS and Secret references, RBAC, security contexts, and NetworkPolicies.
External endpoints and enabled optional components.
Install DPS#
Install the pinned chart and wait for Kubernetes readiness:
helm upgrade --install dps ngc/dps \
--namespace dps \
--create-namespace \
--version "${DPS_RELEASE}" \
--values values.yaml \
--wait \
--timeout 15m
Verify the Installation#
First verify the Helm release and Kubernetes resources:
helm status dps --namespace dps
kubectl get pods,services,ingresses,persistentvolumeclaims --namespace dps
All required workloads must be ready, and PVCs must be bound. When you expose the API or UI, confirm that its DNS name resolves to the intended endpoint. If you use Gateway API, inspect the Gateway and Route status instead of Ingress resources.
Install the matching client by using Installing dpsctl, then configure its endpoint. For a private CA, set the CA path instead of disabling certificate verification:
export DPSCTL_HOST="api.dps.example.com"
export DPSCTL_PORT="443"
export DPSCTL_CA_CERT_PATH="/path/to/api-ca.crt"
dpsctl login
dpsctl server-version
dpsctl --version
dpsctl verify --dps-server --database --auth
Confirm login returns status.ok: true, the client and server releases match,
and each requested component check is healthy. For an Ingress deployment, run
dpsctl verify --ui. In DPS 0.9, the UI verification checks
the dps-ui Ingress. For a Gateway API deployment, inspect the Gateway and
Route status and test the UI endpoint directly.
If you enabled the DPS Agent, verify that its workload is ready before you import a topology:
kubectl rollout status deployment/dps-server-agent --namespace dps
kubectl get pods --namespace dps --selector app=dps-server-agent
If you prepared BMC credentials, continue with a topology and run the read-only connection and health gates before allowing power writes:
dpsctl device list
dpsctl topology validate "<topology-file>"
dpsctl topology import "<topology-file>"
dpsctl check connection --topology "<topology-name>"
dpsctl verify bmc-health start \
--topology "<topology-name>" \
--skip-writes \
--wait
Import only after validation and site approval. The connection and BMC health checks require the imported topology. For an agent-managed topology, these checks also exercise the route from DPS to the assigned agent and BMC. Review the report before rerunning a health check with write probes.
Continue Configuration#
Installation creates the control plane; it does not define your facility power model or authorize control of hardware. Continue with Deploying DPS to model and import the topology and configure power policies.
For a first managed pilot with explicit safety gates, use Run the MaxLPS Power Pilot.
Configure Optional Integrations#
Configure only the integrations required for your deployment.
Configure Zapp Telemetry#
Scope: This section covers DPS integration and the Zapp timing settings that affect DPS behavior. It assumes that Zapp is already deployed and operational. If you have not deployed Zapp, follow the Zapp deployment instructions before configuring this integration.
The current chart selects bmc or zapp for public metrics through
dps.telemetry.metrics.source. Excursion mitigation always consumes the Zapp
aggregator stream when a strategy is enabled.
For Zapp-backed metrics or excursion mitigation, configure
zapp.aggregatorService.url, select the matching TLS mode, and provide the CA
or mTLS Secret required by that mode. Do not use a grpc:// endpoint or
insecureSkipVerify on an untrusted network.
zapp:
aggregatorService:
url: "grpcs://zapp-aggregator-client.zapp.svc.cluster.local:9999"
tls:
transportSecurity: "mtls"
existingSecret: "dps-zapp-aggregator-mtls"
dps:
telemetry:
metrics:
source: zapp
The dps-zapp-aggregator-mtls Secret is a placeholder name. Provide a
Kubernetes Secret that contains the certificate authority certificate, client
certificate, and client key required for mTLS.
If DPS is not configured to consume Zapp telemetry, topology management, resource group policies, and power allocation continue to function. Features that require live Zapp-backed power telemetry, such as excursion detection and mitigation, do not receive telemetry readings.
Zapp Telemetry Polling Configuration#
Zapp controls how often DPS receives updated telemetry. The packaged Zapp sensor catalog uses these polling intervals:
Zapp sensor poll |
Default |
DPS data affected |
|---|---|---|
|
|
GPU power and requested or set GPU power limits |
|
|
Chassis power and other component power, energy, temperature, and power limit readings |
For all supported Helm values and sensor configuration options, refer to the Zapp configuration reference.
To change these defaults, copy the complete Zapp known-sensors.yaml catalog
into a ConfigMap and update each sensor_polls[].interval. The ConfigMap must
contain the known-sensors.yaml key. Set zapp.knownSensors.existingConfigMap
in the Zapp Helm values to the ConfigMap name. The sensor_polls list must
contain exactly the gpuPower and platform polls, and each interval must be
positive. Configure either known_sensors_file or inline sensor_polls, not
both.
DPS retains the latest value for each metric. A value
remains fresh for the longer of 15s or three times the polling interval
advertised in the Zapp sensor manifest. With the default intervals, gpuPower
readings expire after 15s, and platform readings expire after 90s when
Zapp does not provide an update. Public metrics responses omit expired or
unavailable readings instead of reporting them as zero. A Zapp stream
disconnect invalidates retained readings immediately.
Zapp polling intervals control how often Zapp collects readings from Redfish.
They do not control how often DPS or the DPS Power Steering Controller requests
metrics. The gpuPower interval refreshes the per-GPU readings that are
available for metrics queries and Power Steering. The platform interval
refreshes the chassis power readings that DPS uses for excursion detection and
mitigation. The dps.prs.schedulerIntervalSeconds setting independently
controls Power Steering control cycles. The interval entry in
dps.excursionMitigation.params independently controls excursion mitigation
checks. When either consumer runs more frequently than the corresponding Zapp
poll, consecutive requests can use the same reading.
Shorter polling intervals make new readings available sooner and improve excursion detection and verification response time. They also increase traffic to the Redfish endpoints or proxy. Longer intervals reduce that traffic but delay updates and extend the time that DPS considers the last reading fresh.
DPS Agent Zapp Capability#
Enable the DPS Agent Zapp capability when DSX hosts must register with Zapp and stream telemetry through Zapp services:
agent:
enabled: true
capabilities:
zapp:
enabled: true
metricsManagementService:
url: "grpcs://zapp-metrics.ns.example:9090"
tls:
transportSecurity: "mtls"
existingSecret: "dps-agent-zapp-metrics-mtls"
zappService:
url: "grpcs://zapp-service.ns.example:50051"
tls:
transportSecurity: "mtls"
existingSecret: "dps-agent-zapp-service-mtls"
Use metricsManagementService for DSX host registration and metrics
management. Use zappService for sensor manifests and telemetry subscription.
The URL scheme and TLS Secret rules are the same as the server aggregator
connection. The Secret names are placeholders. For transportSecurity: "tls",
provide ca.crt. For transportSecurity: "mtls", provide ca.crt, tls.crt,
and tls.key. For Zapp installation and service endpoint configuration, refer
to the
Zapp deployment and configuration guide.
Prometheus Metrics#
dps-server exposes Prometheus metrics at /metrics through the dedicated
<release>-server-metrics Service on port 9090, separate from the HTTP API
Service. The chart ships a ServiceMonitor template (disabled by default) for
in-cluster Prometheus, and the metrics endpoint can also be scraped from outside
the cluster. Refer to Prometheus Monitoring for the endpoint,
authentication, and both deployment setups.
Configure Alertmanager#
Configure an HTTPS Alertmanager endpoint whose certificate chain is trusted by
the dps-server container, and keep certificate verification enabled.
dps:
monitoring:
enabled: true
alertmanager:
url: "https://alertmanager.example.com"
timeout: "5s"
tls:
insecureSkipVerify: false
Configure Excursion Mitigation#
After configuring Zapp and Alertmanager, follow Excursion Mitigation to validate the remaining prerequisites and select a strategy.
dps:
excursionMitigation:
strategy: "simple"
params: ""
Configure Nautobot#
Enable the Nautobot integration only after provisioning a read-capable token
through an existing Secret. Do not put the token in values.yaml.
dps:
nautobot:
enabled: true
url: "https://nautobot.example.com"
tls:
insecureSkipVerify: false
tokenSecret:
existingSecret: "dps-nautobot-token"
key: "token"
Upgrade, Roll Back, or Uninstall#
Upgrade#
Review the target release notes and compare its chart defaults with the version you currently run.
Capture the current release metadata and effective values. Protect the output according to your Secret-handling policy because an earlier install might have stored sensitive values in the Helm release:
helm status dps --namespace dps helm get values dps --namespace dps --all > pre-upgrade-values.yaml
Back up external PostgreSQL and any external Power Steering object storage. Confirm that restore procedures have been tested.
Update the overlay for renamed, removed, or newly required values. Render and review the target chart.
Upgrade to an explicit version:
helm upgrade dps ngc/dps \ --namespace dps \ --version "<target-release-version>" \ --values values.yaml \ --wait \ --timeout 15m
Repeat the Kubernetes, version, component, and BMC verification gates.
Roll Back#
Use rollback only when the target release notes confirm compatibility with the current database and persistent data:
helm history dps --namespace dps
helm rollback dps "<revision>" --namespace dps --wait --timeout 15m
Helm rollback restores Kubernetes manifests. It does not restore an external database, object storage, or their schemas. If the failed upgrade changed persistent data incompatibly, use the release-specific recovery procedure and your tested backups instead of assuming that Helm rollback is sufficient.
Uninstall#
Capture required evidence and backups before uninstalling:
helm uninstall dps --namespace dps
The command removes Helm-managed resources. Externally managed Secrets, databases, object storage, and some retained persistent volumes can remain. Review them individually under your retention policy. Delete the namespace or persistent data only through an approved, recoverable decommission procedure.
Troubleshooting#
Preserve the rendered chart, Helm status, events, component health output, and a short time-bounded log sample before changing values. Redact passwords, tokens, private keys, BMC credentials, and unnecessary workload identifiers. Use Deployment Component Unhealthy for installation failures and Cannot Connect or Log In for login failures. For BMC connectivity or health failures, use BMC or Redfish Calls Fail. For database certificate errors, use Troubleshooting.