Using PTP hardware

Precision Time Protocol (PTP) hardware is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. Red Hat does not recommend using them in production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process.

For more information about the support scope of Red Hat Technology Preview features, see https://access.redhat.com/support/offerings/techpreview/.

About PTP hardware

OKD allows you use Precision Time Protocol (PTP) hardware on your nodes. You can configure linuxptp services on nodes that have PTP-capable hardware.

The PTP Operator works with PTP-capable devices on clusters provisioned only on bare-metal infrastructure.

You can use the OKD console or oc CLI to install PTP by deploying the PTP Operator. The PTP Operator creates and manages the linuxptp services and provides the following features:

  • Discovery of the PTP-capable devices in the cluster.

  • Management of the configuration of linuxptp services.

  • Notification of PTP clock events that negatively affect the performance and reliability of your application with the PTP Operator cloud-event-proxy sidecar.

About PTP

The Precision Time Protocol (PTP) is used to synchronize clocks in a network. When used in conjunction with hardware support, PTP is capable of sub-microsecond accuracy, and is more accurate than Network Time Protocol (NTP).

The linuxptp package includes the ptp4l and phc2sys programs for clock synchronization. ptp4l implements the PTP boundary clock and ordinary clock. ptp4l synchronizes the PTP hardware clock to the source clock with hardware time stamping and synchronizes the system clock to the source clock with software time stamping. phc2sys is used for hardware time stamping to synchronize the system clock to the PTP hardware clock on the network interface controller (NIC).

Elements of a PTP domain

PTP is used to synchronize multiple nodes connected in a network, with clocks for each node. The following type of clocks can be included in configurations:

Grandmaster clock

The grandmaster clock provides standard time information to other clocks across the network and ensures accurate and stable synchronisation. The grandmaster clock writes time stamps and responds to time requests from other clocks.

Ordinary clock

The ordinary clock has a single port connection that can play the role of source or destination clock, depending on its position in the network. The ordinary clock can read and write time stamps.

Boundary clock

The boundary clock has ports in two or more communication paths and can be a source and a destination to other destination clocks at the same time. The boundary clock works as a destination clock upstream. The destination clock receives the timing message, adjusts for delay, and then creates a new source time signal to pass down the network. The boundary clock produces a new timing packet that is still correctly synced with the source clock and can reduce the number of connected devices reporting directly to the source clock.

Advantages of PTP over NTP

One of the main advantages that PTP has over NTP is the hardware support present in various network interface controllers (NIC) and network switches. The specialized hardware allows PTP to account for delays in message transfer and improves the accuracy of time synchronization. To achieve the best possible accuracy, it is recommended that all networking components between PTP clocks are PTP hardware enabled.

Hardware-based PTP provides optimal accuracy, since the NIC can time stamp the PTP packets at the exact moment they are sent and received. Compare this to software-based PTP, which requires additional processing of the PTP packets by the operating system.

Before enabling PTP, ensure that NTP is disabled for the required nodes. You can disable the chrony time service (chronyd) using a MachineConfig custom resource. For more information, see Disabling chrony time service.

Installing the PTP Operator using the CLI

As a cluster administrator, you can install the Operator by using the CLI.

Prerequisites

  • A cluster installed on bare-metal hardware with nodes that have hardware that supports PTP.

  • Install the OpenShift CLI (oc).

  • Log in as a user with cluster-admin privileges.

Procedure

  1. To create a namespace for the PTP Operator, enter the following command:

    1. $ cat << EOF| oc create -f -
    2. apiVersion: v1
    3. kind: Namespace
    4. metadata:
    5. name: openshift-ptp
    6. annotations:
    7. workload.openshift.io/allowed: management
    8. labels:
    9. name: openshift-ptp
    10. openshift.io/cluster-monitoring: "true"
    11. EOF
  2. To create an Operator group for the Operator, enter the following command:

    1. $ cat << EOF| oc create -f -
    2. apiVersion: operators.coreos.com/v1
    3. kind: OperatorGroup
    4. metadata:
    5. name: ptp-operators
    6. namespace: openshift-ptp
    7. spec:
    8. targetNamespaces:
    9. - openshift-ptp
    10. EOF
  3. Subscribe to the PTP Operator.

    1. Run the following command to set the OKD major and minor version as an environment variable, which is used as the channel value in the next step.

      1. $ OC_VERSION=$(oc version -o yaml | grep openshiftVersion | \
      2. grep -o '[0-9]*[.][0-9]*' | head -1)
    2. To create a subscription for the PTP Operator, enter the following command:

      1. $ cat << EOF| oc create -f -
      2. apiVersion: operators.coreos.com/v1alpha1
      3. kind: Subscription
      4. metadata:
      5. name: ptp-operator-subscription
      6. namespace: openshift-ptp
      7. spec:
      8. channel: "${OC_VERSION}"
      9. name: ptp-operator
      10. source: redhat-operators
      11. sourceNamespace: openshift-marketplace
      12. EOF
  4. To verify that the Operator is installed, enter the following command:

    1. $ oc get csv -n openshift-ptp \
    2. -o custom-columns=Name:.metadata.name,Phase:.status.phase

    Example output

    1. Name Phase
    2. ptp-operator.4.4.0-202006160135 Succeeded

Installing the PTP Operator using the web console

As a cluster administrator, you can install the PTP Operator using the web console.

You have to create the namespace and operator group as mentioned in the previous section.

