Application Descriptor Specifications¶
Introduction¶
ICOS is an agnostic Meta Operating System. The aim of this document is to define the minimalist syntax required to provide ICOS with an agnostic Application Descriptor manifest to run on the ICOS system.
Application model¶
An application is made of a set of components plus the interaction between them. Different entities that do not make sense separately (for instance a Deployment and a Service exposing it) should be defined as part of the same component. Therefore, they will run in the same resources (which could be a list of nodes in the same cluster).
Note
having two manifests that have requirements in the same component does not make sense, because in fact we created the component so that we can group together entities that do not need computational resources with entities that need them. (Aka. Docker compose does this grouping and calls it a service).
Overall structure of the application Descriptor File¶
It has 2 mandatory sections: components and manifests. And three optional: requirements, policies and communication.
name: uc4-app-emds
description: "the description"
namespace: uc4
components:
- name: house-component
type: dcompose
manifests:
- name: house-manifest
manifests:
# List of manifests in the specified format
Components section¶
For each component we need to specify a name, a list of manifests belonging to this component and the type of the orchestration engine that the manifests are prepared for.
name: my_application
description: "the description"
[namespace: optional-namespace]
components:
- name: component-1
type: dcompose
manifests:
- name: comp-1-manifest
- name: component-2
type: kubernetes
manifests:
- name: comp-2-manifest-1
- name: comp-2-manifest-2
- name: component-3
type: multiple
manifests:
- name: comp-3-manifest1
Supported types are:
-
dcompose: A docker compose manifest is provided in the list of manifests.
-
kubernetes: A kubernetes manifest is provided.
-
multiple: Means that both a kubernetes and dcompose manifests are provided, this gives more flexibility to the icos system to schedule the components in any resource, regardless of the orchestration engine. Whereas if a component is specified type kubernetes, it can only be scheduled at kubernetes clusters
Note
In the current icos implementation it is not allowed to mix component types. I.e. if one of the components is type kubernetes, the rest should be either kubernetes or multiple, and the application will be scheduled at kubernetes clusters.
Requirements¶
Requirements section states the requested resources of the application. It can apply to all applications, in which case the section will appear at the same level as the components or to each component, in which case it will be specified under the component it applies to.
Note
At the moment the former option has not been implemented.
name: my_application
description: "my app description"
[namespace: optional-namespace]
components:
- name: component-1
type: dcompose
manifests:
- name: comp-1-manifest1
requirements:
architecture: intel
cpu: 0.5
memory: 200Mb
nodelabel:
key: <node-label-key>
values:
- <node-label-robot1>
- <node-label-robot2>
devices: squat.ai/video
replicas: 7
Accepted requirements are:
-
architecture: intel/x86_64 or arm64/aarch64
-
cpu: number of cpu cores requested.
-
memory: Amount of memory requested, the unit can be specified (following K8s syntax).
-
devices: devices that are necessary to be present for the component to run.
-
nodelabel: often the component is intended to run on specific nodes of the icos system (i.e. specific robots, specific houses, specific cars…). In that case a (key,value) pair can be specified to identify the nodes. Value can be a list of nodes, which would imply that replicas of the component will be deployed in all of the specified values (nodes)
-
replicas: specify the number of replicas of the component.
-
deployment/replicaset/job: to accommodate the k8s and dcompose workload types. If the previous requirements are specified under this tag it means that resources should be provided by the number of replicas specified but scheduled only once (i.e. the replicas are inside the manifest). See examples below.
A note on defining the requirements for the iCOS header¶
In k8s the smallest deployable units of computing are the Pods, therefore resources are allocated to Pods, whereas in ICOS the resource allocation unit is the component.
Because each container has its own resource needs, the user (Application developer) needs to abstract (add up) the needs of each container (which can be part of a workload management controller such as Deployment, ReplicaSets , Job in K8s…) that belong to the same component. Similarly, if a component contains several manifests each of them with their list of requirements, in the header the requirements for each manifest should be merged. I.e.
- manifests:
- apiVersion: apps/v1
kind: Deployment
metadata:
name: comp-2-manifest1
namespace: demo
labels:
app: video-producer
spec:
replicas: 1
selector:
matchLabels:
app: video-producer
template:
metadata:
name: video-producer
labels:
app: video-producer
spec:
containers:
- name: hello-cloud-one
image: busybox
command: [ 'sleep' ]
args: [ '100' ]
resources:
requests:
cpu: 0.5
memory: 200Mi
- manifests:
- apiVersion: apps/v1
kind: Deployment
metadata:
name: comp-2-manifest2
namespace: demo
labels:
app: video-producer
spec:
replicas: 1
selector:
matchLabels:
app: video-producer
template:
metadata:
name: video-producer
labels:
app: video-producer
spec:
containers:
- name: hello-cloud-two
image: busybox
command: [ 'sleep' ]
args: [ '100' ]
resources:
requests:
cpu: 0.5
memory: 200Mi
squat.io/video: 1
- name: component-2
type: kubernetes
manifests:
- name: comp-2-manifest1
- name: comp-2-manifest2
requirements:
devices: squat.ai/video
cpu: 1
memory: 400Mi
The implications of placing two manifests in the same component is that their requirements will be merged and a suitable target will be searched matching ALL the requirements from both components. Therefore, it is understood that if two manifests can run apart from each other they should belong to different components so that the matchmaking process has more options.
When considering replicas or workload management controller such as Deployment, ReplicaSets , Job that imply replicas for a better allocation they should belong to different components. Affinity between components can be specified in the communication section.
- manifests:
- apiVersion: apps/v1
kind: Deployment
metadata:
name: comp-2-manifest1
namespace: demo
labels:
app: video-producer
spec:
replicas: 5
selector:
matchLabels:
app: video-producer
template:
metadata:
name: video-producer
labels:
app: video-producer
spec:
containers:
- name: hello-cloud-two
image: busybox
command: [ 'sleep' ]
args: [ '100' ]
resources:
requests:
cpu: 0.5
memory: 200Mi
squat.io/video: 1
Would result in a header like:
- name: component-2
type: kubernetes
manifests:
- name: comp-2-manifest1
- name: comp-2-manifest2
requirements:
deployment:
replicas: 5
devices: squat.ai/video
cpu: 0.5
memory: 200Mi
Note
the management of replicas has not been implemented.
From Docker compose to ICOS header¶
An example for Docker compose:
version: '3.8'
services:
frontend:
image: example/webapp
deploy:
replicas: 6
resources:
reservations:
cpus: '0.25'
memory: 20M
The header would look like:
- name: component-1
type: kubernetes
manifests:
- name: comp-1-manifest1
requirements:
deployment:
replicas: 6
cpu: 0.25
memory: 20Mi
Scheduling or runtime?¶
When are requirements taken into account? In the current version at scheduling time only. However some of the requirements could be monitored and enforced at runtime too, in any case the remediation action to take would be defined by icos (i.e. migrate).
Policies¶
Policies are more dynamic than requirements. They are rules that can be defined by the user. As requirements, policies can be inside a component or outside if they apply to all the applications.
The syntax is as follows:
The rest of the dictionary entries depending on the type of policy. Supported types:
-
Security
-
Scheduler
-
Custom
Security policy¶
policies:
- name: securitypolicyexample
type: security
level:low # or médium high
[remediation_action: none # or default or migrate
functionality: encription]
Security level specifies the minimal security level for the application to run: low, medium or high. The system will define the thresholds.
Note
TODO: Provide a description for the meaning of each level (low, medium, high) in terms of usability (storage encryption or vulnerability level of the node)
Scheduling time or runtime? both
Custom policy¶
The metric and remediation action are provided by the user. Only runtime.
policies:
- name: my-policy
type: custom
fromTemplate: compss-under-allocation
remediation: scale-up
variables:
thresholdTimeSeconds: 120
compssTask: provesOtel.example_task
Scheduling policy¶
Scheduling policy is checked at scheduling type. It defines the scheduling strategy to use.
policies:
- name: scheduling-scoring
type: scheduler
algorithm: scoring
performance: 0.5
energyconsumption: 0.3
security:0.1
Comunication¶
This section specifies the relationship between the components in terms of communication between them (this is necessary in case the components run in different clusters so that ClusterLink can be set up). It will also be used at scheduling time to find a more accuratel allocation.
dependencies:
# any random name, can be optional
- name: ffmpeg-export
# name of the service that is exported, has to map to the service name defined in manifest
exportServiceName: mjpeg-service
# name of the component that the service belongs to, is used to determine where the export is created
exportingComponent: ffmpeg
# defines the port for the import and export (same for both)
port: 8080
# name of the component that the service has to be imported for, is used to determine where the import is created
importingComponent: mjpeg