Observability Stack Configuration#

The BCM cm-kubernetes-setup wizard deploys the foundational observability components in Kubernetes by default. Additional configuration enables time-series and logging data sources from BCM.

Configure storage and retention for Prometheus#

  1. Create a new YAML file on the BCM head node for this setup:

    cat << EOF > prom_config.yaml
    prometheus:
      prometheusSpec:
        retention: 90d
        additionalArgs:
          - name: storage.tsdb.no-lockfile
            value: ""
        storageSpec:
          volumeClaimTemplate:
            spec:
              accessModes: ["ReadWriteOnce"]
              storageClassName: local-path
              resources:
                requests:
                  storage: 300Gi
    EOF
    

Note

The preceding prom_config.yaml sets a 90-day retention period. The local-path StorageClass uses the shared storage pool selected during Kubernetes installation. Estimate your storage requirements before setting a longer retention period.

  1. Install/upgrade CRDs:

    kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-community/helm-charts/refs/tags/kube-prometheus-stack-87.18.0/charts/kube-prometheus-stack/charts/crds/crds/crd-alertmanagerconfigs.yaml
    kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-community/helm-charts/refs/tags/kube-prometheus-stack-87.18.0/charts/kube-prometheus-stack/charts/crds/crds/crd-alertmanagers.yaml
    kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-community/helm-charts/refs/tags/kube-prometheus-stack-87.18.0/charts/kube-prometheus-stack/charts/crds/crds/crd-podmonitors.yaml
    kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-community/helm-charts/refs/tags/kube-prometheus-stack-87.18.0/charts/kube-prometheus-stack/charts/crds/crds/crd-probes.yaml
    kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-community/helm-charts/refs/tags/kube-prometheus-stack-87.18.0/charts/kube-prometheus-stack/charts/crds/crds/crd-prometheusagents.yaml
    kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-community/helm-charts/refs/tags/kube-prometheus-stack-87.18.0/charts/kube-prometheus-stack/charts/crds/crds/crd-prometheuses.yaml
    kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-community/helm-charts/refs/tags/kube-prometheus-stack-87.18.0/charts/kube-prometheus-stack/charts/crds/crds/crd-prometheusrules.yaml
    kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-community/helm-charts/refs/tags/kube-prometheus-stack-87.18.0/charts/kube-prometheus-stack/charts/crds/crds/crd-scrapeconfigs.yaml
    kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-community/helm-charts/refs/tags/kube-prometheus-stack-87.18.0/charts/kube-prometheus-stack/charts/crds/crds/crd-servicemonitors.yaml
    kubectl apply --server-side -f https://raw.githubusercontent.com/prometheus-community/helm-charts/refs/tags/kube-prometheus-stack-87.18.0/charts/kube-prometheus-stack/charts/crds/crds/crd-thanosrulers.yaml
    
  2. With the configuration file in place, apply these values to the K8s cluster

    helm upgrade kube-prometheus-stack prometheus-community/kube-prometheus-stack \
      -n prometheus -f prom_config.yaml --reuse-values --version 87.18.0
    

Configure storage and retention for Loki#

This will require a redeployment of the Helm chart for Loki as we need to set a new storage value and we can’t resize this live.

  1. Create a new YAML file on the BCM head node for this setup:

    cat << EOF > loki_config.yaml
    backend:
      replicas: 3
    chunksCache:
      writebackSizeLimit: 500MB
    commonConfig:
      replication_factor: 3
    compactor:
      replicas: 0
    deploymentMode: SimpleScalable
    distributor:
      maxUnavailable: 0
      replicas: 0
    indexGateway:
      maxUnavailable: 0
      replicas: 0
    ingester:
      replicas: 0
    loki:
      limits_config:
        ingestion_rate_mb: 75
        ingestion_burst_size_mb: 150
        per_stream_rate_limit: 16MB
        per_stream_rate_limit_burst: 64MB
        retention_period: 90d
      auth_enabled: false
      commonConfig:
        replication_factor: 3
      schemaConfig:
        configs:
        - from: '2025-09-04'
          index:
            period: 24h
            prefix: loki_index_
          object_store: s3
          schema: v13
          store: tsdb
      storage:
        type: s3
        bucketNames:
         chunks: loki-chunks-bucket
         ruler: loki-ruler-bucket
         admin: loki-admin-bucket
    minio:
      enabled: true
      persistence:
        size: 500Gi
    querier:
      maxUnavailable: 0
      replicas: 0
    queryFrontend:
      maxUnavailable: 0
      replicas: 0
    queryScheduler:
      replicas: 0
    read:
      replicas: 3
    singleBinary:
      replicas: 0
    write:
      replicas: 3
    EOF
    
  2. Uninstall the existing Helm chart:

    helm uninstall loki -n loki
    
  3. Delete any lingering PVCs:

    kubectl delete pvc --all -n loki
    
  4. Install the Helm chart for Loki, using the new values:

    helm install loki grafana/loki -n loki -f loki_config.yaml
    