Procedure

  1. Install the PTP Operator using the OKD web console:

    1. In the OKD web console, click OperatorsOperatorHub.

    2. Choose PTP Operator from the list of available Operators, and then click Install.

    3. On the Install Operator page, under A specific namespace on the cluster select openshift-ptp. Then, click Install.

  2. Optional: Verify that the PTP Operator installed successfully:

    1. Switch to the OperatorsInstalled Operators page.

    2. Ensure that PTP Operator is listed in the openshift-ptp project with a Status of InstallSucceeded.

      During installation an Operator might display a Failed status. If the installation later succeeds with an InstallSucceeded message, you can ignore the Failed message.

      If the operator does not appear as installed, to troubleshoot further:

      • Go to the OperatorsInstalled Operators page and inspect the Operator Subscriptions and Install Plans tabs for any failure or errors under Status.

      • Go to the WorkloadsPods page and check the logs for pods in the openshift-ptp project.

Automated discovery of PTP network devices

The PTP Operator adds the NodePtpDevice.ptp.openshift.io custom resource definition (CRD) to OKD.

The PTP Operator searchs your cluster for PTP-capable network devices on each node. It creates and updates a NodePtpDevice custom resource (CR) object for each node that provides a compatible PTP device.

One CR is created for each node and shares the same name as the node. The .status.devices list provides information about the PTP devices on a node.

The following is an example of a NodePtpDevice CR created by the PTP Operator:

  1. apiVersion: ptp.openshift.io/v1
  2. kind: NodePtpDevice
  3. metadata:
  4. creationTimestamp: "2019-11-15T08:57:11Z"
  5. generation: 1
  6. name: dev-worker-0 (1)
  7. namespace: openshift-ptp (2)
  8. resourceVersion: "487462"
  9. selfLink: /apis/ptp.openshift.io/v1/namespaces/openshift-ptp/nodeptpdevices/dev-worker-0
  10. uid: 08d133f7-aae2-403f-84ad-1fe624e5ab3f
  11. spec: {}
  12. status:
  13. devices: (3)
  14. - name: eno1
  15. - name: eno2
  16. - name: ens787f0
  17. - name: ens787f1
  18. - name: ens801f0
  19. - name: ens801f1
  20. - name: ens802f0
  21. - name: ens802f1
  22. - name: ens803
1The value for the name parameter is the same as the name of the node.
2The CR is created in openshift-ptp namespace by PTP Operator.
3The devices collection includes a list of the PTP capable devices discovered by the Operator on the node.

To return a complete list of PTP capable network devices in your cluster, run the following command:

  1. $ oc get NodePtpDevice -n openshift-ptp -o yaml

Configuring linuxptp services as ordinary clock

The PTP Operator adds the PtpConfig.ptp.openshift.io custom resource definition (CRD) to OKD. You can configure the linuxptp services (ptp4l, phc2sys) by creating a PtpConfig custom resource (CR) object.

Prerequisites

  • Install the OpenShift CLI (oc).

  • Log in as a user with cluster-admin privileges.

  • Install the PTP Operator.

Procedure

  1. Create the following PtpConfig CR, and then save the YAML in the ordinary-clock-ptp-config.yaml file.

    1. apiVersion: ptp.openshift.io/v1
    2. kind: PtpConfig
    3. metadata:
    4. name: ordinary-clock-ptp-config (1)
    5. namespace: openshift-ptp
    6. spec:
    7. profile: (2)
    8. - name: "profile1" (3)
    9. interface: "ens787f1" (4)
    10. ptp4lOpts: "-s -2" (5)
    11. phc2sysOpts: "-a -r" (6)
    12. ptp4lConf: "" (7)
    13. recommend: (8)
    14. - profile: "profile1" (9)
    15. priority: 10 (10)
    16. match: (11)
    17. - nodeLabel: "node-role.kubernetes.io/worker" (12)
    18. nodeName: "compute-0.example.com" (13)
    1The name of the PtpConfig CR.
    2Specify an array of one or more profile objects.
    3Specify the name of a profile object which uniquely identifies a profile object.
    4Specify the network interface name to use by the ptp4l service, for example ens787f1.
    5Specify system config options for the ptp4l service, for example -s -2. The options should not include the network interface name -i <interface> and service config file -f /etc/ptp4l.conf because the network interface name and the service config file are automatically appended.
    6Specify system config options for the phc2sys service, for example -a -r. If this field is empty the PTP Operator does not start the phc2sys service.
    7Specify a string that contains the configuration to replace the default /etc/ptp4l.conf file. To use the default configuration, leave the field empty.
    8Specify an array of one or more recommend objects which define rules on how the profile should be applied to nodes.
    9Specify the profile object name defined in the profile section.
    10Specify the priority with an integer value between 0 and 99. A larger number gets lower priority, so a priority of 99 is lower than a priority of 10. If a node can be matched with multiple profiles according to rules defined in the match field, the profile with the higher priority is applied to that node.
    11Specify match rules with nodeLabel or nodeName.
    12Specify nodeLabel with the key of node.Labels from the node object.
    13Specify nodeName with node.Name from the node object.
  2. Create the CR by running the following command:

    1. $ oc create -f ordinary-clock-ptp-config.yaml

