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.

  1. Review Release Notes for release-specific behavior and upgrade notes.

  2. Locate the release in the DPS collection on NGC.

  3. 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.

  4. Set the selected chart version in your shell. Use the chart version shown by NGC exactly.

    export DPS_RELEASE="<release-version>"
    
  5. 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 postgres:18.1-alpine default is for evaluation, not a production support policy.

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 StorageClass or component-specific storage classes. Inspect the selected chart’s values for their sizes.

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.com and from the cluster nodes to nvcr.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.transportSecurity as tls or mutual TLS (mtls) and provide dps.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 dpsctl sign-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.allowedOrigins to 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

gpuPower

1s

GPU power and requested or set GPU power limits

platform

30s

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#

  1. Review the target release notes and compare its chart defaults with the version you currently run.

  2. 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
    
  3. Back up external PostgreSQL and any external Power Steering object storage. Confirm that restore procedures have been tested.

  4. Update the overlay for renamed, removed, or newly required values. Render and review the target chart.

  5. Upgrade to an explicit version:

    helm upgrade dps ngc/dps \
      --namespace dps \
      --version "<target-release-version>" \
      --values values.yaml \
      --wait \
      --timeout 15m
    
  6. 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.