edgefarm.network Examples¶
This section contains examples of how to use the edgefarm.network API.
Complex Example¶
This example explains a complex scenario of how edgefarm.network
can be used. The image shows the network architecture.
Let's assume there are two applications called app1
and app2
that are deployed together on the same Edge Nodes and need to communicate with each other to form a final result. app1
might generate some sensor data and app2
uses these sensor data and filters them e.g. using a geo-located fence. The results generated by app2
need to be transported to the cloud where they can be processed further. Further let's assume that there are differnt kinds of Edge Nodes. Some with small disk capacity and some with large disk capacity leading to different data retention capabilities.
To control the deployment we label our NodePools with app1/network=small
and app1/network=big
to distinguish between the different types of Edge Nodes.
Users¶
First the needed users are created in Network.spec.parameters.users
We create three users: app1
and app2
that can communicate with each other via some specific topics. app1
is able to publish some topics that app2
can subscribe to. In addition app2
is allowed to publish to topic3
. So, both apps can work toghether to form a final result published on topic3
by app2
. The user external-access
can only subscribe to topic3
.
Limits are set to -1
which means unlimited.
users:
- name: "app1" #(1)!
limits:
payload: -1
data: -1
subscriptions: -1
permissions:
pub:
allow:
- "topic1.>"
- "a.b.*.c.>"
deny: []
sub:
allow: []
deny: []
- name: "app2" #(2)!
limits:
payload: -1
data: -1
subscriptions: -1
permissions:
pub:
allow:
- "topic3"
deny: []
sub:
allow:
- "topic1.>"
- "a.b.*.c.>"
deny: []
- name: "external-access" #(3)!
limits:
payload: -1
data: -1
subscriptions: -1
permissions:
sub:
allow:
- "topic3"
deny: []
pub:
allow: []
deny: []
writeToSecret:
name: external-access-creds
app1
is only allowed to publish to specific topicsapp2
is allowed to subscribe to.app2
is allowed to subscribe toapp1
published topics is allowed to publish totopic3
.external-access
is only allowed to subscribe to a specific topic fromapp2
. The connection credentials are stored in a specific secret that is accessible by the user by reading a Kubernetes secret.
Subnetworks¶
Now let's describe the different storage capabilities of the Edge Nodes. The first type is a small embedded Linux device with very limited storage capabilities while the other is a full blown server with lots of storage. However, we want both types of devices to be able to communicate and to utilize their storage capabilities.
To achieve this we can create two subnetworks: small
and big
. The small
subnetwork will be used by the small embedded Linux devices while the big
subnetwork will be used by the full blown servers. This way stream can be created for different subnetworks and the storage capabilities of the devices can be used. Eventually, each node with the corresponding node pool labeled with "app1/network=small" or "app1/network=big" will have an instance of this network.
subNetworks:
- name: small
limits:
fileStorage: 300M
inMemoryStorage: 10M
nodepoolSelector:
matchLabels:
app1/network: small
- name: big
limits:
fileStorage: 10G
inMemoryStorage: 1000M
nodepoolSelector:
matchLabels:
app1/network: big
Streams¶
Let's create the streams that are needed for the applications to communicate with each other.
Streams can be added in Network.spec.parameters.streams
.
This example creates one stream for each subnetwork, with barly the same configuration. The difference is the data retention for the stream on the small
subnetwork is much shorter than the one on the big
subnetwork. Both streams are configured to behave the same way when it comes to collecting subjects.
These streams are meant for the user app1
to communicate with each other.
streams:
- name: app-stream-small #(1)!
type: Standard
subNetworkRef: small
config:
subjects:
- topic1.>
- a.b.*.c.>
retention: Limits
discard: Old
maxConsumers: -1
maxMsgs: -1
storage: File
maxBytes: 100000000 # 100MB
- name: app-stream-big #(2)!
type: Standard
subNetworkRef: big
config:
subjects:
- topic1.>
- a.b.*.c.>
retention: Limits
discard: Old
maxConsumers: -1
maxMsgs: -1
storage: File
maxBytes: 100000000 # 10GB
- name: results-stream-small #(3)!
type: Standard
subNetworkRef: small
config:
subjects:
- topic3
retention: Limits
discard: Old
maxConsumers: -1
maxMsgs: -1
storage: File
maxBytes: 200000000 # 200MB
- name: results-stream-big #(4)!
type: Standard
subNetworkRef: big
config:
subjects:
- topic3
retention: Limits
discard: Old
maxConsumers: -1
maxMsgs: -1
storage: File
maxBytes: 200000000 # 200MB
- name: aggregate-stream #(5)!
type: Aggregate
references:
- results-stream-small
- results-stream-big
config:
retention: Limits
discard: Old
maxConsumers: -1
maxMsgs: -1
storage: File
maxBytes: 200000000 # 20GB
- The stream for
app1
on thesmall
subnetwork has only the size of 100 MB due to limited storage capabilities. - The stream for
app1
on thebig
subnetwork has the size of 10 GB due to large storage capabilities. - The stream for
app2
on thesmall
subnetwork has only the size of 200 MB. This should be enough to store our final results. - The stream for
app2
on thebig
subnetwork is configured the same way as the one on thesmall
subnetwork. - The aggregate stream is used to aggregate the results from
app2
on thesmall
andbig
subnetwork. This stream is configured to have the size of 20 GB.
Final network manifest¶
Let's put the pieces together. See the final network manifest below.
apiVersion: streams.network.edgefarm.io/v1alpha1
kind: Network
metadata:
name: mynetwork
namespace: mynamespace
spec:
parameters:
users:
- name: "app1"
limits:
payload: -1
data: -1
subscriptions: -1
permissions:
pub:
allow:
- "topic1.>"
- "a.b.*.c.>"
deny: []
sub:
allow: []
deny: []
- name: "app2"
limits:
payload: -1
data: -1
subscriptions: -1
permissions:
pub:
allow:
- "topic3"
deny: []
sub:
allow:
- "topic1.>"
- "a.b.*.c.>"
deny: []
- name: "external-access"
limits:
payload: -1
data: -1
subscriptions: -1
permissions:
sub:
allow:
- "topic3"
deny: []
pub:
allow: []
deny: []
writeToSecret:
name: external-access-creds
subNetworks:
- name: small
limits:
fileStorage: 100M
inMemoryStorage: 10M
nodepoolSelector:
matchLabels:
app1/network: small
- name: big
limits:
fileStorage: 1G
inMemoryStorage: 10M
nodepoolSelector:
matchLabels:
app1/network: big
streams:
- name: app-stream-small #(1)!
type: Standard
subNetworkRef: small
config:
subjects:
- topic1.>
- a.b.*.c.>
retention: Limits
discard: Old
maxConsumers: -1
maxMsgs: -1
storage: File
maxBytes: 100000000 # 100MB
- name: app-stream-big #(2)!
type: Standard
subNetworkRef: big
config:
subjects:
- topic1.>
- a.b.*.c.>
retention: Limits
discard: Old
maxConsumers: -1
maxMsgs: -1
storage: File
maxBytes: 10000000000 # 10GB
- name: results-stream-small #(3)!
type: Standard
subNetworkRef: small
config:
subjects:
- topic3
retention: Limits
discard: Old
maxConsumers: -1
maxMsgs: -1
storage: File
maxBytes: 2000000 # 200MB
- name: results-stream-big #(4)!
type: Standard
subNetworkRef: big
config:
subjects:
- topic3
retention: Limits
discard: Old
maxConsumers: -1
maxMsgs: -1
storage: File
maxBytes: 2000000 # 200MB
- name: aggregate-stream #(5)!
type: Aggregate
references:
- results-stream-small
- results-stream-big
config:
retention: Limits
discard: Old
maxConsumers: -1
maxMsgs: -1
storage: File
maxBytes: 20000000000 # 20GB
Connect the applications to the network¶
Now that the network is created, the applications can be connected to the network. This is done by defining an edgefarm.applications
definition and using the special edgefarm-network
trait.
This is an example how the manifests look like for app1
and app2
.
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: app1
namespace: mynamespace
spec:
components: #(1)!
- name: app1-small
type: edgefarm-applications
properties:
name: app1
image: docker.io/myapp/app1:1.0.0
nodepoolSelector:
matchLabels:
app1/network: small
traits:
- type: edgefarm-network
properties:
network:
name: mynetwork
subnetwork: small #(2)!
user: app1
- name: app1-big
type: edgefarm-applications
properties:
name: app1
image: docker.io/myapp/app1:1.0.0
nodepoolSelector:
matchLabels:
app1/network: big
traits:
- type: edgefarm-network
properties:
network:
name: mynetwork
subnetwork: big #(3)!
user: app1
- We define two components representing
app1
in different subnetworks. Both components connect to the same network using the same user credentials but on different subnetworks. This way, both components running on different types of Edge Nodes can behave the same. - The
app1-small
component connects to thesmall
subnetwork. - The
app1-big
component connects to thebig
subnetwork.
The Application manifest for app2
looks pretty similar to the one for app1
.
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: app2
namespace: mynamespace
spec:
components:
- name: app2-small
type: edgefarm-applications
properties:
name: app2
image: docker.io/myapp/app2:1.0.0
nodepoolSelector:
matchLabels:
app1/network: small
traits:
- type: edgefarm-network
properties:
network:
name: mynetwork
subnetwork: small
user: app2
- name: app2-big
type: edgefarm-applications
properties:
name: app2
image: docker.io/myapp/app2:1.0.0
nodepoolSelector:
matchLabels:
app1/network: big
traits:
- type: edgefarm-network
properties:
network:
name: mynetwork
subnetwork: big
user: app2
Connect external applications to the network¶
To connect external applications to the network, the user external-access
can be used. The credentials for this user are stored in a Kubernetes secret. To read the creds file
for this user, use the following command:
$ kubectl get secrets -n mynamespace external-access-creds -o jsonpath='{.data.creds}' | base64 -d
-----BEGIN NATS USER JWT-----
eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ.eyJqdGkiOiJZVFNMWFhaT1hVUkkyQk9NWlc1N0hYUEg3UUozRE5MMklOV1VHSEdaV0xQR0NBUzNKQVBRIiwiaWF0IjoxNzAyNjM4MDY4LCJpc3MiOiJBQzNDSFhCNlJWT1hMR0ZIVEFIWEFFU1BBVkVOR1E2NjRXTk9aSEVGQ0tJUURMVkNJSTczVEVZTiIsInN1YiI6IlVEVkxVUE1TQzJPVExUMktEUU82VjRRSFZTWFZDWkpNNDJJVVY0NzJVQjdXRTRDQk8yUFZXVVhMIiwibmF0cyI6eyJwdWIiOnt9LCJzdWIiOnsiYWxsb3ciOlsidG9waWMzIiwiX0lOQk9YLlx1MDAzZSJdfSwic3VicyI6LTEsImRhdGEiOi0xLCJwYXlsb2FkIjotMSwidHlwZSI6InVzZXIiLCJ2ZXJzaW9uIjoyfX0.tXFgmL1J_uJYqbi2bCi-f9htJSPw8Jiv1n5NCsib8yZ4UwUFIwNuViBu4AlMDDaT4z2c73UH_M-o-b03Uu0CBw
------END NATS USER JWT------
************************* IMPORTANT *************************
NKEY Seed printed below can be used to sign and prove identity.
NKEYs are sensitive and should be treated as secrets.
-----BEGIN USER NKEY SEED-----
SUANAEIEIUD5ZOOE2P63QQKKOOC3A32JVY4X2IEV2S5AXATXVY7LDHSCWM
------END USER NKEY SEED------
*************************************************************
As edgefarm.network
uses NATS.io as the underlying messaging system, the credentials are in the form of a JWT token and a NKEY seed. The JWT token is used to authenticate the user while the NKEY seed is used to prove idendity.