Verification steps

  1. Check that the PtpConfig profile is applied to node.

    1. Get the list of pods in the openshift-ptp namespace by running the following command:

      1. $ oc get pods -n openshift-ptp -o wide

      Example output

      1. NAME READY STATUS RESTARTS AGE IP NODE
      2. linuxptp-daemon-4xkbb 1/1 Running 0 43m 10.1.196.24 compute-0.example.com
      3. linuxptp-daemon-tdspf 1/1 Running 0 43m 10.1.196.25 compute-1.example.com
      4. ptp-operator-657bbb64c8-2f8sj 1/1 Running 0 43m 10.129.0.61 control-plane-1.example.com
    2. Check that the profile is correct. Examine the logs of the linuxptp daemon that corresponds to the node you specified in the PtpConfig profile. Run the following command:

      1. $ oc logs linuxptp-daemon-4xkbb -n openshift-ptp

      Example output

      1. I1115 09:41:17.117596 4143292 daemon.go:107] in applyNodePTPProfile
      2. I1115 09:41:17.117604 4143292 daemon.go:109] updating NodePTPProfile to:
      3. I1115 09:41:17.117607 4143292 daemon.go:110] ------------------------------------
      4. I1115 09:41:17.117612 4143292 daemon.go:102] Profile Name: profile1
      5. I1115 09:41:17.117616 4143292 daemon.go:102] Interface: ens787f1
      6. I1115 09:41:17.117620 4143292 daemon.go:102] Ptp4lOpts: -s -2
      7. I1115 09:41:17.117623 4143292 daemon.go:102] Phc2sysOpts: -a -r
      8. I1115 09:41:17.117626 4143292 daemon.go:116] ------------------------------------

Configuring linuxptp services as boundary clock

The PTP Operator adds the PtpConfig.ptp.openshift.io custom resource definition (CRD) to OKD. You can configure the linuxptp services (ptp4l, phc2sys) by creating a PtpConfig custom resource (CR) object.

Prerequisites

  • Install the OpenShift CLI (oc).

  • Log in as a user with cluster-admin privileges.

  • Install the PTP Operator.

Procedure

  1. Create the following PtpConfig CR, and then save the YAML in the boundary-clock-ptp-config.yaml file.

    1. apiVersion: ptp.openshift.io/v1
    2. kind: PtpConfig
    3. metadata:
    4. name: boundary-clock-ptp-config (1)
    5. namespace: openshift-ptp
    6. spec:
    7. profile: (2)
    8. - name: "profile1" (3)
    9. interface: "" (4)
    10. ptp4lOpts: "-s -2" (5)
    11. ptp4lConf: | (6)
    12. [ens1f0] (7)
    13. masterOnly 0
    14. [ens1f3] (8)
    15. masterOnly 1
    16. [global]
    17. #
    18. # Default Data Set
    19. #
    20. twoStepFlag 1
    21. #slaveOnly 1
    22. priority1 128
    23. priority2 128
    24. domainNumber 24
    25. #utc_offset 37
    26. clockClass 248
    27. clockAccuracy 0xFE
    28. offsetScaledLogVariance 0xFFFF
    29. free_running 0
    30. freq_est_interval 1
    31. dscp_event 0
    32. dscp_general 0
    33. dataset_comparison G.8275.x
    34. G.8275.defaultDS.localPriority 128
    35. #
    36. # Port Data Set
    37. #
    38. logAnnounceInterval -3
    39. logSyncInterval -4
    40. logMinDelayReqInterval -4
    41. logMinPdelayReqInterval -4
    42. announceReceiptTimeout 3
    43. syncReceiptTimeout 0
    44. delayAsymmetry 0
    45. fault_reset_interval 4
    46. neighborPropDelayThresh 20000000
    47. masterOnly 0
    48. G.8275.portDS.localPriority 128
    49. #
    50. # Run time options
    51. #
    52. assume_two_step 0
    53. logging_level 6
    54. path_trace_enabled 0
    55. follow_up_info 0
    56. hybrid_e2e 0
    57. inhibit_multicast_service 0
    58. net_sync_monitor 0
    59. tc_spanning_tree 0
    60. tx_timestamp_timeout 10
    61. #was 1 (default !)
    62. unicast_listen 0
    63. unicast_master_table 0
    64. unicast_req_duration 3600
    65. use_syslog 1
    66. verbose 0
    67. summary_interval -4
    68. kernel_leap 1
    69. check_fup_sync 0
    70. #
    71. # Servo Options
    72. #
    73. pi_proportional_const 0.0
    74. pi_integral_const 0.0
    75. pi_proportional_scale 0.0
    76. pi_proportional_exponent -0.3
    77. pi_proportional_norm_max 0.7
    78. pi_integral_scale 0.0
    79. pi_integral_exponent 0.4
    80. pi_integral_norm_max 0.3
    81. step_threshold 0
    82. first_step_threshold 0.00002
    83. max_frequency 900000000
    84. clock_servo pi
    85. sanity_freq_limit 200000000
    86. ntpshm_segment 0
    87. #
    88. # Transport options
    89. #
    90. transportSpecific 0x0
    91. ptp_dst_mac 01:1B:19:00:00:00
    92. p2p_dst_mac 01:80:C2:00:00:0E
    93. udp_ttl 1
    94. udp6_scope 0x0E
    95. uds_address /var/run/ptp4l
    96. #
    97. # Default interface options
    98. #
    99. clock_type OC
    100. network_transport UDPv4
    101. delay_mechanism E2E
    102. time_stamping hardware
    103. tsproc_mode filter
    104. delay_filter moving_median
    105. delay_filter_length 10
    106. egressLatency 0
    107. ingressLatency 0
    108. boundary_clock_jbod 1
    109. #
    110. # Clock description
    111. #
    112. productDescription ;;
    113. revisionData ;;
    114. manufacturerIdentity 00:00:00
    115. userDescription ;
    116. timeSource 0xA0
    117. phc2sysOpts: "-a -r" (9)
    118. recommend: (10)
    119. - profile: "profile1" (11)
    120. priority: 10 (12)
    121. match: (13)
    122. - nodeLabel: "node-role.kubernetes.io/worker" (14)
    123. nodeName: "compute-0.example.com" (15)
    1The name of the PtpConfig CR.
    2Specify an array of one or more profile objects.
    3Specify the name of a profile object which uniquely identifies a profile object.
    4This field should remain empty for boundary clock.
    5Specify system config options for the ptp4l service, for example -s -2. The options should not include the network interface name -i <interface> and service config file -f /etc/ptp4l.conf because the network interface name and the service config file are automatically appended.
    6Specify the needed configuration to start ptp4l as boundary clock. For example, ens1f0 synchronizes from a grandmaster clock and ens1f3 synchronizes connected devices.
    7The interface name to synchronize from.
    8The interface to synchronize devices connected to the interface.
    9Specify system config options for the phc2sys service, for example -a -r. If this field is empty the PTP Operator does not start the phc2sys service.
    10Specify an array of one or more recommend objects which define rules on how the profile should be applied to nodes.
    11Specify the profile object name defined in the profile section.
    12Specify the priority with an integer value between 0 and 99. A larger number gets lower priority, so a priority of 99 is lower than a priority of 10. If a node can be matched with multiple profiles according to rules defined in the match field, the profile with the higher priority is applied to that node.
    13Specify match rules with nodeLabel or nodeName.
    14Specify nodeLabel with the key of node.Labels from the node object.
    15Specify nodeName with node.Name from the node object.
  2. Create the CR by running the following command:

    1. $ oc create -f boundary-clock-ptp-config.yaml