Enable Prometheus scrape endpoint in BCM#

  1. On the BCM head node (both BCM head nodes, if configured for HA) using sed to inline edit the configuration:

    sed -i 's/# EnablePrometheusExporterService = true/EnablePrometheusExporterService = true/g' /cm/local/apps/cmd/etc/cmd.conf
    
  2. Disable certificate-based authentication for the scrape endpoint, and enable extra information to be added to the metrics:

    cm-manipulate-advanced-config.py PrometheusExporterExtraInfo=1 PrometheusExporterInfo=1 PrometheusExporterEnum=0 PrometheusExporterRequireCertificate=0 PrometheusLabelIncludeSerialNumber=1 PrometheusLabelIncludePartNumber=1 PrometheusLabelIncludeSystemName=1 MaxMeasurablesPerProducer=1600
    

    If you have integrated your BMS with BCM, then you will additionally need a config like so:

    cm-manipulate-advanced-config.py PushMonitoringDeviceStatusMetrics=CDUStatus,CDULiquidSystemPressure,CDULiquidReturnTemperature
    
  3. Restart the cmd service:

    systemctl restart cmd
    
  4. After cmd restarts, run the following to validate that metrics is being successfully exported through curl:

    curl -sk https://localhost:8081/exporter | tail -n 2
    

    The exporter could take some time to start from restart of cmd:

    writetime_total{base_type="Device",category="default",hostname="node001",type="PhysicalNode",parameter="vda"} 0
    writetime_total{base_type="Device",category="default",hostname="node001",type="PhysicalNode",parameter="vdb"} 3882985
    

Configure Prometheus to scrape metrics from BCM endpoint#

With Prometheus deployed earlier through the BCM K8s wizard, interaction with the Prometheus operator is required to make configuration changes, enabling this data source.

Prepare the configuration files#

K8s typically uses YAML files with custom values to make configuration changes. Create three of these YAML files on the BCM head node for this setup.

  1. bcm_prom_endpoint.yaml:

    cat << EOF > /tmp/bcm_prom_endpoint.yaml
    apiVersion: v1
    kind: Endpoints
    metadata:
      name: external-bcmexporter
      namespace: prometheus
      labels:
        app: external-bcmexporter
    subsets:
      - addresses:
    $(cmsh -c 'device; list -f ip:0 -t headnode' | xargs -I{} echo "    - ip: {}")
        ports:
        - name: metrics
          port: 8081
    EOF
    

Note

Replace $(cmsh -c 'device; list -f ip:0 -t headnode' | xargs -I{} echo "    - ip: {}") in the preceding YAML file with the command output from the BCM head node. The output produces one - ip: <IP of head node> entry for each BCM head node.

  1. bcm_prom_svc.yaml:

    cat << EOF > /tmp/bcm_prom_svc.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: external-bcmexporter
      namespace: prometheus
      labels:
        app: external-bcmexporter
    spec:
      clusterIP: None
      ports:
      - name: metrics
        port: 8081
        targetPort: 8081
    EOF
    
  2. bcm_prom_svcmon.yaml:

    cat << EOF > /tmp/bcm_prom_svcmon.yaml
    apiVersion: monitoring.coreos.com/v1
    kind: ServiceMonitor
    metadata:
      name: external-bcmexporter
      namespace: prometheus
      labels:
        release: kube-prometheus-stack
    spec:
      endpoints:
      - port: metrics
        interval: 30s
        path: /exporter
        scheme: https
        tlsConfig:
          insecureSkipVerify: true
      selector:
        matchLabels:
          app: external-bcmexporter
      namespaceSelector:
        matchNames:
          - prometheus
    EOF
    
  3. With these configuration files in place, apply these values to the K8s cluster:

    kubectl apply -f /tmp/bcm_prom_endpoint.yaml
    kubectl apply -f /tmp/bcm_prom_svc.yaml
    kubectl apply -f /tmp/bcm_prom_svcmon.yaml
    

Configure Prometheus to scrape metrics from DCGM endpoints#

As with the scraping of metrics from the BCM Prometheus endpoint, we also need to configure the Prometheus instance in K8s to scrape the dcgm-exporter service from each GB200 compute tray.

Prepare the configuration files#

Select the Ubuntu release of the DGX software image:

The datacenter-gpu-manager-exporter package is already installed. No package download or installation is required.

On an internet-connected host, run the command for the target DGX node architecture, regardless of the download host architecture. Replace the example package version in the URL if your deployment requires a different version.

