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.
Add the public NGC Helm repository. The DPS chart does not require an NGC API key:
helm repo add ngc https://helm.ngc.nvidia.com/nvidia helm repo update ngc helm search repo ngc/dps --versions
The published DPS chart and container images are public and do not require NGC credentials.
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.
Network access from the installation workstation to
helm.ngc.nvidia.comand from the cluster nodes tonvcr.io. The published DPS chart and images are public and do not require pull credentials. If you copy the artifacts to a private registry mirror, configure the credentials that the mirror requires.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 plaintext gRPC and HTTP connections. TLS is not enabled for the API or UI by default. 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#
The chart defaults to plaintext gRPC with
dps.serverTLS.transportSecurity: insecure, and it does not enable HTTPS for
the HTTP API or UI. Supply TLS through your service mesh or other platform
infrastructure, or terminate gRPC TLS directly on the DPS
server. Authentication configuration does not enable encryption by itself.
For deployments beyond evaluation:
To terminate gRPC TLS on the server, configure
dps.serverTLS.transportSecurityastlsor mutual TLS (mtls) and providedps.serverTLS.existingSecret. Configure matching agent transport settings. For external authentication and authorization, configure TLS at the proxy or surrounding platform. Deploy the proxy as a sidecar in the server Pod.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 LDAP, OIDC, or external authentication and authorization by following Choose an Authentication Mode. That guide explains server configuration. For UI and
dpsctlsign-in, refer to Sign In to DPS. Use Configure Service-Specific mTLS when machine clients need certificate access to specific gRPC services.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 user and service accounts. Refer to User Accounts and Service 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 setup in Configure LDAP Mode and the Secret configuration in LDAP Credentials.
For OIDC, replace the LDAP authentication settings with the overlay and client setup in Configure OIDC Mode. For a deployment-managed authentication proxy, follow Configure External Authentication and Authorization.
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; refer to
Configure Service-Specific mTLS for certificate and ingress requirements.
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"
Authenticate through the procedure for your server’s setup in Configure Server Authentication. Then check the versions and deployment:
dpsctl server-version
dpsctl --version
dpsctl verify --dps-server --database
Confirm the client and server releases match and each requested component
check is healthy. For LDAP or local JWT configuration, also run
dpsctl verify --auth; this check does not validate OIDC or external proxy
authentication. Refer to Cannot Connect or Log In for access failures.
For an Ingress deployment, run dpsctl verify --ui, which 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. Import it only after validation and site approval. The following commands list the devices, validate the topology file, and import it:
dpsctl device list
dpsctl topology validate "<topology-file>"
dpsctl topology import "<topology-file>"
On a new installation, import does not route the topology’s nodes to an Agent, so the connection and BMC health checks cannot reach them yet. Topology activation creates that routing and applies each managed node’s power policy. Activate the topology through Managing Topologies only after your site approves power changes. After the topology appears in dpsctl topology list --active, run the read-only connection and health checks:
dpsctl check connection --topology "<topology-name>"
dpsctl verify bmc-health start \
--topology "<topology-name>" \
--skip-writes \
--wait
These checks exercise the route from DPS Core through the assigned Agent to each 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.