Verification steps

  1. Check that the PtpConfig profile is applied to node.

    1. Get the list of pods in the openshift-ptp namespace by running the following command:

      1. $ oc get pods -n openshift-ptp -o wide

      Example output

      1. NAME READY STATUS RESTARTS AGE IP NODE
      2. linuxptp-daemon-4xkbb 1/1 Running 0 43m 10.1.196.24 compute-0.example.com
      3. linuxptp-daemon-tdspf 1/1 Running 0 43m 10.1.196.25 compute-1.example.com
      4. ptp-operator-657bbb64c8-2f8sj 1/1 Running 0 43m 10.129.0.61 control-plane-1.example.com
    2. Check that the profile is correct. Examine the logs of the linuxptp daemon that corresponds to the node you specified in the PtpConfig profile. Run the following command:

      1. $ oc logs linuxptp-daemon-4xkbb -n openshift-ptp

      Example output

      1. I1115 09:41:17.117596 4143292 daemon.go:107] in applyNodePTPProfile
      2. I1115 09:41:17.117604 4143292 daemon.go:109] updating NodePTPProfile to:
      3. I1115 09:41:17.117607 4143292 daemon.go:110] ------------------------------------
      4. I1115 09:41:17.117612 4143292 daemon.go:102] Profile Name: profile1
      5. I1115 09:41:17.117616 4143292 daemon.go:102] Interface:
      6. I1115 09:41:17.117620 4143292 daemon.go:102] Ptp4lOpts: -s -2
      7. I1115 09:41:17.117623 4143292 daemon.go:102] Phc2sysOpts: -a -r
      8. I1115 09:41:17.117626 4143292 daemon.go:116] ------------------------------------

Troubleshooting common PTP Operator issues

Troubleshoot common problems with the PTP Operator by performing the following steps.

Prerequisites

  • Install the OKD CLI (oc).

  • Log in as a user with cluster-admin privileges.

  • Install the PTP Operator on a bare-metal cluster with hosts that support PTP.