For x86_64 DGX nodes:

curl -fLO "https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2604/x86_64/datacenter-gpu-manager-exporter_4.8.4.3955-1_amd64.deb"

For aarch64 DGX nodes:

curl -fLO "https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2604/sbsa/datacenter-gpu-manager-exporter_4.8.4.3955-1_arm64.deb"

Transfer the downloaded package to the BCM head node. The download host does not need to run BCM or match the DGX node architecture. Copy the package to /cm/images/<image name>/tmp/dcgm-exporter.deb. Then install it inside that image:

cm-chroot /cm/images/<image name>
dpkg -i /tmp/dcgm-exporter.deb
exit

Enable the dcgm-exporter service on the software image:

cm-chroot-sw-img /cm/images/<image name> << EOF
  systemctl enable nvidia-dcgm-exporter.service
  exit
EOF

Enable the XID errors count metric on the software image used for DGX nodes:

echo "DCGM_EXP_XID_ERRORS_COUNT,         gauge,   Count of XID Errors within user-specified time window (see xid-count-window-size param)." >> /cm/images/<image name>/etc/dcgm-exporter/default-counters.csv

Run an image update, writing the changes to active nodes:

cmsh -c "device; foreach -c dgx-gb200 (imageupdate -w)"

Using PDSH, restart the service.:

pdsh -g category=dgx-gb200 'systemctl restart nvidia-dcgm-exporter.service'

Create three YAML files on the BCM head node for this setup to define the external-dcgmexporter service monitor scraping. These files assume that your GB200 compute trays are in a category named dgx-gb200.

  1. dcgm_prom_endpoint.yaml:

    cat << EOF > /tmp/dcgm_prom_endpoint.yaml
    apiVersion: v1
    kind: Endpoints
    metadata:
      name: external-dcgmexporter
      namespace: prometheus
      labels:
        app: external-dcgmexporter
    subsets:
      - addresses:
    $(cmsh -c 'device; list -c dgx-gb200 -t physicalnode -f ip:0' | xargs -I{} echo "    - ip: {}")
        ports:
        - name: metrics
          port: 9400
    EOF
    

Note

Replace $(cmsh -c 'device; list -c dgx-gb200 -t physicalnode -f ip:0' | xargs -I{} echo "    - ip: {}") in the preceding YAML file with the command output from the BCM head node. The output produces one - ip: <IP of dgx compute> entry for each DGX compute node in the dgx-vr200 category.

  1. dcgm_prom_svc.yaml:

    cat << EOF > /tmp/dcgm_prom_svc.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: external-dcgmexporter
      namespace: prometheus
      labels:
        app: external-dcgmexporter
    spec:
      clusterIP: None
      ports:
      - name: metrics
        port: 9400
        targetPort: 9400
    EOF
    
  2. dcgm_prom_svcmon.yaml:

    cat << EOF > /tmp/dcgm_prom_svcmon.yaml
    apiVersion: monitoring.coreos.com/v1
    kind: ServiceMonitor
    metadata:
      name: external-dcgmexporter
      namespace: prometheus
      labels:
        release: kube-prometheus-stack
    spec:
      endpoints:
      - port: metrics
        interval: 30s
        path: /metrics
        scheme: http
      selector:
        matchLabels:
          app: external-dcgmexporter
      namespaceSelector:
        matchNames:
          - prometheus
    EOF
    
  3. With these configuration files in place, we can now apply these values to the K8s cluster:

    kubectl apply -f /tmp/dcgm_prom_endpoint.yaml
    kubectl apply -f /tmp/dcgm_prom_svc.yaml
    kubectl apply -f /tmp/dcgm_prom_svcmon.yaml
    
  4. We can validate that DCGM exporter is working by issuing a curl to the endpoint listening on 9400/tcp:

    pdsh -g category=dgx-gb200 'curl -s http://localhost:9400/metrics | grep DCGM | tail -n 1' | dshbak -c
    ----------------
    b06-p1-dgx-06-c06
    ----------------
    DCGM_EXP_XID_ERRORS_COUNT{gpu="3",UUID="GPU-843eece3-8d4c-82e2-0f6d-eddd48380b14",pci_bus_id="00000019:01:00.0",device="nvidia3",modelName="NVIDIA GB200",Hostname="b06-p1-dgx-06-c06",DCGM_FI_DRIVER_VERSION="570.172.08",window_size_in_ms="300000"} 0
    ----------------
    b06-p1-dgx-06-c07
    ----------------
    DCGM_EXP_XID_ERRORS_COUNT{gpu="3",UUID="GPU-2635e627-944b-5810-e599-78747aef0107",pci_bus_id="00000019:01:00.0",device="nvidia3",modelName="NVIDIA GB200",Hostname="b06-p1-dgx-06-c07",DCGM_FI_DRIVER_VERSION="570.172.08",window_size_in_ms="300000"} 0
    ----------------
    b06-p1-dgx-06-c08
    ----------------
    DCGM_EXP_XID_ERRORS_COUNT{gpu="3",UUID="GPU-059a99b0-8f4a-43ee-9e22-e843be6fbf78",pci_bus_id="00000019:01:00.0",device="nvidia3",modelName="NVIDIA GB200",Hostname="b06-p1-dgx-06-c08",DCGM_FI_DRIVER_VERSION="570.172.08",window_size_in_ms="300000"} 0
    ----------------
    b06-p1-dgx-06-c09
    ----------------
    DCGM_EXP_XID_ERRORS_COUNT{gpu="3",UUID="GPU-26d2e46e-ed78-f470-c5a1-09d9f76bb400",pci_bus_id="00000019:01:00.0",device="nvidia3",modelName="NVIDIA GB200",Hostname="b06-p1-dgx-06-c09",DCGM_FI_DRIVER_VERSION="570.172.08",window_size_in_ms="300000"} 0
    

