PTP Metrics Exporter

Overview

The PTP Metrics Exporter is packaged as a system application and is managed using the system application and system helm-override commands.

The application runs as a Kubernetes DaemonSet, deploying one pod per labelled node. Each pod collects PTP synchronization statistics from ptp4l (via the read-only UDS socket), and from phc2sys and ts2phc (via their monitoring sockets), and exposes them in OpenMetrics format for consumption by monitoring tools such as Prometheus.

For in-cluster access, for example from Prometheus or other monitoring pods, use the Kubernetes service DNS name:

ptp-metrics-exporter.ptp-metrics-exporter.svc.cluster.local:9110

This headless service (clusterIP: None) resolves directly to the pod IPs of the exporter DaemonSet on each node. Individual pods can also be reached via their host IP or pod IP on port 9110.

Prerequisites

Before applying the application, PTP instance configuration files must exist at /etc/linuxptp/ptpinstance/ in the following format:

  • ptp4l-<instance>.conf — contains uds_ro_address in [global]

  • phc2sys-<instance>.conf — contains mon_socket_path in [global]

  • ts2phc-<instance>.conf — contains mon_socket_path in [global]

For examples of configuring PTP instances, see Example PTP Instance Configurations.

Procedure

  1. Apply the node label to each target node so that the DaemonSet schedules a pod on the node.

    ~(keystone_admin)]$ system host-label-assign <hostname> ptp-metrics-exporter=enabled
    
  2. Upload and apply the application.

    ~(keystone_admin)]$ system application-upload ptp-metrics-exporter-<version>.tgz
    ~(keystone_admin)]$ system application-apply ptp-metrics-exporter
    

Configuration Parameters

The exporter is configured through Helm chart values. Overrides can be applied using the system helm-override-update command.

Parameter

Default

Description

exporter.collectionIntervalPtp4lSeconds

60

The frequency, in seconds, for polling ptp4l via UDS.

exporter.collectionIntervalPhc2sysSeconds

60

The frequency, in seconds, for polling the phc2sys monitoring socket.

exporter.collectionIntervalTs2phcSeconds

60

The frequency, in seconds, for polling the ts2phc monitoring socket.

exporter.npProbeIntervalSeconds

60

Frequency at which disabled data sources (for example, OFFSET_STATS_NP) are re-probed.

exporter.ptp4lClockClassLockedList

"6,7,135"

Comma-separated clock classes considered “locked” for sync_state.

exporter.logLevel

INFO

Log verbosity (DEBUG, INFO, WARNING, ERROR).

service.port

9110

TCP port for the metrics HTTP endpoint.

nodeSelector.ptp-metrics-exporter

"enabled"

Node label selector for DaemonSet scheduling.

resources.requests.cpu

0

CPU request.

resources.limits.cpu

200m

CPU limit.

resources.requests.memory

0

Memory request.

resources.limits.memory

128Mi

Memory limit.

The following example overrides the ptp4l collection interval.

~(keystone_admin)]$ system helm-override-update ptp-metrics-exporter \
    ptp-metrics-exporter ptp-metrics-exporter \
    --set exporter.collectionIntervalPtp4lSeconds=2

Re-apply the application for the override to take effect.

~(keystone_admin)]$ system application-apply ptp-metrics-exporter

Architecture Overview

The exporter runs as a DaemonSet with one pod per labelled node. Each pod:

  1. Watches /host/etc/linuxptp/ptpinstance/ for configuration file changes (inotify).

  2. For each discovered ptp4l instance, polls via SOCK_DGRAM UDS at the configured interval.

  3. For each phc2sys or ts2phc instance, connects to the monitoring socket (SOCK_STREAM, JSON protocol).

  4. Stores collected data in an in-memory snapshot, rather than collecting on-demand per HTTP request.

  5. Serves /metrics from the snapshot, so HTTP serving never blocks on collection.

The pod uses the following volume mounts.

Container Path

Host Path

Mode

Purpose

/var/run

/var/run

RW

UDS sockets (the exporter creates a reply socket for DGRAM).

/host/proc

/proc

RO

psutil reads the phc2sys and ts2phc command line for configuration discovery.

/host/etc/linuxptp/ptpinstance

/etc/linuxptp/ptpinstance

RO

Configuration watcher (inotify).

/tmp

emptyDir (memory-backed, 32Mi)

RW

Python temporary files.

The exporter runs with the following security context:

  • Runs as non-root (UID 65534 / nobody).

  • Read-only root filesystem.

  • All Linux capabilities dropped.

  • No privilege escalation.

Results

The application is applied and the exporter pods are running on the labelled nodes. For the API reference describing the /metrics, /healthz, and /readyz endpoints and the full set of exported metrics, see the PTP Metrics Exporter API reference.

Troubleshooting Exporter Pods

Exporter Pods Fail to Schedule

Verify that the node label is present.

~(keystone_admin)]$ system host-label-list <hostname> | grep ptp-metrics-exporter

Add the label to the node if it is missing.

~(keystone_admin)]$ system host-label-assign <hostname> ptp-metrics-exporter=enabled

Metrics returning NaN

  • ptp4l not running or UDS socket missing: verify that /var/run/ptp4l-<instance>-ro exists on the host.

  • phc2sys or ts2phc not patched: verify that mon_socket_path is present in the daemon configuration and that the socket file exists.

  • summary_interval not configured or set to 0: stability metrics (ptp_offset_rms_ns, ptp_offset_mean_ns, ptp_offset_stddev_ns) report NaN because no meaningful aggregation occurs with a single sample.

Collection errors increasing

Check the ptp_exporter_source_state metric:

  • 0 (unknown) — probe pending; it is attempted at the next npProbeIntervalSeconds boundary.

  • 1 (enabled) — source healthy and being collected.

  • 2 (disabled) — source returned an error on probe. It is re-probed periodically. Verify that the daemon is running and that the socket exists.

Pod CrashLoopBackOff

Check the pod logs.

~(keystone_admin)]$ kubectl -n ptp-metrics-exporter logs -l app=ptp-metrics-exporter

Verifying the metrics endpoint manually

From the host, query the endpoints directly.

~(keystone_admin)]$ curl http://<pod-ip>:9110/metrics
~(keystone_admin)]$ curl http://<pod-ip>:9110/healthz
~(keystone_admin)]$ curl http://<pod-ip>:9110/readyz