Procedure

  1. Check the Operator and operands are successfully deployed in the cluster for the configured nodes.

    1. $ oc get pods -n openshift-ptp -o wide

    Example output

    1. NAME READY STATUS RESTARTS AGE IP NODE
    2. linuxptp-daemon-lmvgn 3/3 Running 0 4d17h 10.1.196.24 compute-0.example.com
    3. linuxptp-daemon-qhfg7 3/3 Running 0 4d17h 10.1.196.25 compute-1.example.com
    4. ptp-operator-6b8dcbf7f4-zndk7 1/1 Running 0 5d7h 10.129.0.61 control-plane-1.example.com

    When the PTP fast event bus is enabled, the number of ready linuxptp-daemon pods is 3/3. If the PTP fast event bus is not enabled, 2/2 is displayed.

  2. Check that supported hardware is found in the cluster.

    1. $ oc -n openshift-ptp get nodeptpdevices.ptp.openshift.io

    Example output

    1. NAME AGE
    2. control-plane-0.example.com 10d
    3. control-plane-1.example.com 10d
    4. compute-0.example.com 10d
    5. compute-1.example.com 10d
    6. compute-2.example.com 10d
  3. Check the available PTP network interfaces for a node:

    1. $ oc -n openshift-ptp get nodeptpdevices.ptp.openshift.io <node_name> -o yaml

    where:

    <node_name>

    Specifies the node you want to query, for example, compute-0.example.com.

    Example output

    1. apiVersion: ptp.openshift.io/v1
    2. kind: NodePtpDevice
    3. metadata:
    4. creationTimestamp: "2021-09-14T16:52:33Z"
    5. generation: 1
    6. name: compute-0.example.com
    7. namespace: openshift-ptp
    8. resourceVersion: "177400"
    9. uid: 30413db0-4d8d-46da-9bef-737bacd548fd
    10. spec: {}
    11. status:
    12. devices:
    13. - name: eno1
    14. - name: eno2
    15. - name: eno3
    16. - name: eno4
    17. - name: enp5s0f0
    18. - name: enp5s0f1
  4. Check that the PTP interface is successfully synchronized to the primary clock by accessing the linuxptp-daemon pod for the corresponding node.

    1. Get the name of the linuxptp-daemon pod and corresponding node you want to troubleshoot by running the following command:

      1. $ oc get pods -n openshift-ptp -o wide

      Example output

      1. NAME READY STATUS RESTARTS AGE IP NODE
      2. linuxptp-daemon-lmvgn 3/3 Running 0 4d17h 10.1.196.24 compute-0.example.com
      3. linuxptp-daemon-qhfg7 3/3 Running 0 4d17h 10.1.196.25 compute-1.example.com
      4. ptp-operator-6b8dcbf7f4-zndk7 1/1 Running 0 5d7h 10.129.0.61 control-plane-1.example.com
    2. Remote shell into the required linuxptp-daemon container:

      1. $ oc rsh -n openshift-ptp -c linuxptp-daemon-container <linux_daemon_container>

      where:

      <linux_daemon_container>

      is the container you want to diagnose, for example linuxptp-daemon-lmvgn.

    3. In the remote shell connection to the linuxptp-daemon container, use the PTP Management Client (pmc) tool to diagnose the network interface. Run the following pmc command to check the sync status of the PTP device, for example ptp4l.

      1. # pmc -u -f /var/run/ptp4l.0.config -b 0 'GET PORT_DATA_SET'

      Example output when the node is successfully synced to the primary clock

      1. sending: GET PORT_DATA_SET
      2. 40a6b7.fffe.166ef0-1 seq 0 RESPONSE MANAGEMENT PORT_DATA_SET
      3. portIdentity 40a6b7.fffe.166ef0-1
      4. portState SLAVE
      5. logMinDelayReqInterval -4
      6. peerMeanPathDelay 0
      7. logAnnounceInterval -3
      8. announceReceiptTimeout 3
      9. logSyncInterval -4
      10. delayMechanism 1
      11. logMinPdelayReqInterval -4
      12. versionNumber 2

About PTP and clock synchronization error events

Cloud native applications such as virtual RAN require access to notifications about hardware timing events that are critical to the functioning of the overall network. Fast event notifications are early warning signals about impending and real-time Precision Time Protocol (PTP) clock synchronization events. PTP clock synchronization errors can negatively affect the performance and reliability of your low latency application, for example, a vRAN application running in a distributed unit (DU).

Loss of PTP synchronization is a critical error for a RAN network. If synchronization is lost on a node, the radio might be shut down and the network Over the Air (OTA) traffic might be shifted to another node in the wireless network. Fast event notifications mitigate against workload errors by allowing cluster nodes to communicate PTP clock sync status to the vRAN application running in the DU.

Event notifications are available to RAN applications running on the same DU node. A publish/subscribe REST API passes events notifications to the messaging bus. Publish/subscribe messaging, or pub/sub messaging, is an asynchronous service to service communication architecture where any message published to a topic is immediately received by all the subscribers to the topic.

Fast event notifications are generated by the PTP Operator in OKD for every PTP-capable network interface. The events are made available using a cloud-event-proxy sidecar container over an Advanced Message Queuing Protocol (AMQP) message bus. The AMQP message bus is provided by the AMQ Interconnect Operator.

PTP fast event notifications are available only for network interfaces configured to use PTP ordinary clocks.

About the PTP fast event notifications framework

You can subscribe Distributed unit (DU) applications to Precision Time Protocol (PTP) fast events notifications that are generated by OKD with the PTP Operator and cloud-event-proxy sidecar container. You enable the cloud-event-proxy sidecar container by setting the enableEventPublisher field to true in the ptpOperatorConfig custom resource (CR) and specifying a transportHost address. PTP fast events use an Advanced Message Queuing Protocol (AMQP) event notification bus provided by the AMQ Interconnect Operator. AMQ Interconnect is a component of Red Hat AMQ, a messaging router that provides flexible routing of messages between any AMQP-enabled endpoints.

The cloud-event-proxy sidecar container can access the same resources as the primary vRAN application without using any of the resources of the primary application and with no significant latency.

The fast events notifications framework uses a REST API for communication and is based on the O-RAN REST API specification. The framework consists of a publisher, subscriber, and an AMQ messaging bus to handle communications between the publisher and subscriber applications. The cloud-event-proxy sidecar is a utility container that runs in a pod that is loosely coupled to the main DU application container on the DU node. It provides an event publishing framework that allows you to subscribe DU applications to published PTP events.