Grafana and querying BCM metrics#

Access Grafana through the BCM head node at the HTTPS /grafana endpoint.

  1. Using a web browser, navigate to https://<headnode>/grafana.

    By default, the administrative account is admin. The password is generated at install time, this can be found by decoding the secret.:

    kubectl get secret -n prometheus kube-prometheus-stack-grafana -o jsonpath="{.data.admin-password}" | base64 --decode; echo
    
    Grafana login page
  2. Once authenticated, click on Explore on the left.

    Grafana Dashboard

    Once in the Explore interface, set the query editor to code and query the metric memorytotal.

  3. BCM provides many metrics out of the box, a list of which can be found in Grafana by using the Metric browser selecting all metrics which include the label job with the value external-bcmexporter.

    Grafana Metric browser
  4. Available metrics from BCM can also be found by inspecting the output of the BCM Prometheus exporter endpoint.

    The following CURL command will inspect the output of the BCM Prometheus exporter endpoint:

    curl -sk https://localhost:8081/exporter | grep -Ev '# HELP|# TYPE' | cut -d '{' -f1 | sort -u
    
    alertlevel
    ...
    writetime_total
    

Forward Run:ai Metrics to the BCM Prometheus Exporter (Optional)#

Start a Kubernetes port-forward in a detached screen session:

screen -d -m kubectl -n runai port-forward sts/prometheus-runai 8888:9090

Note

The port-forward does not survive a BCM head node reboot, and nothing restarts it automatically. Metric forwarding stops until you run the preceding command again. Terminating the screen session has the same effect.

Add a Prometheus metric forwarder in BCM that reads metrics from the Run:ai Prometheus federation pod:

cmsh
partition use base
prometheusmetricforwarders
add runai
set urls http://localhost:8888/federate?match%5B%5D=%7B__name__%3D~%22runai_.*%22%7D
set method get
commit

Validate that the metrics are exported, using curl. The label set is abbreviated in the following example:

curl -sk https://localhost:8081/exporter | grep '^runai_' | head -n2
runai_action_scheduling_latency_milliseconds{action="stalegangeviction",job="external-bcmexporter",namespace="prometheus",...} 0 1789483922392
runai_action_scheduling_latency_milliseconds{action="preempt",job="external-bcmexporter",namespace="prometheus",...} 0 1789483862392

Download the NVIS Run:ai dashboard:

wget https://support2.brightcomputing.com/nmc-obs-dashboards/nvis-runai-intelligence.json

Import the downloaded dashboard into Grafana:

  1. Select Dashboards in the left panel.

    The Grafana Dashboards page
  2. Select the New drop-down menu in the upper-right corner.

    The New drop-down menu in Grafana
  3. Select Import dashboard from the drop-down list.

  4. Select Upload dashboard JSON file.

    The Grafana dashboard import page
  5. Select the downloaded JSON file in the pop-up window.

    Selecting the dashboard JSON file
  6. Select a folder for the dashboard, if needed, and then select Import.

    Choosing a folder and importing the dashboard

Install NMC Grafana dashboards#

NVIDIA Mission Control provides a set of Grafana dashboards that consolidate monitoring data across the cluster. These dashboards help you track ongoing operations and troubleshoot issues. They serve as a starting point for visualizing infrastructure telemetry. Modify or extend them based on your facility’s capabilities.

Prerequisites#

Before installing the dashboards, configure rack metadata in BCM. Then install and configure the Infinity data source to process data from the BCM REST API and UFM REST API.

