DSX plugin example

Example ZAPP Listener deployment that uses DSX plugin components.

Use this example to deploy a ZAPP Listener that uses DSX plugin components to collect GPU power metrics from Redfish-capable hosts.

The standard ZAPP Listener binary includes the DSX component registrations. This example configures the registered dsxMetrics component type in the listener pipeline.

Deployment pattern

Deploy the ZAPP Aggregator first. Then deploy a ZAPP Listener with a DSX pipeline.

In this pattern:

  • zapp.listeners defines and enables the DSX Redfish listener
  • dsxMetrics manages the host inventory and polls Redfish metrics
  • DSX_REDFISH_PROXY_ENDPOINT configures an optional deployment-wide Redfish proxy endpoint
  • known_sensors_file loads the chart-provided DSX sensor catalog
  • host_persistence_path preserves host registrations in the listener data volume
  • metrics_service.listen_address exposes the DSX management gRPC service inside the listener pod
  • aggregatorStreamer forwards time-series telemetry to the ZAPP Aggregator

Encryption Secret

The built-in DSX listener persists managed host registrations. Before you enable the listener, create a Kubernetes Secret for the persistence encryption key:

apiVersion: v1
kind: Secret
metadata:
  name: dsx-encryption
type: Opaque
data:
  key: <base64-encoded-32-byte-key>

The mounted Secret value must be exactly 32 bytes after Kubernetes decodes it. Use a raw AES-256 key, and keep the same key while reusing the same listener data volume.

Metrics service TLS Secret

This example enables TLS for the DSX management gRPC service. Create a Kubernetes Secret that contains the server certificate and private key:

apiVersion: v1
kind: Secret
metadata:
  name: dsx-metrics-tls
type: kubernetes.io/tls
data:
  tls.crt: <base64-encoded-certificate>
  tls.key: <base64-encoded-private-key>

ZAPP Listener values

Configure the DSX listener under zapp.listeners. Helm replaces list values as a whole. If your values file redefines zapp.listeners, include the complete listener entry, including config.pipeline, for every listener you want to keep.

zapp:
  enabled: true
  image:
    repository: nvcr.io/nvidia/zapp
    tag: ""
    pullPolicy: IfNotPresent

  aggregatorHost: "zapp-aggregator.<namespace>.svc.cluster.local:9991"
  metricsPort: 8888
  manifestUI: true

  knownSensors:
    existingConfigMap: ""

  listeners:
    - name: redfish
      enabled: true
      replicas: 1
      grpcServices:
        zappService:
          portName: zapp-grpc
          port: 50051
        metricsManagementService:
          portName: dsx-management
          port: 9090
      encryption:
        existingSecret: dsx-encryption
        key: key
        mountPath: /secrets/dsx-encryption
      metricsServiceTLS:
        enabled: true
        transportSecurity: tls
        existingSecret: dsx-metrics-tls
        certFile: tls.crt
        keyFile: tls.key
        mountPath: /secrets/dsx-metrics-tls
      extraEnv:
        - name: DSX_REDFISH_PROXY_ENDPOINT
          value: "https://redfish-proxy.example.com"
      config:
        pipeline: |
          metricsPort: 8011
          components:
            dsxMetrics:
              type: dsxMetrics
              metrics_service:
                listen_address: :9090
                tls:
                  transportSecurity: ${env.DSX_METRICS_TRANSPORT_SECURITY}
                  certs:
                    certFile: ${env.DSX_METRICS_TLS_CERT_FILE}
                    keyFile: ${env.DSX_METRICS_TLS_KEY_FILE}
                    caFile: ${env.DSX_METRICS_TLS_CA_FILE}
              host_persistence_path: /data
              max_hosts: 10000
              proxy:
                endpoint: ${env.DSX_REDFISH_PROXY_ENDPOINT}
              known_sensors_file: /etc/zapp/known-sensors/known-sensors.yaml
              targets:
                - target: zappService
                  cap: 64
                  leaky: true
                - target: aggregator
                  cap: 64
                  leaky: true
            zappService:
              type: grpcServer
              address: :50051
            listener:
              type: udpListener
              network: udp
              address: :9091
              targets:
                - target: payloadProcessor
                  cap: 1000
                  leaky: true
            payloadProcessor:
              type: payloadProcessor
              timeseries:
                targets:
                  - target: aggregator
              default:
                targets:
                  - target: aggregator
            aggregator:
              type: aggregatorStreamer

Important fields:

  • zapp.image selects the ZAPP Listener image that contains the DSX components
  • zapp.aggregatorHost points the listener at the ZAPP Aggregator listener gRPC service
  • zapp.listeners[].name becomes part of the StatefulSet and Service names
  • zapp.listeners[].enabled enables the DSX listener entry
  • zapp.listeners[].encryption.existingSecret points to the Secret with the raw 32-byte persistence key
  • zapp.listeners[].metricsServiceTLS enables TLS for the DSX management gRPC service and mounts the TLS Secret
  • zapp.listeners[].extraEnv sets the optional Redfish proxy endpoint
  • zapp.listeners[].grpcServices exposes the DSX management and ZAPP gRPC ports through the listener Service
  • zapp.knownSensors.existingConfigMap replaces the packaged DSX sensor catalog when you provide a ConfigMap with a known-sensors.yaml key
  • zapp.listeners[].config.pipeline contains the dsxMetrics component and loads the mounted DSX sensor catalog with known_sensors_file
  • dsxMetrics.metrics_service.listen_address opens the DSX management gRPC service inside the listener pod

Direct Redfish mode

The listener selects direct or proxy access for each host, not for the deployment. A host registered through the DSX management API with a BMC endpoint and credentials always uses a direct Redfish session, even when DSX_REDFISH_PROXY_ENDPOINT is set. A host registered without credentials uses the proxy, and its registration fails to poll when no proxy endpoint is configured.

For a direct-only deployment, register every host with credentials and leave DSX_REDFISH_PROXY_ENDPOINT empty. The listener persists these registrations in the encrypted host inventory when host_persistence_path is enabled.

Install the example

Create a values file from the DSX listener snippet, then install the listener chart.

helm upgrade --install zapp-dsx <path-to-zapp-chart> \
  --namespace <namespace> \
  --values dsx-listener-values.yaml \
  --set-string zapp.aggregatorHost=zapp-aggregator.<namespace>.svc.cluster.local:9991

With release name zapp-dsx, the built-in DSX listener StatefulSet name is zapp-dsx-listener-redfish.

Validate the DSX listener

Check the listener pod:

kubectl get pods --namespace <namespace>

Port-forward the listener metrics endpoint:

kubectl --namespace <namespace> port-forward svc/zapp-dsx-listener-redfish 8011:8011

Open the manifest page:

http://localhost:8011/manifest

If management API clients need to reach the listener through Kubernetes networking, use the headless Service ports named dsx-management and zapp-grpc.

To test the DSX management gRPC service from your workstation, port-forward the StatefulSet to the metrics_service.listen_address port:

kubectl --namespace <namespace> port-forward statefulset/zapp-dsx-listener-redfish 19090:9090

If dsxctl is available, query one GPU reading. Replace node-01:0 with a registered node and GPU pair:

dsxctl --address localhost:19090 \
  --transport-security tls \
  --server-ca <path-to-server-ca> \
  query node-01:0