DU applications run the cloud-event-proxy container in a sidecar pattern to subscribe to PTP events. The following workflow describes how a DU application uses PTP fast events:

  1. DU application requests a subscription: The DU sends an API request to the cloud-event-proxy sidecar to create a PTP events subscription. The cloud-event-proxy sidecar creates a subscription resource.

  2. cloud-event-proxy sidecar creates the subscription: The event resource is persisted by the cloud-event-proxy sidecar. The cloud-event-proxy sidecar container sends an acknowledgment with an ID and URL location to access the stored subscription resource. The sidecar creates an AMQ messaging listener protocol for the resource specified in the subscription.

  3. DU application receives the PTP event notification: The cloud-event-proxy sidecar container listens to the address specified in the resource qualifier. The DU events consumer processes the message and passes it to the return URL specified in the subscription.

  4. cloud-event-proxy sidecar validates the PTP event and posts it to the DU application: The cloud-event-proxy sidecar receives the event, unwraps the cloud events object to retrieve the data, and fetches the return URL to post the event back to the DU consumer application.

  5. DU application uses the PTP event: The DU application events consumer receives and processes the PTP event.

Installing the AMQ messaging bus

To pass PTP fast event notifications between publisher and subscriber on a node, you must install and configure an AMQ messaging bus to run locally on the node. You do this by installing the AMQ Interconnect Operator for use in the cluster.

Prerequisites

  • Install the OKD CLI (oc).

  • Log in as a user with cluster-admin privileges.

Procedure

Verification

  1. Check that the AMQ Interconnect Operator is available and the required pods are running:

    1. $ oc get pods -n amq-interconnect

    Example output

    1. NAME READY STATUS RESTARTS AGE
    2. amq-interconnect-645db76c76-k8ghs 1/1 Running 0 23h
    3. interconnect-operator-5cb5fc7cc-4v7qm 1/1 Running 0 23h
  2. Check that the required linuxptp-daemon PTP event producer pods are running in the openshift-ptp namespace.

    1. $ oc get pods -n openshift-ptp

    Example output

    1. NAME READY STATUS RESTARTS AGE
    2. linuxptp-daemon-2t78p 3/3 Running 0 12h
    3. linuxptp-daemon-k8n88 3/3 Running 0 12h

Configuring the PTP fast event notifications publisher

To start using PTP fast event notifications for a network interface in your cluster, you must enable the fast event publisher in the PTP Operator PtpOperatorConfig custom resource (CR) and configure ptpClockThreshold values in a PtpConfig CR that you create.

Prerequisites

  • Install the OKD CLI (oc).

  • Log in as a user with cluster-admin privileges.

  • Install the PTP Operator and AMQ Interconnect Operator.

Procedure

  1. Modify the spec.ptpEventConfig field of the PtpOperatorConfig resource and set appropriate values by running the following command:

    1. $ oc edit PtpOperatorConfig default -n openshift-ptp
    1. ...
    2. spec:
    3. daemonNodeSelector:
    4. node-role.kubernetes.io/worker: ""
    5. ptpEventConfig:
    6. enableEventPublisher: true (1)
    7. transportHost: amqp://<instance_name>.<namespace>.svc.cluster.local (2)
    1Set enableEventPublisher to true to enable PTP fast event notifications.
    2Set transportHost to the AMQ router you configured where <instance_name> and <namespace> correspond to the AMQ Interconnect router instance name and namespace, for example, amqp://amq-interconnect.amq-interconnect.svc.cluster.local
  2. Create a PtpConfig custom resource for the PTP enabled interface, and set the required values for ptpClockThreshold, for example:

    1. apiVersion: ptp.openshift.io/v1
    2. kind: PtpConfig
    3. metadata:
    4. name: example-ptpconfig
    5. namespace: openshift-ptp
    6. spec:
    7. profile:
    8. - name: "profile1"
    9. interface: "enp5s0f0"
    10. ptp4lOpts: "-2 -s --summary_interval -4"
    11. phc2sysOpts: "-a -r -m -n 24 -N 8 -R 16"
    12. ptpClockThreshold:
    13. holdOverTimeout: 5 (1)
    14. maxOffsetThreshold: 100 (2)
    15. minOffsetThreshold: -100 (3)
    16. recommend:
    17. - profile: "profile1"
    18. priority: 4
    19. match:
    20. - nodeLabel: "node-role.kubernetes.io/worker"
    1Number of seconds to stay in the clock holdover state. Holdover state is the period between local and master clock synchronizations.
    2Maximum offset value in nanoseconds. Offset is the time difference between the local and master clock.
    3Minimum offset value in nanoseconds.

PTP fast event notifications REST API reference

You can use the PTP fast event notifications REST API to subscribe an application to the PTP events that are generated for the parent node. PTP fast events notifications are available on each node where a PTP capable network interface is configured.

You can subscribe DU applications to PTP event notifications by using the resource address /cluster/node/<node_name>/ptp, where <node_name> is the cluster node running the DU application.

Status request are sent by making a REST API PUT call to /subscriptions/status/<subscription_id>. The API call returns events through the AMQP event bus to the subscribed address.