The NMC Grafana dashboards filter BCM metrics by rack using built-in queries and variables. If nodes are not assigned to racks in BCM, rack-scoped panels may display no data even when Prometheus is scraping metrics successfully.

Note

This procedure installs the Infinity plugin by listing it under grafana.plugins, which downloads the plugin from the internet. It is therefore for internet-connected installations only. For air-gapped deployments, install the plugin from the local registry instead by following Install NMC Grafana dashboards.

  1. Create the rack objects in BCM, using values that match your deployment:

    cmsh -c "rack; add <rack-name>; set height <rack-height>; set x-coordinate <x-coordinate>; set y-coordinate <y-coordinate>; commit"
    
  2. Assign each node to its rack and rack unit. Run this command once for each node:

    cmsh -c "device; use <node-name>; set rack <rack-name>; rackposition; deviceposition <rack-unit>; deviceheight <node-height>; commit"
    
  3. Confirm that BCM reports the rack for each node:

    cmsh -c "device; use <node-name>; get rack"
    
  4. Create a user to access the BCM REST API. Create user apiuser with a unique password of your choosing (do not reuse a shared or previously published value) with a read-only BCM profile:

    cmsh -c "user; add apiuser; set password <your-bcm-api-password>; set profile readonly; commit"
    
  5. Create a new file with the following values, substituting the BCM password you set above and your UFM REST API credentials. Keep each Infinity datasource’s allowed host scoped to its own API path:

    cat << EOF > grafana_infinity.yaml
    grafana:
      enabled: true
      plugins:
        - yesoreyeram-infinity-datasource
      additionalDataSources:
        - name: BCM API
          type: yesoreyeram-infinity-datasource
          access: proxy
          isDefault: false
          basicAuth: true
          basicAuthUser: apiuser
          jsonData:
            auth_method: 'basicAuth'
            allowedHosts:
              - https://master:8081/rest/v1/
            tlsSkipVerify: true
            timeoutInSeconds: 60
          secureJsonData:
            basicAuthPassword: <your-bcm-api-password>
        - name: UFM API
          type: yesoreyeram-infinity-datasource
          access: proxy
          isDefault: false
          basicAuth: true
          basicAuthUser: <your-ufm-api-user>
          jsonData:
            auth_method: 'basicAuth'
            allowedHosts:
              - https://master:11443/ufmRest/
            tlsSkipVerify: true
            timeoutInSeconds: 60
          secureJsonData:
            basicAuthPassword: <your-ufm-api-password>
    EOF
    
  6. Run the following command to apply the values

    helm upgrade kube-prometheus-stack prometheus-community/kube-prometheus-stack \
      -n prometheus -f grafana_infinity.yaml --reuse-values --version 87.18.0
    
  7. To access the UFM REST API, install a port-forwarding rule in BCM. Gather the UFM appliance IP address and substitute it in the following command sequence:

    cmsh
    partition use base
    ufmsettings
    set -e forward 443:11443
    commit
    

Add the Loki Data Source#

The Kubernetes installation wizard deploys Loki but does not register it as a Grafana data source. NVIDIA Mission Control dashboards that display service logs, such as [Heimdall] Job Manager, resolve their log panels through a Loki data source. Without it, those panels are empty even though Loki is receiving logs.

  1. Add the following entry to the additionalDataSources list in grafana_infinity.yaml:

    - name: Loki
      type: loki
      uid: loki
      url: http://loki-gateway.loki.svc.cluster.local:80
      access: proxy
      isDefault: false
    
  2. Apply the updated values:

    helm upgrade kube-prometheus-stack prometheus-community/kube-prometheus-stack \
      -n prometheus -f grafana_infinity.yaml --reuse-values --version 87.18.0
    
  3. In Grafana, select Connections > Data sources, select Loki, and confirm that the connection test succeeds.

Download#

The dashboards are packaged as a Helm chart (.tgz file). Download the package appropriate to the customer account type:

OEMs must have an NVOnline account with Site Access. Contact the NVIDIA account team to set up an account if needed.

Via NVIDIA Partners Portal - Content ID: 1151785

DGX Customers must be onboarded to NGC with entitlement to access the NMC collection to download the Helm chart directly.:

helm fetch "https://helm.ngc.nvidia.com/nvidia/nv-mission-control/charts/nmc-grafana-dashboards-27.3.8.tgz" \
  --username='$oauthtoken' \
  --password="$NGC_API_KEY"

