Skip to content

Latest commit

 

History

History
239 lines (188 loc) · 13.9 KB

README.md

File metadata and controls

239 lines (188 loc) · 13.9 KB

Eclipse Symphony

Symphony, as a toolchain orchestrator, is designed to provide consistent, end-to-end management workflows across heterogeneous edge environments. Key features include:

  • Deploying distributed applications and device updates across various device types.
  • Managing workflows with distributed stages, such as running tests on remote machines and collecting results.
  • Centrally managing configurations with context-specific overrides.

Symphony provides flexible options to connect to underlying systems like Eclipse BlueChi, Eclipse Pullpiri and Eclipse Ankaios, as shown in the following diagram. A key construct of extension is called a provider. Symphony allows extensions with two types of providers:

  • A Target Provider that participates in Symphony's state-seeking process, such as applying a software to a custom system.
  • A Stage Provider that participates in Symphony's distributed workflow, such as running a task on a specific machine.

For this challenge, we'll mostly focus on the target providers. However, we are also open to scenarios that leverage custom stage providers.

Symphony

  1. Symphony offers a collection of native providers to interact with common software deployment and management tools like Helm, Docker, Azure IoT Edge, Device Update for IoT Hub, Windows 10/11 Sideloading and Kubernetes artifacts.

  2. Symphony also welcome contributions of providers, such as the recent Eclipse Pullpiri provider contributed by LGE.

  3. Symphony supports a remote agent written in any programming language and communicates with the Symphony control plane over MQTT. A remote agent can:

    • Participate in Symphony state-seeking process, such as applying software to a custom system.
    • Participate in Symphony workflow, such as running a task on a specific system.

    For example, Eclipse Ankaios is exploring this route using Symphony's Python SDK (PoC).

  4. Symphony also provides a pre-built agent over MQTT. This full-featured agent is able to load additional providers, such as a script provider that can perform software update operations using PowerShell or Bash. This route can be used for USB-attached devices such as flashing a RTOS system.

  5. Symphony also allows a remote agent to implement Symphony target provider interface as a web server. Although this can be used for a remote agent, it's more commonly used in a sidecar pattern for process isolation on the same control plane (such as granting minimum required access to a provider process).

  6. Similar to the MQTT-based agent, Symphony also provides a pre-built agent over HTTP that is able to load additional providers, such as a script provider.

  7. For constrained devices, you can implement a pulling agent, which is essentially a web client querying Symphony for stated states for the represented target devices. Symphony offers a sample pulling agent named Piccolo that supports Docker, WebAssembly and eBPF payloads. Piccolo is written in Rust and is 4MB in side. We anticipate even smaller pulling agents can be authored for the most constrained devices.

  8. The script provider can also be directly loaded to the Symphony control plane. This can be used for cases like managing cloud-based resources, or resources co-located with the control plane itself.

  9. Symphony provides HTTP(S) and MQTT binding out-of-box. Additional protocols like CAN can be supported with additional protocol bindings.

Installing Symphony

Using Maestro

You can use Symphony's CLI, maestro, to install Symphony. To get maestro, run this command:

wget -q https://raw.githubusercontent.com/eclipse-symphony/symphony/master/cli/install/install.sh -O - | /bin/bash

And once maestro is installed, you can use this command to install Symphony to your current K8s context:

maestro up

NOTE: If you don't have a current K8s context, maestro can install Minikube on your machine first and then install Symphony. Because Minikube can't assign a public IP, the post-command condition check will fail. Use Ctrl+C to stop the command. You'll still be able to access Symphony using kubectl.

Using Helm

Alternatively, you can use Helm (v3) to install Symphony on to a Kubernetes cluster such as AKS, K3s and Minikube:

helm install symphony oci://ghcr.io/eclipse-symphony/helm/symphony --version '0.48.32'

NOTE: For this hackathon, make sure to use the 0.48.32 version.

Basic usage of Symphony

Once you've installed Symphony, you can use standard K8s tools like kubectl to interact with Symphony. Essentially, you need to create Solution objects that describe your applications, Target objects that describe your infrastructure, and Instance objects that describe an deployment, which maps a Solution to one mor multiple Targets.

A Solution is comprised of one or multiple Component, and each Component has an associated type. Corresponding, a Target has one or more bindings that bind a component type to a Target Provider.

You can follow instructions here to deploying a hello-world solution to K8s using Symphony. And additional scenarios can be found here.

Deploy a MQTT broker

In this hackathon, we'll use a MQTT broker to facilitate communication between Symphony and the remote agent, which you'll run from your machine or on your target device. We offer a sample deployment file at eclispe-symphony/mosquitto/mosquitto.yaml, which you can use to deploy a mosquitto test MQTT broker with anoymous access enabled.

kubectl apply -f eclipse-symphony/mosquitto/mosquitto.yaml

Once deployment is complete, you should see a mosquitto-service service in your service list. This will the broker your agents connect to.

kubectl get svc
NAME                TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)
...
mosquitto-service   LoadBalancer   10.0.231.136   172.179.118.100   1883:32640/TCP
...

If you are using Minikube, you'll need to use K8s port forwarding to expose the service to your local machine. Then, you'll be able to access the MQTT broker through tcp://localhost:1883.

kubectl port-forward svc/mosquitto-service 1883:1883

Prepare truck templates

When a truck docks at a field office, a Symphony workflow (Campaign) is executed to register the truck as a Target object with Symphony, using a predefined truck template. We offer four sample truck templates (as Catalog objects) under the eclipse-symphony/truck-templates folder:

Template (Catalog) Description
mock-truck.yaml A truck that uses a mock Target provider, which doesn't do any actual deployments.
reefer-truck.yaml A reefer truck with built-in refrigeration units to transport perishable goods like food and pharmaceuticals.
box-truck.yaml A Trucks with enclosed cargo areas.
flatbed-truck.yaml A Truck with an open, flat trailer, used for transporting large, heavy items that don’t fit within standard truck dimensions.

Except for the mock-truck, all truck templates are configured to use a MQTT Target Provider that delegate state-seeking calls to a remote agent, which you'll set up later.

To provision these templates, simply use the kubectl command from the truck-templates folder:

kubectl apply -f eclipse-symphony/truck-templates/.

Once the Catalogs are provisioned, you can use kubectl to list them out (Each Catalog belongs to a CatalogContainer, which can contain multiple versions of the Catalog):

kubectl get catalogcontainer

NAME            AGE
box-truck       8s
flatbed-truck   8s
mock-truck      5m33s
reefer-truck    102s

kubectl get catalog

NAME                 AGE
box-truck-v-v1       12s
flatbed-truck-v-v1   12s
mock-truck-v-v1      5m36s
reefer-truck-v-v1    106s

NOTE: If you are using a local mosquitto broker, you need to update brokerAddress in the templates to tcp://localhost:1883.

Prepare the truck docking workflow

The truck docking workflow is defined as a Symphony Campaign object. To define the docker working flow:

kubectl apply -f eclipse-symphony/workflows/docking.yaml

Deploy Symphony sample portal (Opera)

To deploy Symphony sample portal, review the eclipse-symphony/portal/opera-deployment.yaml file. Especially, if you want to use OpenAI features, you need to set OPENAI_API_KEY to your OpenAI API key. Then, you can deploy the portal using kubectl:

kubectl apply -f eclipse-symphony/portal/opera-deployment.yaml

If you are using Minikube, you'll need to use K8s port forwarding to expose the service to your local machine.

kubectl port-forward svc/opera-service 3000:3000

Docking a mock truck

To test out the docking workflow, you can create an Activation object to activate the above Campaign. For example, the following activation activates the docking workflow using the mock-truck template:

apiVersion: workflow.symphony/v1
kind: Activation
metadata:
  name: mock-truck-docking-activation
spec:
  campaign: "docking:v1"
  stage: ""
  inputs:    
    truck-template: mock-truck:v1

To apply the activation, use kubectl:

kubectl apply -f <your activation file>

NOTE: You can use the provided *-activation.yaml files to activate the workflow for different truck types.

NOTE: Once an activation is created it can't be updated, as it serves as workflow executiong record. To re-activate a campaign, you'll need to re-create the activation object (by deleting it and recreating it), or to create a new activation object.

If you've activated the workflow for all truck templates, you should see a number of Target objects created:

kubectl get target

NAME            STATUS
box-truck       Succeeded
flatbed-truck   Succeeded
mock-truck      Succeeded
reefer-truck    Succeeded

You can also see these targets on the Opera targets view if you've deployed Opera: opera

Generating a Symphony agent configuration

You can generate a Symphony Agent configuration file using maestro (see Installing Symphony section for instructions to install maestro using a single command).

Run maestro with the following paramters:

Parameter Value
--mqtt-broker MQTT broker address. If you've deployed MQTT broker as instructed above, you should set this value to the public IP of your mosquitto-service, for example tcp://172.179.118.110:1883 or tcp://localhost:1883.
--mqtt-client-id An unique MQTT client id of your choice.
--target Symphony Target object name that this agent represents. This needs to match with the Symphony Target object name.
--config-only Use this flag to generate the configuration file only. Otherwise, the agent will be directly launched.

For example:

maestro agent --mqtt-broker tcp://172.179.118.110:1883 --mqtt-client-id box-truck --target box-truck --config-only

The above command generates a symphony-agent-box-truck.json file under the <you home>/.symphony folder. We also provides sample agent configuration files under the eclipse-symphony/agent folder for your reference.

Customizing the agent configuration file

By default, the generated agent configuration file uses a mock Target provider (providers.target.mock). You can switch to a different Target Provider as needed - such as using a script provider, a Docker provider, or a custom provider (requires rebuild Symphony binary).

For example, instead of the default mock provider:

"box-truck": {
  "type": "providers.target.mock",
  "config": {}
},

You can switch to a Docker provider:

"box-truck": {
  "type": "providers.target.docker",
  "config": {}
},

Launching the agent

Once you've created the customized agent configuration file, you can launch a new instance of Symphony Agent through command line:

~/.symphony/symphony-api -c <your agent configuration file> -l Debug
# for example
~/.symphony/symphony-api -c ~/.symphony/symphony-agent-box-truck.json -l Debug

Deploying sample applications

We offer a few sample applications that you can use for quick tests.

Solution Target Instance Description
box-solution.yaml box-truck box-instance.yaml Deploy a Redis container to the box truck, which uses a Docker provider

To define and deploy the box truck application

 kubectl apply -f eclipse-symphony/solution/box-solution.yaml 
 kubectl apply -f eclipse-symphony/solution/box-instance.yaml

This deployes a Redis container to your target machine. If you use docker ps you should see the container running. Optionally, you can use docker rm -r <container id> to remove the container and observe Symphony brings it back to its desired state.

To delete the app, use:

kubectl delete instance box-instance

You should obseve the Docker container removed from your machine.