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

  4. 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, or helm search returns 401 or 403, 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.

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

    export DPS_RELEASE="<release-version>"
    
  6. 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.

  • 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.dps and ui.dps

For production deployments, follow the Prepare a Secure Deployment section.

For deployments beyond evaluation:

  • Configure dps.serverTLS.transportSecurity as tls or mutual TLS (mtls) and provide dps.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 with dps.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.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 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

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.