Installation#

  1. Upload the dashboard chart (.tgz file) to the BCM head node. Run the following commands from the directory that contains the chart.

  2. Enable dashboard folders in Grafana.

    helm upgrade -n prometheus kube-prometheus-stack prometheus-community/kube-prometheus-stack \
      --reuse-values --version 87.18.0 \
      --set grafana.sidecar.dashboards.enabled=true \
      --set grafana.sidecar.dashboards.provider.foldersFromFilesStructure=true
    
  1. Extract the chart, keep only the dashboards for this platform, and install the repackaged chart. Update the input filename if needed.

    tar -xzvf nmc-grafana-dashboards-27.3.8.tgz -C /tmp/
    find /tmp/nmc-grafana-dashboards/dashboards -mindepth 1 -maxdepth 1 -type d ! -name 'b200' -exec rm -rf -- {} +
    tar -czvf /tmp/nmc-grafana-dashboards.tar.gz -C /tmp/ nmc-grafana-dashboards
    helm upgrade --install -n prometheus nmc-dashboards /tmp/nmc-grafana-dashboards.tar.gz --set dgx_system=b200
    
  1. Extract the chart, keep only the dashboards for this platform, and install the repackaged chart. Update the input filename if needed.

    tar -xzvf nmc-grafana-dashboards-27.3.8.tgz -C /tmp/
    find /tmp/nmc-grafana-dashboards/dashboards -mindepth 1 -maxdepth 1 -type d ! -name 'gb200' -exec rm -rf -- {} +
    tar -czvf /tmp/nmc-grafana-dashboards.tar.gz -C /tmp/ nmc-grafana-dashboards
    helm upgrade --install -n prometheus nmc-dashboards /tmp/nmc-grafana-dashboards.tar.gz --set dgx_system=gb200
    
  1. Extract the chart, keep only the dashboards for this platform, and install the repackaged chart. Update the input filename if needed.

    tar -xzvf nmc-grafana-dashboards-27.3.8.tgz -C /tmp/
    find /tmp/nmc-grafana-dashboards/dashboards -mindepth 1 -maxdepth 1 -type d ! -name 'b300' -exec rm -rf -- {} +
    tar -czvf /tmp/nmc-grafana-dashboards.tar.gz -C /tmp/ nmc-grafana-dashboards
    helm upgrade --install -n prometheus nmc-dashboards /tmp/nmc-grafana-dashboards.tar.gz --set dgx_system=b300
    
  1. Extract the chart, keep only the dashboards for this platform, and install the repackaged chart. Update the input filename if needed.

    tar -xzvf nmc-grafana-dashboards-27.3.8.tgz -C /tmp/
    find /tmp/nmc-grafana-dashboards/dashboards -mindepth 1 -maxdepth 1 -type d ! -name 'gb300' -exec rm -rf -- {} +
    tar -czvf /tmp/nmc-grafana-dashboards.tar.gz -C /tmp/ nmc-grafana-dashboards
    helm upgrade --install -n prometheus nmc-dashboards /tmp/nmc-grafana-dashboards.tar.gz --set dgx_system=gb300
    
  1. Extract the chart, keep only the dashboards for this platform, and install the repackaged chart. Update the input filename if needed.

    tar -xzvf nmc-grafana-dashboards-27.3.8.tgz -C /tmp/
    find /tmp/nmc-grafana-dashboards/dashboards -mindepth 1 -maxdepth 1 -type d ! -name 'vrnvl72' -exec rm -rf -- {} +
    tar -czvf /tmp/nmc-grafana-dashboards.tar.gz -C /tmp/ nmc-grafana-dashboards
    helm upgrade --install -n prometheus nmc-dashboards /tmp/nmc-grafana-dashboards.tar.gz --set dgx_system=vrnvl72
    

Accessing dashboards#

  1. In a browser, open: https://<headnode>/grafana

  2. Login using default credentials

  3. Navigate to Dashboards in the Grafana UI.

    Deployed dashboards will be denoted with a number, for example:

    1. 01. SuperPOD Overall Dashboard

Customization and BMS integration#

The dashboards included in this Helm chart are provided as examples. They are fully functional out of the box but are intended to be customized to match the customer’s specific cluster environment.

One dashboard, BMS View of Cluster, is configured to use NVIDIA Cronus as the Building Management System (BMS) data source. It displays power, liquid cooling, environmental, and other facility-level metrics.

Most customers will need to:

  1. Integrate their own BMS with NVIDIA BCM.

  2. Update the dashboard’s data source and queries to reflect their own BMS setup.

These dashboards serve as a starting point for visualizing infrastructure telemetry. The customer is encouraged to modify or extend them based on the facility’s capabilities and telemetry available. In some dashboards we show what filtering by rack can look like, but you might need to customize the filters to fit your situation.

Adapt Dashboards to Non-DGX Systems#