The PTP fast events notifications REST API is served at [http://localhost:8080/](http://localhost:8080/) by default. The following API endpoints are available:

  • /api/cloudNotifications/v1/publishers

    • POST: Creates a new publisher

    • GET: Retrieves a list of publishers

  • /api/cloudNotifications/v1/publishers/<publisher_id>

    • GET: Creates a new status ping request for the specified publisher id
  • /api/cloudNotifications/v1/subscriptions

    • POST: Creates a new subscription

    • GET: Retrieves a list of subscriptions

  • /api/cloudNotifications/v1/subscriptions/<subscription_id>

    • GET: Creates a new status ping request for the specified subscription id
  • api/cloudNotifications/v1/subscriptions/status/<subscription_id>

    • PUT: Creates a new status ping request for the specified subscription id
  • /api/cloudNotifications/v1/health

    • GET: Returns the health status of cloudNotifications API

api/cloudNotifications/v1/publishers

HTTP method

POST api/cloudNotifications/v1/publishers

Description

Creates a new publisher. If publisher creation is successful, or if it already exists, a 201 Created status code is returned.

Table 1. Query parameters
ParameterType

publisher

data

Example payload

  1. {
  2. "id": "56e8a064-dc4b-4428-8085-91c18ea07930",
  3. "endpointUri": "http://localhost:8080/api/cloudNotifications/v1/dummy",
  4. "uriLocation": "http://localhost:8080/api/cloudNotifications/v1/publishers/56e8a064-dc4b-4428-8085-91c18ea07930",
  5. "resource": "/cluster/node/compute-1.example.com/ptp"
  6. }

Example oc exec curl command

  1. $ oc exec -it linuxptp-daemon-5j265 -n openshift-ptp -c cloud-event-proxy -- curl --location --request POST 'http://localhost:8080/api/cloudNotifications/v1/publishers' --header 'Content-Type: application/json' --insecure --data ' {
  2. "id": "56e8a064-dc4b-4428-8085-91c18ea07930",
  3. "endpointUri": "http://localhost:8080/api/cloudNotifications/v1/dummy",
  4. "uriLocation": "http://localhost:8080/api/cloudNotifications/v1/publishers/56e8a064-dc4b-4428-8085-91c18ea07930",
  5. "resource": "/cluster/node/compute-1.example.com/ptp"
  6. }'

HTTP method

GET api/cloudNotifications/v1/publishers

Description

Returns a list of publishers. If publishers exist, a 200 OK status code is returned along with the list of publishers.

Example oc exec curl command

  1. $ oc exec -it linuxptp-daemon-5j265 -n openshift-ptp -c cloud-event-proxy -- curl --location http://localhost:8080/api/cloudNotifications/v1/publishers

Example return

  1. [
  2. {
  3. "id": "56e8a064-dc4b-4428-8085-91c18ea07930",
  4. "endpointUri": "http://localhost:8080/api/cloudNotifications/v1/dummy",
  5. "uriLocation": "http://localhost:8080/api/cloudNotifications/v1/publishers/56e8a064-dc4b-4428-8085-91c18ea07930",
  6. "resource": "/cluster/node/compute-1.example.com/ptp"
  7. }
  8. ]

api/cloudNotifications/v1/publishers/<publisher_id>

HTTP method

GET api/cloudNotifications/v1/publishers/<publisher_id>

Description

Returns the publisher with id <publisher_id>.

Table 2. Query parameters
ParameterType

<publisher_id>

string

Example oc exec curl command

  1. $ oc exec -it linuxptp-daemon-5j265 -n openshift-ptp -c cloud-event-proxy -- curl --location http://localhost:8080/api/cloudNotifications/v1/publishers/56e8a064-dc4b-4428-8085-91c18ea07930

Example return

  1. {
  2. "id":"56e8a064-dc4b-4428-8085-91c18ea07930",
  3. "endpointUri":"http://localhost:8080/api/cloudNotifications/v1/dummy",
  4. "uriLocation":"http://localhost:8080/api/cloudNotifications/v1/publishers/56e8a064-dc4b-4428-8085-91c18ea07930",
  5. "resource":"/cluster/node/compute-1.example.com/ptp"
  6. }

api/cloudNotifications/v1/subscriptions

HTTP method

GET api/cloudNotifications/v1/subscriptions

Description

Returns a list of subscriptions. If subscriptions exist, a 200 OK status code is returned along with the list of subscriptions.

Example oc exec curl command

  1. $ oc exec -it linuxptp-daemon-5j265 -n openshift-ptp -c cloud-event-proxy -- curl --location http://localhost:8080/api/cloudNotifications/v1/subscriptions

Example return

  1. [
  2. {
  3. "id": "75b1ad8f-c807-4c23-acf5-56f4b7ee3826",
  4. "endpointUri": "http://localhost:8080/api/cloudNotifications/v1/dummy",
  5. "uriLocation": "http://localhost:8080/api/cloudNotifications/v1/subscriptions/75b1ad8f-c807-4c23-acf5-56f4b7ee3826",
  6. "resource": "/cluster/node/compute-1.example.com/ptp"
  7. }
  8. ]

HTTP method

POST api/cloudNotifications/v1/subscriptions

Description

Creates a new subscription. If a subscription is successfully created, or if it already exists, a 201 Created status code is returned.

Table 3. Query parameters
ParameterType

subscription

data

Example payload

  1. {
  2. "id": "56e8a064-dc4b-4428-8085-91c18ea07930",
  3. "endpointUri": "http://localhost:8080/api/cloudNotifications/v1/dummy",
  4. "uriLocation": "http://localhost:8080/api/cloudNotifications/v1/subscriptions/56e8a064-dc4b-4428-8085-91c18ea07930",
  5. "resource": "/cluster/node/compute-1.example.com/ptp"
  6. }

