Custom Discovery Handlers
Last updated
Was this helpful?
Last updated
Was this helpful?
Akri has with sample brokers and applications to demonstrate usage. However, there may be protocols you would like to use to discover resources that have not been implemented as Discovery Handlers yet. To enable the discovery of resources via a new protocol, you will implement a Discovery Handler (DH), which does discovery on behalf of the Agent. A Discovery Handler is anything that implements the DiscoveryHandler
service and Registration
client defined in the . These DHs run as their own Pods and are expected to register with the Agent, which hosts the Registration
service defined in the gRPC interface.
This document will walk you through the development steps to implement a Discovery Handler. If you would rather walk through an example, see Akri's , which walks through creating a Discovery Handler that discovers HTTP based devices. This document will also cover the steps to get your Discovery Handler added to Akri, should you wish to .
Before continuing, you may wish to reference the and documentation. They will provide a good understanding of Akri, how it works, and what components it is composed of.
A Discovery Handler can be written in any language using protobuf; however, Akri has provided a template for accelerating the development of Rust Discovery Handlers. This document will walk through both of those options. If using the Rust template, still read through the non-Rust section to gain context on the Discovery Handler interface.
This section covers how to use to create a Discovery Handler in the language of your choosing. It consists of three steps:
Registering your Discovery Handler with the Akri Agent
Specifying device filtering in a Configuration
Implementing the DiscoveryHandler
service
Discovery Handlers and Agents run on each worker Node in a cluster. A Discovery Handler should register with the Agent running on its Node at the Agent's registration socket, which defaults to /var/lib/akri/agent-registration.sock
. The directory can be changed when installing Akri by setting agent.host.discoveryHandlers
. For example, to request that the Agent's Registration
service live at ~/akri/sockets/agent-registration.sock
set agent.host.discoveryHandlers=~/akri/sockets
when installing Akri. The Agent hosts the Registration
service defined in on this socket.
When registering with the Agent, a Discovery Handler specifies its name (the one that will later be specified in Configurations), the endpoint of its Discovery Handler service, and whether the devices it discovers are shared (visible to multiple nodes).
Also note, that a Discovery Handler must also specify an EndpointType
of either UDS
or Network
in the RegisterDiscoveryHandlerRequest
. While Discovery Handlers must register with the Agent's Registration
service over UDS, a DiscoveryHandler
service can run over UDS or an IP based endpoint. However, the current convention is to use UDS for both registration and discovery.
When creating a Discovery Handler, you must decide what name to give it and add any details you would like your Discovery Handler to receive in the discovery_details
string. The Agent passes this string to Discovery Handlers as part of a DiscoverRequest
. A Discovery Handler must then parse this string -- Akri's built in Discovery Handlers store an expected structure in it as serialized YAML -- to determine what to discover, filter out of discovery, and so on.
For example, a Configuration that uses the ONVIF Discovery Handler, which allows filtering IP cameras by IP address, MAC address, and scopes, looks like the following.
The discoveryHandler.name
must match RegisterDiscoveryHandlerRequest.name
the Discovery Handler uses when registering with the Agent. Once you know what will be passed to your Discovery Handler, its time to implement the discovery functionality.
DiscoveryHandler
serviceNote, Discover
creates a streamed connection with the Agent, where the Agent gets the receiving end of the channel and the Discovery Handler sends device updates via the sending end of the channel. If the Agent drops its end, the Discovery Handler should stop discovery and attempt to re-register with the Agent. The Agent may drop its end due to an error or a deleted Configuration.
This template abstracts away the work of registering with the Agent and creating the Discovery Handler service. All you need to do is specify the Discovery Handler name, whether discovered devices are sharable, implement discovery, and build the Discovery Handler.
Specifying the Discovery Handler name and whether devices are sharable
Implementing discovery
A DiscoveryHandlerImpl
Struct has been created (in discovery_handler.rs
) that minimally implements the DiscoveryHandler
service. Fill in the discover
function, which returns the list of discovered devices
.
Build the Discovery Handler container
Build your Discovery Handler and push it to your container registry. To do so, we simply need to run this step from the base folder of the Akri repo:
Save the name of your image. We will pass it into our Akri installation command when we are ready to deploy our Discovery Handler.
Now that you have created a Discovery Handler, deploy Akri and see how it discovers the devices and creates Akri Instances for each Device.
Also set the name the Discovery Handler will register under (custom.configuration.discoveryHandlerName
) and a name for the Discovery Handler and Configuration (custom.discovery.name
and custom.configuration.name
). All these settings come together as the following Akri installation command:
Watch as the Agent, Controller, and Discovery Handler Pods are spun up and as Instances are created for each of the discovery devices.
Inspect the Instances' brokerProperties
. They will be set as environment variables in Pods that request the Instance's/device's resource.
The empty nginx brokers do not do anything with the devices they've requested. Exec into the Pods to confirm that the Device.properties
(Instance's brokerProperties
) were set as environment variables.
Now that you have a working Discovery Handler and broker, we'd love for you to contribute your code to Akri. The following steps will need to be completed to do so:
Create an Issue with a feature request for this Discovery Handler.
Implement your Discovery Handler and a document named /akri/docs/<name>-configuration.md
on how to create a Configuration that uses your Discovery Handler.
For a Discovery Handler to be considered fully implemented the following must be included in the PR.
A sample Configuration that uses the new protocol in the form of a Helm template and values.
(Optional) A sample end application that utilizes the services exposed by the Configuration
Github workflow[s] for broker [and sample app] to build containers and push to Akri container repository.
Discovery Handlers are passed information about what subset of devices to discover from a Configuration's discoveryDetails
. Akri's Configuration CRD takes in , which is defined structurally in Rust as follows:
The service should have all the functionality desired for discovering devices via your protocol and filtering for only the desired set. Each device a Discovery Handler discovers is represented by the Device
type, as shown in a subset of the below. A Discovery Handler sets a unique id
for the device, device connection information that needs to be set as environment variables in Pods that request the device in properties
, and any mounts or devices that should be available to requesting Pods.
Rust Discovery Handler development can be kick-started using Akri's and .
Install and use the tool to pull down Akri's template, specifying the name of the project with the --name
parameter.
Inside the newly created akri-discovery-handler
project, navigate to main.rs
. It contains all the logic to register our DiscoveryHandler
with the Akri Agent. We only need to specify the DiscoveryHandler
name and whether the devices discovered by our DiscoveryHandler
can be shared. This is the name the Discovery Handler uses when registering with the Agent. It is later specified in a Configuration to tell the Agent which Discovery Handler to use. For example, in Akri's , name
is set to udev
and shared
to false
as all devices are locally attached to nodes. The Discovery Handler name also resolves to the name of the socket the template serves the Discovery Handler on.
Akri has provided Helm templates for custom Discovery Handlers and their Configurations. These templates are provided as a starting point. They may need to be modified to meet the needs of a Discovery Handler. When installing Akri, specify that you want to deploy a custom Discovery Handler as a DaemonSet by setting custom.discovery.enabled=true
. Specify the container for that DaemonSet as the Discovery Handler that you built by setting custom.discovery.image.repository=$DH_IMAGE
and custom.discovery.image.repository=$TAGS
. To automatically deploy a custom Configuration, set custom.configuration.enabled=true
. Customize the Configuration's discovery_details
string to contain any filtering information: custom.configuration.discoveryDetails=<filtering info>
.
Note: Be sure to consult the to see whether your Kubernetes distribution needs any additional configuration.
Note: See for information on how to set the crictl configuration variable AKRI_HELM_CRICTL_CONFIGURATION
If you simply wanted Akri to expose discovered devices to the cluster as Kubernetes resources, you could stop here. If you have a workload that could utilize one of these resources, you could . Alternatively, you could have Akri automatically deploy workloads to discovered devices. We call these workloads brokers. To quickly see this, deploy empty nginx pods to discovered resources, by updating our Configuration to include a broker PodSpec.
Now that you can discover new devices, see our to utilize discovered devices.
Create a proposal and put in PR for it to be added to the .
Create a pull request, that includes Discovery Handler and Dockerfile in the and directories, respectively. Be sure to also update the minor version of Akri. See to learn more about our versioning strategy.
A new implementation
A for the new resource.
Dockerfile[s] for broker [and sample app] and associated update to the
Documentation on how to use the new sample Configuration, like the