The bundled dashboards assume DGX naming conventions. Some PromQL queries match literal strings such as DGX GB200 Compute Tray and the GB300 and VR200 equivalents, and the DCGM scrape procedure assumes a BCM node category named dgx-gb200. On OEM and other non-DGX GB200, GB300, and VR200 systems, these strings differ, so panels return no data even when Prometheus scrapes successfully. Treat an empty panel as a configuration gap, not as a healthy system.

To adapt the dashboards to your environment, complete the following steps:

  1. Confirm your BCM category name. The procedures on this page use dgx-gb200 as an example. List your categories, and substitute your category name in every command that references dgx-gb200, including the image update, the pdsh service restart, and the address list in dcgm_prom_endpoint.yaml:

    cmsh -c "category; list"
    
  2. Assign rack metadata to every node. The dashboards filter BCM metrics by rack through built-in variables, so rack-scoped panels display no data until each node has a rack assignment. If you skipped this configuration, create the rack objects and set the rack and rack position of each node as described in steps 1 through 3 of Prerequisites.

  3. Normalize platform-specific strings at scrape time. In bcm_prom_svcmon.yaml, add a metricRelabelings block to the endpoint. The block maps the system-name or part-number string of your platform onto a canonical label that the dashboards can query. The following example maps every system name that contains Compute Tray to component_type="compute_tray":

    endpoints:
    - port: metrics
      interval: 30s
      path: /exporter
      scheme: https
      tlsConfig:
        insecureSkipVerify: true
      metricRelabelings:
      - sourceLabels: [system_name]
        regex: '.*Compute Tray.*'
        targetLabel: component_type
        replacement: compute_tray
    

    Set sourceLabels to the label that your exporter emits. The available labels depend on the PrometheusLabelInclude* settings that you enabled in Enable Prometheus scrape endpoint in BCM.

  4. Update the remaining dashboard queries. Export the dashboard JSON from Grafana, and search it for DGX, Compute Tray, GB200, GB300, and VR200. Replace each literal match with the canonical label from step 3 or with a dashboard variable. Also review template variable definitions, legend formats, value mappings, and any alert rules that reuse the same expressions.

Reduce BCM monitoring directory size#

BCM maintains an internal monitoring directory used for rendering data in BaseView. In larger clusters, this directory can grow significantly over time. On the BCM head node, use the following script to check current usage:

/cm/local/apps/cmd/scripts/monitoring/cm-monitoring-disk-usage.py

Once the observability stack configured in this section is collecting data, you can reduce the metrics storage requirements from BCM and depend on the data retention of Prometheus and Loki to store the cluster historical data. The following steps reduce the maximal monitoring directory size by disabling consolidators and setting appropriate sample limits for data producers.

  1. On the BCM head node, open cmsh and navigate to the monitoring setup context:

    [bcm-headnode-01]% monitoring
    [bcm-headnode-01->monitoring]% setup
    [bcm-headnode-01->monitoring->setup]%
    
  2. Disable consolidators for all monitoring data producers:

    [bcm-headnode-01->monitoring->setup]% foreach * (set consolidator none)
    [bcm-headnode-01->monitoring->setup*]% commit
    
  3. Configure the JobSampler to use bright sampling (rather than Both) and limit the maximum number of retained samples:

    [bcm-headnode-01->monitoring->setup]% use jobsampler
    [bcm-headnode-01->monitoring->setup[JobSampler]]% set maximalsamples 1024
    [bcm-headnode-01->monitoring->setup*[JobSampler*]]% jobmetricsettings
    [bcm-headnode-01->monitoring->setup*[JobSampler*]->jobmetricsettings]% set samplingtype bright
    [bcm-headnode-01->monitoring->setup*[JobSampler*]->jobmetricsettings*]% commit
    
  4. Set maximalsamples to 1024 for all data producers:

    [bcm-headnode-01->monitoring->setup]% foreach * (set maximalsamples 1024)
    [bcm-headnode-01->monitoring->setup*]% commit
    
  5. Disable monitoring backups:

    [bcm-headnode-01->monitoring->setup]% device
    [bcm-headnode-01->device]% foreach -t headnode (roles; use backup; set disabled yes)
    [bcm-headnode-01->device]% commit
    
  6. Verify the results:

    /cm/local/apps/cmd/scripts/monitoring/cm-monitoring-disk-usage.py
    

    Expected output after applying these settings:

    Number of used entities:      350724
    Number of used measurables:   20485
    Number of measurables:        20485
    Number of data producers:     105
    Number of consolidators:      2
    
    Current monitoring directory: /var/spool/cmd/monitoring
    Monitoring directory size:    68.671 GB
    Maximal directory size:       88.002 GB
    

    Note

    For lower numbers, clear the existing monitoring data after running these steps. Refer to section 14.8.4 of the BCM Administration Guide.

Configure Grafana Single Sign-On with Keycloak#

