Roles

A service is composed of a set of microservices. As we have mentioned earlier on microservices are the result of instantiating multiple times a component.

However, a component simply specifies how a piece of code can be started to constitute an instance of a microsevice.

In a service, the same component could be run playing multiple roles. Think, for instance of a postgress database. In a service we could have different Postgress database microservices, each one with its own persistent volume, serving different purposes, probably configured very differently one from each other.

Kumori’s service model captures this variability through its `role`concept. A role is just a specification of how a microservice based on some artifact must be deployed (it is actually more general, as we will see when discussing multi versions, and sub-services).

More specificallly let us look at how roles are specified within a Kumori service application:

role: [string]: #Role

That is, roles are specified as a dictionary, where entries are the role names.

Role themselves have the following definition:

#Role: #Deployment & {
	...
}

#Deployment: {
   name:      string
   artifact:  #Artifact
   config:    #Configurable | {[string]: #Configurable}
   meta:      {...}
}

So, essentially, a #Role is a #Deployment, with some constraints that play a role when spreading the deployment configuration.

The most common case will be when a role is implemented by a single component, in which case we provide a #ComponentArtifact. However, as will be shown in a later section it will also be useful to allow more general services as the implementation of a role, in which case a #ServiceArtifact will be employed

Role configuration

Field config is intended to define how the configuration of the artifact implementing a role should be set based on the configuration of the service itself.

In its simplest form, field config defines a structure that must fit the configuration structure of the artifact implementing the role. The values it provides for each field will be derived from the values of the service’s own configuration.

At deployment time, values provided in the deployment manifest will be spread first to the configuration section of the service, and, from there downwards to each artifact implementing a role, according to this config field.

The process is recursive: if an artifact is itself a service application, the config field will spread the deployment config to the config of the service, which, in turn, will be spread to the config of the artifacts of its own roles.

More generally, field config can represent a dictionary of #Configurable. Each field of the structure representing a subset of instances of the role with different configurations. This feature is WIP.

We now have a look at some of the fields.

Scaling

The scale component of the config is used to specify scaling properties of the role. This part of the specification can refer to the scaling part of the service app configuration. When the role is based on a component, the scale field of the config must have at least an hsize field with a numeric value (0 or positive). It may also have a qos field that will be spread to the component manifest and can be used to configure its vertical size.

config: scale: #ScaleSpec

#ScaleSpec: {
  #servers: string
  #roles:   string

  ["qos"]: [#servers]: #QoSSpec

  ["detail"]: [#roles]: #ScaleSpec

  // MUST be used by (and it is only valid for) component roles
  ["hsize"]: uint
}

This property sets the scaling parameters for the role:

  • The qos field, when present, sets that the role must be configured to withstand a given load (in requests per second) with the given maximum response time. The field will be typically derived from the qos field set in the scale field of the service config.

  • The detail can be derived from the scale of the service config, or, by default, it can follow the detail provided on deployment. A detail field cannot be provided when the role is implemented by a component.

  • The hsize field can only be provided for a component-backed role (and it should be provided in this case)

  • The maximum number of instances allowed for a component role can be set by providing the limit within the scale field of the component’s config, if the caracteristic is set by the component, or by the restriction in the hsize field of the role, if it belongs to the service definition

Resilience

The resilience field of the config gives a hint to the platform to ensure that instances are placed in a suffiently large number of availbaility zones, so that a resilience number of failures cannot take the microservice down.

This parameter should probably be derived from the resilience of the service application itself.

Role vsets

Kumori’s service model has provisions to represent multiple implementations of the same role. This is useful in a variety of scenarios, particularly in controlled upgrade paths for a role.

The abstraction Kumori Platform uses is that of tags associated to client channels to access the different versions of a microservice behind a connector, as shown when discussing a components' configuration.

While the tag approach is quite general, our current expression of the model exposes it through version sets.

A role in a service application belongs by default to its own vset with its same name. The default vset of a role only has that role within the vset. However, a role can belong to many non-default vsets.