Example oc exec curl command

  1. $ oc exec -it linuxptp-daemon-5j265 -n openshift-ptp -c cloud-event-proxy -- curl --location --request POST 'http://localhost:8080/api/cloudNotifications/v1/subscriptions' --header 'Content-Type: application/json' --insecure --data ' {
  2. "id": "56e8a064-dc4b-4428-8085-91c18ea07930",
  3. "endpointUri": "http://localhost:8080/api/cloudNotifications/v1/dummy",
  4. "uriLocation": "http://localhost:8080/api/cloudNotifications/v1/subscriptions/75b1ad8f-dc4b-4428-8085-91c18ea07930",
  5. "resource": "/cluster/node/compute-1.example.com/ptp"
  6. }'

api/cloudNotifications/v1/subscriptions/<subscription_id>

HTTP method

GET api/cloudNotifications/v1/subscriptions/<subscription_id>

Description

Returns details for the subscription with id <subscription_id>

Table 4. Query parameters
ParameterType

<subscription_id>

string

Example oc exec curl command

  1. $ oc exec -it linuxptp-daemon-5j265 -n openshift-ptp -c cloud-event-proxy -- curl --location http://localhost:8080/api/cloudNotifications/v1/subscriptions/48210fb3-45be-4ce0-aa9b-41a0e58730ab

Example return

  1. {"id":"48210fb3-45be-4ce0-aa9b-41a0e58730ab","endpointUri":"http://localhost:8080/api/cloudNotifications/v1/dummy","uriLocation":"http://localhost:8080/api/cloudNotifications/v1/subscriptions/48210fb3-45be-4ce0-aa9b-41a0e58730ab","resource":"/cluster/node/compute-1.example.com/ptp"}

api/cloudNotifications/v1/subscriptions/status/<subscription_id>

HTTP method

PUT api/cloudNotifications/v1/subscriptions/status/<subscription_id>

Description

Creates a new status ping request for subscription with id <subscription_id>. If a subscription is present, the status request is successful and a 202 Accepted status code is returned.

Table 5. Query parameters
ParameterType

<subscription_id>

string

Example oc exec curl command

  1. $ oc exec -it linuxptp-daemon-5j265 -n openshift-ptp -c cloud-event-proxy -- curl --location --request PUT http://localhost:8080/api/cloudNotifications/v1/subscriptions/status/48210fb3-45be-4ce0-aa9b-41a0e58730ab

Example output

  1. {"status":"ping sent"}

api/cloudNotifications/v1/health/

HTTP method

GET api/cloudNotifications/v1/health/

Description

Returns the health status for the cloudNotifications REST API.

Example oc exec curl command

  1. $ oc exec -it linuxptp-daemon-5j265 -n openshift-ptp -c cloud-event-proxy -- curl --location http://localhost:8080/api/cloudNotifications/v1/health

Example return

  1. OK

Monitoring PTP fast event metrics using the CLI

You can monitor fast events bus metrics directly from cloud-event-proxy containers using the oc CLI.

PTP fast event notification metrics are also available in the OKD web console.

Prerequisites

  • Install the OKD CLI (oc).

  • Log in as a user with cluster-admin privileges.

  • Install and configure the PTP Operator.

Procedure

  1. Get the list of active linuxptp-daemon pods.

    1. $ oc get pods -n openshift-ptp

    Example output

    1. NAME READY STATUS RESTARTS AGE
    2. linuxptp-daemon-2t78p 3/3 Running 0 8h
    3. linuxptp-daemon-k8n88 3/3 Running 0 8h
  2. Access the metrics for the required cloud-event-proxy container by running the following command:

    1. $ oc exec -it <linuxptp-daemon> -n openshift-ptp -c cloud-event-proxy -- curl 127.0.0.1:9091/metrics

    where:

    <linuxptp-daemon>

    Specifies the pod you want to query, for example, linuxptp-daemon-2t78p.

    Example output

    1. # HELP cne_amqp_events_published Metric to get number of events published by the transport
    2. # TYPE cne_amqp_events_published gauge
    3. cne_amqp_events_published{address="/cluster/node/compute-1.example.com/ptp/status",status="success"} 1041
    4. # HELP cne_amqp_events_received Metric to get number of events received by the transport
    5. # TYPE cne_amqp_events_received gauge
    6. cne_amqp_events_received{address="/cluster/node/compute-1.example.com/ptp",status="success"} 1019
    7. # HELP cne_amqp_receiver Metric to get number of receiver created
    8. # TYPE cne_amqp_receiver gauge
    9. cne_amqp_receiver{address="/cluster/node/mock",status="active"} 1
    10. cne_amqp_receiver{address="/cluster/node/compute-1.example.com/ptp",status="active"} 1
    11. cne_amqp_receiver{address="/cluster/node/compute-1.example.com/redfish/event",status="active"}
    12. ...

Monitoring PTP fast event metrics in the web console

You can monitor PTP fast event metrics in the OKD web console by using the pre-configured and self-updating Prometheus monitoring stack.

Prerequisites

  • Install the OKD CLI oc.

  • Log in as a user with cluster-admin privileges.

Procedure

  1. Enter the following command to return the list of available PTP metrics from the cloud-event-proxy sidecar container:

    1. $ oc exec -it <linuxptp_daemon_pod> -n openshift-ptp -c cloud-event-proxy -- curl 127.0.0.1:9091/metrics

    where:

    <linuxptp_daemon_pod>

    Specifies the pod you want to query, for example, linuxptp-daemon-2t78p.

  2. Copy the name of the PTP metric you want to query from the list of returned metrics, for example, cne_amqp_events_received.

  3. In the OKD web console, click ObserveMetrics.

  4. Paste the PTP metric into the Expression field, and click Run queries.

Additional resources