Configure Grafana to delegate user authentication to the nmc Keycloak realm. Before you begin, install Keycloak and the observability stack.

You need the following information and access:

  • Administrative access to Keycloak and Grafana.

  • The public Grafana hostname, represented as <grafana-hostname>.

  • The Keycloak hostname, represented as <keycloak-hostname>.

  • DNS records that let the Grafana pod resolve <keycloak-hostname>.

  • A trusted TLS certificate on each endpoint.

Configure the Grafana Public URL#

Grafana must advertise its public URL so that Keycloak can redirect users after authentication. Create /tmp/grafana-sso.yaml with the following content. Replace <grafana-hostname> with the hostname that users enter to access Grafana.

grafana:
  grafana.ini:
    server:
      root_url: https://<grafana-hostname>/grafana/
      serve_from_sub_path: true

Apply the values file with the command for your deployment.

helm upgrade kube-prometheus-stack prometheus-community/kube-prometheus-stack \
  -n prometheus --reuse-values -f /tmp/grafana-sso.yaml --version 87.18.0 \
  --wait --timeout 5m

Use the unpacked chart from your air-gapped installation bundle. The following example uses /tmp/airgapped/helm-charts; replace this path if you extracted the bundle elsewhere.

helm upgrade kube-prometheus-stack /tmp/airgapped/helm-charts/kube-prometheus-stack \
  -n prometheus --reuse-values -f /tmp/grafana-sso.yaml \
  --wait --timeout 5m

Create the Keycloak Client#

  1. Sign in to the Keycloak administration console.

    Keycloak administrator sign-in page
  2. Select Manage realms, and then select the nmc realm.

    Manage realms option in the Keycloak administration console NMC realm selected in the Keycloak administration console
  3. Select Clients > Create client.

    Create client option for the NMC realm
  4. Enter the following values, and then select Next:

    • Client type: OpenID Connect

    • Client ID: grafana-oauth

    • Name: Grafana

    OpenID Connect settings for the Grafana client
  5. Enable Client authentication, select Standard flow, and clear Direct access grants. Leave the other authentication flows disabled, and then select Next.

  6. Enter the following URLs, and then select Save:

    • Root URL: https://<grafana-hostname>/grafana/

    • Home URL: https://<grafana-hostname>/grafana/

    • Valid redirect URIs: https://<grafana-hostname>/grafana/login/generic_oauth

    • Valid post logout redirect URIs: https://<grafana-hostname>/grafana/

    • Web origins: https://<grafana-hostname>

    Login settings for the Grafana client in Keycloak
  7. Open the Credentials tab and copy the value from Client secret. Store this value in an approved credential store.

Warning

Treat the client secret as a credential. Do not include it in logs, screenshots, documentation, or source control. If the secret is exposed, regenerate it in Keycloak before you continue.

  1. Open the Client scopes tab and confirm that email, profile, and roles have the Default assigned type.

    Default client scopes assigned to the Grafana client

Enable Generic OAuth in Grafana#

  1. Sign in to Grafana as an administrator.

    Grafana administrator sign-in page
  2. Select Administration > Authentication > Generic OAuth.

    Authentication providers in Grafana administration settings
  3. Enter the following values:

    Table 4 Generic OAuth settings#

    Field

    Value

    Display name

    OAuth

    Client ID

    grafana-oauth

    Client secret

    The secret that you copied from Keycloak

    Scopes

    openid profile email

    Allow sign up

    Enabled

    Sign out redirect URL

    https://<keycloak-hostname>/realms/nmc/protocol/openid-connect/logout?post_logout_redirect_uri=https%3A%2F%2F<grafana-hostname>%2Fgrafana%2F&client_id=grafana-oauth

  4. Select Enter OpenID Connect Discovery URL, and then enter the following URL:

    https://<keycloak-hostname>/realms/nmc/.well-known/openid-configuration

    Grafana uses the discovery document to populate the authorization, token, and user information endpoints.

  5. Select Save and enable.

    Generic OAuth enabled in Grafana

Warning

Do not enable TLS skip verify in a production deployment. Configure Grafana to trust the certificate authority that issued the Keycloak certificate. Use TLS skip verify only for temporary testing, because it disables certificate and hostname validation.

Verify Single Sign-On#

  1. Open https://<grafana-hostname>/grafana/ in a private browser window.

  2. Select Sign in with OAuth.

    OAuth sign-in option on the Grafana login page
  3. Sign in with an authorized user from the nmc realm.

    NMC realm sign-in page displayed after the Grafana redirect

Note

Users must have an email address configured for Grafana generic OAuth/OIDC authentication. Without one, Grafana cannot retrieve the user information needed to complete sign-in.

  1. Confirm that Grafana opens after Keycloak authenticates the user.